#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 982 of file aligner.h.
|
Implements EMAN::Aligner. Definition at line 988 of file aligner.h. References align(). 00989 { 00990 return align(this_img, to_img, "sqeuclidean", Dict()); 00991 }
|
|
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 1576 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. 01578 { 01579 01580 if (!to || !this_img) throw NullPointerException("Input image is null"); // not sure if this is necessary, it was there before I started 01581 01582 if (to->get_ndim() != 3 || this_img->get_ndim() != 3) throw ImageDimensionException("The Refine3D aligner only works for 3D images"); 01583 01584 #ifdef EMAN2_USING_CUDA 01585 if(EMData::usecuda == 1) { 01586 if(!this_img->cudarwdata) this_img->copy_to_cuda(); 01587 if(!to->cudarwdata) to->copy_to_cuda(); 01588 } 01589 #endif 01590 01591 float sdi = 0.0; 01592 float sdj = 0.0; 01593 float sdk = 0.0; 01594 float sdx = 0.0; 01595 float sdy = 0.0; 01596 float sdz = 0.0; 01597 bool mirror = false; 01598 01599 Transform* t; 01600 if (params.has_key("xform.align3d") ) { 01601 // Unlike the 2d refine aligner, this class doesn't require the starting transform's 01602 // parameters to form the starting guess. Instead the Transform itself 01603 // is perturbed carefully (using quaternion rotation) to overcome problems that arise 01604 // when you use orthogonally-based Euler angles 01605 t = params["xform.align3d"]; 01606 }else { 01607 t = new Transform(); // is the identity 01608 } 01609 01610 float spincoeff = params.set_default("spin_coeff",10.0f); // spin coefficient, controls speed of convergence (sort of) 01611 01612 int np = 6; // the number of dimensions 01613 Dict gsl_params; 01614 gsl_params["this"] = this_img; 01615 gsl_params["with"] = to; 01616 gsl_params["snr"] = params["snr"]; 01617 gsl_params["mirror"] = mirror; 01618 gsl_params["transform"] = t; 01619 gsl_params["spincoeff"] = spincoeff; 01620 Dict altered_cmp_params(cmp_params); 01621 01622 const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex; 01623 gsl_vector *ss = gsl_vector_alloc(np); 01624 01625 float stepi = params.set_default("stepi",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway 01626 float stepj = params.set_default("stepj",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway 01627 float stepk = params.set_default("stepk",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway 01628 float stepx = params.set_default("stepx",1.0f); 01629 float stepy = params.set_default("stepy",1.0f); 01630 float stepz = params.set_default("stepz",1.0f); 01631 01632 //gsl_vector_set(ss, 0, stepw); 01633 gsl_vector_set(ss, 0, stepi); 01634 gsl_vector_set(ss, 1, stepj); 01635 gsl_vector_set(ss, 2, stepk); 01636 gsl_vector_set(ss, 3, stepx); 01637 gsl_vector_set(ss, 4, stepy); 01638 gsl_vector_set(ss, 5, stepz); 01639 01640 gsl_vector *x = gsl_vector_alloc(np); 01641 gsl_vector_set(x, 0, sdi); 01642 gsl_vector_set(x, 1, sdj); 01643 gsl_vector_set(x, 2, sdk); 01644 gsl_vector_set(x, 3, sdx); 01645 gsl_vector_set(x, 4, sdy); 01646 gsl_vector_set(x, 5, sdz); 01647 01648 gsl_multimin_function minex_func; 01649 Cmp *c = Factory < Cmp >::get(cmp_name, altered_cmp_params); 01650 01651 gsl_params["cmp"] = (void *) c; 01652 minex_func.f = &refalifn3dquat; 01653 01654 minex_func.n = np; 01655 minex_func.params = (void *) &gsl_params; 01656 01657 gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, np); 01658 gsl_multimin_fminimizer_set(s, &minex_func, x, ss); 01659 01660 int rval = GSL_CONTINUE; 01661 int status = GSL_SUCCESS; 01662 int iter = 1; 01663 01664 float precision = params.set_default("precision",0.01f); 01665 int maxiter = params.set_default("maxiter",100); 01666 while (rval == GSL_CONTINUE && iter < maxiter) { 01667 iter++; 01668 status = gsl_multimin_fminimizer_iterate(s); 01669 if (status) { 01670 break; 01671 } 01672 rval = gsl_multimin_test_size(gsl_multimin_fminimizer_size(s), precision); 01673 } 01674 01675 int maxshift = params.set_default("maxshift",-1); 01676 01677 if (maxshift <= 0) { 01678 maxshift = this_img->get_xsize() / 4; 01679 } 01680 float fmaxshift = static_cast<float>(maxshift); 01681 01682 EMData *result; 01683 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)) 01684 { 01685 float n0 = (float)gsl_vector_get(s->x, 0); 01686 float n1 = (float)gsl_vector_get(s->x, 1); 01687 float n2 = (float)gsl_vector_get(s->x, 2); 01688 float x = (float)gsl_vector_get(s->x, 3); 01689 float y = (float)gsl_vector_get(s->x, 4); 01690 float z = (float)gsl_vector_get(s->x, 5); 01691 01692 Transform tsoln = refalin3d_perturbquat(t,spincoeff,n0,n1,n2,x,y,z); 01693 01694 result = this_img->process("xform",Dict("transform",&tsoln)); 01695 result->set_attr("xform.align3d",&tsoln); 01696 result->set_attr("score", result->cmp(cmp_name,to,cmp_params)); 01697 01698 //coda goes here 01699 } else { // The refine aligner failed - this shift went beyond the max shift 01700 result = this_img->process("xform",Dict("transform",t)); 01701 result->set_attr("xform.align3d",t); 01702 } 01703 01704 //EMData *result = this_img->process("xform",Dict("transform",t)); 01705 delete t; 01706 t = 0; 01707 gsl_vector_free(x); 01708 gsl_vector_free(ss); 01709 gsl_multimin_fminimizer_free(s); 01710 01711 if ( c != 0 ) delete c; 01712 return result; 01713 }
|
|
Implements EMAN::Aligner. Definition at line 998 of file aligner.h. 00999 { 01000 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision."; 01001 }
|
|
Get the Aligner's name. Each Aligner is identified by a unique name.
Implements EMAN::Aligner. Definition at line 993 of file aligner.h. 00994 {
00995 return NAME;
00996 }
|
|
Implements EMAN::Aligner. Definition at line 1008 of file aligner.h. References EMAN::TypeDict::put(). 01009 { 01010 TypeDict d; 01011 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used"); 01012 d.put("stepx", EMObject::FLOAT, "The initial simplex step size in x. Default is 1"); 01013 d.put("stepy", EMObject::FLOAT, "The initial simplex step size in y. Default is 1"); 01014 d.put("stepz", EMObject::FLOAT, "The initial simplex step size in z. Default is 1." ); 01015 d.put("stepn0", EMObject::FLOAT, "The initial simplex step size in the first quaternion vecotr component. Default is 1." ); 01016 d.put("stepn1", EMObject::FLOAT, "The initial simplex step size in the second quaternion vecotr component. Default is 1." ); 01017 d.put("stepn2", EMObject::FLOAT, "The initial simplex step size in the third quaternion vecotr component. Default is 1." ); 01018 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."); 01019 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.01." ); 01020 d.put("maxiter", EMObject::INT, "The maximum number of iterations that can be performed by the Simplex minimizer. Default is 100."); 01021 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."); 01022 return d; 01023 }
|
|
Definition at line 1003 of file aligner.h. 01004 { 01005 return new Refine3DAlignerQuaternion(); 01006 }
|
|
Definition at line 75 of file aligner.cpp. |