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

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


Constructor & Destructor Documentation

EMAN::EmanOrientationGenerator::EmanOrientationGenerator  )  [inline]
 

Definition at line 1023 of file symmetry.h.

Referenced by NEW().

01023 {};

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

Definition at line 1024 of file symmetry.h.

01024 {};

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

00361 {
00362         float delta = params.set_default("delta", 0.0f);
00363         int n = params.set_default("n", 0);
00364 
00365         if ( delta <= 0 && n <= 0 ) throw InvalidParameterException("Error, you must specify a positive non-zero delta or n");
00366         if ( delta > 0 && n > 0 ) throw InvalidParameterException("Error, the delta and the n arguments are mutually exclusive");
00367 
00368         if ( n > 0 ) {
00369                 delta = get_optimal_delta(sym,n);
00370         }
00371 
00372         bool inc_mirror = params.set_default("inc_mirror",false);
00373         Dict delimiters = sym->get_delimiters(inc_mirror);
00374         float altmax = delimiters["alt_max"];
00375         float azmax = delimiters["az_max"];
00376 
00377         bool perturb = params.set_default("perturb",false);
00378 
00379         float alt_iterator = 0.0f;
00380 
00381         // #If it's a h symmetry then the alt iterator starts at very close
00382         // #to the altmax... the object is a h symmetry then it knows its alt_min...
00383         if (sym->is_h_sym()) alt_iterator = delimiters["alt_min"];
00384 
00385         vector<Transform> ret;
00386         while ( alt_iterator <= altmax ) {
00387                 float h = get_az_delta(delta,alt_iterator, sym->get_max_csym() );
00388 
00389                 // not sure what this does code taken from EMAN1 - FIXME original author add comments
00390                 if ( (alt_iterator > 0) && ( (azmax/h) < 2.8f) ) h = azmax / 2.1f;
00391                 else if (alt_iterator == 0) h = azmax;
00392 
00393                 float az_iterator = 0.0f;
00394 
00395                 float azmax_adjusted = azmax;
00396 
00397                 bool d_odd_mirror_flag = false;
00398                 get_az_max(sym,altmax, inc_mirror,alt_iterator, h,d_odd_mirror_flag, azmax_adjusted);
00399 
00400 
00401                 while ( az_iterator <= azmax_adjusted ) {
00402                         // FIXME: add an intelligent comment - this was copied from old code
00403 //                      if ( az_iterator > 180.0 && alt_iterator > 180.0/(2.0-0.001) && alt_iterator < 180.0/(2.0+0.001) ) {
00404 //                              az_iterator +=  h;
00405 //                              continue;
00406 //                      }
00407 //                      // Now that I am handling the boundaries very specifically, I don't think we need
00408                         // the above if statement. But I am leaving it there in case I need to reconsider.
00409 
00410                         if (alt_iterator == 0 && az_iterator > 0){
00411                                 az_iterator += h;
00412                                 continue; // We only ever need to generate on orientation at alt=0
00413                         }
00414 
00415 
00416                         float alt_soln = alt_iterator;
00417                         float az_soln = az_iterator;
00418 
00419                         if (sym->is_platonic_sym()) {
00420                                 if ( sym->is_in_asym_unit(alt_soln, az_soln,inc_mirror) == false ) {
00421                                         az_iterator += h;
00422                                         continue;
00423                                 }
00424                                 // Some objects have alignment offsets (icos and tet particularly)
00425                                 az_soln += sym->get_az_alignment_offset();
00426                         }
00427 
00428                         if ( perturb &&  alt_soln != 0 ) {
00429                                 alt_soln += Util::get_gauss_rand(0.0f,.25f*delta);
00430                                 az_soln += Util::get_gauss_rand(0.0f,h/4.0f);
00431                         }
00432 
00433                         add_orientation(ret,az_soln,alt_soln);
00434 
00435                         // Add helical symmetry orientations on the other side of the equator (if we're including
00436                         // mirror orientations)
00437                         if ( sym->is_h_sym() && inc_mirror && alt_iterator != (float) delimiters["alt_min"] ) {
00438                                 add_orientation(ret, az_soln,2.0f*(float)delimiters["alt_min"]-alt_soln);
00439                         }
00440 
00441                         az_iterator += h;
00442                         if ( (az_iterator > azmax_adjusted) && d_odd_mirror_flag) {
00443                                 azmax_adjusted = azmax;
00444                                 az_iterator += azmax/2.0f;
00445                         }
00446                 }
00447                 alt_iterator += delta;
00448         }
00449 
00450         return ret;
00451 }

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

References EMAN::EMConsts::deg2rad.

Referenced by gen_orientations(), and get_orientations_tally().

00281 {
00282         // convert altitude into radians
00283         float tmp = (float)(EMConsts::deg2rad * altitude);
00284 
00285         // This is taken from EMAN1 project3d.C
00286         // This wasn't working like it was supposed to. Rather than
00287         // figuring it out, I'm just replacing it --steve
00288 /*      float h=floor(360.0f/(delta*1.1547f));  // the 1.1547 makes the overall distribution more like a hexagonal mesh
00289         h=(int)floor(h*sin(tmp)+.5f);
00290         if (h==0) h=1;
00291         h=abs(maxcsym)*floor(h/(float)abs(maxcsym)+.5f);
00292         if ( h == 0 ) h = (float)maxcsym;
00293         h=2.0f*M_PI/h;
00294 
00295         return (float)(EMConsts::rad2deg*h);*/
00296 
00297         return altitude==0?360.0f:delta/sin(tmp);
00298 
00299 }

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

01042 { 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 1037 of file symmetry.h.

References NAME.

01037 { 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 302 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().

00303 {
00304         //FIXME THIS IS SO SIMILAR TO THE gen_orientations function that they should be probably use
00305         // a common routine - SAME ISSUE FOR OTHER ORIENTATION GENERATORS
00306         bool inc_mirror = params.set_default("inc_mirror",false);
00307         Dict delimiters = sym->get_delimiters(inc_mirror);
00308         float altmax = delimiters["alt_max"];
00309         float azmax = delimiters["az_max"];
00310 
00311         float alt_iterator = 0.0f;
00312 
00313         // #If it's a h symmetry then the alt iterator starts at very close
00314         // #to the altmax... the object is a h symmetry then it knows its alt_min...
00315         if (sym->is_h_sym()) alt_iterator = delimiters["alt_min"];
00316 
00317         int tally = 0;
00318         while ( alt_iterator <= altmax ) {
00319                 float h = get_az_delta(delta,alt_iterator, sym->get_max_csym() );
00320 
00321                 // not sure what this does code taken from EMAN1 - FIXME original author add comments
00322                 if ( (alt_iterator > 0) && ( (azmax/h) < 2.8f) ) h = azmax / 2.1f;
00323                 else if (alt_iterator == 0) h = azmax;
00324 
00325                 float az_iterator = 0.0f;
00326 
00327                 float azmax_adjusted = azmax;
00328                 bool d_odd_mirror_flag = false;
00329                 get_az_max(sym,altmax, inc_mirror,alt_iterator, h,d_odd_mirror_flag, azmax_adjusted);
00330 
00331                 while ( az_iterator <= azmax_adjusted ) {
00332                         // FIXME: add an intelligent comment - this was copied from old code
00333 //                      if ( az_iterator > 180.0 && alt_iterator > 180.0/(2.0-0.001) && alt_iterator < 180.0/(2.0+0.001) ) {
00334 //                              az_iterator +=  h;
00335 //                              continue;
00336 //                      }
00337 
00338                         if (sym->is_platonic_sym()) {
00339                                 if ( sym->is_in_asym_unit(alt_iterator, az_iterator,inc_mirror) == false ) {
00340                                         az_iterator += h;
00341                                         continue;
00342                                 }
00343                         }
00344 
00345                         tally++;
00346                         if ( sym->is_h_sym() && inc_mirror && alt_iterator != (float) delimiters["alt_min"] ) {
00347                                 tally++;
00348                         }
00349                         az_iterator += h;
00350                         if ( (az_iterator > azmax_adjusted) && d_odd_mirror_flag) {
00351                                 azmax_adjusted = azmax;
00352                                 az_iterator += azmax/2.0f;
00353                         }
00354                 }
00355                 alt_iterator += delta;
00356         }
00357         return tally;
00358 }

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

References EMAN::EMObject::BOOL, EMAN::EMObject::FLOAT, EMAN::OrientationGenerator::get_param_types(), EMAN::EMObject::INT, and EMAN::TypeDict::put().

01049                 {
01050                         TypeDict d = OrientationGenerator::get_param_types();
01051                         d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument.");
01052                         d.put("perturb", EMObject::BOOL, "Whether or not to perturb the generated orientations in a small local area, default is false.");
01053                         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.");
01054                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01055                         return d;
01056                 }

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

Factory support function NEW.

Returns:
a newly instantiated class of this type

Definition at line 1029 of file symmetry.h.

References EmanOrientationGenerator().

01030                 {
01031                         return new EmanOrientationGenerator();
01032                 }

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

Referenced by get_name().


The documentation for this class was generated from the following files:
Generated on Tue May 25 17:38:27 2010 for EMAN2 by  doxygen 1.4.4