#include <aligner.h>


Public Member Functions | |
| virtual EMData * | align (EMData *this_img, EMData *to_img, const string &cmp_name="dot", const Dict &cmp_params=Dict()) const |
| To align 'this_img' with another image passed in through its parameters. | |
| virtual EMData * | align (EMData *this_img, EMData *to_img) const |
| virtual string | get_name () const |
| Get the Aligner's name. | |
| virtual string | get_desc () const |
| virtual TypeDict | get_param_types () const |
Static Public Member Functions | |
| static Aligner * | NEW () |
Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision. Uses quaternions extensively, separates the in plane (phi) rotation and the 2 rotations that define a point on the sphere (POTS), manipulating them independently. The POTS is"jiggled" in a local circular sub manifold of the sphere (of radius stepdelta). Phi is allowed to vary as a normal variable. The result is combined into a single transform and then a similarity is computed, etc. Translation also varies.
Definition at line 595 of file aligner.h.
| EMData * Refine3DAligner::align | ( | EMData * | this_img, | |
| EMData * | to_img, | |||
| const string & | cmp_name = "dot", |
|||
| const Dict & | cmp_params = Dict() | |||
| ) | const [virtual] |
To align 'this_img' with another image passed in through its parameters.
The alignment uses a user-given comparison method to compare the two images. If none is given, a default one is used.
| this_img | The image to be compared. | |
| to_img | 'this_img" is aligned with 'to_img'. | |
| cmp_name | The comparison method to compare the two images. | |
| cmp_params | The parameter dictionary for comparison method. |
Implements EMAN::Aligner.
Definition at line 1229 of file aligner.cpp.
References EMAN::EMData::get_ndim(), EMAN::EMData::get_xsize(), EMAN::Dict::has_key(), ImageDimensionException, NullPointerException, EMAN::Aligner::params, phi, EMAN::EMData::process(), refalifn3d(), refalin3d_perturb(), EMAN::EMData::set_attr(), EMAN::Dict::set_default(), status, t, x, and y.
Referenced by align().
01231 { 01232 01233 if (!to || !this_img) throw NullPointerException("Input image is null"); // not sure if this is necessary, it was there before I started 01234 01235 if (to->get_ndim() != 3 || this_img->get_ndim() != 3) throw ImageDimensionException("The Refine3D aligner only works for 3D images"); 01236 01237 float saz = 0.0; 01238 float sphi = 0.0; 01239 float salt = 0.0; 01240 float sdx = 0.0; 01241 float sdy = 0.0; 01242 float sdz = 0.0; 01243 bool mirror = false; 01244 Transform* t; 01245 if (params.has_key("xform.align3d") ) { 01246 // Unlike the 2d refine aligner, this class doesn't require the starting transform's 01247 // parameters to form the starting guess. Instead the Transform itself 01248 // is perturbed carefully (using quaternion rotation) to overcome problems that arise 01249 // when you use orthogonally-based Euler angles 01250 t = params["xform.align3d"]; 01251 }else { 01252 t = new Transform(); // is the identity 01253 } 01254 01255 int np = 6; // the number of dimensions 01256 Dict gsl_params; 01257 gsl_params["this"] = this_img; 01258 gsl_params["with"] = to; 01259 gsl_params["snr"] = params["snr"]; 01260 gsl_params["mirror"] = mirror; 01261 gsl_params["transform"] = t; 01262 01263 const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex; 01264 gsl_vector *ss = gsl_vector_alloc(np); 01265 01266 float stepx = params.set_default("stepx",1.0f); 01267 float stepy = params.set_default("stepy",1.0f); 01268 float stepz = params.set_default("stepz",1.0f); 01269 // Default step is 5 degree - note in EMAN1 it was 0.1 radians 01270 float half_circle_step = 180.0f; // This shouldn't be altered 01271 float stepphi = params.set_default("stephi",5.0f); 01272 float stepdelta = params.set_default("stepdelta",5.0f); 01273 01274 gsl_vector_set(ss, 0, stepx); 01275 gsl_vector_set(ss, 1, stepy); 01276 gsl_vector_set(ss, 2, stepz); 01277 gsl_vector_set(ss, 3, half_circle_step); 01278 gsl_vector_set(ss, 4, stepdelta); 01279 gsl_vector_set(ss, 5, stepphi); 01280 01281 gsl_vector *x = gsl_vector_alloc(np); 01282 gsl_vector_set(x, 0, sdx); 01283 gsl_vector_set(x, 1, sdy); 01284 gsl_vector_set(x, 2, sdz); 01285 gsl_vector_set(x, 3, saz); 01286 gsl_vector_set(x, 4, salt); 01287 gsl_vector_set(x, 5, sphi); 01288 01289 gsl_multimin_function minex_func; 01290 Cmp *c = Factory < Cmp >::get(cmp_name, cmp_params); 01291 gsl_params["cmp"] = (void *) c; 01292 minex_func.f = &refalifn3d; 01293 01294 minex_func.n = np; 01295 minex_func.params = (void *) &gsl_params; 01296 01297 gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, np); 01298 gsl_multimin_fminimizer_set(s, &minex_func, x, ss); 01299 01300 int rval = GSL_CONTINUE; 01301 int status = GSL_SUCCESS; 01302 int iter = 1; 01303 01304 float precision = params.set_default("precision",0.04f); 01305 int maxiter = params.set_default("maxiter",60); 01306 while (rval == GSL_CONTINUE && iter < maxiter) { 01307 iter++; 01308 status = gsl_multimin_fminimizer_iterate(s); 01309 if (status) { 01310 break; 01311 } 01312 rval = gsl_multimin_test_size(gsl_multimin_fminimizer_size(s), precision); 01313 } 01314 01315 int maxshift = params.set_default("maxshift",-1); 01316 01317 if (maxshift <= 0) { 01318 maxshift = this_img->get_xsize() / 4; 01319 } 01320 float fmaxshift = static_cast<float>(maxshift); 01321 EMData *result; 01322 if ( fmaxshift >= (float)gsl_vector_get(s->x, 0) && fmaxshift >= (float)gsl_vector_get(s->x, 1) && fmaxshift >= (float)gsl_vector_get(s->x, 2)) 01323 { 01324 float x = (float)gsl_vector_get(s->x, 0); 01325 float y = (float)gsl_vector_get(s->x, 1); 01326 float z = (float)gsl_vector_get(s->x, 2); 01327 01328 float arc = (float)gsl_vector_get(s->x, 3); 01329 float delta = (float)gsl_vector_get(s->x, 4); 01330 float phi = (float)gsl_vector_get(s->x, 5); 01331 01332 Transform tsoln = refalin3d_perturb(t,delta,arc,phi,x,y,z); 01333 01334 result = this_img->process("math.transform",Dict("transform",&tsoln)); 01335 result->set_attr("xform.align3d",&tsoln); 01336 01337 } else { // The refine aligner failed - this shift went beyond the max shift 01338 result = this_img->process("math.transform",Dict("transform",t)); 01339 result->set_attr("xform.align3d",t); 01340 } 01341 01342 delete t; 01343 t = 0; 01344 01345 gsl_vector_free(x); 01346 gsl_vector_free(ss); 01347 gsl_multimin_fminimizer_free(s); 01348 01349 if ( c != 0 ) delete c; 01350 return result; 01351 }
| virtual EMData* EMAN::Refine3DAligner::align | ( | EMData * | this_img, | |
| EMData * | to_img | |||
| ) | const [inline, virtual] |
Implements EMAN::Aligner.
Definition at line 601 of file aligner.h.
References align().
00602 { 00603 return align(this_img, to_img, "sqeuclidean", Dict()); 00604 }
| virtual string EMAN::Refine3DAligner::get_name | ( | ) | const [inline, virtual] |
Get the Aligner's name.
Each Aligner is identified by a unique name.
Implements EMAN::Aligner.
Definition at line 606 of file aligner.h.
| virtual string EMAN::Refine3DAligner::get_desc | ( | ) | const [inline, virtual] |
Implements EMAN::Aligner.
Definition at line 611 of file aligner.h.
00612 { 00613 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision."; 00614 }
| static Aligner* EMAN::Refine3DAligner::NEW | ( | ) | [inline, static] |
| virtual TypeDict EMAN::Refine3DAligner::get_param_types | ( | ) | const [inline, virtual] |
Implements EMAN::Aligner.
Definition at line 621 of file aligner.h.
References EMAN::EMObject::FLOAT, EMAN::EMObject::INT, EMAN::TypeDict::put(), and EMAN::EMObject::TRANSFORM.
00622 { 00623 TypeDict d; 00624 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used"); 00625 d.put("stepx", EMObject::FLOAT, "The x increment used to create the starting simplex. Default is 1"); 00626 d.put("stepy", EMObject::FLOAT,"The y increment used to create the starting simplex. Default is 1"); 00627 d.put("stepz", EMObject::FLOAT, "The z increment used to create the starting simplex. Default is 1." ); 00628 d.put("stepphi", EMObject::FLOAT, "The phi incremenent used to creat the starting simplex. This is the increment applied to the inplane rotation. Default is 5." ); 00629 d.put("stepdelta", EMObject::FLOAT,"The angular increment which represents a good initial step along the sphere, thinking in terms of quaternions. Default is 5."); 00630 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.04." ); 00631 d.put("maxiter", EMObject::INT, "The maximum number of iterations that can be performed by the Simplex minimizer. Default is 60."); 00632 d.put("maxshift", EMObject::INT,"Maximum translation in pixels in any direction. If the solution yields a shift beyond this value in any direction, then the refinement is judged a failure and the original alignment is used as the solution."); 00633 return d; 00634 }
1.5.6