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