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 2011

Definition at line 1134 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 1143 of file aligner.h.

References align().

01144                         {
01145                                 return align(this_img, to_img, "sqeuclidean", Dict());
01146                         }

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 2059 of file aligner.cpp.

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

Referenced by align().

02060 {
02061 
02062         vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params);
02063 
02064         Dict t;
02065         Transform* tr = (Transform*) alis[0]["xform.align3d"];
02066         t["transform"] = tr;
02067         EMData* soln = this_img->process("xform",t);
02068         soln->set_attr("xform.align3d",tr);
02069         delete tr; tr = 0;
02070 
02071         return soln;
02072 
02073 }

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

Implements EMAN::Aligner.

Definition at line 1158 of file aligner.h.

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

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

References NAME.

01154                         {
01155                                 return NAME;
01156                         }

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

Implements EMAN::Aligner.

Definition at line 1168 of file aligner.h.

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

01169                         {
01170                                 TypeDict d;
01171                                 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (asymmetry).");
01172                                 d.put("orientgen", EMObject::STRING,"Advanced. The orientation generation strategy. Default is eman");
01173                                 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10");
01174                                 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");
01175                                 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10");
01176                                 d.put("phi0", EMObject::FLOAT,"Lower bound for phi. Default it 0");
01177                                 d.put("phi1", EMObject::FLOAT,"Upper bound for phi. Default it 360");
01178                                 d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)");
01179                                 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.");
01180                                 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.");
01181                                 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.");
01182                                 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");
01183                                 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
01184                                 return d;
01185                         }

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

Definition at line 1163 of file aligner.h.

01164                         {
01165                                 return new RT3DSphereAligner();
01166                         }

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 2075 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(), EMAN::Transform::set_trans(), sqrt(), and t.

Referenced by align().

02075                                                                                                                                                                  {
02076 
02077         if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) {
02078                 throw ImageDimensionException("This aligner only works for 3D images");
02079         }
02080 
02081         int searchx = 0;
02082         int searchy = 0;
02083         int searchz = 0;
02084          
02085         bool dotrans = params.set_default("dotrans",1);
02086         if (params.has_key("search")) {
02087                 vector<string> check;
02088                 check.push_back("searchx");
02089                 check.push_back("searchy");
02090                 check.push_back("searchz");
02091                 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) {
02092                         if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters");
02093                 }
02094                 int search  = params["search"];
02095                 searchx = search;
02096                 searchy = search;
02097                 searchz = search;
02098         } else {
02099                 searchx = params.set_default("searchx",3);
02100                 searchy = params.set_default("searchy",3);
02101                 searchz = params.set_default("searchz",3);
02102         }
02103 
02104         float lphi = params.set_default("phi0",0.0f);
02105         float uphi = params.set_default("phi1",360.0f);
02106         float dphi = params.set_default("dphi",10.f);
02107         float threshold = params.set_default("threshold",0.f);
02108         if (threshold < 0.0f) throw InvalidParameterException("The threshold parameter must be greater than or equal to zero");
02109         bool verbose = params.set_default("verbose",false);
02110         
02111         //in case we arre aligning tomos
02112         Dict altered_cmp_params(cmp_params);
02113         if (cmp_name == "ccc.tomo") {
02114                 altered_cmp_params.set_default("searchx", searchx);
02115                 altered_cmp_params.set_default("searchy", searchy);
02116                 altered_cmp_params.set_default("searchz", searchz);
02117                 altered_cmp_params.set_default("norm", true);
02118         }
02119 
02120         vector<Dict> solns;
02121         if (nsoln == 0) return solns; // What was the user thinking?
02122         for (unsigned int i = 0; i < nsoln; ++i ) {
02123                 Dict d;
02124                 d["score"] = 1.e24;
02125                 Transform t; // identity by default
02126                 d["xform.align3d"] = &t; // deep copy is going on here
02127                 solns.push_back(d);
02128         }
02129 
02130         Dict d;
02131         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
02132         if ( params.has_key("delta") && params.has_key("n") ) {
02133                 throw InvalidParameterException("The delta and n parameters are mutually exclusive in the RT3DSphereAligner aligner");
02134         } else if ( params.has_key("n") ) {
02135                 d["n"] = params["n"];
02136         } else {
02137                 // If they didn't specify either then grab the default delta - if they did supply delta we're still safe doing this
02138                 d["delta"] = params.set_default("delta",10.f);
02139         }
02140 
02141         if ((string)params.set_default("orientgen","eman")=="eman") d["perturb"]=0;
02142         Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1"));
02143         vector<Transform> transforms = sym->gen_orientations((string)params.set_default("orientgen","eman"),d);
02144 
02145         bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0;
02146         
02147         //precompute fixed FT, saves a LOT of time!!!
02148         EMData * this_imgfft = 0;
02149         if(dotrans || tomography){
02150                 this_imgfft = this_img->do_fft();
02151         }
02152         
02153         
02154 #ifdef EMAN2_USING_CUDA 
02155         if(EMData::usecuda == 1) {
02156                 cout << "Using CUDA for 3D alignment" << endl;
02157                 if(!to->getcudarodata()) to->copy_to_cudaro(); // Safer call
02158                 if(!this_img->getcudarwdata()) this_img->copy_to_cuda();
02159                 if(this_imgfft) this_imgfft->copy_to_cuda();
02160         }
02161 #endif
02162 
02163         Transform trans = Transform();
02164         bool use_cpu = true;
02165         for(vector<Transform>::const_iterator trans_it = transforms.begin(); trans_it != transforms.end(); trans_it++) {
02166                 Dict params = trans_it->get_params("eman");
02167                 
02168                 if (verbose) {
02169                         float alt = params["alt"];
02170                         float az = params["az"];
02171                         cout << "Trying angle alt: " << alt << " az: " << az << endl;
02172                 }
02173 
02174                 for( float phi = lphi; phi < uphi; phi += dphi ) { 
02175                         Transform t(params);
02176                         params["phi"] = phi;
02177                         t.set_rotation(params);
02178                         EMData* transformed = to->process("xform",Dict("transform",&t));
02179                         
02180                         //need to do things a bit diffrent if we want to compare two tomos
02181                         float best_score = 0.0f;
02182                         // Dotrans is effectievly ignored for tomography
02183                         if(dotrans || tomography){
02184                                 EMData* ccf = transformed->calc_ccf(this_imgfft);
02185 #ifdef EMAN2_USING_CUDA 
02186                                 if(this_img->getcudarwdata()){
02187                                         use_cpu = false;
02188                                         CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz);
02189                                         trans.set_trans((float)-data->px, (float)-data->py, (float)-data->pz);
02190                                         t = trans*t;    //composite transform to reflect the fact that we have done a rotation first and THEN a transformation
02191                                         if (tomography) {
02192                                                 float2 stats = get_stats_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize());
02193                                                 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
02194                                         } else {
02195                                                 best_score = -data->peak;
02196                                         }
02197                                         delete data;
02198                                 }
02199 #endif
02200                                 if(use_cpu){
02201                                         if(tomography) ccf->process_inplace("normalize");
02202                                         IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz);
02203                                         trans.set_trans((float)-point[0], (float)-point[1], (float)-point[2]);
02204                                         t = trans*t;    //composite transform to reflect the fact that we have done a rotation first and THEN a transformation
02205                                         best_score = -ccf->get_value_at_wrap(point[0], point[1], point[2]);
02206                                 }
02207                                 delete ccf; ccf =0;
02208                                 delete transformed; transformed = 0;// this is to stop a mem leak
02209                         }
02210 
02211                         if(!tomography){
02212                                 if(!transformed) transformed = to->process("xform",Dict("transform",&t));
02213                                 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
02214                                 delete transformed; transformed = 0;
02215                         }
02216 
02217                         unsigned int j = 0;
02218                         //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;
02219                         for ( vector<Dict>::iterator it = solns.begin(); it != solns.end(); ++it, ++j ) {
02220                                 if ( (float)(*it)["score"] > best_score ) { // Note greater than - EMAN2 preferes minimums as a matter of policy
02221                                         vector<Dict>::reverse_iterator rit = solns.rbegin();
02222                                         copy(rit+1,solns.rend()-j,rit);
02223                                         Dict& d = (*it);
02224                                         d["score"] = best_score;
02225                                         t.invert(); //We actually moved the ref onto the moving, so we need to invert to do the opposite(this is done b/c the ref is aligned to the sym axis, whereas the mvoing is not)
02226                                         d["xform.align3d"] = &t; // deep copy is going on here
02227                                         break;
02228                                 }
02229                         }
02230 
02231                 }
02232         }
02233         delete sym; sym = 0;
02234         if(this_imgfft) {delete this_imgfft; this_imgfft = 0;}
02235         
02236         //Free up resources (for an expensive opperation like this move data to and from device is a small % of time)
02237         #ifdef EMAN2_USING_CUDA
02238                 this_img->copy_from_device();
02239                 to->ro_free();
02240         #endif
02241         
02242         return solns;
02243 
02244 }


Member Data Documentation

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

Definition at line 1187 of file aligner.h.

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Tue Jul 12 13:47:58 2011 for EMAN2 by  doxygen 1.4.7