#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 1229 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 2258 of file aligner.cpp.
References EMAN::EMData::process(), EMAN::EMData::set_attr(), t, and xform_align_nbest().
Referenced by align().
02259 { 02260 02261 vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params); 02262 02263 Dict t; 02264 Transform* tr = (Transform*) alis[0]["xform.align3d"]; 02265 t["transform"] = tr; 02266 EMData* soln = this_img->process("xform",t); 02267 soln->set_attr("xform.align3d",tr); 02268 delete tr; tr = 0; 02269 02270 return soln; 02271 02272 }
virtual string EMAN::RT3DSphereAligner::get_desc | ( | ) | const [inline, virtual] |
Implements EMAN::Aligner.
Definition at line 1253 of file aligner.h.
01254 { 01255 return "3D rotational and translational alignment using spherical sampling. Can reduce the search space if symmetry is supplied"; 01256 }
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 1263 of file aligner.h.
References EMAN::EMObject::BOOL, EMAN::EMObject::FLOAT, EMAN::EMObject::INT, EMAN::TypeDict::put(), and EMAN::EMObject::STRING.
01264 { 01265 TypeDict d; 01266 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (asymmetry)."); 01267 d.put("orientgen", EMObject::STRING,"Advanced. The orientation generation strategy. Default is eman"); 01268 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10"); 01269 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"); 01270 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10"); 01271 d.put("phi0", EMObject::FLOAT,"Lower bound for phi. Default it 0"); 01272 d.put("phi1", EMObject::FLOAT,"Upper bound for phi. Default it 360"); 01273 d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)"); 01274 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."); 01275 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."); 01276 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."); 01277 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"); 01278 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out."); 01279 return d; 01280 }
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 2274 of file aligner.cpp.
References EMAN::EMData::calc_ccf(), EMAN::EMData::calc_max_location_wrap(), calc_max_location_wrap_cuda(), EMAN::Cmp::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().
02274 { 02275 02276 if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) { 02277 throw ImageDimensionException("This aligner only works for 3D images"); 02278 } 02279 02280 int searchx = 0; 02281 int searchy = 0; 02282 int searchz = 0; 02283 02284 bool dotrans = params.set_default("dotrans",1); 02285 if (params.has_key("search")) { 02286 vector<string> check; 02287 check.push_back("searchx"); 02288 check.push_back("searchy"); 02289 check.push_back("searchz"); 02290 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) { 02291 if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters"); 02292 } 02293 int search = params["search"]; 02294 searchx = search; 02295 searchy = search; 02296 searchz = search; 02297 } else { 02298 searchx = params.set_default("searchx",3); 02299 searchy = params.set_default("searchy",3); 02300 searchz = params.set_default("searchz",3); 02301 } 02302 02303 float lphi = params.set_default("phi0",0.0f); 02304 float uphi = params.set_default("phi1",360.0f); 02305 float dphi = params.set_default("dphi",10.f); 02306 float threshold = params.set_default("threshold",0.f); 02307 if (threshold < 0.0f) throw InvalidParameterException("The threshold parameter must be greater than or equal to zero"); 02308 bool verbose = params.set_default("verbose",false); 02309 02310 //in case we arre aligning tomos 02311 Dict altered_cmp_params(cmp_params); 02312 if (cmp_name == "ccc.tomo") { 02313 altered_cmp_params.set_default("searchx", searchx); 02314 altered_cmp_params.set_default("searchy", searchy); 02315 altered_cmp_params.set_default("searchz", searchz); 02316 altered_cmp_params.set_default("norm", true); 02317 } 02318 02319 vector<Dict> solns; 02320 if (nsoln == 0) return solns; // What was the user thinking? 02321 for (unsigned int i = 0; i < nsoln; ++i ) { 02322 Dict d; 02323 d["score"] = 1.e24; 02324 Transform t; // identity by default 02325 d["xform.align3d"] = &t; // deep copy is going on here 02326 solns.push_back(d); 02327 } 02328 02329 Dict d; 02330 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 02331 if ( params.has_key("delta") && params.has_key("n") ) { 02332 throw InvalidParameterException("The delta and n parameters are mutually exclusive in the RT3DSphereAligner aligner"); 02333 } else if ( params.has_key("n") ) { 02334 d["n"] = params["n"]; 02335 } else { 02336 // If they didn't specify either then grab the default delta - if they did supply delta we're still safe doing this 02337 d["delta"] = params.set_default("delta",10.f); 02338 } 02339 02340 if ((string)params.set_default("orientgen","eman")=="eman") d["perturb"]=0; 02341 Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1")); 02342 vector<Transform> transforms = sym->gen_orientations((string)params.set_default("orientgen","eman"),d); 02343 02344 bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0; 02345 02346 //precompute fixed FT, saves a LOT of time!!! 02347 EMData * this_imgfft = 0; 02348 if(dotrans || tomography){ 02349 this_imgfft = this_img->do_fft(); 02350 } 02351 02352 02353 #ifdef EMAN2_USING_CUDA 02354 if(EMData::usecuda == 1) { 02355 cout << "Using CUDA for 3D alignment" << endl; 02356 if(!to->getcudarodata()) to->copy_to_cudaro(); // Safer call 02357 if(!this_img->getcudarwdata()) this_img->copy_to_cuda(); 02358 if(this_imgfft) this_imgfft->copy_to_cuda(); 02359 } 02360 #endif 02361 02362 Transform trans = Transform(); 02363 Cmp* c = Factory <Cmp>::get(cmp_name, cmp_params); 02364 bool use_cpu = true; 02365 for(vector<Transform>::const_iterator trans_it = transforms.begin(); trans_it != transforms.end(); trans_it++) { 02366 Dict params = trans_it->get_params("eman"); 02367 02368 if (verbose) { 02369 float alt = params["alt"]; 02370 float az = params["az"]; 02371 cout << "Trying angle alt: " << alt << " az: " << az << endl; 02372 } 02373 02374 for( float phi = lphi; phi < uphi; phi += dphi ) { 02375 Transform t(params); 02376 params["phi"] = phi; 02377 t.set_rotation(params); 02378 EMData* transformed = to->process("xform",Dict("transform",&t)); 02379 02380 //need to do things a bit diffrent if we want to compare two tomos 02381 float best_score = 0.0f; 02382 // Dotrans is effectievly ignored for tomography 02383 if(dotrans || tomography){ 02384 EMData* ccf = transformed->calc_ccf(this_imgfft); 02385 #ifdef EMAN2_USING_CUDA 02386 if(this_img->getcudarwdata()){ 02387 // I use the following code rather than ccc.tomo to avoid doing two CCCs 02388 use_cpu = false; 02389 CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz); 02390 trans.set_trans((float)-data->px, (float)-data->py, (float)-data->pz); 02391 t = trans*t; //composite transform to reflect the fact that we have done a rotation first and THEN a transformation 02392 if (tomography) { 02393 float2 stats = get_stats_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize()); 02394 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 02395 } else { 02396 best_score = -data->peak; 02397 } 02398 delete data; 02399 } 02400 #endif 02401 if(use_cpu){ 02402 // I use the following code rather than ccc.tomo to avoid doing two CCCs 02403 if(tomography) ccf->process_inplace("normalize"); 02404 IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz); 02405 trans.set_trans((float)-point[0], (float)-point[1], (float)-point[2]); 02406 t = trans*t; //composite transform to reflect the fact that we have done a rotation first and THEN a transformation 02407 best_score = -ccf->get_value_at_wrap(point[0], point[1], point[2]); 02408 } 02409 delete ccf; ccf =0; 02410 delete transformed; transformed = 0;// this is to stop a mem leak 02411 } 02412 02413 if(!tomography){ 02414 if(!transformed) transformed = to->process("xform",Dict("transform",&t)); 02415 best_score = c->cmp(this_img,transformed); 02416 delete transformed; transformed = 0; 02417 } 02418 02419 unsigned int j = 0; 02420 //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; 02421 for ( vector<Dict>::iterator it = solns.begin(); it != solns.end(); ++it, ++j ) { 02422 if ( (float)(*it)["score"] > best_score ) { // Note greater than - EMAN2 preferes minimums as a matter of policy 02423 vector<Dict>::reverse_iterator rit = solns.rbegin(); 02424 copy(rit+1,solns.rend()-j,rit); 02425 Dict& d = (*it); 02426 d["score"] = best_score; 02427 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) 02428 d["xform.align3d"] = &t; // deep copy is going on here 02429 break; 02430 } 02431 } 02432 02433 } 02434 } 02435 delete sym; sym = 0; 02436 if(this_imgfft) {delete this_imgfft; this_imgfft = 0;} 02437 02438 //Free up resources (for an expensive opperation like this move data to and from device is a small % of time) 02439 #ifdef EMAN2_USING_CUDA 02440 this_img->copy_from_device(); 02441 to->ro_free(); 02442 #endif 02443 02444 return solns; 02445 02446 }
const string RT3DSphereAligner::NAME = "rotate_translate_3d" [static] |