#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 1587 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. 01589 { 01590 01591 if (!to || !this_img) throw NullPointerException("Input image is null"); // not sure if this is necessary, it was there before I started 01592 01593 if (to->get_ndim() != 3 || this_img->get_ndim() != 3) throw ImageDimensionException("The Refine3D aligner only works for 3D images"); 01594 01595 #ifdef EMAN2_USING_CUDA 01596 if(EMData::usecuda == 1) { 01597 if(!this_img->getcudarwdata()) this_img->copy_to_cuda(); 01598 if(!to->getcudarwdata()) to->copy_to_cuda(); 01599 } 01600 #endif 01601 01602 float sdi = 0.0; 01603 float sdj = 0.0; 01604 float sdk = 0.0; 01605 float sdx = 0.0; 01606 float sdy = 0.0; 01607 float sdz = 0.0; 01608 bool mirror = false; 01609 01610 Transform* t; 01611 if (params.has_key("xform.align3d") ) { 01612 // Unlike the 2d refine aligner, this class doesn't require the starting transform's 01613 // parameters to form the starting guess. Instead the Transform itself 01614 // is perturbed carefully (using quaternion rotation) to overcome problems that arise 01615 // when you use orthogonally-based Euler angles 01616 t = params["xform.align3d"]; 01617 }else { 01618 t = new Transform(); // is the identity 01619 } 01620 01621 float spincoeff = params.set_default("spin_coeff",10.0f); // spin coefficient, controls speed of convergence (sort of) 01622 01623 int np = 6; // the number of dimensions 01624 Dict gsl_params; 01625 gsl_params["this"] = this_img; 01626 gsl_params["with"] = to; 01627 gsl_params["snr"] = params["snr"]; 01628 gsl_params["mirror"] = mirror; 01629 gsl_params["transform"] = t; 01630 gsl_params["spincoeff"] = spincoeff; 01631 Dict altered_cmp_params(cmp_params); 01632 01633 const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex; 01634 gsl_vector *ss = gsl_vector_alloc(np); 01635 01636 float stepi = params.set_default("stepn0",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway 01637 float stepj = params.set_default("stepn1",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway 01638 float stepk = params.set_default("stepn2",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway 01639 float stepx = params.set_default("stepx",1.0f); 01640 float stepy = params.set_default("stepy",1.0f); 01641 float stepz = params.set_default("stepz",1.0f); 01642 01643 //gsl_vector_set(ss, 0, stepw); 01644 gsl_vector_set(ss, 0, stepi); 01645 gsl_vector_set(ss, 1, stepj); 01646 gsl_vector_set(ss, 2, stepk); 01647 gsl_vector_set(ss, 3, stepx); 01648 gsl_vector_set(ss, 4, stepy); 01649 gsl_vector_set(ss, 5, stepz); 01650 01651 gsl_vector *x = gsl_vector_alloc(np); 01652 gsl_vector_set(x, 0, sdi); 01653 gsl_vector_set(x, 1, sdj); 01654 gsl_vector_set(x, 2, sdk); 01655 gsl_vector_set(x, 3, sdx); 01656 gsl_vector_set(x, 4, sdy); 01657 gsl_vector_set(x, 5, sdz); 01658 01659 gsl_multimin_function minex_func; 01660 Cmp *c = Factory < Cmp >::get(cmp_name, altered_cmp_params); 01661 01662 gsl_params["cmp"] = (void *) c; 01663 minex_func.f = &refalifn3dquat; 01664 01665 minex_func.n = np; 01666 minex_func.params = (void *) &gsl_params; 01667 01668 gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, np); 01669 gsl_multimin_fminimizer_set(s, &minex_func, x, ss); 01670 01671 int rval = GSL_CONTINUE; 01672 int status = GSL_SUCCESS; 01673 int iter = 1; 01674 01675 float precision = params.set_default("precision",0.01f); 01676 int maxiter = params.set_default("maxiter",100); 01677 while (rval == GSL_CONTINUE && iter < maxiter) { 01678 iter++; 01679 status = gsl_multimin_fminimizer_iterate(s); 01680 if (status) { 01681 break; 01682 } 01683 rval = gsl_multimin_test_size(gsl_multimin_fminimizer_size(s), precision); 01684 } 01685 01686 int maxshift = params.set_default("maxshift",-1); 01687 01688 if (maxshift <= 0) { 01689 maxshift = this_img->get_xsize() / 4; 01690 } 01691 float fmaxshift = static_cast<float>(maxshift); 01692 01693 EMData *result; 01694 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)) 01695 { 01696 float n0 = (float)gsl_vector_get(s->x, 0); 01697 float n1 = (float)gsl_vector_get(s->x, 1); 01698 float n2 = (float)gsl_vector_get(s->x, 2); 01699 float x = (float)gsl_vector_get(s->x, 3); 01700 float y = (float)gsl_vector_get(s->x, 4); 01701 float z = (float)gsl_vector_get(s->x, 5); 01702 01703 Transform tsoln = refalin3d_perturbquat(t,spincoeff,n0,n1,n2,x,y,z); 01704 01705 result = this_img->process("xform",Dict("transform",&tsoln)); 01706 result->set_attr("xform.align3d",&tsoln); 01707 result->set_attr("score", result->cmp(cmp_name,to,cmp_params)); 01708 01709 //coda goes here 01710 } else { // The refine aligner failed - this shift went beyond the max shift 01711 result = this_img->process("xform",Dict("transform",t)); 01712 result->set_attr("xform.align3d",t); 01713 result->set_attr("score",0.0); 01714 } 01715 01716 //EMData *result = this_img->process("xform",Dict("transform",t)); 01717 delete t; 01718 t = 0; 01719 gsl_vector_free(x); 01720 gsl_vector_free(ss); 01721 gsl_multimin_fminimizer_free(s); 01722 01723 if ( c != 0 ) delete c; 01724 01725 //Free up resources (for an expensive opperation like this move data to and from device is a small % of time) 01726 #ifdef EMAN2_USING_CUDA 01727 to->copy_from_device(); 01728 this_img->ro_free(); 01729 #endif 01730 01731 return result; 01732 }
|
|
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. |