EMAN::RT3DSphereAligner Class Reference
[a function or class that is CUDA enabled]

3D rotational and translational alignment using spherical sampling, can reduce the search space based on symmetry. More...

#include <aligner.h>

Inheritance diagram for EMAN::RT3DSphereAligner:

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

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
 See Aligner comments for more details.
virtual EMDataalign (EMData *this_img, EMData *to_img) const
 See Aligner comments for more details.
virtual vector< Dictxform_align_nbest (EMData *this_img, EMData *to_img, const unsigned int nsoln, const string &cmp_name, const Dict &cmp_params) const
 See Aligner comments for more details.
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 = "rotate_translate_3d"

Detailed Description

3D rotational and translational alignment using spherical sampling, can reduce the search space based on symmetry.

can also make use of different OrientationGenerators (random, for example) 2X more efficient than the RT3DGridAligner The aligner actually aligns the reference to the 'moving' and then takes the inverse of the resulting transform. This is necessary because, in the case of symmetry (i.e. not c1), the reference symmetry axis must be aligned to the EMAN2 symmetry axis, restricting the search space to the asymmetrical points on a sphere. We note that if the reference symmetry axis is not aligned to the EMAN2 symmetry axis, the best thing is to do a full search (i.e. specify sym='c1') unless you really know what you are doing!

Parameters:
sym The symmtery to use as the basis of the spherical sampling
orietgen Advanced. The orientation generation strategy
delta Angle the separates points on the sphere. This is exclusive of the 'n' paramater
n An alternative to the delta argument, this is the number of points you want generated on the sphere
dphi The angle increment in the phi direction
lphi Lower bound for the phi direction
uphi Upper bound for the phi direction
dotrans Do a translational search
search 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
searchx The maximum length of the detectable translational shift in the x direction- if you supply this parameter you can not supply the maxshift parameters
searchy The maximum length of the detectable translational shift in the y direction- if you supply this parameter you can not supply the maxshift parameters
searchz The maximum length of the detectable translational shift in the z direction- if you supply this parameter you can not supply the maxshift parameters
verbose Turn this on to have useful information printed to standard out
Author:
John Flanagan and David Woolford
Date:
Feb 2010

Definition at line 1119 of file aligner.h.


Member Function Documentation

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

See Aligner comments for more details.

Implements EMAN::Aligner.

Definition at line 1128 of file aligner.h.

References align().

01129                         {
01130                                 return align(this_img, to_img, "sqeuclidean", Dict());
01131                         }

EMData * RT3DSphereAligner::align ( EMData this_img,
EMData to_img,
const string &  cmp_name = "sqeuclidean",
const Dict cmp_params = Dict() 
) const [virtual]

See Aligner comments for more details.

Implements EMAN::Aligner.

Definition at line 2002 of file aligner.cpp.

References EMAN::EMData::process(), EMAN::EMData::set_attr(), t, and xform_align_nbest().

Referenced by align().

02003 {
02004 
02005         vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params);
02006 
02007         Dict t;
02008         Transform* tr = (Transform*) alis[0]["xform.align3d"];
02009         t["transform"] = tr;
02010         EMData* soln = this_img->process("xform",t);
02011         soln->set_attr("xform.align3d",tr);
02012         delete tr; tr = 0;
02013 
02014         return soln;
02015 
02016 }

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

Implements EMAN::Aligner.

Definition at line 1143 of file aligner.h.

01144                         {
01145                                 return "3D rotational and translational alignment using spherical sampling. Can reduce the search space if symmetry is supplied";
01146                         }

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

References NAME.

01139                         {
01140                                 return NAME;
01141                         }

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

Implements EMAN::Aligner.

Definition at line 1153 of file aligner.h.

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

01154                         {
01155                                 TypeDict d;
01156                                 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (asymmetry).");
01157                                 d.put("orientgen", EMObject::STRING,"Advanced. The orientation generation strategy. Default is eman");
01158                                 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10");
01159                                 d.put("n", EMObject::INT,"An alternative to the delta argument, this is the number of points you want generated on the sphere. Default is OFF");
01160                                 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10");
01161                                 d.put("phi0", EMObject::FLOAT,"Lower bound for phi. Default it 0");
01162                                 d.put("phi1", EMObject::FLOAT,"Upper bound for phi. Default it 360");
01163                                 d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)");
01164                                 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.");
01165                                 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.");
01166                                 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.");
01167                                 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");
01168                                 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
01169                                 return d;
01170                         }

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

Definition at line 1148 of file aligner.h.

01149                         {
01150                                 return new RT3DSphereAligner();
01151                         }

vector< Dict > RT3DSphereAligner::xform_align_nbest ( EMData this_img,
EMData to_img,
const unsigned int  nsoln,
const string &  cmp_name,
const Dict cmp_params 
) const [virtual]

See Aligner comments for more details.

Reimplemented from EMAN::Aligner.

Definition at line 2018 of file aligner.cpp.

References EMAN::EMData::calc_ccf(), EMAN::EMData::calc_max_location_wrap(), calc_max_location_wrap_cuda(), EMAN::EMData::cmp(), copy(), data, EMAN::EMData::do_fft(), EMAN::Symmetry3D::gen_orientations(), 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::Dict::set_default(), sqrt(), and t.

Referenced by align().

02018                                                                                                                                                                  {
02019 
02020         if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) {
02021                 throw ImageDimensionException("This aligner only works for 3D images");
02022         }
02023 
02024         int searchx = 0;
02025         int searchy = 0;
02026         int searchz = 0;
02027          
02028         bool dotrans = params.set_default("dotrans",1);
02029         if (params.has_key("search")) {
02030                 vector<string> check;
02031                 check.push_back("searchx");
02032                 check.push_back("searchy");
02033                 check.push_back("searchz");
02034                 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) {
02035                         if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters");
02036                 }
02037                 int search  = params["search"];
02038                 searchx = search;
02039                 searchy = search;
02040                 searchz = search;
02041         } else {
02042                 searchx = params.set_default("searchx",3);
02043                 searchy = params.set_default("searchy",3);
02044                 searchz = params.set_default("searchz",3);
02045         }
02046 
02047         float lphi = params.set_default("phi0",0.0f);
02048         float uphi = params.set_default("phi1",360.0f);
02049         float dphi = params.set_default("dphi",10.f);
02050         float threshold = params.set_default("threshold",0.f);
02051         if (threshold < 0.0f) throw InvalidParameterException("The threshold parameter must be greater than or equal to zero");
02052         bool verbose = params.set_default("verbose",false);
02053         
02054         //in case we arre aligning tomos
02055         Dict altered_cmp_params(cmp_params);
02056         if (cmp_name == "ccc.tomo") {
02057                 altered_cmp_params.set_default("searchx", searchx);
02058                 altered_cmp_params.set_default("searchy", searchy);
02059                 altered_cmp_params.set_default("searchz", searchz);
02060                 altered_cmp_params.set_default("norm", true);
02061         }
02062 
02063         vector<Dict> solns;
02064         if (nsoln == 0) return solns; // What was the user thinking?
02065         for (unsigned int i = 0; i < nsoln; ++i ) {
02066                 Dict d;
02067                 d["score"] = 1.e24;
02068                 Transform t; // identity by default
02069                 d["xform.align3d"] = &t; // deep copy is going on here
02070                 solns.push_back(d);
02071         }
02072 
02073         Dict d;
02074         d["inc_mirror"] = true; // This should probably always be true for 3D case. If it ever changes we might have to make inc_mirror a parameter
02075         if ( params.has_key("delta") && params.has_key("n") ) {
02076                 throw InvalidParameterException("The delta and n parameters are mutually exclusive in the RT3DSphereAligner aligner");
02077         } else if ( params.has_key("n") ) {
02078                 d["n"] = params["n"];
02079         } else {
02080                 // If they didn't specify either then grab the default delta - if they did supply delta we're still safe doing this
02081                 d["delta"] = params.set_default("delta",10.f);
02082         }
02083 
02084         if ((string)params.set_default("orientgen","eman")=="eman") d["perturb"]=0;
02085         Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1"));
02086         vector<Transform> transforms = sym->gen_orientations((string)params.set_default("orientgen","eman"),d);
02087 
02088         float verbose_alt = -1.0f;
02089         bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0;
02090         
02091         //precompute fixed FT, saves a LOT of time!!!
02092         EMData * this_imgfft = 0;
02093         if(dotrans || tomography){
02094                 this_imgfft = this_img->do_fft();
02095         }
02096         
02097         
02098 #ifdef EMAN2_USING_CUDA 
02099         if(EMData::usecuda == 1) {
02100                 cout << "Using CUDA for 3D alignment" << endl;
02101                 if(!to->isrodataongpu()) to->copy_to_cudaro();
02102                 if(!this_img->cudarwdata) this_img->copy_to_cuda();
02103                 if(this_imgfft) this_imgfft->copy_to_cuda();
02104         }
02105 #endif
02106 
02107         bool use_cpu = true;
02108         for(vector<Transform>::const_iterator trans_it = transforms.begin(); trans_it != transforms.end(); trans_it++) {
02109                 Dict params = trans_it->get_params("eman");
02110                 Transform t(params);
02111                 if (verbose) {
02112                         float alt = params["alt"];
02113                         float az = params["az"];
02114                         cout << "Trying angle alt: " << alt << " az: " << az << endl;
02115                 }
02116 
02117                 for( float phi = lphi; phi < uphi; phi += dphi ) { 
02118                         
02119                         params["phi"] = phi;
02120                         t.set_rotation(params);
02121                         EMData* transformed = to->process("xform",Dict("transform",&t));
02122                         
02123                         //need to do things a bit diffrent if we want to compare two tomos
02124                         float best_score;
02125                         if(dotrans || tomography){
02126                                 EMData* ccf = transformed->calc_ccf(this_imgfft);
02127 #ifdef EMAN2_USING_CUDA 
02128                                 if(this_img->cudarwdata){
02129                                         use_cpu = false;
02130                                         float2 stats = get_stats_cuda(ccf->cudarwdata, ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize());
02131                                         CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->cudarwdata, ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz);
02132                                         t.set_trans((float)-data->px, (float)-data->py, (float)-data->pz);
02133                                         best_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
02134                                         delete data;
02135                                 }
02136 #endif
02137                                 if(use_cpu){
02138                                         if(tomography) ccf->process_inplace("normalize");
02139                                         IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz);
02140                                         t.set_trans((float)-point[0], (float)-point[1], (float)-point[2]);
02141                                         best_score = -ccf->get_value_at_wrap(point[0], point[1], point[2]);
02142                                         delete transformed; // this is to stop a mem leak
02143                                         transformed = to->process("xform",Dict("transform",&t));
02144                                 }
02145                                 delete ccf; ccf =0;
02146                         }
02147 
02148                         if(!tomography){
02149                                 best_score = transformed->cmp(cmp_name,this_img,cmp_params); //this is not very efficient as it creates a new cmp object for each iteration
02150                                 
02151                         }
02152                         delete transformed; transformed =0;
02153 
02154                         unsigned int j = 0;
02155                         //cout << "alt " <<float(t.get_rotation("eman").get("alt")) << " az " << float(t.get_rotation("eman").get("az")) << " phi " << float(t.get_rotation("eman").get("phi")) << endl;
02156                         for ( vector<Dict>::iterator it = solns.begin(); it != solns.end(); ++it, ++j ) {
02157                                 if ( (float)(*it)["score"] > best_score ) { // Note greater than - EMAN2 preferes minimums as a matter of policy
02158                                         vector<Dict>::reverse_iterator rit = solns.rbegin();
02159                                         copy(rit+1,solns.rend()-j,rit);
02160                                         Dict& d = (*it);
02161                                         d["score"] = best_score;
02162                                         t.invert();
02163                                         d["xform.align3d"] = &t; // deep copy is going on here
02164                                         break;
02165                                 }
02166                         }
02167 
02168                 }
02169         }
02170         delete sym; sym = 0;
02171         if(this_imgfft) {delete this_imgfft; this_imgfft = 0;}
02172         return solns;
02173 
02174 }


Member Data Documentation

const string RT3DSphereAligner::NAME = "rotate_translate_3d" [static]

Definition at line 1172 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:26 2011 for EMAN2 by  doxygen 1.4.7