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