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

References align().

01391                         {
01392                                 return align(this_img, to_img, "sqeuclidean", Dict());
01393                         }

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

01971 {
01972         
01973         if (!to || !this_img) throw NullPointerException("Input image is null"); // not sure if this is necessary, it was there before I started
01974 
01975         if (to->get_ndim() != 3 || this_img->get_ndim() != 3) throw ImageDimensionException("The Refine3D aligner only works for 3D images");
01976 
01977 #ifdef EMAN2_USING_CUDA 
01978         if(EMData::usecuda == 1) {
01979                 if(!this_img->getcudarwdata()) this_img->copy_to_cuda();
01980                 if(!to->getcudarwdata()) to->copy_to_cuda();
01981         }
01982 #endif
01983 
01984         float sdi = 0.0;
01985         float sdj = 0.0;
01986         float sdk = 0.0;
01987         float sdx = 0.0;
01988         float sdy = 0.0;
01989         float sdz = 0.0;
01990         bool mirror = false;
01991         
01992         Transform* t;
01993         if (params.has_key("xform.align3d") ) {
01994                 // Unlike the 2d refine aligner, this class doesn't require the starting transform's
01995                 // parameters to form the starting guess. Instead the Transform itself
01996                 // is perturbed carefully (using quaternion rotation) to overcome problems that arise
01997                 // when you use orthogonally-based Euler angles
01998                 t = params["xform.align3d"];
01999         }else {
02000                 t = new Transform(); // is the identity
02001         }
02002         
02003         float spincoeff =  params.set_default("spin_coeff",10.0f); // spin coefficient, controls speed of convergence (sort of)
02004         
02005         int np = 6; // the number of dimensions
02006         Dict gsl_params;
02007         gsl_params["this"] = this_img;
02008         gsl_params["with"] = to;
02009         gsl_params["snr"]  = params["snr"];
02010         gsl_params["mirror"] = mirror;
02011         gsl_params["transform"] = t;    
02012         gsl_params["spincoeff"] = spincoeff;
02013         Dict altered_cmp_params(cmp_params);
02014         
02015         const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
02016         gsl_vector *ss = gsl_vector_alloc(np);
02017         
02018         float stepi = params.set_default("stepn0",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway
02019         float stepj = params.set_default("stepn1",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway
02020         float stepk = params.set_default("stepn2",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway
02021         float stepx = params.set_default("stepx",1.0f);
02022         float stepy = params.set_default("stepy",1.0f);
02023         float stepz = params.set_default("stepz",1.0f);
02024         
02025         //gsl_vector_set(ss, 0, stepw);
02026         gsl_vector_set(ss, 0, stepi);
02027         gsl_vector_set(ss, 1, stepj);
02028         gsl_vector_set(ss, 2, stepk);
02029         gsl_vector_set(ss, 3, stepx);
02030         gsl_vector_set(ss, 4, stepy);
02031         gsl_vector_set(ss, 5, stepz);
02032         
02033         gsl_vector *x = gsl_vector_alloc(np);
02034         gsl_vector_set(x, 0, sdi);
02035         gsl_vector_set(x, 1, sdj);
02036         gsl_vector_set(x, 2, sdk);
02037         gsl_vector_set(x, 3, sdx);
02038         gsl_vector_set(x, 4, sdy);
02039         gsl_vector_set(x, 5, sdz);
02040         
02041         gsl_multimin_function minex_func;
02042         Cmp *c = Factory < Cmp >::get(cmp_name, altered_cmp_params);
02043                 
02044         gsl_params["cmp"] = (void *) c;
02045         minex_func.f = &refalifn3dquat;
02046 
02047         minex_func.n = np;
02048         minex_func.params = (void *) &gsl_params;
02049         
02050         gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, np);
02051         gsl_multimin_fminimizer_set(s, &minex_func, x, ss);
02052         
02053         int rval = GSL_CONTINUE;
02054         int status = GSL_SUCCESS;
02055         int iter = 1;
02056         
02057         float precision = params.set_default("precision",0.01f);
02058         int maxiter = params.set_default("maxiter",100);
02059         while (rval == GSL_CONTINUE && iter < maxiter) {
02060                 iter++;
02061                 status = gsl_multimin_fminimizer_iterate(s);
02062                 if (status) {
02063                         break;
02064                 }
02065                 rval = gsl_multimin_test_size(gsl_multimin_fminimizer_size(s), precision);
02066         }
02067 
02068         int maxshift = params.set_default("maxshift",-1);
02069 
02070         if (maxshift <= 0) {
02071                 maxshift = this_img->get_xsize() / 4;
02072         }
02073         float fmaxshift = static_cast<float>(maxshift);
02074         
02075         EMData *result;
02076         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))
02077         {
02078                 float n0 = (float)gsl_vector_get(s->x, 0);
02079                 float n1 = (float)gsl_vector_get(s->x, 1);
02080                 float n2 = (float)gsl_vector_get(s->x, 2);
02081                 float x = (float)gsl_vector_get(s->x, 3);
02082                 float y = (float)gsl_vector_get(s->x, 4);
02083                 float z = (float)gsl_vector_get(s->x, 5);
02084                 
02085                 Transform tsoln = refalin3d_perturbquat(t,spincoeff,n0,n1,n2,x,y,z);
02086                         
02087                 result = this_img->process("xform",Dict("transform",&tsoln));
02088                 result->set_attr("xform.align3d",&tsoln);
02089                 result->set_attr("score", result->cmp(cmp_name,to,cmp_params));
02090                 
02091          //coda goes here
02092         } else { // The refine aligner failed - this shift went beyond the max shift
02093                 result = this_img->process("xform",Dict("transform",t));
02094                 result->set_attr("xform.align3d",t);
02095                 result->set_attr("score",0.0);
02096         }
02097         
02098         //EMData *result = this_img->process("xform",Dict("transform",t));
02099         delete t;
02100         gsl_vector_free(x);
02101         gsl_vector_free(ss);
02102         gsl_multimin_fminimizer_free(s);
02103 
02104         if (c != 0) delete c;
02105         
02106         return result;
02107 }

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

Implements EMAN::Aligner.

Definition at line 1400 of file aligner.h.

01401                         {
01402                                 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision.";
01403                         }

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

References NAME.

01396                         {
01397                                 return NAME;
01398                         }

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

Implements EMAN::Aligner.

Definition at line 1410 of file aligner.h.

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

01411                         {
01412                                 TypeDict d;
01413                                 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used");
01414                                 d.put("stepx", EMObject::FLOAT, "The initial simplex step size in x. Default is 1");
01415                                 d.put("stepy", EMObject::FLOAT, "The initial simplex step size in y. Default is 1");
01416                                 d.put("stepz", EMObject::FLOAT, "The initial simplex step size in z. Default is 1." );
01417                                 d.put("stepn0", EMObject::FLOAT, "The initial simplex step size in the first quaternion vecotr component. Default is 1." );
01418                                 d.put("stepn1", EMObject::FLOAT, "The initial simplex step size in the second quaternion vecotr component. Default is 1." );
01419                                 d.put("stepn2", EMObject::FLOAT, "The initial simplex step size in the third quaternion vecotr component. Default is 1." );
01420                                 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.");
01421                                 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.01." );
01422                                 d.put("maxiter", EMObject::INT, "The maximum number of iterations that can be performed by the Simplex minimizer. Default is 100.");
01423                                 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.");
01424                                 return d;
01425                         }

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

Definition at line 1405 of file aligner.h.

01406                         {
01407                                 return new Refine3DAlignerQuaternion();
01408                         }


Member Data Documentation

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

Definition at line 1427 of file aligner.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Thu May 3 10:08:50 2012 for EMAN2 by  doxygen 1.4.7