EMAN::Refine3DAlignerGridInefficient Class Reference

#include <aligner.h>

Inheritance diagram for EMAN::Refine3DAlignerGridInefficient:

Inheritance graph
[legend]
Collaboration diagram for EMAN::Refine3DAlignerGridInefficient:

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_grid_slow"

Detailed Description

Definition at line 898 of file aligner.h.


Member Function Documentation

virtual EMData* EMAN::Refine3DAlignerGridInefficient::align ( EMData this_img,
EMData to_img 
) const [inline, virtual]

Implements EMAN::Aligner.

Definition at line 904 of file aligner.h.

References align().

00905                         {
00906                                 return align(this_img, to_img, "sqeuclidean", Dict());
00907                         }

EMData * Refine3DAlignerGridInefficient::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 1713 of file aligner.cpp.

References EMAN::EMData::calc_ccf(), EMAN::EMData::calc_max_location_wrap(), calc_max_location_wrap_cuda(), EMAN::EMData::cmp(), data, EMAN::EMData::do_fft(), EMAN::EMData::get_attr(), EMAN::EMData::get_ndim(), get_stats_cuda(), EMAN::EMData::get_value_at_wrap(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), ImageDimensionException, InvalidParameterException, EMAN::Aligner::params, phi, EMAN::EMData::process(), EMAN::EMData::process_inplace(), EMAN::EMData::set_attr(), EMAN::Dict::set_default(), EMAN::Transform::set_trans(), sqrt(), and t.

Referenced by align().

01715 {
01716         if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) {
01717                 throw ImageDimensionException("This aligner only works for 3D images");
01718         }
01719 
01720         Transform* t;
01721         if (params.has_key("xform.align3d") ) {
01722                 // Unlike the 2d refine aligner, this class doesn't require the starting transform's
01723                 // parameters to form the starting guess. Instead the Transform itself
01724                 // is perturbed carefully (using quaternion rotation) to overcome problems that arise
01725                 // when you use orthogonally-based Euler angles
01726                 t = params["xform.align3d"];
01727         }else {
01728                 t = new Transform(); // is the identity
01729         }
01730         
01731         int searchx = 0;
01732         int searchy = 0;
01733         int searchz = 0;
01734         
01735         bool dotrans = params.set_default("dotrans",1);
01736         if (params.has_key("search")) {
01737                 vector<string> check;
01738                 check.push_back("searchx");
01739                 check.push_back("searchy");
01740                 check.push_back("searchz");
01741                 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) {
01742                         if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters");
01743                 }
01744                 int search  = params["search"];
01745                 searchx = search;
01746                 searchy = search;
01747                 searchz = search;
01748         } else {
01749                 searchx = params.set_default("searchx",3);
01750                 searchy = params.set_default("searchy",3);
01751                 searchz = params.set_default("searchz",3);
01752         }       
01753         
01754         float raz = params.set_default("raz",6.0f);
01755         float ralt = params.set_default("ralt",6.0f);
01756         float rphi = params.set_default("rphi",6.0f);
01757         float saz = params.set_default("saz",2.0f);
01758         float salt = params.set_default("salt",2.0f);
01759         float sphi = params.set_default("sphi",2.0f);
01760         bool verbose = params.set_default("verbose",false);
01761         
01762         bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0;
01763         EMData * tofft = 0;
01764         if(dotrans || tomography){
01765                 tofft = to->do_fft();
01766         }
01767         
01768 #ifdef EMAN2_USING_CUDA 
01769         if(EMData::usecuda == 1) {
01770                 if(!this_img->isrodataongpu()) this_img->copy_to_cudaro();
01771                 if(!to->cudarwdata) to->copy_to_cuda();
01772                 if(to->cudarwdata){if(tofft) tofft->copy_to_cuda();}
01773         }
01774 #endif
01775 
01776         Dict d;
01777         d["type"] = "eman"; // d is used in the loop below
01778         bool use_cpu = true;
01779         EMData* best_match = new EMData();
01780         best_match->set_attr("score", 0.0f);
01781         for ( float alt = -ralt; alt < ralt; alt += salt) {
01782                 // An optimization for the range of az is made at the top of the sphere
01783                 // If you think about it, this is just a coarse way of making this approach slightly more efficient
01784                 for ( float az = -raz; az < raz; az += saz ){
01785                         if (verbose) {
01786                                 cout << "Trying angle alt " << alt << " az " << az << endl;
01787                         }
01788                         for( float phi = -rphi; phi < rphi; phi += sphi ) {
01789                                 d["alt"] = alt;
01790                                 d["phi"] = phi; 
01791                                 d["az"] = az;
01792                                 Transform tr(d);
01793                                 tr = tr*(*t);   // compose transforms
01794                                 
01795                                 EMData* transformed = this_img->process("xform",Dict("transform",&tr));
01796                                 
01797                                 //need to do things a bit diffrent if we want to compare two tomos
01798                                 float score;
01799                                 if(dotrans || tomography){
01800                                         EMData* ccf = transformed->calc_ccf(tofft);
01801 #ifdef EMAN2_USING_CUDA 
01802                                         if(to->cudarwdata){
01803                                                 use_cpu = false;
01804                                                 float2 stats = get_stats_cuda(ccf->cudarwdata, ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize());
01805                                                 CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->cudarwdata, ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz);
01806                                                 tr.set_trans((float)-data->px, (float)-data->py, (float)-data->pz);
01807                                                 score = -(data->peak - stats.x)/sqrt(stats.y); // Normalize, this is better than calling the norm processor since we only need to normalize one point
01808                                         }
01809 #endif
01810                                         if(use_cpu){
01811                                                 if(tomography) ccf->process_inplace("normalize");       
01812                                                 IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz);
01813                                                 tr.set_trans((float)-point[0], (float)-point[1], (float)-point[2]);
01814                                                 score = -ccf->get_value_at_wrap(point[0], point[1], point[2]);
01815                                                 delete transformed; // this is to stop a mem leak
01816                                                 transformed = this_img->process("xform",Dict("transform",&tr));
01817                                         }
01818                                         delete ccf; ccf =0;
01819                                 }
01820 
01821                                 if(!tomography){
01822                                         score = transformed->cmp(cmp_name,to,cmp_params); //this is not very efficient as it creates a new cmp object for each iteration
01823                                 
01824                                 }
01825                                 
01826                                 float best_score = best_match->get_attr("score");
01827                                 if(score < best_score) {
01828                                         delete best_match;
01829                                         best_match = transformed;
01830                                         best_match->set_attr("xform.align3d",&tr);
01831                                         best_match->set_attr("score", score);
01832                                 } else {
01833                                         delete transformed; transformed = 0;
01834                                 }
01835                                         
01836                         }
01837                 }
01838         }
01839 
01840         if(tofft) {delete tofft; tofft = 0;}
01841         
01842         return best_match;
01843         
01844 }

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

Implements EMAN::Aligner.

Definition at line 914 of file aligner.h.

00915                         {
00916                                 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision.";
00917                         }

virtual string EMAN::Refine3DAlignerGridInefficient::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 909 of file aligner.h.

References NAME.

00910                         {
00911                                 return NAME;
00912                         }

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

Implements EMAN::Aligner.

Definition at line 924 of file aligner.h.

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

00925                         {
00926                                 TypeDict d;
00927                                 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used");
00928                                 d.put("saz", EMObject::FLOAT, "The angular step size for az. Default is 2." );
00929                                 d.put("salt", EMObject::FLOAT, "The The angular step size for alt. Default is 2." );
00930                                 d.put("sphi", EMObject::FLOAT, "The The angular step size for phi. Default is 2." );
00931                                 d.put("raz", EMObject::FLOAT, "The angular range(+- this amount) for az. Default is 180." );
00932                                 d.put("ralt", EMObject::FLOAT, "The The angular range(+- this amount) for alt. Default is 6." );
00933                                 d.put("rphi", EMObject::FLOAT, "The The angular range(+- this amount) for phi. Default is 6." );        
00934                                 d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)");
00935                                 d.put("search", EMObject::INT,"The maximum length of the detectable translational shift - if you supply this parameter you can not supply the maxshiftx, maxshifty or maxshiftz parameters. Each approach is mutually exclusive.");
00936                                 d.put("searchx", EMObject::INT,"The maximum length of the detectable translational shift in the x direction- if you supply this parameter you can not supply the maxshift parameters. Default is 3.");
00937                                 d.put("searchy", EMObject::INT,"The maximum length of the detectable translational shift in the y direction- if you supply this parameter you can not supply the maxshift parameters. Default is 3.");
00938                                 d.put("searchz", EMObject::INT,"The maximum length of the detectable translational shift in the z direction- if you supply this parameter you can not supply the maxshift parameters. Default is 3");
00939                                 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.");
00940                                 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
00941                                 return d;
00942                         }

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

Definition at line 919 of file aligner.h.

00920                         {
00921                                 return new Refine3DAlignerGridInefficient();
00922                         }


Member Data Documentation

const string Refine3DAlignerGridInefficient::NAME = "refine_3d_grid_slow" [static]

Definition at line 944 of file aligner.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Mon Mar 7 18:01:25 2011 for EMAN2 by  doxygen 1.4.7