Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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

OrientationGeneratorNEW ()
 Factory support function NEW.

Static Public Attributes

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 1083 of file symmetry.h.


Constructor & Destructor Documentation

EMAN::EmanOrientationGenerator::EmanOrientationGenerator  )  [inline]
 

Definition at line 1086 of file symmetry.h.

01086 {};

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

Definition at line 1087 of file symmetry.h.

01087 {};

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 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::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 EMAN::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

Referenced by gen_orientations(), and get_orientations_tally().

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

Returns:
the unique name of this class

Implements EMAN::FactoryBase.

Definition at line 1100 of file symmetry.h.

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.

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

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

Reimplemented from EMAN::OrientationGenerator.

Definition at line 1111 of file symmetry.h.

References 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                 }

OrientationGenerator* EMAN::EmanOrientationGenerator::NEW  )  [inline, static]
 

Factory support function NEW.

Returns:
a newly instantiated class of this type

Definition at line 1092 of file symmetry.h.

01093                 {
01094                         return new EmanOrientationGenerator();
01095                 }

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 47 of file symmetry.cpp.


The documentation for this class was generated from the following files:
Generated on Tue Jun 11 13:49:48 2013 for EMAN2 by  doxygen 1.3.9.1