EMAN::Refine3DAlignerQuaternion Class Reference
[a function or class that is CUDA enabled]

Refine alignment. More...

#include <aligner.h>

Inheritance diagram for EMAN::Refine3DAlignerQuaternion:

Inheritance graph
[legend]
Collaboration diagram for EMAN::Refine3DAlignerQuaternion:

Collaboration graph
[legend]
List of all members.

Public Member Functions

virtual EMDataalign (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 EMDataalign (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 AlignerNEW ()

Static Public Attributes

static const string NAME = "refine_3d"

Detailed Description

Refine alignment.

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.

Parameters:
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.
Author:
John Flanagan (with code recyled from David Woolford)
Date:
Feb 3rd 2011

Definition at line 968 of file aligner.h.


Member Function Documentation

virtual EMData* EMAN::Refine3DAlignerQuaternion::align ( EMData this_img,
EMData to_img 
) const [inline, virtual]

Implements EMAN::Aligner.

Definition at line 974 of file aligner.h.

References align().

00975                         {
00976                                 return align(this_img, to_img, "sqeuclidean", Dict());
00977                         }

EMData * Refine3DAlignerQuaternion::align ( EMData this_img,
EMData to_img,
const string &  cmp_name = "sqeuclidean",
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.

Parameters:
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.
Returns:
The aligned image.

Implements EMAN::Aligner.

Definition at line 1574 of file aligner.cpp.

References EMAN::EMData::get_ndim(), EMAN::EMData::get_xsize(), EMAN::Dict::has_key(), ImageDimensionException, NullPointerException, EMAN::Aligner::params, EMAN::EMData::process(), refalifn3dquat(), refalin3d_perturbquat(), EMAN::EMData::set_attr(), EMAN::Dict::set_default(), status, t, x, and y.

Referenced by align().

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

virtual string EMAN::Refine3DAlignerQuaternion::get_desc (  )  const [inline, virtual]

Implements EMAN::Aligner.

Definition at line 984 of file aligner.h.

00985                         {
00986                                 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision.";
00987                         }

virtual string EMAN::Refine3DAlignerQuaternion::get_name (  )  const [inline, virtual]

Get the Aligner's name.

Each Aligner is identified by a unique name.

Returns:
The Aligner's name.

Implements EMAN::Aligner.

Definition at line 979 of file aligner.h.

References NAME.

00980                         {
00981                                 return NAME;
00982                         }

virtual TypeDict EMAN::Refine3DAlignerQuaternion::get_param_types (  )  const [inline, virtual]

Implements EMAN::Aligner.

Definition at line 994 of file aligner.h.

References EMAN::EMObject::FLOAT, EMAN::EMObject::INT, EMAN::TypeDict::put(), and EMAN::EMObject::TRANSFORM.

00995                         {
00996                                 TypeDict d;
00997                                 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used");
00998                                 d.put("stepx", EMObject::FLOAT, "The initial simplex step size in x. Default is 1");
00999                                 d.put("stepy", EMObject::FLOAT, "The initial simplex step size in y. Default is 1");
01000                                 d.put("stepz", EMObject::FLOAT, "The initial simplex step size in z. Default is 1." );
01001                                 d.put("stepn0", EMObject::FLOAT, "The initial simplex step size in the first quaternion vecotr component. Default is 1." );
01002                                 d.put("stepn1", EMObject::FLOAT, "The initial simplex step size in the second quaternion vecotr component. Default is 1." );
01003                                 d.put("stepn2", EMObject::FLOAT, "The initial simplex step size in the third quaternion vecotr component. Default is 1." );
01004                                 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.");
01005                                 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.01." );
01006                                 d.put("maxiter", EMObject::INT, "The maximum number of iterations that can be performed by the Simplex minimizer. Default is 100.");
01007                                 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.");
01008                                 return d;
01009                         }

static Aligner* EMAN::Refine3DAlignerQuaternion::NEW (  )  [inline, static]

Definition at line 989 of file aligner.h.

00990                         {
00991                                 return new Refine3DAlignerQuaternion();
00992                         }


Member Data Documentation

const string Refine3DAlignerQuaternion::NAME = "refine_3d" [static]

Definition at line 1011 of file aligner.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Mon Mar 7 18:01:25 2011 for EMAN2 by  doxygen 1.4.7