#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 1134 of file aligner.h.
|
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 }
|
|
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 }
|
|
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 }
|
|
Get the Aligner's name. Each Aligner is identified by a unique name.
Implements EMAN::Aligner. Definition at line 1153 of file aligner.h. 01154 {
01155 return NAME;
01156 }
|
|
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 }
|
|
Definition at line 1163 of file aligner.h. 01164 { 01165 return new RT3DSphereAligner(); 01166 }
|
|
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 }
|
|
Definition at line 77 of file aligner.cpp. |