#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 1536 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 2433 of file aligner.cpp.
References EMAN::EMData::process(), EMAN::EMData::set_attr(), t, and xform_align_nbest().
Referenced by align().
02434 { 02435 02436 vector<Dict> alis = xform_align_nbest(this_img,to,1,cmp_name,cmp_params); 02437 02438 Dict t; 02439 Transform* tr = (Transform*) alis[0]["xform.align3d"]; 02440 t["transform"] = tr; 02441 EMData* soln = this_img->process("xform",t); 02442 soln->set_attr("xform.align3d",tr); 02443 delete tr; tr = 0; 02444 02445 return soln; 02446 02447 }
virtual string EMAN::RT3DSphereAligner::get_desc | ( | ) | const [inline, virtual] |
Implements EMAN::Aligner.
Definition at line 1560 of file aligner.h.
01561 { 01562 return "3D rotational and translational alignment using spherical sampling. Can reduce the search space if symmetry is supplied"; 01563 }
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 1570 of file aligner.h.
References EMAN::EMObject::BOOL, EMAN::EMObject::FLOAT, EMAN::EMObject::INT, EMAN::TypeDict::put(), and EMAN::EMObject::STRING.
01571 { 01572 TypeDict d; 01573 d.put("sym", EMObject::STRING,"The symmtery to use as the basis of the spherical sampling. Default is c1 (asymmetry)."); 01574 d.put("orientgen", EMObject::STRING,"Advanced. The orientation generation strategy. Default is eman"); 01575 d.put("delta", EMObject::FLOAT,"Angle the separates points on the sphere. This is exclusive of the \'n\' paramater. Default is 10"); 01576 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"); 01577 d.put("dphi", EMObject::FLOAT,"The angle increment in the phi direction. Default is 10"); 01578 d.put("phi0", EMObject::FLOAT,"Lower bound for phi. Default it 0"); 01579 d.put("phi1", EMObject::FLOAT,"Upper bound for phi. Default it 360"); 01580 d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)"); 01581 d.put("fsrotate", EMObject::BOOL,"Do rotations in Fourier space"); 01582 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."); 01583 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."); 01584 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."); 01585 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"); 01586 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out."); 01587 return d; 01588 }
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 2449 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().
02449 { 02450 02451 if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) { 02452 throw ImageDimensionException("This aligner only works for 3D images"); 02453 } 02454 02455 int searchx = 0; 02456 int searchy = 0; 02457 int searchz = 0; 02458 02459 bool dotrans = params.set_default("dotrans",1); 02460 bool fsrotate = params.set_default("fsrotate",0); 02461 if (params.has_key("search")) { 02462 vector<string> check; 02463 check.push_back("searchx"); 02464 check.push_back("searchy"); 02465 check.push_back("searchz"); 02466 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) { 02467 if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters"); 02468 } 02469 int search = params["search"]; 02470 searchx = search; 02471 searchy = search; 02472 searchz = search; 02473 } else { 02474 searchx = params.set_default("searchx",3); 02475 searchy = params.set_default("searchy",3); 02476 searchz = params.set_default("searchz",3); 02477 } 02478 02479 float lphi = params.set_default("phi0",0.0f); 02480 float uphi = params.set_default("phi1",360.0f); 02481 float dphi = params.set_default("dphi",10.f); 02482 float threshold = params.set_default("threshold",0.f); 02483 if (threshold < 0.0f) throw InvalidParameterException("The threshold parameter must be greater than or equal to zero"); 02484 bool verbose = params.set_default("verbose",false); 02485 02486 //in case we arre aligning tomos 02487 Dict altered_cmp_params(cmp_params); 02488 if (cmp_name == "ccc.tomo") { 02489 altered_cmp_params.set_default("searchx", searchx); 02490 altered_cmp_params.set_default("searchy", searchy); 02491 altered_cmp_params.set_default("searchz", searchz); 02492 altered_cmp_params.set_default("norm", true); 02493 } 02494 02495 vector<Dict> solns; 02496 if (nsoln == 0) return solns; // What was the user thinking? 02497 for (unsigned int i = 0; i < nsoln; ++i ) { 02498 Dict d; 02499 d["score"] = 1.e24; 02500 Transform t; // identity by default 02501 d["xform.align3d"] = &t; // deep copy is going on here 02502 solns.push_back(d); 02503 } 02504 02505 Dict d; 02506 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 02507 if ( params.has_key("delta") && params.has_key("n") ) { 02508 throw InvalidParameterException("The delta and n parameters are mutually exclusive in the RT3DSphereAligner aligner"); 02509 } else if ( params.has_key("n") ) { 02510 d["n"] = params["n"]; 02511 } else { 02512 // If they didn't specify either then grab the default delta - if they did supply delta we're still safe doing this 02513 d["delta"] = params.set_default("delta",10.f); 02514 } 02515 02516 if ((string)params.set_default("orientgen","eman")=="eman") d["perturb"]=0; 02517 Symmetry3D* sym = Factory<Symmetry3D>::get((string)params.set_default("sym","c1")); 02518 vector<Transform> transforms = sym->gen_orientations((string)params.set_default("orientgen","eman"),d); 02519 02520 bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0; 02521 02522 //precompute fixed FT, saves a LOT of time!!! 02523 EMData * this_imgfft = 0; 02524 if(dotrans || tomography){ 02525 this_imgfft = this_img->do_fft(); 02526 } 02527 EMData * to_fft = 0; 02528 if(fsrotate){ 02529 to_fft = to->do_fft(); 02530 } 02531 02532 02533 #ifdef EMAN2_USING_CUDA 02534 if(EMData::usecuda == 1) { 02535 cout << "Using CUDA for 3D alignment" << endl; 02536 if(!to->getcudarodata()) to->copy_to_cudaro(); // Safer call 02537 if(!this_img->getcudarwdata()) this_img->copy_to_cuda(); 02538 if(this_imgfft) this_imgfft->copy_to_cuda(); 02539 } 02540 #endif 02541 02542 Transform trans = Transform(); 02543 Cmp* c = Factory <Cmp>::get(cmp_name, cmp_params); 02544 02545 bool use_cpu = true; 02546 for(vector<Transform>::const_iterator trans_it = transforms.begin(); trans_it != transforms.end(); trans_it++) { 02547 Dict params = trans_it->get_params("eman"); 02548 02549 if (verbose) { 02550 float alt = params["alt"]; 02551 float az = params["az"]; 02552 cout << "Trying angle alt: " << alt << " az: " << az << endl; 02553 } 02554 02555 for( float phi = lphi; phi < uphi; phi += dphi ) { 02556 params["phi"] = phi; 02557 Transform t(params); 02558 02559 EMData* transformed; 02560 if(fsrotate){ 02561 transformed = to_fft->process("rotateinfs",Dict("transform",&t)); 02562 } else { 02563 transformed = to->process("xform",Dict("transform",&t)); 02564 } 02565 02566 //need to do things a bit diffrent if we want to compare two tomos 02567 float best_score = 0.0f; 02568 // Dotrans is effectievly ignored for tomography 02569 if(dotrans || tomography){ 02570 EMData* ccf = transformed->calc_ccf(this_imgfft); 02571 #ifdef EMAN2_USING_CUDA 02572 if(EMData::usecuda == 1){ 02573 // I use the following code rather than ccc.tomo to avoid doing two CCCs 02574 use_cpu = false; 02575 CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz); 02576 trans.set_trans((float)-data->px, (float)-data->py, (float)-data->pz); 02577 t = trans*t; //composite transform to reflect the fact that we have done a rotation first and THEN a transformation 02578 if (tomography) { 02579 float2 stats = get_stats_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize()); 02580 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 02581 } else { 02582 best_score = -data->peak; 02583 } 02584 delete data; 02585 } 02586 #endif 02587 if(use_cpu){ 02588 // I use the following code rather than ccc.tomo to avoid doing two CCCs 02589 if(tomography) ccf->process_inplace("normalize"); 02590 IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz); 02591 trans.set_trans((float)-point[0], (float)-point[1], (float)-point[2]); 02592 t = trans*t; //composite transform to reflect the fact that we have done a rotation first and THEN a transformation 02593 best_score = -ccf->get_value_at_wrap(point[0], point[1], point[2]); 02594 } 02595 delete ccf; ccf =0; 02596 delete transformed; transformed = 0;// this is to stop a mem leak 02597 } 02598 02599 if(!tomography){ 02600 if(!transformed) transformed = to->process("xform",Dict("transform",&t)); 02601 best_score = c->cmp(this_img,transformed); 02602 delete transformed; transformed = 0; 02603 } 02604 02605 unsigned int j = 0; 02606 //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; 02607 for ( vector<Dict>::iterator it = solns.begin(); it != solns.end(); ++it, ++j ) { 02608 if ( (float)(*it)["score"] > best_score ) { // Note greater than - EMAN2 preferes minimums as a matter of policy 02609 vector<Dict>::reverse_iterator rit = solns.rbegin(); 02610 copy(rit+1,solns.rend()-j,rit); 02611 Dict& d = (*it); 02612 d["score"] = best_score; 02613 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) 02614 d["xform.align3d"] = &t; // deep copy is going on here 02615 break; 02616 } 02617 } 02618 02619 } 02620 } 02621 02622 if(this_imgfft) {delete this_imgfft; this_imgfft = 0;} 02623 if(fsrotate){delete to_fft;} 02624 if(sym!=0) delete sym; 02625 if (c != 0) delete c; 02626 02627 return solns; 02628 02629 }
const string RT3DSphereAligner::NAME = "rotate_translate_3d" [static] |