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

References align().

01084                         {
01085                                 return align(this_img, to_img, "sqeuclidean", Dict());
01086                         }

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

01787 {
01788         
01789         if (!to || !this_img) throw NullPointerException("Input image is null"); // not sure if this is necessary, it was there before I started
01790 
01791         if (to->get_ndim() != 3 || this_img->get_ndim() != 3) throw ImageDimensionException("The Refine3D aligner only works for 3D images");
01792 
01793 #ifdef EMAN2_USING_CUDA 
01794         if(EMData::usecuda == 1) {
01795                 if(!this_img->getcudarwdata()) this_img->copy_to_cuda();
01796                 if(!to->getcudarwdata()) to->copy_to_cuda();
01797         }
01798 #endif
01799 
01800         float sdi = 0.0;
01801         float sdj = 0.0;
01802         float sdk = 0.0;
01803         float sdx = 0.0;
01804         float sdy = 0.0;
01805         float sdz = 0.0;
01806         bool mirror = false;
01807         
01808         Transform* t;
01809         if (params.has_key("xform.align3d") ) {
01810                 // Unlike the 2d refine aligner, this class doesn't require the starting transform's
01811                 // parameters to form the starting guess. Instead the Transform itself
01812                 // is perturbed carefully (using quaternion rotation) to overcome problems that arise
01813                 // when you use orthogonally-based Euler angles
01814                 t = params["xform.align3d"];
01815         }else {
01816                 t = new Transform(); // is the identity
01817         }
01818         
01819         float spincoeff =  params.set_default("spin_coeff",10.0f); // spin coefficient, controls speed of convergence (sort of)
01820         
01821         int np = 6; // the number of dimensions
01822         Dict gsl_params;
01823         gsl_params["this"] = this_img;
01824         gsl_params["with"] = to;
01825         gsl_params["snr"]  = params["snr"];
01826         gsl_params["mirror"] = mirror;
01827         gsl_params["transform"] = t;    
01828         gsl_params["spincoeff"] = spincoeff;
01829         Dict altered_cmp_params(cmp_params);
01830         
01831         const gsl_multimin_fminimizer_type *T = gsl_multimin_fminimizer_nmsimplex;
01832         gsl_vector *ss = gsl_vector_alloc(np);
01833         
01834         float stepi = params.set_default("stepn0",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway
01835         float stepj = params.set_default("stepn1",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway
01836         float stepk = params.set_default("stepn2",1.0f); // doesn't really matter b/c the vecor part will be normalized anyway
01837         float stepx = params.set_default("stepx",1.0f);
01838         float stepy = params.set_default("stepy",1.0f);
01839         float stepz = params.set_default("stepz",1.0f);
01840         
01841         //gsl_vector_set(ss, 0, stepw);
01842         gsl_vector_set(ss, 0, stepi);
01843         gsl_vector_set(ss, 1, stepj);
01844         gsl_vector_set(ss, 2, stepk);
01845         gsl_vector_set(ss, 3, stepx);
01846         gsl_vector_set(ss, 4, stepy);
01847         gsl_vector_set(ss, 5, stepz);
01848         
01849         gsl_vector *x = gsl_vector_alloc(np);
01850         gsl_vector_set(x, 0, sdi);
01851         gsl_vector_set(x, 1, sdj);
01852         gsl_vector_set(x, 2, sdk);
01853         gsl_vector_set(x, 3, sdx);
01854         gsl_vector_set(x, 4, sdy);
01855         gsl_vector_set(x, 5, sdz);
01856         
01857         gsl_multimin_function minex_func;
01858         Cmp *c = Factory < Cmp >::get(cmp_name, altered_cmp_params);
01859                 
01860         gsl_params["cmp"] = (void *) c;
01861         minex_func.f = &refalifn3dquat;
01862 
01863         minex_func.n = np;
01864         minex_func.params = (void *) &gsl_params;
01865         
01866         gsl_multimin_fminimizer *s = gsl_multimin_fminimizer_alloc(T, np);
01867         gsl_multimin_fminimizer_set(s, &minex_func, x, ss);
01868         
01869         int rval = GSL_CONTINUE;
01870         int status = GSL_SUCCESS;
01871         int iter = 1;
01872         
01873         float precision = params.set_default("precision",0.01f);
01874         int maxiter = params.set_default("maxiter",100);
01875         while (rval == GSL_CONTINUE && iter < maxiter) {
01876                 iter++;
01877                 status = gsl_multimin_fminimizer_iterate(s);
01878                 if (status) {
01879                         break;
01880                 }
01881                 rval = gsl_multimin_test_size(gsl_multimin_fminimizer_size(s), precision);
01882         }
01883 
01884         int maxshift = params.set_default("maxshift",-1);
01885 
01886         if (maxshift <= 0) {
01887                 maxshift = this_img->get_xsize() / 4;
01888         }
01889         float fmaxshift = static_cast<float>(maxshift);
01890         
01891         EMData *result;
01892         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))
01893         {
01894                 float n0 = (float)gsl_vector_get(s->x, 0);
01895                 float n1 = (float)gsl_vector_get(s->x, 1);
01896                 float n2 = (float)gsl_vector_get(s->x, 2);
01897                 float x = (float)gsl_vector_get(s->x, 3);
01898                 float y = (float)gsl_vector_get(s->x, 4);
01899                 float z = (float)gsl_vector_get(s->x, 5);
01900                 
01901                 Transform tsoln = refalin3d_perturbquat(t,spincoeff,n0,n1,n2,x,y,z);
01902                         
01903                 result = this_img->process("xform",Dict("transform",&tsoln));
01904                 result->set_attr("xform.align3d",&tsoln);
01905                 result->set_attr("score", result->cmp(cmp_name,to,cmp_params));
01906                 
01907          //coda goes here
01908         } else { // The refine aligner failed - this shift went beyond the max shift
01909                 result = this_img->process("xform",Dict("transform",t));
01910                 result->set_attr("xform.align3d",t);
01911                 result->set_attr("score",0.0);
01912         }
01913         
01914         //EMData *result = this_img->process("xform",Dict("transform",t));
01915         delete t;
01916         gsl_vector_free(x);
01917         gsl_vector_free(ss);
01918         gsl_multimin_fminimizer_free(s);
01919 
01920         if ( c != 0 ) delete c;
01921         
01922         //Free up resources (for an expensive opperation like this move data to and from device is a small % of time)
01923         #ifdef EMAN2_USING_CUDA
01924                 to->copy_from_device();
01925                 this_img->ro_free();
01926         #endif
01927         
01928         return result;
01929 }

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

Implements EMAN::Aligner.

Definition at line 1093 of file aligner.h.

01094                         {
01095                                 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision.";
01096                         }

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

01089                         {
01090                                 return NAME;
01091                         }

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

Implements EMAN::Aligner.

Definition at line 1103 of file aligner.h.

References EMAN::TypeDict::put().

01104                         {
01105                                 TypeDict d;
01106                                 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used");
01107                                 d.put("stepx", EMObject::FLOAT, "The initial simplex step size in x. Default is 1");
01108                                 d.put("stepy", EMObject::FLOAT, "The initial simplex step size in y. Default is 1");
01109                                 d.put("stepz", EMObject::FLOAT, "The initial simplex step size in z. Default is 1." );
01110                                 d.put("stepn0", EMObject::FLOAT, "The initial simplex step size in the first quaternion vecotr component. Default is 1." );
01111                                 d.put("stepn1", EMObject::FLOAT, "The initial simplex step size in the second quaternion vecotr component. Default is 1." );
01112                                 d.put("stepn2", EMObject::FLOAT, "The initial simplex step size in the third quaternion vecotr component. Default is 1." );
01113                                 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.");
01114                                 d.put("precision", EMObject::FLOAT, "The precision which, if achieved, can stop the iterative refinement before reaching the maximum iterations. Default is 0.01." );
01115                                 d.put("maxiter", EMObject::INT, "The maximum number of iterations that can be performed by the Simplex minimizer. Default is 100.");
01116                                 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.");
01117                                 return d;
01118                         }

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

Definition at line 1098 of file aligner.h.

01099                         {
01100                                 return new Refine3DAlignerQuaternion();
01101                         }


Member Data Documentation

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

Definition at line 78 of file aligner.cpp.


The documentation for this class was generated from the following files:
Generated on Thu Nov 17 12:45:17 2011 for EMAN2 by  doxygen 1.3.9.1