#include <aligner.h>
Inheritance diagram for EMAN::RT3DSphereAligner:
Public Member Functions | |
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. | |
virtual EMData * | align (EMData *this_img, EMData *to_img) const |
See Aligner comments for more details. | |
virtual vector< Dict > | xform_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 Aligner * | NEW () |
Static Public Attributes | |
static const string | NAME = "rotate_translate_3d" |
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!
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 |
Definition at line 1134 of file aligner.h.
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 2026 of file aligner.cpp.
References EMAN::EMData::process(), EMAN::EMData::set_attr(), t, and xform_align_nbest().
Referenced by align().
02027 { 02028 02029 vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params); 02030 02031 Dict t; 02032 Transform* tr = (Transform*) alis[0]["xform.align3d"]; 02033 t["transform"] = tr; 02034 EMData* soln = this_img->process("xform",t); 02035 soln->set_attr("xform.align3d",tr); 02036 delete tr; tr = 0; 02037 02038 return soln; 02039 02040 }
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] |
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] |
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 2042 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().
02042 { 02043 02044 if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) { 02045 throw ImageDimensionException("This aligner only works for 3D images"); 02046 } 02047 02048 int searchx = 0; 02049 int searchy = 0; 02050 int searchz = 0; 02051 02052 bool dotrans = params.set_default("dotrans",1); 02053 if (params.has_key("search")) { 02054 vector<string> check; 02055 check.push_back("searchx"); 02056 check.push_back("searchy"); 02057 check.push_back("searchz"); 02058 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) { 02059 if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters"); 02060 } 02061 int search = params["search"]; 02062 searchx = search; 02063 searchy = search; 02064 searchz = search; 02065 } else { 02066 searchx = params.set_default("searchx",3); 02067 searchy = params.set_default("searchy",3); 02068 searchz = params.set_default("searchz",3); 02069 } 02070 02071 float lphi = params.set_default("phi0",0.0f); 02072 float uphi = params.set_default("phi1",360.0f); 02073 float dphi = params.set_default("dphi",10.f); 02074 float threshold = params.set_default("threshold",0.f); 02075 if (threshold < 0.0f) throw InvalidParameterException("The threshold parameter must be greater than or equal to zero"); 02076 bool verbose = params.set_default("verbose",false); 02077 02078 //in case we arre aligning tomos 02079 Dict altered_cmp_params(cmp_params); 02080 if (cmp_name == "ccc.tomo") { 02081 altered_cmp_params.set_default("searchx", searchx); 02082 altered_cmp_params.set_default("searchy", searchy); 02083 altered_cmp_params.set_default("searchz", searchz); 02084 altered_cmp_params.set_default("norm", true); 02085 } 02086 02087 vector<Dict> solns; 02088 if (nsoln == 0) return solns; // What was the user thinking? 02089 for (unsigned int i = 0; i < nsoln; ++i ) { 02090 Dict d; 02091 d["score"] = 1.e24; 02092 Transform t; // identity by default 02093 d["xform.align3d"] = &t; // deep copy is going on here 02094 solns.push_back(d); 02095 } 02096 02097 Dict d; 02098 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 02099 if ( params.has_key("delta") && params.has_key("n") ) { 02100 throw InvalidParameterException("The delta and n parameters are mutually exclusive in the RT3DSphereAligner aligner"); 02101 } else if ( params.has_key("n") ) { 02102 d["n"] = params["n"]; 02103 } else { 02104 // If they didn't specify either then grab the default delta - if they did supply delta we're still safe doing this 02105 d["delta"] = params.set_default("delta",10.f); 02106 } 02107 02108 if ((string)params.set_default("orientgen","eman")=="eman") d["perturb"]=0; 02109 Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1")); 02110 vector<Transform> transforms = sym->gen_orientations((string)params.set_default("orientgen","eman"),d); 02111 02112 bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0; 02113 02114 //precompute fixed FT, saves a LOT of time!!! 02115 EMData * this_imgfft = 0; 02116 if(dotrans || tomography){ 02117 this_imgfft = this_img->do_fft(); 02118 } 02119 02120 02121 #ifdef EMAN2_USING_CUDA 02122 if(EMData::usecuda == 1) { 02123 cout << "Using CUDA for 3D alignment" << endl; 02124 if(!to->isrodataongpu()) to->copy_to_cudaro(); 02125 if(!this_img->getcudarwdata()) this_img->copy_to_cuda(); 02126 if(this_imgfft) this_imgfft->copy_to_cuda(); 02127 } 02128 #endif 02129 02130 Transform trans = Transform(); 02131 bool use_cpu = true; 02132 for(vector<Transform>::const_iterator trans_it = transforms.begin(); trans_it != transforms.end(); trans_it++) { 02133 Dict params = trans_it->get_params("eman"); 02134 02135 if (verbose) { 02136 float alt = params["alt"]; 02137 float az = params["az"]; 02138 cout << "Trying angle alt: " << alt << " az: " << az << endl; 02139 } 02140 02141 for( float phi = lphi; phi < uphi; phi += dphi ) { 02142 Transform t(params); 02143 params["phi"] = phi; 02144 t.set_rotation(params); 02145 EMData* transformed = to->process("xform",Dict("transform",&t)); 02146 02147 //need to do things a bit diffrent if we want to compare two tomos 02148 float best_score = 0.0f; 02149 // Dotrans is effectievly ignored for tomography 02150 if(dotrans || tomography){ 02151 EMData* ccf = transformed->calc_ccf(this_imgfft); 02152 #ifdef EMAN2_USING_CUDA 02153 if(this_img->getcudarwdata()){ 02154 use_cpu = false; 02155 CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->getcudarwdata(), 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->getcudarwdata(), 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 }
const string RT3DSphereAligner::NAME = "rotate_translate_3d" [static] |