#include <aligner.h>
Inheritance diagram for EMAN::Refine3DAlignerGrid:
Public Member Functions | |
virtual EMData * | align (EMData *this_img, EMData *to_img, const string &cmp_name="sqeuclidean", const Dict &cmp_params=Dict()) const |
To align 'this_img' with another image passed in through its parameters. | |
virtual EMData * | align (EMData *this_img, EMData *to_img) const |
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 = "refine_3d_grid" |
Refines a preliminary 3D alignment using a sampling grid. This is a port from tomohunter, but the az sampling scheme is altered cuch that the points on the sphere are equidistant (Improves speed several hundered times). The distance between the points on the sphere is 'delta' and the range(distance from the pole, 0,0,0 position) is given as 'range'. IN general this refinement scheme is a bit slower than the Quaternion Simplex aligner, but perfroms better in the presence of noise(according to current dogma).
xform.align3d | The Transform from the previous course alignment. If unspecified the identity matrix is used | |
delta | The angluar distance bewteen points on the spehere used in the grid | |
range | The size of the grid. Measured in angluar distance from the north pole | |
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 1390 of file aligner.h.
|
Implements EMAN::Aligner. Definition at line 1396 of file aligner.h. References align(). 01397 { 01398 return align(this_img, to_img, "sqeuclidean", Dict()); 01399 }
|
|
To align 'this_img' with another image passed in through its parameters. The alignment uses a user-given comparison method to compare the two images. If none is given, a default one is used.
Implements EMAN::Aligner. Definition at line 2279 of file aligner.cpp. References EMAN::EMData::calc_ccf(), EMAN::EMData::calc_max_location_wrap(), calc_max_location_wrap_cuda(), EMAN::Cmp::cmp(), data, EMAN::EMData::do_fft(), EMAN::Dict::end(), 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, CudaPeakInfo::peak, phi, EMAN::EMData::process(), EMAN::EMData::process_inplace(), CudaPeakInfo::px, CudaPeakInfo::py, CudaPeakInfo::pz, EMAN::EMData::set_attr(), EMAN::Dict::set_default(), EMAN::Transform::set_trans(), sqrt(), and t. 02281 { 02282 if ( this_img->get_ndim() != 3 || to->get_ndim() != 3 ) { 02283 throw ImageDimensionException("This aligner only works for 3D images"); 02284 } 02285 02286 Transform* t; 02287 if (params.has_key("xform.align3d") ) { 02288 // Unlike the 2d refine aligner, this class doesn't require the starting transform's 02289 // parameters to form the starting guess. Instead the Transform itself 02290 // is perturbed carefully (using quaternion rotation) to overcome problems that arise 02291 // when you use orthogonally-based Euler angles 02292 t = params["xform.align3d"]; 02293 }else { 02294 t = new Transform(); // is the identity 02295 } 02296 02297 int searchx = 0; 02298 int searchy = 0; 02299 int searchz = 0; 02300 bool dotrans = params.set_default("dotrans",1); 02301 if (params.has_key("search")) { 02302 vector<string> check; 02303 check.push_back("searchx"); 02304 check.push_back("searchy"); 02305 check.push_back("searchz"); 02306 for(vector<string>::const_iterator cit = check.begin(); cit != check.end(); ++cit) { 02307 if (params.has_key(*cit)) throw InvalidParameterException("The search parameter is mutually exclusive of the searchx, searchy, and searchz parameters"); 02308 } 02309 int search = params["search"]; 02310 searchx = search; 02311 searchy = search; 02312 searchz = search; 02313 } else { 02314 searchx = params.set_default("searchx",3); 02315 searchy = params.set_default("searchy",3); 02316 searchz = params.set_default("searchz",3); 02317 } 02318 02319 float delta = params.set_default("delta",1.0f); 02320 float range = params.set_default("range",10.0f); 02321 bool verbose = params.set_default("verbose",false); 02322 02323 bool tomography = (cmp_name == "ccc.tomo") ? 1 : 0; 02324 EMData * tofft = 0; 02325 if(dotrans || tomography){ 02326 tofft = to->do_fft(); 02327 } 02328 02329 #ifdef EMAN2_USING_CUDA 02330 if(EMData::usecuda == 1) { 02331 if(!this_img->getcudarodata()) this_img->copy_to_cudaro(); // This is safer 02332 if(!to->getcudarwdata()) to->copy_to_cuda(); 02333 if(to->getcudarwdata()){if(tofft) tofft->copy_to_cuda();} 02334 } 02335 #endif 02336 02337 Dict d; 02338 d["type"] = "eman"; // d is used in the loop below 02339 Dict best; 02340 // best["score"] = numeric_limits<float>::infinity(); 02341 best["score"] = 1.0e37; 02342 bool use_cpu = true; 02343 Transform tran = Transform(); 02344 Cmp* c = Factory <Cmp>::get(cmp_name, cmp_params); 02345 02346 for ( float alt = 0; alt < range; alt += delta) { 02347 // now compute a sane az step size 02348 float saz = 360; 02349 if(alt != 0) saz = delta/sin(alt*M_PI/180.0f); // This gives consistent az step sizes(arc lengths) 02350 for ( float az = 0; az < 360; az += saz ){ 02351 if (verbose) { 02352 cout << "Trying angle alt " << alt << " az " << az << endl; 02353 } 02354 // account for any changes in az 02355 for( float phi = -range-az; phi < range-az; phi += delta ) { 02356 d["alt"] = alt; 02357 d["phi"] = phi; 02358 d["az"] = az; 02359 Transform tr(d); 02360 tr = tr*(*t); // compose transforms, this moves to the pole (aprox) 02361 02362 //EMData* transformed = this_img->process("xform",Dict("transform",&tr)); 02363 EMData* transformed; 02364 transformed = this_img->process("xform",Dict("transform",&tr)); 02365 02366 //need to do things a bit diffrent if we want to compare two tomos 02367 float score = 0.0f; 02368 if(dotrans || tomography){ 02369 EMData* ccf = transformed->calc_ccf(tofft); 02370 #ifdef EMAN2_USING_CUDA 02371 if(EMData::usecuda == 1){ 02372 use_cpu = false; 02373 CudaPeakInfo* data = calc_max_location_wrap_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz); 02374 tran.set_trans((float)-data->px, (float)-data->py, (float)-data->pz); 02375 //CudaPeakInfoFloat* data = calc_max_location_wrap_intp_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize(), searchx, searchy, searchz); 02376 //tran.set_trans(-data->xintp, -data->yintp, -data->zintp); 02377 tr = tran*tr; // to reflect the fact that we have done a rotation first and THEN a transformation 02378 if (tomography) { 02379 float2 stats = get_stats_cuda(ccf->getcudarwdata(), ccf->get_xsize(), ccf->get_ysize(), ccf->get_zsize()); 02380 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 02381 } else { 02382 score = -data->peak; 02383 } 02384 delete data; 02385 } 02386 #endif 02387 if(use_cpu){ 02388 if(tomography) ccf->process_inplace("normalize"); 02389 //vector<float> fpoint = ccf->calc_max_location_wrap_intp(searchx,searchy,searchz); 02390 //tran.set_trans(-fpoint[0], -fpoint[1], -fpoint[2]); 02391 //score = -fpoint[3]; 02392 IntPoint point = ccf->calc_max_location_wrap(searchx,searchy,searchz); 02393 tran.set_trans((float)-point[0], (float)-point[1], (float)-point[2]); 02394 score = -ccf->get_value_at_wrap(point[0], point[1], point[2]); 02395 tr = tran*tr;// to reflect the fact that we have done a rotation first and THEN a transformation 02396 02397 } 02398 delete ccf; ccf =0; 02399 delete transformed; transformed = 0;// this is to stop a mem leak 02400 } 02401 02402 if(!tomography){ 02403 if(!transformed) transformed = this_img->process("xform",Dict("transform",&tr)); // we are returning a map 02404 score = c->cmp(to,transformed); 02405 delete transformed; transformed = 0;// this is to stop a mem leak 02406 } 02407 02408 if(score < float(best["score"])) { 02409 // printf("%f\n",score); 02410 best["score"] = score; 02411 best["xform.align3d"] = &tr; // I wonder if this will cause a mem leak? 02412 } 02413 } 02414 } 02415 } 02416 02417 if(tofft) {delete tofft; tofft = 0;} 02418 if (c != 0) delete c; 02419 02420 //make aligned map; 02421 EMData* best_match = this_img->process("xform",Dict("transform", best["xform.align3d"])); // we are returning a map 02422 best_match->set_attr("xform.align3d", best["xform.align3d"]); 02423 best_match->set_attr("score", float(best["score"])); 02424 02425 return best_match; 02426 02427 }
|
|
Implements EMAN::Aligner. Definition at line 1406 of file aligner.h. 01407 { 01408 return "Refines a preliminary 3D alignment using a simplex algorithm. Subpixel precision."; 01409 }
|
|
Get the Aligner's name. Each Aligner is identified by a unique name.
Implements EMAN::Aligner. Definition at line 1401 of file aligner.h. 01402 {
01403 return NAME;
01404 }
|
|
Implements EMAN::Aligner. Definition at line 1416 of file aligner.h. References EMAN::TypeDict::put(). 01417 { 01418 TypeDict d; 01419 d.put("xform.align3d", EMObject::TRANSFORM,"The Transform storing the starting guess. If unspecified the identity matrix is used"); 01420 d.put("delta", EMObject::FLOAT, "The angular step size. Default is 1." ); 01421 d.put("range", EMObject::FLOAT, "The angular range size. Default is 10." ); 01422 d.put("dotrans", EMObject::BOOL,"Do a translational search. Default is True(1)"); 01423 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."); 01424 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."); 01425 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."); 01426 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"); 01427 d.put("verbose", EMObject::BOOL,"Turn this on to have useful information printed to standard out."); 01428 return d; 01429 }
|
|
Definition at line 1411 of file aligner.h. 01412 { 01413 return new Refine3DAlignerGrid(); 01414 }
|
|
Definition at line 82 of file aligner.cpp. |