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

References align().

01239                         {
01240                                 return align(this_img, to_img, "sqeuclidean", Dict());
01241                         }

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

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

02259 {
02260 
02261         vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params);
02262 
02263         Dict t;
02264         Transform* tr = (Transform*) alis[0]["xform.align3d"];
02265         t["transform"] = tr;
02266         EMData* soln = this_img->process("xform",t);
02267         soln->set_attr("xform.align3d",tr);
02268         delete tr; tr = 0;
02269 
02270         return soln;
02271 
02272 }

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

Implements EMAN::Aligner.

Definition at line 1253 of file aligner.h.

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

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

01249                         {
01250                                 return NAME;
01251                         }

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

Implements EMAN::Aligner.

Definition at line 1263 of file aligner.h.

References EMAN::TypeDict::put().

01264                         {
01265                                 TypeDict d;
01266                                 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (asymmetry).");
01267                                 d.put("orientgen", EMObject::STRING,"Advanced. The orientation generation strategy. Default is eman");
01268                                 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10");
01269                                 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");
01270                                 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10");
01271                                 d.put("phi0", EMObject::FLOAT,"Lower bound for phi. Default it 0");
01272                                 d.put("phi1", EMObject::FLOAT,"Upper bound for phi. Default it 360");
01273                                 d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)");
01274                                 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.");
01275                                 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.");
01276                                 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.");
01277                                 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");
01278                                 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
01279                                 return d;
01280                         }

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

Definition at line 1258 of file aligner.h.

01259                         {
01260                                 return new RT3DSphereAligner();
01261                         }

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

References EMAN::EMData::calc_ccf(), EMAN::EMData::calc_max_location_wrap(), calc_max_location_wrap_cuda(), EMAN::Cmp::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().

02274                                                                                                                                                                  {
02275 
02276         if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) {
02277                 throw ImageDimensionException("This aligner only works for 3D images");
02278         }
02279 
02280         int searchx = 0;
02281         int searchy = 0;
02282         int searchz = 0;
02283          
02284         bool dotrans = params.set_default("dotrans",1);
02285         if (params.has_key("search")) {
02286                 vector<string> check;
02287                 check.push_back("searchx");
02288                 check.push_back("searchy");
02289                 check.push_back("searchz");
02290                 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) {
02291                         if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters");
02292                 }
02293                 int search  = params["search"];
02294                 searchx = search;
02295                 searchy = search;
02296                 searchz = search;
02297         } else {
02298                 searchx = params.set_default("searchx",3);
02299                 searchy = params.set_default("searchy",3);
02300                 searchz = params.set_default("searchz",3);
02301         }
02302 
02303         float lphi = params.set_default("phi0",0.0f);
02304         float uphi = params.set_default("phi1",360.0f);
02305         float dphi = params.set_default("dphi",10.f);
02306         float threshold = params.set_default("threshold",0.f);
02307         if (threshold < 0.0f) throw InvalidParameterException("The threshold parameter must be greater than or equal to zero");
02308         bool verbose = params.set_default("verbose",false);
02309         
02310         //in case we arre aligning tomos
02311         Dict altered_cmp_params(cmp_params);
02312         if (cmp_name == "ccc.tomo") {
02313                 altered_cmp_params.set_default("searchx", searchx);
02314                 altered_cmp_params.set_default("searchy", searchy);
02315                 altered_cmp_params.set_default("searchz", searchz);
02316                 altered_cmp_params.set_default("norm", true);
02317         }
02318 
02319         vector<Dict> solns;
02320         if (nsoln == 0) return solns; // What was the user thinking?
02321         for (unsigned int i = 0; i < nsoln; ++i ) {
02322                 Dict d;
02323                 d["score"] = 1.e24;
02324                 Transform t; // identity by default
02325                 d["xform.align3d"] = &t; // deep copy is going on here
02326                 solns.push_back(d);
02327         }
02328 
02329         Dict d;
02330         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
02331         if ( params.has_key("delta") && params.has_key("n") ) {
02332                 throw InvalidParameterException("The delta and n parameters are mutually exclusive in the RT3DSphereAligner aligner");
02333         } else if ( params.has_key("n") ) {
02334                 d["n"] = params["n"];
02335         } else {
02336                 // If they didn't specify either then grab the default delta - if they did supply delta we're still safe doing this
02337                 d["delta"] = params.set_default("delta",10.f);
02338         }
02339 
02340         if ((string)params.set_default("orientgen","eman")=="eman") d["perturb"]=0;
02341         Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1"));
02342         vector<Transform> transforms = sym->gen_orientations((string)params.set_default("orientgen","eman"),d);
02343 
02344         bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0;
02345         
02346         //precompute fixed FT, saves a LOT of time!!!
02347         EMData * this_imgfft = 0;
02348         if(dotrans || tomography){
02349                 this_imgfft = this_img->do_fft();
02350         }
02351         
02352         
02353 #ifdef EMAN2_USING_CUDA 
02354         if(EMData::usecuda == 1) {
02355                 cout << "Using CUDA for 3D alignment" << endl;
02356                 if(!to->getcudarodata()) to->copy_to_cudaro(); // Safer call
02357                 if(!this_img->getcudarwdata()) this_img->copy_to_cuda();
02358                 if(this_imgfft) this_imgfft->copy_to_cuda();
02359         }
02360 #endif
02361 
02362         Transform trans = Transform();
02363         Cmp* c = Factory <Cmp>::get(cmp_name, cmp_params);
02364         bool use_cpu = true;
02365         for(vector<Transform>::const_iterator trans_it = transforms.begin(); trans_it != transforms.end(); trans_it++) {
02366                 Dict params = trans_it->get_params("eman");
02367                 
02368                 if (verbose) {
02369                         float alt = params["alt"];
02370                         float az = params["az"];
02371                         cout << "Trying angle alt: " << alt << " az: " << az << endl;
02372                 }
02373 
02374                 for( float phi = lphi; phi < uphi; phi += dphi ) { 
02375                         Transform t(params);
02376                         params["phi"] = phi;
02377                         t.set_rotation(params);
02378                         EMData* transformed = to->process("xform",Dict("transform",&t));
02379                         
02380                         //need to do things a bit diffrent if we want to compare two tomos
02381                         float best_score = 0.0f;
02382                         // Dotrans is effectievly ignored for tomography
02383                         if(dotrans || tomography){
02384                                 EMData* ccf = transformed->calc_ccf(this_imgfft);
02385 #ifdef EMAN2_USING_CUDA 
02386                                 if(this_img->getcudarwdata()){
02387                                         // I use the following code rather than ccc.tomo to avoid doing two CCCs
02388                                         use_cpu = false;
02389                                         CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz);
02390                                         trans.set_trans((float)-data->px, (float)-data->py, (float)-data->pz);
02391                                         t = trans*t;    //composite transform to reflect the fact that we have done a rotation first and THEN a transformation
02392                                         if (tomography) {
02393                                                 float2 stats = get_stats_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize());
02394                                                 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
02395                                         } else {
02396                                                 best_score = -data->peak;
02397                                         }
02398                                         delete data;
02399                                 }
02400 #endif
02401                                 if(use_cpu){
02402                                         // I use the following code rather than ccc.tomo to avoid doing two CCCs
02403                                         if(tomography) ccf->process_inplace("normalize");
02404                                         IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz);
02405                                         trans.set_trans((float)-point[0], (float)-point[1], (float)-point[2]);
02406                                         t = trans*t;    //composite transform to reflect the fact that we have done a rotation first and THEN a transformation
02407                                         best_score = -ccf->get_value_at_wrap(point[0], point[1], point[2]);
02408                                 }
02409                                 delete ccf; ccf =0;
02410                                 delete transformed; transformed = 0;// this is to stop a mem leak
02411                         }
02412 
02413                         if(!tomography){
02414                                 if(!transformed) transformed = to->process("xform",Dict("transform",&t));
02415                                 best_score = c->cmp(this_img,transformed);
02416                                 delete transformed; transformed = 0;
02417                         }
02418 
02419                         unsigned int j = 0;
02420                         //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;
02421                         for ( vector<Dict>::iterator it = solns.begin(); it != solns.end(); ++it, ++j ) {
02422                                 if ( (float)(*it)["score"] > best_score ) { // Note greater than - EMAN2 preferes minimums as a matter of policy
02423                                         vector<Dict>::reverse_iterator rit = solns.rbegin();
02424                                         copy(rit+1,solns.rend()-j,rit);
02425                                         Dict& d = (*it);
02426                                         d["score"] = best_score;
02427                                         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)
02428                                         d["xform.align3d"] = &t; // deep copy is going on here
02429                                         break;
02430                                 }
02431                         }
02432 
02433                 }
02434         }
02435         delete sym; sym = 0;
02436         if(this_imgfft) {delete this_imgfft; this_imgfft = 0;}
02437         
02438         //Free up resources (for an expensive opperation like this move data to and from device is a small % of time)
02439         #ifdef EMAN2_USING_CUDA
02440                 this_img->copy_from_device();
02441                 to->ro_free();
02442         #endif
02443         
02444         return solns;
02445 
02446 }


Member Data Documentation

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

Definition at line 80 of file aligner.cpp.


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