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 982 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 988 of file aligner.h.

References align().

00989                         {
00990                                 return align(this_img, to_img, "sqeuclidean", Dict());
00991                         }

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 1587 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().

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 }

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

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                         }

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 993 of file aligner.h.

References NAME.

00994                         {
00995                                 return NAME;
00996                         }

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

Implements EMAN::Aligner.

Definition at line 1008 of file aligner.h.

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

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                         }

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

Definition at line 1003 of file aligner.h.

01004                         {
01005                                 return new Refine3DAlignerQuaternion();
01006                         }


Member Data Documentation

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

Definition at line 1025 of file aligner.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Tue Jul 12 13:47:57 2011 for EMAN2 by  doxygen 1.4.7