Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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

AlignerNEW ()

Static Public Attributes

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

References align().

01462                         {
01463                                 return align(this_img, to_img, "sqeuclidean", Dict());
01464                         }

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 2139 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.

02141 {
02142         
02143         if (!to || !this_img) throw NullPointerException("Input image is null"); // not sure if this is necessary, it was there before I started
02144 
02145         if (to->get_ndim() != 3 || this_img->get_ndim() != 3) throw ImageDimensionException("The Refine3D aligner only works for 3D images");
02146 
02147 #ifdef EMAN2_USING_CUDA 
02148         if(EMData::usecuda == 1) {
02149                 if(!this_img->getcudarwdata()) this_img->copy_to_cuda();
02150                 if(!to->getcudarwdata()) to->copy_to_cuda();
02151         }
02152 #endif
02153 
02154         float sdi = 0.0;
02155         float sdj = 0.0;
02156         float sdk = 0.0;
02157         float sdx = 0.0;
02158         float sdy = 0.0;
02159         float sdz = 0.0;
02160         bool mirror = false;
02161         
02162         Transform* t;
02163         if (params.has_key("xform.align3d") ) {
02164                 // Unlike the 2d refine aligner, this class doesn't require the starting transform's
02165                 // parameters to form the starting guess. Instead the Transform itself
02166                 // is perturbed carefully (using quaternion rotation) to overcome problems that arise
02167                 // when you use orthogonally-based Euler angles
02168                 t = params["xform.align3d"];
02169         }else {
02170                 t = new Transform(); // is the identity
02171         }
02172         
02173         float spincoeff =  params.set_default("spin_coeff",10.0f); // spin coefficient, controls speed of convergence (sort of)
02174         
02175         int np = 6; // the number of dimensions
02176         Dict gsl_params;
02177         gsl_params["this"] = this_img;
02178         gsl_params["with"] = to;
02179         gsl_params["snr"]  = params["snr"];
02180         gsl_params["mirror"] = mirror;
02181         gsl_params["transform"] = t;    
02182         gsl_params["spincoeff"] = spincoeff;
02183         Dict altered_cmp_params(cmp_params);
02184         
02185         const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
02186         gsl_vector *ss = gsl_vector_alloc(np);
02187         
02188         float stepi = params.set_default("stepn0",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway
02189         float stepj = params.set_default("stepn1",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway
02190         float stepk = params.set_default("stepn2",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway
02191         float stepx = params.set_default("stepx",1.0f);
02192         float stepy = params.set_default("stepy",1.0f);
02193         float stepz = params.set_default("stepz",1.0f);
02194         
02195         //gsl_vector_set(ss, 0, stepw);
02196         gsl_vector_set(ss, 0, stepi);
02197         gsl_vector_set(ss, 1, stepj);
02198         gsl_vector_set(ss, 2, stepk);
02199         gsl_vector_set(ss, 3, stepx);
02200         gsl_vector_set(ss, 4, stepy);
02201         gsl_vector_set(ss, 5, stepz);
02202         
02203         gsl_vector *x = gsl_vector_alloc(np);
02204         gsl_vector_set(x, 0, sdi);
02205         gsl_vector_set(x, 1, sdj);
02206         gsl_vector_set(x, 2, sdk);
02207         gsl_vector_set(x, 3, sdx);
02208         gsl_vector_set(x, 4, sdy);
02209         gsl_vector_set(x, 5, sdz);
02210         
02211         gsl_multimin_function minex_func;
02212         Cmp *c = Factory < Cmp >::get(cmp_name, altered_cmp_params);
02213                 
02214         gsl_params["cmp"] = (void *) c;
02215         minex_func.f = &refalifn3dquat;
02216 
02217         minex_func.n = np;
02218         minex_func.params = (void *) &gsl_params;
02219         
02220         gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, np);
02221         gsl_multimin_fminimizer_set(s, &minex_func, x, ss);
02222         
02223         int rval = GSL_CONTINUE;
02224         int status = GSL_SUCCESS;
02225         int iter = 1;
02226         
02227         float precision = params.set_default("precision",0.01f);
02228         int maxiter = params.set_default("maxiter",100);
02229         while (rval == GSL_CONTINUE && iter < maxiter) {
02230                 iter++;
02231                 status = gsl_multimin_fminimizer_iterate(s);
02232                 if (status) {
02233                         break;
02234                 }
02235                 rval = gsl_multimin_test_size(gsl_multimin_fminimizer_size(s), precision);
02236         }
02237 
02238         int maxshift = params.set_default("maxshift",-1);
02239 
02240         if (maxshift <= 0) {
02241                 maxshift = this_img->get_xsize() / 4;
02242         }
02243         float fmaxshift = static_cast<float>(maxshift);
02244         
02245         EMData *result;
02246         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))
02247         {
02248                 float n0 = (float)gsl_vector_get(s->x, 0);
02249                 float n1 = (float)gsl_vector_get(s->x, 1);
02250                 float n2 = (float)gsl_vector_get(s->x, 2);
02251                 float x = (float)gsl_vector_get(s->x, 3);
02252                 float y = (float)gsl_vector_get(s->x, 4);
02253                 float z = (float)gsl_vector_get(s->x, 5);
02254                 
02255                 Transform tsoln = refalin3d_perturbquat(t,spincoeff,n0,n1,n2,x,y,z);
02256                         
02257                 result = this_img->process("xform",Dict("transform",&tsoln));
02258                 result->set_attr("xform.align3d",&tsoln);
02259                 result->set_attr("score", result->cmp(cmp_name,to,cmp_params));
02260                 
02261          //coda goes here
02262         } else { // The refine aligner failed - this shift went beyond the max shift
02263                 result = this_img->process("xform",Dict("transform",t));
02264                 result->set_attr("xform.align3d",t);
02265                 result->set_attr("score",0.0);
02266         }
02267         
02268         //EMData *result = this_img->process("xform",Dict("transform",t));
02269         delete t;
02270         gsl_vector_free(x);
02271         gsl_vector_free(ss);
02272         gsl_multimin_fminimizer_free(s);
02273 
02274         if (c != 0) delete c;
02275         
02276         return result;
02277 }

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

Implements EMAN::Aligner.

Definition at line 1471 of file aligner.h.

01472                         {
01473                                 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision.";
01474                         }

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

01467                         {
01468                                 return NAME;
01469                         }

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

Implements EMAN::Aligner.

Definition at line 1481 of file aligner.h.

References EMAN::TypeDict::put().

01482                         {
01483                                 TypeDict d;
01484                                 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used");
01485                                 d.put("stepx", EMObject::FLOAT, "The initial simplex step size in x. Default is 1");
01486                                 d.put("stepy", EMObject::FLOAT, "The initial simplex step size in y. Default is 1");
01487                                 d.put("stepz", EMObject::FLOAT, "The initial simplex step size in z. Default is 1." );
01488                                 d.put("stepn0", EMObject::FLOAT, "The initial simplex step size in the first quaternion vecotr component. Default is 1." );
01489                                 d.put("stepn1", EMObject::FLOAT, "The initial simplex step size in the second quaternion vecotr component. Default is 1." );
01490                                 d.put("stepn2", EMObject::FLOAT, "The initial simplex step size in the third quaternion vecotr component. Default is 1." );
01491                                 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.");
01492                                 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.01." );
01493                                 d.put("maxiter", EMObject::INT, "The maximum number of iterations that can be performed by the Simplex minimizer. Default is 100.");
01494                                 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.");
01495                                 return d;
01496                         }

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

Definition at line 1476 of file aligner.h.

01477                         {
01478                                 return new Refine3DAlignerQuaternion();
01479                         }


Member Data Documentation

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

Definition at line 83 of file aligner.cpp.


The documentation for this class was generated from the following files:
Generated on Tue Jun 11 13:41:51 2013 for EMAN2 by  doxygen 1.3.9.1