#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 | |
Aligner * | NEW () |
Static Public Attributes | |
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 1119 of file aligner.h.
|
See Aligner comments for more details.
Implements EMAN::Aligner. Definition at line 1128 of file aligner.h. References align(). 01129 { 01130 return align(this_img, to_img, "sqeuclidean", Dict()); 01131 }
|
|
See Aligner comments for more details.
Implements EMAN::Aligner. Definition at line 2002 of file aligner.cpp. References EMAN::EMData::process(), EMAN::EMData::set_attr(), t, and xform_align_nbest(). 02003 { 02004 02005 vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params); 02006 02007 Dict t; 02008 Transform* tr = (Transform*) alis[0]["xform.align3d"]; 02009 t["transform"] = tr; 02010 EMData* soln = this_img->process("xform",t); 02011 soln->set_attr("xform.align3d",tr); 02012 delete tr; tr = 0; 02013 02014 return soln; 02015 02016 }
|
|
Implements EMAN::Aligner. Definition at line 1143 of file aligner.h. 01144 { 01145 return "3D rotational and translational alignment using spherical sampling. Can reduce the search space if symmetry is supplied"; 01146 }
|
|
Get the Aligner's name. Each Aligner is identified by a unique name.
Implements EMAN::Aligner. Definition at line 1138 of file aligner.h. 01139 {
01140 return NAME;
01141 }
|
|
Implements EMAN::Aligner. Definition at line 1153 of file aligner.h. References EMAN::TypeDict::put(). 01154 { 01155 TypeDict d; 01156 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (asymmetry)."); 01157 d.put("orientgen", EMObject::STRING,"Advanced. The orientation generation strategy. Default is eman"); 01158 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10"); 01159 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"); 01160 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10"); 01161 d.put("phi0", EMObject::FLOAT,"Lower bound for phi. Default it 0"); 01162 d.put("phi1", EMObject::FLOAT,"Upper bound for phi. Default it 360"); 01163 d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)"); 01164 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."); 01165 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."); 01166 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."); 01167 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"); 01168 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out."); 01169 return d; 01170 }
|
|
Definition at line 1148 of file aligner.h. 01149 { 01150 return new RT3DSphereAligner(); 01151 }
|
|
See Aligner comments for more details.
Reimplemented from EMAN::Aligner. Definition at line 2018 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(). 02018 { 02019 02020 if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) { 02021 throw ImageDimensionException("This aligner only works for 3D images"); 02022 } 02023 02024 int searchx = 0; 02025 int searchy = 0; 02026 int searchz = 0; 02027 02028 bool dotrans = params.set_default("dotrans",1); 02029 if (params.has_key("search")) { 02030 vector<string> check; 02031 check.push_back("searchx"); 02032 check.push_back("searchy"); 02033 check.push_back("searchz"); 02034 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) { 02035 if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters"); 02036 } 02037 int search = params["search"]; 02038 searchx = search; 02039 searchy = search; 02040 searchz = search; 02041 } else { 02042 searchx = params.set_default("searchx",3); 02043 searchy = params.set_default("searchy",3); 02044 searchz = params.set_default("searchz",3); 02045 } 02046 02047 float lphi = params.set_default("phi0",0.0f); 02048 float uphi = params.set_default("phi1",360.0f); 02049 float dphi = params.set_default("dphi",10.f); 02050 float threshold = params.set_default("threshold",0.f); 02051 if (threshold < 0.0f) throw InvalidParameterException("The threshold parameter must be greater than or equal to zero"); 02052 bool verbose = params.set_default("verbose",false); 02053 02054 //in case we arre aligning tomos 02055 Dict altered_cmp_params(cmp_params); 02056 if (cmp_name == "ccc.tomo") { 02057 altered_cmp_params.set_default("searchx", searchx); 02058 altered_cmp_params.set_default("searchy", searchy); 02059 altered_cmp_params.set_default("searchz", searchz); 02060 altered_cmp_params.set_default("norm", true); 02061 } 02062 02063 vector<Dict> solns; 02064 if (nsoln == 0) return solns; // What was the user thinking? 02065 for (unsigned int i = 0; i < nsoln; ++i ) { 02066 Dict d; 02067 d["score"] = 1.e24; 02068 Transform t; // identity by default 02069 d["xform.align3d"] = &t; // deep copy is going on here 02070 solns.push_back(d); 02071 } 02072 02073 Dict d; 02074 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 02075 if ( params.has_key("delta") && params.has_key("n") ) { 02076 throw InvalidParameterException("The delta and n parameters are mutually exclusive in the RT3DSphereAligner aligner"); 02077 } else if ( params.has_key("n") ) { 02078 d["n"] = params["n"]; 02079 } else { 02080 // If they didn't specify either then grab the default delta - if they did supply delta we're still safe doing this 02081 d["delta"] = params.set_default("delta",10.f); 02082 } 02083 02084 if ((string)params.set_default("orientgen","eman")=="eman") d["perturb"]=0; 02085 Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1")); 02086 vector<Transform> transforms = sym->gen_orientations((string)params.set_default("orientgen","eman"),d); 02087 02088 float verbose_alt = -1.0f; 02089 bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0; 02090 02091 //precompute fixed FT, saves a LOT of time!!! 02092 EMData * this_imgfft = 0; 02093 if(dotrans || tomography){ 02094 this_imgfft = this_img->do_fft(); 02095 } 02096 02097 02098 #ifdef EMAN2_USING_CUDA 02099 if(EMData::usecuda == 1) { 02100 cout << "Using CUDA for 3D alignment" << endl; 02101 if(!to->isrodataongpu()) to->copy_to_cudaro(); 02102 if(!this_img->cudarwdata) this_img->copy_to_cuda(); 02103 if(this_imgfft) this_imgfft->copy_to_cuda(); 02104 } 02105 #endif 02106 02107 bool use_cpu = true; 02108 for(vector<Transform>::const_iterator trans_it = transforms.begin(); trans_it != transforms.end(); trans_it++) { 02109 Dict params = trans_it->get_params("eman"); 02110 Transform t(params); 02111 if (verbose) { 02112 float alt = params["alt"]; 02113 float az = params["az"]; 02114 cout << "Trying angle alt: " << alt << " az: " << az << endl; 02115 } 02116 02117 for( float phi = lphi; phi < uphi; phi += dphi ) { 02118 02119 params["phi"] = phi; 02120 t.set_rotation(params); 02121 EMData* transformed = to->process("xform",Dict("transform",&t)); 02122 02123 //need to do things a bit diffrent if we want to compare two tomos 02124 float best_score; 02125 if(dotrans || tomography){ 02126 EMData* ccf = transformed->calc_ccf(this_imgfft); 02127 #ifdef EMAN2_USING_CUDA 02128 if(this_img->cudarwdata){ 02129 use_cpu = false; 02130 float2 stats = get_stats_cuda(ccf->cudarwdata, ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize()); 02131 CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->cudarwdata, ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz); 02132 t.set_trans((float)-data->px, (float)-data->py, (float)-data->pz); 02133 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 02134 delete data; 02135 } 02136 #endif 02137 if(use_cpu){ 02138 if(tomography) ccf->process_inplace("normalize"); 02139 IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz); 02140 t.set_trans((float)-point[0], (float)-point[1], (float)-point[2]); 02141 best_score = -ccf->get_value_at_wrap(point[0], point[1], point[2]); 02142 delete transformed; // this is to stop a mem leak 02143 transformed = to->process("xform",Dict("transform",&t)); 02144 } 02145 delete ccf; ccf =0; 02146 } 02147 02148 if(!tomography){ 02149 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 02150 02151 } 02152 delete transformed; transformed =0; 02153 02154 unsigned int j = 0; 02155 //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; 02156 for ( vector<Dict>::iterator it = solns.begin(); it != solns.end(); ++it, ++j ) { 02157 if ( (float)(*it)["score"] > best_score ) { // Note greater than - EMAN2 preferes minimums as a matter of policy 02158 vector<Dict>::reverse_iterator rit = solns.rbegin(); 02159 copy(rit+1,solns.rend()-j,rit); 02160 Dict& d = (*it); 02161 d["score"] = best_score; 02162 t.invert(); 02163 d["xform.align3d"] = &t; // deep copy is going on here 02164 break; 02165 } 02166 } 02167 02168 } 02169 } 02170 delete sym; sym = 0; 02171 if(this_imgfft) {delete this_imgfft; this_imgfft = 0;} 02172 return solns; 02173 02174 }
|
|
Definition at line 77 of file aligner.cpp. |