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

References align().

01456                         {
01457                                 return align(this_img, to_img, "sqeuclidean", Dict());
01458                         }

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

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

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

Implements EMAN::Aligner.

Definition at line 1465 of file aligner.h.

01466                         {
01467                                 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision.";
01468                         }

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

01461                         {
01462                                 return NAME;
01463                         }

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

Implements EMAN::Aligner.

Definition at line 1475 of file aligner.h.

References EMAN::TypeDict::put().

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

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

Definition at line 1470 of file aligner.h.

01471                         {
01472                                 return new Refine3DAlignerQuaternion();
01473                         }


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 Mon Aug 13 13:41:31 2012 for EMAN2 by  doxygen 1.3.9.1