Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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

AlignerNEW ()

Static Public Attributes

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

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

02028 {
02029 
02030         vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params);
02031 
02032         Dict t;
02033         Transform* tr = (Transform*) alis[0]["xform.align3d"];
02034         t["transform"] = tr;
02035         EMData* soln = this_img->process("xform",t);
02036         soln->set_attr("xform.align3d",tr);
02037         delete tr; tr = 0;
02038 
02039         return soln;
02040 
02041 }

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.

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::TypeDict::put().

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                         }

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 2043 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::Dict::end(), EMAN::Symmetry3D::gen_orientations(), EMAN::Factory< T >::get(), 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::Transform::invert(), CudaPeakInfo::peak, phi, EMAN::EMData::process(), EMAN::EMData::process_inplace(), CudaPeakInfo::px, CudaPeakInfo::py, CudaPeakInfo::pz, EMAN::Dict::set_default(), EMAN::Transform::set_rotation(), EMAN::Transform::set_trans(), sqrt(), and t.

Referenced by align().

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


Member Data Documentation

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

Definition at line 77 of file aligner.cpp.


The documentation for this class was generated from the following files:
Generated on Thu Mar 10 22:59:50 2011 for EMAN2 by  doxygen 1.3.9.1