#include <symmetry.h>
Inheritance diagram for EMAN::EmanOrientationGenerator:
Public Member Functions | |
EmanOrientationGenerator () | |
virtual | ~EmanOrientationGenerator () |
virtual string | get_name () const |
Return "eman". | |
virtual string | get_desc () const |
Get a description. | |
virtual TypeDict | get_param_types () const |
Get a dictionary containing the permissable parameters of this class. | |
virtual vector< Transform > | gen_orientations (const Symmetry3D *const sym) const |
generate orientations given some symmetry type | |
Static Public Member Functions | |
static OrientationGenerator * | NEW () |
Factory support function NEW. | |
Static Public Attributes | |
static const string | NAME = "eman" |
The name of this class - used to access it from factories etc. Should be "icos". | |
Private Member Functions | |
EmanOrientationGenerator (const EmanOrientationGenerator &) | |
Disallow copy construction. | |
EmanOrientationGenerator & | operator= (const EmanOrientationGenerator &) |
Disallow assignment. | |
virtual int | get_orientations_tally (const Symmetry3D *const sym, const float &delta) const |
This function returns how many orientations will be generated for a given delta (angular spacing) It does this by simulated gen_orientations. | |
float | get_az_delta (const float &delta, const float &altitude, const int maxcsym) const |
Gets the optimum azimuth delta (angular step) for a given altitude, delta and maximum symmetry. |
Historically, it is an adaptation of the method first used in EMAN1 and developed by Steve Ludtke. In EMAN2 it is more or less the same thing, but with more precise treatmeant of the platonic symmetries. In terms of approach, the altitude angles in the asymmetric unit are traversed constantly in steps of "prop" (a parameter of this class). However, the azimuth steps vary according to altitude, and this helps to achieve a more even distribution of orientations.
Definition at line 1021 of file symmetry.h.
EMAN::EmanOrientationGenerator::EmanOrientationGenerator | ( | ) | [inline] |
virtual EMAN::EmanOrientationGenerator::~EmanOrientationGenerator | ( | ) | [inline, virtual] |
EMAN::EmanOrientationGenerator::EmanOrientationGenerator | ( | const EmanOrientationGenerator & | ) | [private] |
Disallow copy construction.
vector< Transform > EmanOrientationGenerator::gen_orientations | ( | const Symmetry3D *const | sym | ) | const [virtual] |
generate orientations given some symmetry type
sym | the symmetry which defines the interesting asymmetric unit |
Implements EMAN::OrientationGenerator.
Definition at line 375 of file symmetry.cpp.
References EMAN::OrientationGenerator::add_orientation(), EMAN::Symmetry3D::get_az_alignment_offset(), get_az_delta(), EMAN::OrientationGenerator::get_az_max(), EMAN::Symmetry3D::get_delimiters(), EMAN::Util::get_gauss_rand(), EMAN::Symmetry3D::get_max_csym(), EMAN::OrientationGenerator::get_optimal_delta(), InvalidParameterException, EMAN::Symmetry3D::is_h_sym(), EMAN::Symmetry3D::is_in_asym_unit(), EMAN::Symmetry3D::is_platonic_sym(), EMAN::FactoryBase::params, and EMAN::Dict::set_default().
00376 { 00377 float delta = params.set_default("delta", 0.0f); 00378 int n = params.set_default("n", 0); 00379 00380 if ( delta <= 0 && n <= 0 ) throw InvalidParameterException("Error, you must specify a positive non-zero delta or n"); 00381 if ( delta > 0 && n > 0 ) throw InvalidParameterException("Error, the delta and the n arguments are mutually exclusive"); 00382 00383 if ( n > 0 ) { 00384 delta = get_optimal_delta(sym,n); 00385 } 00386 00387 bool inc_mirror = params.set_default("inc_mirror",false); 00388 Dict delimiters = sym->get_delimiters(inc_mirror); 00389 float altmax = delimiters["alt_max"]; 00390 float azmax = delimiters["az_max"]; 00391 00392 float paltmin = params.set_default("alt_min",0.0); 00393 float paltmax = params.set_default("alt_max",180.0); 00394 if (altmax>paltmax) altmax=paltmax; 00395 00396 bool perturb = params.set_default("perturb",true); 00397 00398 float alt_iterator = 0.0f; 00399 00400 // #If it's a h symmetry then the alt iterator starts at very close 00401 // #to the altmax... the object is a h symmetry then it knows its alt_min... 00402 if (sym->is_h_sym()) alt_iterator = delimiters["alt_min"]; 00403 00404 vector<Transform> ret; 00405 while ( alt_iterator <= altmax ) { 00406 float h = get_az_delta(delta,alt_iterator, sym->get_max_csym() ); 00407 00408 // not sure what this does code taken from EMAN1 - FIXME original author add comments 00409 if ( (alt_iterator > 0) && ( (azmax/h) < 2.8f) ) h = azmax / 2.1f; 00410 else if (alt_iterator == 0) h = azmax; 00411 00412 float az_iterator = 0.0f; 00413 00414 float azmax_adjusted = azmax; 00415 00416 bool d_odd_mirror_flag = false; 00417 get_az_max(sym,altmax, inc_mirror,alt_iterator, h,d_odd_mirror_flag, azmax_adjusted); 00418 if (alt_iterator<paltmin) { alt_iterator += delta; continue; } 00419 00420 00421 while ( az_iterator <= azmax_adjusted ) { 00422 // FIXME: add an intelligent comment - this was copied from old code 00423 // if ( az_iterator > 180.0 && alt_iterator > 180.0/(2.0-0.001) && alt_iterator < 180.0/(2.0+0.001) ) { 00424 // az_iterator += h; 00425 // continue; 00426 // } 00427 // // Now that I am handling the boundaries very specifically, I don't think we need 00428 // the above if statement. But I am leaving it there in case I need to reconsider. 00429 00430 if (alt_iterator == 0 && az_iterator > 0){ 00431 az_iterator += h; 00432 continue; // We only ever need to generate on orientation at alt=0 00433 } 00434 00435 00436 float alt_soln = alt_iterator; 00437 float az_soln = az_iterator; 00438 00439 if (sym->is_platonic_sym()) { 00440 if ( sym->is_in_asym_unit(alt_soln, az_soln,inc_mirror) == false ) { 00441 az_iterator += h; 00442 continue; 00443 } 00444 // Some objects have alignment offsets (icos and tet particularly) 00445 az_soln += sym->get_az_alignment_offset(); 00446 } 00447 00448 if ( perturb && alt_soln != 0 ) { 00449 alt_soln += Util::get_gauss_rand(0.0f,.125f*delta); 00450 az_soln += Util::get_gauss_rand(0.0f,h*.125f); 00451 } 00452 00453 add_orientation(ret,az_soln,alt_soln); 00454 00455 // Add helical symmetry orientations on the other side of the equator (if we're including 00456 // mirror orientations) 00457 if ( sym->is_h_sym() && inc_mirror && alt_iterator != (float) delimiters["alt_min"] ) { 00458 add_orientation(ret, az_soln,2.0f*(float)delimiters["alt_min"]-alt_soln); 00459 } 00460 00461 az_iterator += h; 00462 if ( (az_iterator > azmax_adjusted) && d_odd_mirror_flag) { 00463 azmax_adjusted = azmax; 00464 az_iterator += azmax/2.0f; 00465 } 00466 } 00467 alt_iterator += delta; 00468 } 00469 00470 return ret; 00471 }
float EmanOrientationGenerator::get_az_delta | ( | const float & | delta, | |
const float & | altitude, | |||
const int | maxcsym | |||
) | const [private] |
Gets the optimum azimuth delta (angular step) for a given altitude, delta and maximum symmetry.
This function is important for the generation of evenly distributed orientations
delta | - the angular spacing of the altitude angles, this is usually the "delta" parameter | |
altitude | the altitude along which the azimuth is going to be varied | |
maxcsym | the maximum csym of the Symmetry3D object - this is usually Symmetry3D::get_max_csym |
Definition at line 290 of file symmetry.cpp.
References EMAN::EMConsts::deg2rad.
Referenced by gen_orientations(), and get_orientations_tally().
00291 { 00292 // convert altitude into radians 00293 float tmp = (float)(EMConsts::deg2rad * altitude); 00294 00295 // This is taken from EMAN1 project3d.C 00296 // This wasn't working like it was supposed to. Rather than 00297 // figuring it out, I'm just replacing it --steve 00298 /* float h=floor(360.0f/(delta*1.1547f)); // the 1.1547 makes the overall distribution more like a hexagonal mesh 00299 h=(int)floor(h*sin(tmp)+.5f); 00300 if (h==0) h=1; 00301 h=abs(maxcsym)*floor(h/(float)abs(maxcsym)+.5f); 00302 if ( h == 0 ) h = (float)maxcsym; 00303 h=2.0f*M_PI/h; 00304 00305 return (float)(EMConsts::rad2deg*h);*/ 00306 00307 return altitude==0?360.0f:delta/sin(tmp); 00308 00309 }
virtual string EMAN::EmanOrientationGenerator::get_desc | ( | ) | const [inline, virtual] |
Get a description.
Implements EMAN::FactoryBase.
Definition at line 1043 of file symmetry.h.
01043 { return "Generate orientations distributed quasi-uniformaly over the asymmetric unit using an altitude-proportional strategy"; }
virtual string EMAN::EmanOrientationGenerator::get_name | ( | ) | const [inline, virtual] |
Return "eman".
Implements EMAN::FactoryBase.
Definition at line 1038 of file symmetry.h.
References NAME.
01038 { return NAME; }
int EmanOrientationGenerator::get_orientations_tally | ( | const Symmetry3D *const | sym, | |
const float & | delta | |||
) | const [private, virtual] |
This function returns how many orientations will be generated for a given delta (angular spacing) It does this by simulated gen_orientations.
sym | the symmetry which defines the interesting asymmetric unit | |
delta | the desired angular spacing of the orientations |
Implements EMAN::OrientationGenerator.
Definition at line 312 of file symmetry.cpp.
References get_az_delta(), EMAN::OrientationGenerator::get_az_max(), EMAN::Symmetry3D::get_delimiters(), EMAN::Symmetry3D::get_max_csym(), EMAN::Symmetry3D::is_h_sym(), EMAN::Symmetry3D::is_in_asym_unit(), EMAN::Symmetry3D::is_platonic_sym(), EMAN::FactoryBase::params, and EMAN::Dict::set_default().
00313 { 00314 //FIXME THIS IS SO SIMILAR TO THE gen_orientations function that they should be probably use 00315 // a common routine - SAME ISSUE FOR OTHER ORIENTATION GENERATORS 00316 bool inc_mirror = params.set_default("inc_mirror",false); 00317 Dict delimiters = sym->get_delimiters(inc_mirror); 00318 float altmax = delimiters["alt_max"]; 00319 float azmax = delimiters["az_max"]; 00320 00321 float paltmin = params.set_default("alt_min",0.0); 00322 float paltmax = params.set_default("alt_max",180.0); 00323 if (altmax>paltmax) altmax=paltmax; 00324 00325 float alt_iterator = 0.0f; 00326 00327 // #If it's a h symmetry then the alt iterator starts at very close 00328 // #to the altmax... the object is a h symmetry then it knows its alt_min... 00329 if (sym->is_h_sym()) alt_iterator = delimiters["alt_min"]; 00330 00331 int tally = 0; 00332 while ( alt_iterator <= altmax ) { 00333 float h = get_az_delta(delta,alt_iterator, sym->get_max_csym() ); 00334 00335 // not sure what this does code taken from EMAN1 - FIXME original author add comments 00336 if ( (alt_iterator > 0) && ( (azmax/h) < 2.8f) ) h = azmax / 2.1f; 00337 else if (alt_iterator == 0) h = azmax; 00338 00339 float az_iterator = 0.0f; 00340 00341 float azmax_adjusted = azmax; 00342 bool d_odd_mirror_flag = false; 00343 get_az_max(sym,altmax, inc_mirror,alt_iterator, h,d_odd_mirror_flag, azmax_adjusted); 00344 if (alt_iterator<paltmin) { alt_iterator += delta; continue; } 00345 00346 while ( az_iterator <= azmax_adjusted ) { 00347 // FIXME: add an intelligent comment - this was copied from old code 00348 // if ( az_iterator > 180.0 && alt_iterator > 180.0/(2.0-0.001) && alt_iterator < 180.0/(2.0+0.001) ) { 00349 // az_iterator += h; 00350 // continue; 00351 // } 00352 00353 if (sym->is_platonic_sym()) { 00354 if ( sym->is_in_asym_unit(alt_iterator, az_iterator,inc_mirror) == false ) { 00355 az_iterator += h; 00356 continue; 00357 } 00358 } 00359 00360 tally++; 00361 if ( sym->is_h_sym() && inc_mirror && alt_iterator != (float) delimiters["alt_min"] ) { 00362 tally++; 00363 } 00364 az_iterator += h; 00365 if ( (az_iterator > azmax_adjusted) && d_odd_mirror_flag) { 00366 azmax_adjusted = azmax; 00367 az_iterator += azmax/2.0f; 00368 } 00369 } 00370 alt_iterator += delta; 00371 } 00372 return tally; 00373 }
virtual TypeDict EMAN::EmanOrientationGenerator::get_param_types | ( | ) | const [inline, virtual] |
Get a dictionary containing the permissable parameters of this class.
Reimplemented from EMAN::OrientationGenerator.
Definition at line 1049 of file symmetry.h.
References EMAN::EMObject::BOOL, EMAN::EMObject::FLOAT, EMAN::OrientationGenerator::get_param_types(), EMAN::EMObject::INT, and EMAN::TypeDict::put().
01050 { 01051 TypeDict d = OrientationGenerator::get_param_types(); 01052 d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument."); 01053 d.put("perturb", EMObject::BOOL, "Whether or not to perturb the generated orientations in a small local area, default is true."); 01054 d.put("n", EMObject::INT, "The number of orientations to generate. This option is mutually exclusively of the delta argument.Will attempt to get as close to the number specified as possible."); 01055 d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false."); 01056 d.put("alt_min", EMObject::FLOAT, "Minimum altitude value to include (alt=0 is Z axis). Default=0"); 01057 d.put("alt_max", EMObject::FLOAT, "Maximum altitude value to include (alt=90 is X-Y plane). Default=no limit"); 01058 return d; 01059 }
static OrientationGenerator* EMAN::EmanOrientationGenerator::NEW | ( | ) | [inline, static] |
Factory support function NEW.
Definition at line 1030 of file symmetry.h.
References EmanOrientationGenerator().
01031 { 01032 return new EmanOrientationGenerator(); 01033 }
EmanOrientationGenerator& EMAN::EmanOrientationGenerator::operator= | ( | const EmanOrientationGenerator & | ) | [private] |
Disallow assignment.
const string EmanOrientationGenerator::NAME = "eman" [static] |
The name of this class - used to access it from factories etc. Should be "icos".
Definition at line 1068 of file symmetry.h.
Referenced by get_name().