EMAN::EmanOrientationGenerator Class Reference

EmanOrientationGenerator generates orientations quasi-evenly distributed in the asymmetric unit. More...

#include <symmetry.h>

Inheritance diagram for EMAN::EmanOrientationGenerator:

Inheritance graph
[legend]
Collaboration diagram for EMAN::EmanOrientationGenerator:

Collaboration graph
[legend]
List of all members.

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< Transformgen_orientations (const Symmetry3D *const sym) const
 generate orientations given some symmetry type

Static Public Member Functions

static OrientationGeneratorNEW ()
 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.
EmanOrientationGeneratoroperator= (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.

Detailed Description

EmanOrientationGenerator generates orientations quasi-evenly distributed in the asymmetric unit.

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.

Author:
David Woolford (based on previous work by Phil Baldwin and Steve Ludtke)
Date:
Feb 2008

Definition at line 1018 of file symmetry.h.


Constructor & Destructor Documentation

EMAN::EmanOrientationGenerator::EmanOrientationGenerator (  )  [inline]

Definition at line 1021 of file symmetry.h.

Referenced by NEW().

01021 {};

virtual EMAN::EmanOrientationGenerator::~EmanOrientationGenerator (  )  [inline, virtual]

Definition at line 1022 of file symmetry.h.

01022 {};

EMAN::EmanOrientationGenerator::EmanOrientationGenerator ( const EmanOrientationGenerator  )  [private]

Disallow copy construction.


Member Function Documentation

vector< Transform > EmanOrientationGenerator::gen_orientations ( const Symmetry3D *const   sym  )  const [virtual]

generate orientations given some symmetry type

Parameters:
sym the symmetry which defines the interesting asymmetric unit
Returns:
a vector of Transform objects containing the set of evenly distributed orientations

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

Parameters:
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
Returns:
the optimal azimuth angular spacing

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.

Returns:
a clear desciption of this class

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".

Returns:
the unique name of this class

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.

Parameters:
sym the symmetry which defines the interesting asymmetric unit
delta the desired angular spacing of the orientations
Returns:
the number of orientations that will be generated using these parameters

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.

Returns:
a dictionary containing the permissable parameters of this class parameters are explained in the dictionary itself

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.

Returns:
a newly instantiated class of this type

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.


Member Data Documentation

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().


The documentation for this class was generated from the following files:
Generated on Thu May 3 10:11:45 2012 for EMAN2 by  doxygen 1.4.7