EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
EMAN::RT3DSphereAligner Class Reference

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]

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. More...
 
virtual EMDataalign (EMData *this_img, EMData *to_img) const
 See Aligner comments for more details. More...
 
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. More...
 
virtual string get_name () const
 Get the Aligner's name. More...
 
virtual string get_desc () const
 
virtual TypeDict get_param_types () const
 
- Public Member Functions inherited from EMAN::Aligner
virtual ~Aligner ()
 
virtual Dict get_params () const
 Get the Aligner parameters in a key/value dictionary. More...
 
virtual void set_params (const Dict &new_params)
 Set the Aligner parameters using a key/value dictionary. More...
 

Static Public Member Functions

static AlignerNEW ()
 

Static Public Attributes

static const string NAME = "rotate_translate_3d"
 

Additional Inherited Members

- Protected Attributes inherited from EMAN::Aligner
Dict params
 

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
symThe symmtery to use as the basis of the spherical sampling
orietgenAdvanced. The orientation generation strategy
deltaAngle the separates points on the sphere. This is exclusive of the 'n' paramater
nAn alternative to the delta argument, this is the number of points you want generated on the sphere
dphiThe angle increment in the phi direction
lphiLower bound for the phi direction
uphiUpper bound for the phi direction
dotransDo a translational search
searchThe 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
searchxThe maximum length of the detectable translational shift in the x direction- if you supply this parameter you can not supply the maxshift parameters
searchyThe maximum length of the detectable translational shift in the y direction- if you supply this parameter you can not supply the maxshift parameters
searchzThe maximum length of the detectable translational shift in the z direction- if you supply this parameter you can not supply the maxshift parameters
verboseTurn this on to have useful information printed to standard out
Author
John Flanagan and David Woolford
Date
Feb 2011

Definition at line 1699 of file aligner.h.

Member Function Documentation

◆ align() [1/2]

virtual EMData * EMAN::RT3DSphereAligner::align ( EMData this_img,
EMData to_img 
) const
inlinevirtual

See Aligner comments for more details.

Implements EMAN::Aligner.

Definition at line 1708 of file aligner.h.

1709 {
1710 return align(this_img, to_img, "sqeuclidean", Dict());
1711 }
virtual EMData * align(EMData *this_img, EMData *to_img, const string &cmp_name="sqeuclidean", const Dict &cmp_params=Dict()) const
See Aligner comments for more details.

References align().

◆ align() [2/2]

virtual EMData * EMAN::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.

Referenced by align().

◆ get_desc()

virtual string EMAN::RT3DSphereAligner::get_desc ( ) const
inlinevirtual

Implements EMAN::Aligner.

Definition at line 1723 of file aligner.h.

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

◆ get_name()

virtual string EMAN::RT3DSphereAligner::get_name ( ) const
inlinevirtual

Get the Aligner's name.

Each Aligner is identified by a unique name.

Returns
The Aligner's name.

Implements EMAN::Aligner.

Definition at line 1718 of file aligner.h.

1719 {
1720 return NAME;
1721 }
static const string NAME
Definition: aligner.h:1753

References NAME.

◆ get_param_types()

virtual TypeDict EMAN::RT3DSphereAligner::get_param_types ( ) const
inlinevirtual

Implements EMAN::Aligner.

Definition at line 1733 of file aligner.h.

1734 {
1735 TypeDict d;
1736 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (asymmetry).");
1737 d.put("orientgen", EMObject::STRING,"Advanced. The orientation generation strategy. Default is eman");
1738 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10");
1739 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");
1740 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10");
1741 d.put("phi0", EMObject::FLOAT,"Lower bound for phi. Default it 0");
1742 d.put("phi1", EMObject::FLOAT,"Upper bound for phi. Default it 360");
1743 d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)");
1744 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.");
1745 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.");
1746 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.");
1747 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");
1748 d.put("initxform", EMObject::TRANSFORM,"The Transform storing the starting position. If unspecified the identity matrix is used");
1749 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out.");
1750 return d;
1751 }

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

◆ NEW()

static Aligner * EMAN::RT3DSphereAligner::NEW ( )
inlinestatic

Definition at line 1728 of file aligner.h.

1729 {
1730 return new RT3DSphereAligner();
1731 }

◆ xform_align_nbest()

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

4394 {
4395
4396 if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) {
4397 throw ImageDimensionException("This aligner only works for 3D images");
4398 }
4399
4400 int searchx = 0;
4401 int searchy = 0;
4402 int searchz = 0;
4403
4404 bool dotrans = params.set_default("dotrans",1);
4405 if (params.has_key("search")) {
4406 vector<string> check;
4407 check.push_back("searchx");
4408 check.push_back("searchy");
4409 check.push_back("searchz");
4410 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) {
4411 if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters");
4412 }
4413 int search = params["search"];
4414 searchx = search;
4415 searchy = search;
4416 searchz = search;
4417 } else {
4418 searchx = params.set_default("searchx",3);
4419 searchy = params.set_default("searchy",3);
4420 searchz = params.set_default("searchz",3);
4421 }
4422
4423 Transform* initxform;
4424 if (params.has_key("initxform") ) {
4425 // Unlike the 2d refine aligner, this class doesn't require the starting transform's
4426 // parameters to form the starting guess. Instead the Transform itself
4427 // is perturbed carefully (using quaternion rotation) to overcome problems that arise
4428 // when you use orthogonally-based Euler angles
4429 initxform = params["initxform"];
4430 }else {
4431 initxform = new Transform(); // is the identity
4432 }
4433
4434 float lphi = params.set_default("phi0",0.0f);
4435 float uphi = params.set_default("phi1",360.0f);
4436 float dphi = params.set_default("dphi",10.f);
4437 float threshold = params.set_default("threshold",0.f);
4438 if (threshold < 0.0f) throw InvalidParameterException("The threshold parameter must be greater than or equal to zero");
4439 bool verbose = params.set_default("verbose",false);
4440
4441 //in case we are aligning tomos
4442 Dict altered_cmp_params(cmp_params);
4443 if (cmp_name == "ccc.tomo") {
4444 altered_cmp_params.set_default("searchx", searchx);
4445 altered_cmp_params.set_default("searchy", searchy);
4446 altered_cmp_params.set_default("searchz", searchz);
4447 altered_cmp_params.set_default("norm", true);
4448 }
4449
4450 vector<Dict> solns;
4451 if (nsoln == 0) return solns; // What was the user thinking?
4452 for (unsigned int i = 0; i < nsoln; ++i ) {
4453 Dict d;
4454 d["score"] = 1.e24;
4455 Transform t; // identity by default
4456 d["xform.align3d"] = &t; // deep copy is going on here
4457 solns.push_back(d);
4458 }
4459
4460 Dict d;
4461 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
4462 if ( params.has_key("delta") && params.has_key("n") ) {
4463 throw InvalidParameterException("The delta and n parameters are mutually exclusive in the RT3DSphereAligner aligner");
4464 } else if ( params.has_key("n") ) {
4465 d["n"] = params["n"];
4466 } else {
4467 // If they didn't specify either then grab the default delta - if they did supply delta we're still safe doing this
4468 d["delta"] = params.set_default("delta",10.f);
4469 }
4470
4471 if ((string)params.set_default("orientgen","eman")=="eman") d["perturb"]=0;
4472 Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1"));
4473 vector<Transform> transforms = sym->gen_orientations((string)params.set_default("orientgen","eman"),d);
4474
4475 bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0;
4476
4477 //precompute fixed FT, saves a LOT of time!!!
4478 EMData * this_imgfft = 0;
4479 if(dotrans || tomography){
4480 this_imgfft = this_img->do_fft();
4481 }
4482
4483#ifdef EMAN2_USING_CUDA
4484 if(EMData::usecuda == 1) {
4485 cout << "Using CUDA for 3D alignment" << endl;
4486 if(!to->getcudarodata()) to->copy_to_cudaro(); // Safer call
4487 if(!this_img->getcudarwdata()) this_img->copy_to_cuda();
4488 if(this_imgfft) this_imgfft->copy_to_cuda();
4489 }
4490#endif
4491
4492 Transform trans = Transform();
4493 Cmp* c = Factory <Cmp>::get(cmp_name, cmp_params);
4494
4495 bool use_cpu = true;
4496 for(vector<Transform>::const_iterator trans_it = transforms.begin(); trans_it != transforms.end(); trans_it++) {
4497 Dict params = trans_it->get_params("eman");
4498
4499 if (verbose) {
4500 float alt = params["alt"];
4501 float az = params["az"];
4502 cout << "Trying angle alt: " << alt << " az: " << az << endl;
4503 }
4504
4505 for( float phi = lphi; phi < uphi; phi += dphi ) {
4506 params["phi"] = phi;
4507 Transform t(params);
4508 t = t*(*initxform);
4509
4510 EMData* transformed;
4511 transformed = to->process("xform",Dict("transform",&t));
4512
4513 //need to do things a bit diffrent if we want to compare two tomos
4514 float best_score = 0.0f;
4515 // Dotrans is effectievly ignored for tomography
4516 if(dotrans || tomography){
4517 EMData* ccf = transformed->calc_ccf(this_imgfft);
4518#ifdef EMAN2_USING_CUDA
4519 if(EMData::usecuda == 1){
4520 // I use the following code rather than ccc.tomo to avoid doing two CCCs
4521 use_cpu = false;
4522 CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz);
4523 trans.set_trans((float)-data->px, (float)-data->py, (float)-data->pz);
4524 t = trans*t; //composite transform to reflect the fact that we have done a rotation first and THEN a transformation
4525 if (tomography) {
4526 float2 stats = get_stats_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize());
4527 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
4528 } else {
4529 best_score = -data->peak;
4530 }
4531 delete data;
4532 }
4533#endif
4534 if(use_cpu){
4535 // I use the following code rather than ccc.tomo to avoid doing two CCCs
4536 if(tomography) ccf->process_inplace("normalize");
4537 IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz);
4538 trans.set_trans((float)-point[0], (float)-point[1], (float)-point[2]);
4539 t = trans*t; //composite transform to reflect the fact that we have done a rotation first and THEN a transformation
4540 best_score = -ccf->get_value_at_wrap(point[0], point[1], point[2]);
4541 }
4542 delete ccf; ccf =0;
4543 delete transformed; transformed = 0;// this is to stop a mem leak
4544 }
4545
4546 if(!tomography){
4547 if(!transformed) transformed = to->process("xform",Dict("transform",&t));
4548 best_score = c->cmp(this_img,transformed);
4549 delete transformed; transformed = 0;
4550 }
4551
4552 unsigned int j = 0;
4553 //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;
4554 for ( vector<Dict>::iterator it = solns.begin(); it != solns.end(); ++it, ++j ) {
4555 if ( (float)(*it)["score"] > best_score ) { // Note greater than - EMAN2 preferes minimums as a matter of policy
4556 vector<Dict>::reverse_iterator rit = solns.rbegin();
4557 copy(rit+1,solns.rend()-j,rit);
4558 Dict& d = (*it);
4559 d["score"] = best_score;
4560 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)
4561 d["xform.align3d"] = &t; // deep copy is going on here
4562 break;
4563 }
4564 }
4565
4566 }
4567 }
4568
4569 if(this_imgfft) {delete this_imgfft; this_imgfft = 0;}
4570 if(sym!=0) delete sym;
4571 if (c != 0) delete c;
4572
4573 return solns;
4574
4575}
Dict params
Definition: aligner.h:147
Cmp class defines image comparison method.
Definition: cmp.h:82
virtual float cmp(EMData *image, EMData *with) const =0
To compare 'image' with another image passed in through its parameters.
Dict is a dictionary to store <string, EMObject> pair.
Definition: emobject.h:385
type set_default(const string &key, type val)
Default setting behavior This can be achieved using a template - d.woolford Jan 2008 (before there wa...
Definition: emobject.h:569
bool has_key(const string &key) const
Ask the Dictionary if it as a particular key.
Definition: emobject.h:511
EMData stores an image's data and defines core image processing routines.
Definition: emdata.h:82
Factory is used to store objects to create new instances.
Definition: emobject.h:725
static T * get(const string &instance_name)
Definition: emobject.h:781
IntPoint defines an integer-coordinate point in a 1D/2D/3D space.
Definition: geometry.h:192
Symmetry3D - A base class for 3D Symmetry objects.
Definition: symmetry.h:57
vector< Transform > gen_orientations(const string &generatorname="eman", const Dict &parms=Dict())
Ask the Symmetry3D object to generate a set of orientations in its asymmetric unit using an Orientati...
Definition: symmetry.cpp:167
A Transform object is a somewhat specialized object designed specifically for EMAN2/Sparx storage of ...
Definition: transform.h:75
void set_trans(const float &x, const float &y, const float &z=0)
Set the post translation component.
Definition: transform.cpp:1036
float2 get_stats_cuda(const float *data, const int nx, const int ny, const int nz)
CudaPeakInfo * calc_max_location_wrap_cuda(const float *in, const int nx, const int ny, const int nz, const int maxdx, const int maxdy, const int maxdz)
EMData * copy() const
This file is a part of "emdata.h", to use functions in this file, you should "#include "emdata....
EMData * sqrt() const
return square root of current image
#define InvalidParameterException(desc)
Definition: exception.h:361
#define ImageDimensionException(desc)
Definition: exception.h:166
EMData * calc_ccf(EMData *with=0, fp_flag fpflag=CIRCULANT, bool center=false)
Calculate Cross-Correlation Function (CCF).
Definition: emdata.cpp:1499
float peak
Definition: cuda_util.h:29

References EMAN::EMData::calc_ccf(), calc_max_location_wrap_cuda(), EMAN::Cmp::cmp(), copy(), EMAN::Symmetry3D::gen_orientations(), EMAN::Factory< T >::get(), get_stats_cuda(), EMAN::Dict::has_key(), ImageDimensionException, InvalidParameterException, EMAN::Transform::invert(), EMAN::Aligner::params, CudaPeakInfo::peak, CudaPeakInfo::px, CudaPeakInfo::py, CudaPeakInfo::pz, EMAN::Dict::set_default(), EMAN::Transform::set_trans(), and sqrt().

Member Data Documentation

◆ NAME

const string RT3DSphereAligner::NAME = "rotate_translate_3d"
static

Definition at line 1753 of file aligner.h.

Referenced by get_name().


The documentation for this class was generated from the following files: