#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 1018 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 379 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::Symmetry3D::get_nsym(), EMAN::OrientationGenerator::get_optimal_delta(), EMAN::Symmetry3D::get_sym(), InvalidParameterException, EMAN::Symmetry3D::is_h_sym(), EMAN::Symmetry3D::is_in_asym_unit(), EMAN::Symmetry3D::is_platonic_sym(), EMAN::FactoryBase::params, EMAN::Dict::set_default(), and t.
00380 { 00381 float delta = params.set_default("delta", 0.0f); 00382 int n = params.set_default("n", 0); 00383 bool breaksym = params.set_default("breaksym",false); 00384 00385 if ( delta <= 0 && n <= 0 ) throw InvalidParameterException("Error, you must specify a positive non-zero delta or n"); 00386 if ( delta > 0 && n > 0 ) throw InvalidParameterException("Error, the delta and the n arguments are mutually exclusive"); 00387 00388 if ( n > 0 ) { 00389 delta = get_optimal_delta(sym,n); 00390 } 00391 00392 bool inc_mirror = params.set_default("inc_mirror",false); 00393 bool inc_mirror_real = inc_mirror; 00394 if (breaksym) inc_mirror=true; // we need to enable mirror generation, then strip them out at the end, or things don't work right... 00395 Dict delimiters = sym->get_delimiters(inc_mirror); 00396 float altmax = delimiters["alt_max"]; 00397 float azmax = delimiters["az_max"]; 00398 00399 float paltmin = params.set_default("alt_min",0.0f); 00400 float paltmax = params.set_default("alt_max",180.0f); 00401 if (altmax>paltmax) altmax=paltmax; 00402 00403 bool perturb = params.set_default("perturb",true); 00404 00405 float alt_iterator = 0.0f; 00406 00407 // #If it's a h symmetry then the alt iterator starts at very close 00408 // #to the altmax... the object is a h symmetry then it knows its alt_min... 00409 if (sym->is_h_sym()) alt_iterator = delimiters["alt_min"]; 00410 00411 vector<Transform> ret; 00412 while ( alt_iterator <= altmax ) { 00413 float h = get_az_delta(delta,alt_iterator, sym->get_max_csym() ); 00414 00415 // not sure what this does code taken from EMAN1 - FIXME original author add comments 00416 if ( (alt_iterator > 0) && ( (azmax/h) < 2.8f) ) h = azmax / 2.1f; 00417 else if (alt_iterator == 0) h = azmax; 00418 00419 float az_iterator = 0.0f; 00420 00421 float azmax_adjusted = azmax; 00422 00423 bool d_odd_mirror_flag = false; 00424 get_az_max(sym,altmax, inc_mirror,alt_iterator, h,d_odd_mirror_flag, azmax_adjusted); 00425 if (alt_iterator<paltmin) { alt_iterator += delta; continue; } 00426 00427 00428 while ( az_iterator <= azmax_adjusted ) { 00429 // FIXME: add an intelligent comment - this was copied from old code 00430 // if ( az_iterator > 180.0 && alt_iterator > 180.0/(2.0-0.001) && alt_iterator < 180.0/(2.0+0.001) ) { 00431 // az_iterator += h; 00432 // continue; 00433 // } 00434 // // Now that I am handling the boundaries very specifically, I don't think we need 00435 // the above if statement. But I am leaving it there in case I need to reconsider. 00436 00437 if (alt_iterator == 0 && az_iterator > 0){ 00438 az_iterator += h; 00439 continue; // We only ever need to generate on orientation at alt=0 00440 } 00441 00442 00443 float alt_soln = alt_iterator; 00444 float az_soln = az_iterator; 00445 00446 if (sym->is_platonic_sym()) { 00447 if ( sym->is_in_asym_unit(alt_soln, az_soln,inc_mirror) == false ) { 00448 az_iterator += h; 00449 continue; 00450 } 00451 // Some objects have alignment offsets (icos and tet particularly) 00452 az_soln += sym->get_az_alignment_offset(); 00453 } 00454 //printf("%f %f/n",alt_soln,az_soln); 00455 if ( perturb && alt_soln != 0 ) { 00456 alt_soln += Util::get_gauss_rand(0.0f,.125f*delta); 00457 az_soln += Util::get_gauss_rand(0.0f,h*.125f); 00458 } 00459 00460 add_orientation(ret,az_soln,alt_soln); 00461 00462 // Add helical symmetry orientations on the other side of the equator (if we're including 00463 // mirror orientations) 00464 if ( sym->is_h_sym() && inc_mirror && alt_iterator != (float) delimiters["alt_min"] ) { 00465 add_orientation(ret, az_soln,2.0f*(float)delimiters["alt_min"]-alt_soln); 00466 } 00467 00468 az_iterator += h; 00469 if ( (az_iterator > azmax_adjusted) && d_odd_mirror_flag) { 00470 azmax_adjusted = azmax; 00471 az_iterator += azmax/2.0f; 00472 } 00473 } 00474 alt_iterator += delta; 00475 } 00476 00477 // With breaksym, values are generated for one asymmetric unit as if symmetry were imposed, then 00478 // the symmetry equivalent points are generated. Used with asymmetric structures with pseudosymmetry 00479 if (breaksym) { 00480 // no iterators here since we are making the list longer as we go 00481 int nwithsym=ret.size(); // transforms in one asym unit 00482 int nsym=sym->get_nsym(); // number of asymmetric units to generate 00483 for (int j=1; j<nsym; j++) { 00484 Transform t=sym->get_sym(j); 00485 for (int i=0; i<nwithsym; i++) { 00486 ret.push_back(ret[i]*t); // add the symmetry modified transform to the end of the vector 00487 } 00488 } 00489 00490 // Now we get rid of anything in the bottom half of the unit sphere if requested 00491 if (!inc_mirror_real) { 00492 vector<Transform> ret2; 00493 for (vector<Transform>::iterator t=ret.begin(); t!=ret.end(); ++t) { 00494 if ((*t)[2][2]>=0) ret2.push_back(*t); 00495 // printf("%f\n",t[2][2]); 00496 } 00497 return ret2; 00498 } 00499 } 00500 00501 return ret; 00502 }
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 291 of file symmetry.cpp.
References EMAN::EMConsts::deg2rad.
Referenced by gen_orientations(), and get_orientations_tally().
00292 { 00293 // convert altitude into radians 00294 float tmp = (float)(EMConsts::deg2rad * altitude); 00295 00296 // This is taken from EMAN1 project3d.C 00297 // This wasn't working like it was supposed to. Rather than 00298 // figuring it out, I'm just replacing it --steve 00299 /* float h=floor(360.0f/(delta*1.1547f)); // the 1.1547 makes the overall distribution more like a hexagonal mesh 00300 h=(int)floor(h*sin(tmp)+.5f); 00301 if (h==0) h=1; 00302 h=abs(maxcsym)*floor(h/(float)abs(maxcsym)+.5f); 00303 if ( h == 0 ) h = (float)maxcsym; 00304 h=2.0f*M_PI/h; 00305 00306 return (float)(EMConsts::rad2deg*h);*/ 00307 00308 return altitude==0?360.0f:delta/sin(tmp); 00309 00310 }
virtual string EMAN::EmanOrientationGenerator::get_desc | ( | ) | const [inline, virtual] |
Get a description.
Implements EMAN::FactoryBase.
Definition at line 1040 of file symmetry.h.
01040 { 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 1035 of file symmetry.h.
References NAME.
01035 { 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 313 of file symmetry.cpp.
References get_az_delta(), EMAN::OrientationGenerator::get_az_max(), EMAN::Symmetry3D::get_delimiters(), EMAN::Symmetry3D::get_max_csym(), EMAN::Symmetry3D::get_nsym(), EMAN::Symmetry3D::is_h_sym(), EMAN::Symmetry3D::is_in_asym_unit(), EMAN::Symmetry3D::is_platonic_sym(), EMAN::FactoryBase::params, and EMAN::Dict::set_default().
00314 { 00315 //FIXME THIS IS SO SIMILAR TO THE gen_orientations function that they should be probably use 00316 // a common routine - SAME ISSUE FOR OTHER ORIENTATION GENERATORS 00317 bool inc_mirror = params.set_default("inc_mirror",false); 00318 bool breaksym = params.set_default("breaksym",false); 00319 Dict delimiters = sym->get_delimiters(inc_mirror); 00320 float altmax = delimiters["alt_max"]; 00321 float azmax = delimiters["az_max"]; 00322 00323 float paltmin = params.set_default("alt_min",0.0f); 00324 float paltmax = params.set_default("alt_max",180.0f); 00325 if (altmax>paltmax) altmax=paltmax; 00326 00327 float alt_iterator = 0.0f; 00328 00329 // #If it's a h symmetry then the alt iterator starts at very close 00330 // #to the altmax... the object is a h symmetry then it knows its alt_min... 00331 if (sym->is_h_sym()) alt_iterator = delimiters["alt_min"]; 00332 00333 int tally = 0; 00334 while ( alt_iterator <= altmax ) { 00335 float h = get_az_delta(delta,alt_iterator, sym->get_max_csym() ); 00336 00337 // not sure what this does code taken from EMAN1 - FIXME original author add comments 00338 if ( (alt_iterator > 0) && ( (azmax/h) < 2.8f) ) h = azmax / 2.1f; 00339 else if (alt_iterator == 0) h = azmax; 00340 00341 float az_iterator = 0.0f; 00342 00343 float azmax_adjusted = azmax; 00344 bool d_odd_mirror_flag = false; 00345 get_az_max(sym,altmax, inc_mirror,alt_iterator, h,d_odd_mirror_flag, azmax_adjusted); 00346 if (alt_iterator<paltmin) { alt_iterator += delta; continue; } 00347 00348 while ( az_iterator <= azmax_adjusted ) { 00349 // FIXME: add an intelligent comment - this was copied from old code 00350 // if ( az_iterator > 180.0 && alt_iterator > 180.0/(2.0-0.001) && alt_iterator < 180.0/(2.0+0.001) ) { 00351 // az_iterator += h; 00352 // continue; 00353 // } 00354 00355 if (sym->is_platonic_sym()) { 00356 if ( sym->is_in_asym_unit(alt_iterator, az_iterator,inc_mirror) == false ) { 00357 az_iterator += h; 00358 continue; 00359 } 00360 } 00361 00362 tally++; 00363 if ( sym->is_h_sym() && inc_mirror && alt_iterator != (float) delimiters["alt_min"] ) { 00364 tally++; 00365 } 00366 az_iterator += h; 00367 if ( (az_iterator > azmax_adjusted) && d_odd_mirror_flag) { 00368 azmax_adjusted = azmax; 00369 az_iterator += azmax/2.0f; 00370 } 00371 } 00372 alt_iterator += delta; 00373 } 00374 00375 if (breaksym) return tally*sym->get_nsym(); 00376 return tally; 00377 }
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 1046 of file symmetry.h.
References EMAN::EMObject::BOOL, EMAN::EMObject::FLOAT, EMAN::OrientationGenerator::get_param_types(), EMAN::EMObject::INT, and EMAN::TypeDict::put().
01047 { 01048 TypeDict d = OrientationGenerator::get_param_types(); 01049 d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument."); 01050 d.put("perturb", EMObject::BOOL, "Whether or not to perturb the generated orientations in a small local area, default is true."); 01051 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."); 01052 d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false."); 01053 d.put("alt_min", EMObject::FLOAT, "Minimum altitude value to include (alt=0 is Z axis). Default=0"); 01054 d.put("alt_max", EMObject::FLOAT, "Maximum altitude value to include (alt=90 is X-Y plane). Default=no limit"); 01055 d.put("breaksym", EMObject::BOOL, "If specified, still generates orientations filling the unit (hemi)sphere, but does it by filling one asymmetric unit, then generating all symmetric equivalents."); 01056 return d; 01057 }
static OrientationGenerator* EMAN::EmanOrientationGenerator::NEW | ( | ) | [inline, static] |
Factory support function NEW.
Definition at line 1027 of file symmetry.h.
References EmanOrientationGenerator().
01028 { 01029 return new EmanOrientationGenerator(); 01030 }
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 1066 of file symmetry.h.
Referenced by get_name().