#include <aligner.h>
Inheritance diagram for EMAN::Refine3DAlignerQuaternion:
Public Member Functions | |
virtual EMData * | align (EMData *this_img, EMData *to_img, const string &cmp_name="sqeuclidean", 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 | |
Aligner * | NEW () |
Static Public Attributes | |
const string | NAME = "refine_3d" |
Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision. Target function for the simplex algorithm is a rotation along an arbitrary axis defined by a quaternion, whose rotation magnitude is defined by the vector length (hence the simplex varies the vecotr component of the quaternion). In addition the simplex varies translation. Using quaternions avoids gimbal lock. The simplex algorithm moves the function downhill in a ameboa like fasion, hence it may get stuck in a local minima if the two 3D models are already roughly aligned.
xform.align3d | The Transform storing the starting guess. If unspecified the identity matrix is used | |
stepx | The initial simplex step size in x | |
stepy | The initial simplex step size in y | |
stepz | The initial simplex step size in z | |
stepn0 | The initial simplex step size in the first quaternion vecotr component | |
stepn1 | The initial simplex step size in the second quaternion vecotr component | |
stepn2 | The initial simplex step size in the third quaternion vecotr component | |
spin_coeff | The multiplier appied to the spin (if it is too small or too large the simplex will not converge) | |
precision | The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations | |
maxiter | The maximum number of iterations that can be performed by the Simplex minimizer | |
maxshift | Maximum translation in pixels in any direction. |
Definition at line 1455 of file aligner.h.
|
Implements EMAN::Aligner. Definition at line 1461 of file aligner.h. References align(). 01462 { 01463 return align(this_img, to_img, "sqeuclidean", Dict()); 01464 }
|
|
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.
Implements EMAN::Aligner. Definition at line 2139 of file aligner.cpp. References EMAN::EMData::cmp(), EMAN::EMData::get_ndim(), EMAN::EMData::get_xsize(), EMAN::Dict::has_key(), ImageDimensionException, NullPointerException, EMAN::Cmp::params, EMAN::EMData::process(), refalin3d_perturbquat(), EMAN::EMData::set_attr(), EMAN::Dict::set_default(), status, t, x, and y. 02141 { 02142 02143 if (!to || !this_img) throw NullPointerException("Input image is null"); // not sure if this is necessary, it was there before I started 02144 02145 if (to->get_ndim() != 3 || this_img->get_ndim() != 3) throw ImageDimensionException("The Refine3D aligner only works for 3D images"); 02146 02147 #ifdef EMAN2_USING_CUDA 02148 if(EMData::usecuda == 1) { 02149 if(!this_img->getcudarwdata()) this_img->copy_to_cuda(); 02150 if(!to->getcudarwdata()) to->copy_to_cuda(); 02151 } 02152 #endif 02153 02154 float sdi = 0.0; 02155 float sdj = 0.0; 02156 float sdk = 0.0; 02157 float sdx = 0.0; 02158 float sdy = 0.0; 02159 float sdz = 0.0; 02160 bool mirror = false; 02161 02162 Transform* t; 02163 if (params.has_key("xform.align3d") ) { 02164 // Unlike the 2d refine aligner, this class doesn't require the starting transform's 02165 // parameters to form the starting guess. Instead the Transform itself 02166 // is perturbed carefully (using quaternion rotation) to overcome problems that arise 02167 // when you use orthogonally-based Euler angles 02168 t = params["xform.align3d"]; 02169 }else { 02170 t = new Transform(); // is the identity 02171 } 02172 02173 float spincoeff = params.set_default("spin_coeff",10.0f); // spin coefficient, controls speed of convergence (sort of) 02174 02175 int np = 6; // the number of dimensions 02176 Dict gsl_params; 02177 gsl_params["this"] = this_img; 02178 gsl_params["with"] = to; 02179 gsl_params["snr"] = params["snr"]; 02180 gsl_params["mirror"] = mirror; 02181 gsl_params["transform"] = t; 02182 gsl_params["spincoeff"] = spincoeff; 02183 Dict altered_cmp_params(cmp_params); 02184 02185 const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex; 02186 gsl_vector *ss = gsl_vector_alloc(np); 02187 02188 float stepi = params.set_default("stepn0",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway 02189 float stepj = params.set_default("stepn1",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway 02190 float stepk = params.set_default("stepn2",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway 02191 float stepx = params.set_default("stepx",1.0f); 02192 float stepy = params.set_default("stepy",1.0f); 02193 float stepz = params.set_default("stepz",1.0f); 02194 02195 //gsl_vector_set(ss, 0, stepw); 02196 gsl_vector_set(ss, 0, stepi); 02197 gsl_vector_set(ss, 1, stepj); 02198 gsl_vector_set(ss, 2, stepk); 02199 gsl_vector_set(ss, 3, stepx); 02200 gsl_vector_set(ss, 4, stepy); 02201 gsl_vector_set(ss, 5, stepz); 02202 02203 gsl_vector *x = gsl_vector_alloc(np); 02204 gsl_vector_set(x, 0, sdi); 02205 gsl_vector_set(x, 1, sdj); 02206 gsl_vector_set(x, 2, sdk); 02207 gsl_vector_set(x, 3, sdx); 02208 gsl_vector_set(x, 4, sdy); 02209 gsl_vector_set(x, 5, sdz); 02210 02211 gsl_multimin_function minex_func; 02212 Cmp *c = Factory < Cmp >::get(cmp_name, altered_cmp_params); 02213 02214 gsl_params["cmp"] = (void *) c; 02215 minex_func.f = &refalifn3dquat; 02216 02217 minex_func.n = np; 02218 minex_func.params = (void *) &gsl_params; 02219 02220 gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, np); 02221 gsl_multimin_fminimizer_set(s, &minex_func, x, ss); 02222 02223 int rval = GSL_CONTINUE; 02224 int status = GSL_SUCCESS; 02225 int iter = 1; 02226 02227 float precision = params.set_default("precision",0.01f); 02228 int maxiter = params.set_default("maxiter",100); 02229 while (rval == GSL_CONTINUE && iter < maxiter) { 02230 iter++; 02231 status = gsl_multimin_fminimizer_iterate(s); 02232 if (status) { 02233 break; 02234 } 02235 rval = gsl_multimin_test_size(gsl_multimin_fminimizer_size(s), precision); 02236 } 02237 02238 int maxshift = params.set_default("maxshift",-1); 02239 02240 if (maxshift <= 0) { 02241 maxshift = this_img->get_xsize() / 4; 02242 } 02243 float fmaxshift = static_cast<float>(maxshift); 02244 02245 EMData *result; 02246 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)) 02247 { 02248 float n0 = (float)gsl_vector_get(s->x, 0); 02249 float n1 = (float)gsl_vector_get(s->x, 1); 02250 float n2 = (float)gsl_vector_get(s->x, 2); 02251 float x = (float)gsl_vector_get(s->x, 3); 02252 float y = (float)gsl_vector_get(s->x, 4); 02253 float z = (float)gsl_vector_get(s->x, 5); 02254 02255 Transform tsoln = refalin3d_perturbquat(t,spincoeff,n0,n1,n2,x,y,z); 02256 02257 result = this_img->process("xform",Dict("transform",&tsoln)); 02258 result->set_attr("xform.align3d",&tsoln); 02259 result->set_attr("score", result->cmp(cmp_name,to,cmp_params)); 02260 02261 //coda goes here 02262 } else { // The refine aligner failed - this shift went beyond the max shift 02263 result = this_img->process("xform",Dict("transform",t)); 02264 result->set_attr("xform.align3d",t); 02265 result->set_attr("score",0.0); 02266 } 02267 02268 //EMData *result = this_img->process("xform",Dict("transform",t)); 02269 delete t; 02270 gsl_vector_free(x); 02271 gsl_vector_free(ss); 02272 gsl_multimin_fminimizer_free(s); 02273 02274 if (c != 0) delete c; 02275 02276 return result; 02277 }
|
|
Implements EMAN::Aligner. Definition at line 1471 of file aligner.h. 01472 { 01473 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision."; 01474 }
|
|
Get the Aligner's name. Each Aligner is identified by a unique name.
Implements EMAN::Aligner. Definition at line 1466 of file aligner.h. 01467 {
01468 return NAME;
01469 }
|
|
Implements EMAN::Aligner. Definition at line 1481 of file aligner.h. References EMAN::TypeDict::put(). 01482 { 01483 TypeDict d; 01484 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used"); 01485 d.put("stepx", EMObject::FLOAT, "The initial simplex step size in x. Default is 1"); 01486 d.put("stepy", EMObject::FLOAT, "The initial simplex step size in y. Default is 1"); 01487 d.put("stepz", EMObject::FLOAT, "The initial simplex step size in z. Default is 1." ); 01488 d.put("stepn0", EMObject::FLOAT, "The initial simplex step size in the first quaternion vecotr component. Default is 1." ); 01489 d.put("stepn1", EMObject::FLOAT, "The initial simplex step size in the second quaternion vecotr component. Default is 1." ); 01490 d.put("stepn2", EMObject::FLOAT, "The initial simplex step size in the third quaternion vecotr component. Default is 1." ); 01491 d.put("spin_coeff", EMObject::FLOAT,"The multiplier appied to the spin (if it is too small or too large the simplex will not converge). Default is 10."); 01492 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.01." ); 01493 d.put("maxiter", EMObject::INT, "The maximum number of iterations that can be performed by the Simplex minimizer. Default is 100."); 01494 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."); 01495 return d; 01496 }
|
|
Definition at line 1476 of file aligner.h. 01477 { 01478 return new Refine3DAlignerQuaternion(); 01479 }
|
|
Definition at line 83 of file aligner.cpp. |