#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 2059 of file aligner.cpp. References EMAN::EMData::process(), EMAN::EMData::set_attr(), t, and xform_align_nbest(). 02060 { 02061 02062 vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params); 02063 02064 Dict t; 02065 Transform* tr = (Transform*) alis[0]["xform.align3d"]; 02066 t["transform"] = tr; 02067 EMData* soln = this_img->process("xform",t); 02068 soln->set_attr("xform.align3d",tr); 02069 delete tr; tr = 0; 02070 02071 return soln; 02072 02073 }
|
|
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 2075 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(). 02075 { 02076 02077 if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) { 02078 throw ImageDimensionException("This aligner only works for 3D images"); 02079 } 02080 02081 int searchx = 0; 02082 int searchy = 0; 02083 int searchz = 0; 02084 02085 bool dotrans = params.set_default("dotrans",1); 02086 if (params.has_key("search")) { 02087 vector<string> check; 02088 check.push_back("searchx"); 02089 check.push_back("searchy"); 02090 check.push_back("searchz"); 02091 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) { 02092 if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters"); 02093 } 02094 int search = params["search"]; 02095 searchx = search; 02096 searchy = search; 02097 searchz = search; 02098 } else { 02099 searchx = params.set_default("searchx",3); 02100 searchy = params.set_default("searchy",3); 02101 searchz = params.set_default("searchz",3); 02102 } 02103 02104 float lphi = params.set_default("phi0",0.0f); 02105 float uphi = params.set_default("phi1",360.0f); 02106 float dphi = params.set_default("dphi",10.f); 02107 float threshold = params.set_default("threshold",0.f); 02108 if (threshold < 0.0f) throw InvalidParameterException("The threshold parameter must be greater than or equal to zero"); 02109 bool verbose = params.set_default("verbose",false); 02110 02111 //in case we arre aligning tomos 02112 Dict altered_cmp_params(cmp_params); 02113 if (cmp_name == "ccc.tomo") { 02114 altered_cmp_params.set_default("searchx", searchx); 02115 altered_cmp_params.set_default("searchy", searchy); 02116 altered_cmp_params.set_default("searchz", searchz); 02117 altered_cmp_params.set_default("norm", true); 02118 } 02119 02120 vector<Dict> solns; 02121 if (nsoln == 0) return solns; // What was the user thinking? 02122 for (unsigned int i = 0; i < nsoln; ++i ) { 02123 Dict d; 02124 d["score"] = 1.e24; 02125 Transform t; // identity by default 02126 d["xform.align3d"] = &t; // deep copy is going on here 02127 solns.push_back(d); 02128 } 02129 02130 Dict d; 02131 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 02132 if ( params.has_key("delta") && params.has_key("n") ) { 02133 throw InvalidParameterException("The delta and n parameters are mutually exclusive in the RT3DSphereAligner aligner"); 02134 } else if ( params.has_key("n") ) { 02135 d["n"] = params["n"]; 02136 } else { 02137 // If they didn't specify either then grab the default delta - if they did supply delta we're still safe doing this 02138 d["delta"] = params.set_default("delta",10.f); 02139 } 02140 02141 if ((string)params.set_default("orientgen","eman")=="eman") d["perturb"]=0; 02142 Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1")); 02143 vector<Transform> transforms = sym->gen_orientations((string)params.set_default("orientgen","eman"),d); 02144 02145 bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0; 02146 02147 //precompute fixed FT, saves a LOT of time!!! 02148 EMData * this_imgfft = 0; 02149 if(dotrans || tomography){ 02150 this_imgfft = this_img->do_fft(); 02151 } 02152 02153 02154 #ifdef EMAN2_USING_CUDA 02155 if(EMData::usecuda == 1) { 02156 cout << "Using CUDA for 3D alignment" << endl; 02157 if(!to->getcudarodata()) to->copy_to_cudaro(); // Safer call 02158 if(!this_img->getcudarwdata()) this_img->copy_to_cuda(); 02159 if(this_imgfft) this_imgfft->copy_to_cuda(); 02160 } 02161 #endif 02162 02163 Transform trans = Transform(); 02164 bool use_cpu = true; 02165 for(vector<Transform>::const_iterator trans_it = transforms.begin(); trans_it != transforms.end(); trans_it++) { 02166 Dict params = trans_it->get_params("eman"); 02167 02168 if (verbose) { 02169 float alt = params["alt"]; 02170 float az = params["az"]; 02171 cout << "Trying angle alt: " << alt << " az: " << az << endl; 02172 } 02173 02174 for( float phi = lphi; phi < uphi; phi += dphi ) { 02175 Transform t(params); 02176 params["phi"] = phi; 02177 t.set_rotation(params); 02178 EMData* transformed = to->process("xform",Dict("transform",&t)); 02179 02180 //need to do things a bit diffrent if we want to compare two tomos 02181 float best_score = 0.0f; 02182 // Dotrans is effectievly ignored for tomography 02183 if(dotrans || tomography){ 02184 EMData* ccf = transformed->calc_ccf(this_imgfft); 02185 #ifdef EMAN2_USING_CUDA 02186 if(this_img->getcudarwdata()){ 02187 use_cpu = false; 02188 CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz); 02189 trans.set_trans((float)-data->px, (float)-data->py, (float)-data->pz); 02190 t = trans*t; //composite transform to reflect the fact that we have done a rotation first and THEN a transformation 02191 if (tomography) { 02192 float2 stats = get_stats_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize()); 02193 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 02194 } else { 02195 best_score = -data->peak; 02196 } 02197 delete data; 02198 } 02199 #endif 02200 if(use_cpu){ 02201 if(tomography) ccf->process_inplace("normalize"); 02202 IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz); 02203 trans.set_trans((float)-point[0], (float)-point[1], (float)-point[2]); 02204 t = trans*t; //composite transform to reflect the fact that we have done a rotation first and THEN a transformation 02205 best_score = -ccf->get_value_at_wrap(point[0], point[1], point[2]); 02206 } 02207 delete ccf; ccf =0; 02208 delete transformed; transformed = 0;// this is to stop a mem leak 02209 } 02210 02211 if(!tomography){ 02212 if(!transformed) transformed = to->process("xform",Dict("transform",&t)); 02213 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 02214 delete transformed; transformed = 0; 02215 } 02216 02217 unsigned int j = 0; 02218 //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; 02219 for ( vector<Dict>::iterator it = solns.begin(); it != solns.end(); ++it, ++j ) { 02220 if ( (float)(*it)["score"] > best_score ) { // Note greater than - EMAN2 preferes minimums as a matter of policy 02221 vector<Dict>::reverse_iterator rit = solns.rbegin(); 02222 copy(rit+1,solns.rend()-j,rit); 02223 Dict& d = (*it); 02224 d["score"] = best_score; 02225 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) 02226 d["xform.align3d"] = &t; // deep copy is going on here 02227 break; 02228 } 02229 } 02230 02231 } 02232 } 02233 delete sym; sym = 0; 02234 if(this_imgfft) {delete this_imgfft; this_imgfft = 0;} 02235 02236 //Free up resources (for an expensive opperation like this move data to and from device is a small % of time) 02237 #ifdef EMAN2_USING_CUDA 02238 this_img->copy_from_device(); 02239 to->ro_free(); 02240 #endif 02241 02242 return solns; 02243 02244 }
|
|
Definition at line 77 of file aligner.cpp. |