EMAN2
Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions
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 1083 of file symmetry.h.


Constructor & Destructor Documentation

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

Definition at line 1086 of file symmetry.h.

Referenced by NEW().

{};
virtual EMAN::EmanOrientationGenerator::~EmanOrientationGenerator ( ) [inline, virtual]

Definition at line 1087 of file symmetry.h.

{};
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:
symthe 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 387 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.

{
        float delta = params.set_default("delta", 0.0f);
        int n = params.set_default("n", 0);
        bool breaksym = params.set_default("breaksym",false);

        if ( delta <= 0 && n <= 0 ) throw InvalidParameterException("Error, you must specify a positive non-zero delta or n");
        if ( delta > 0 && n > 0 ) throw InvalidParameterException("Error, the delta and the n arguments are mutually exclusive");

        if ( n > 0 ) {
                delta = get_optimal_delta(sym,n);
        }

        bool inc_mirror = params.set_default("inc_mirror",false);
        bool inc_mirror_real = inc_mirror;
        if (breaksym) inc_mirror=true;          // we need to enable mirror generation, then strip them out at the end, or things don't work right...
        Dict delimiters = sym->get_delimiters(inc_mirror);
        float altmax = delimiters["alt_max"];
        float azmax = delimiters["az_max"];

        float paltmin = params.set_default("alt_min",0.0f);
        float paltmax = params.set_default("alt_max",180.0f);
        if (altmax>paltmax) altmax=paltmax;

        bool perturb = params.set_default("perturb",true);

        float alt_iterator = 0.0f;

        // #If it's a h symmetry then the alt iterator starts at very close
        // #to the altmax... the object is a h symmetry then it knows its alt_min...
        if (sym->is_h_sym()) alt_iterator = delimiters["alt_min"];

        vector<Transform> ret;
        while ( alt_iterator <= altmax ) {
                float h = get_az_delta(delta,alt_iterator, sym->get_max_csym() );

                // not sure what this does code taken from EMAN1 - FIXME original author add comments
                if ( (alt_iterator > 0) && ( (azmax/h) < 2.8f) ) h = azmax / 2.1f;
                else if (alt_iterator == 0) h = azmax;

                float az_iterator = 0.0f;

                float azmax_adjusted = azmax;

                bool d_odd_mirror_flag = false;
                get_az_max(sym,altmax, inc_mirror,alt_iterator, h,d_odd_mirror_flag, azmax_adjusted);
                if (alt_iterator<paltmin) { alt_iterator += delta; continue; }


                while ( az_iterator <= azmax_adjusted ) {
                        // FIXME: add an intelligent comment - this was copied from old code
//                      if ( az_iterator > 180.0 && alt_iterator > 180.0/(2.0-0.001) && alt_iterator < 180.0/(2.0+0.001) ) {
//                              az_iterator +=  h;
//                              continue;
//                      }
//                      // Now that I am handling the boundaries very specifically, I don't think we need
                        // the above if statement. But I am leaving it there in case I need to reconsider.

                        if (alt_iterator == 0 && az_iterator > 0){
                                az_iterator += h;
                                continue; // We only ever need to generate on orientation at alt=0
                        }


                        float alt_soln = alt_iterator;
                        float az_soln = az_iterator;

                        if (sym->is_platonic_sym()) {
                                if ( sym->is_in_asym_unit(alt_soln, az_soln,inc_mirror) == false ) {
                                        az_iterator += h;
                                        continue;
                                }
                                // Some objects have alignment offsets (icos and tet particularly)
                                az_soln += sym->get_az_alignment_offset();
                        }
//printf("%f %f/n",alt_soln,az_soln);
                        if ( perturb &&  alt_soln != 0 ) {
                                alt_soln += Util::get_gauss_rand(0.0f,.125f*delta);
                                az_soln += Util::get_gauss_rand(0.0f,h*.125f);
                        }

                        add_orientation(ret,az_soln,alt_soln);

                        // Add helical symmetry orientations on the other side of the equator (if we're including
                        // mirror orientations)
                        if ( sym->is_h_sym() && inc_mirror && alt_iterator != (float) delimiters["alt_min"] ) {
                                add_orientation(ret, az_soln,2.0f*(float)delimiters["alt_min"]-alt_soln);
                        }

                        az_iterator += h;
                        if ( (az_iterator > azmax_adjusted) && d_odd_mirror_flag) {
                                azmax_adjusted = azmax;
                                az_iterator += azmax/2.0f;
                        }
                }
                alt_iterator += delta;
        }
        
        // With breaksym, values are generated for one asymmetric unit as if symmetry were imposed, then
        // the symmetry equivalent points are generated. Used with asymmetric structures with pseudosymmetry
        if (breaksym) {
                // no iterators here since we are making the list longer as we go
                int nwithsym=ret.size();        // transforms in one asym unit
                int nsym=sym->get_nsym();       // number of asymmetric units to generate
                for (int j=1; j<nsym; j++) {
                        Transform t=sym->get_sym(j);
                        for (int i=0; i<nwithsym; i++) {
                                ret.push_back(ret[i]*t);                // add the symmetry modified transform to the end of the vector
                        }
                }
                
                // Now we get rid of anything in the bottom half of the unit sphere if requested
                if (!inc_mirror_real) {
                        vector<Transform> ret2;
                        for (vector<Transform>::iterator t=ret.begin(); t!=ret.end(); ++t) {
                                if ((*t)[2][2]>=0) ret2.push_back(*t); 
//                              printf("%f\n",t[2][2]);
                        }
                        return ret2;
                }
        }

        return ret;
}
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
altitudethe altitude along which the azimuth is going to be varied
maxcsymthe maximum csym of the Symmetry3D object - this is usually Symmetry3D::get_max_csym
Returns:
the optimal azimuth angular spacing

Definition at line 299 of file symmetry.cpp.

References EMAN::EMConsts::deg2rad.

Referenced by gen_orientations(), and get_orientations_tally().

{
        // convert altitude into radians
        float tmp = (float)(EMConsts::deg2rad * altitude);

        // This is taken from EMAN1 project3d.C
        // This wasn't working like it was supposed to. Rather than
        // figuring it out, I'm just replacing it --steve
/*      float h=floor(360.0f/(delta*1.1547f));  // the 1.1547 makes the overall distribution more like a hexagonal mesh
        h=(int)floor(h*sin(tmp)+.5f);
        if (h==0) h=1;
        h=abs(maxcsym)*floor(h/(float)abs(maxcsym)+.5f);
        if ( h == 0 ) h = (float)maxcsym;
        h=2.0f*M_PI/h;

        return (float)(EMConsts::rad2deg*h);*/

        return altitude==0?360.0f:delta/sin(tmp);

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

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

References NAME.

{ 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:
symthe symmetry which defines the interesting asymmetric unit
deltathe desired angular spacing of the orientations
Returns:
the number of orientations that will be generated using these parameters

Implements EMAN::OrientationGenerator.

Definition at line 321 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().

{
        //FIXME THIS IS SO SIMILAR TO THE gen_orientations function that they should be probably use
        // a common routine - SAME ISSUE FOR OTHER ORIENTATION GENERATORS
        bool inc_mirror = params.set_default("inc_mirror",false);
        bool breaksym = params.set_default("breaksym",false);
        Dict delimiters = sym->get_delimiters(inc_mirror);
        float altmax = delimiters["alt_max"];
        float azmax = delimiters["az_max"];

        float paltmin = params.set_default("alt_min",0.0f);
        float paltmax = params.set_default("alt_max",180.0f);
        if (altmax>paltmax) altmax=paltmax;
        
        float alt_iterator = 0.0f;

        // #If it's a h symmetry then the alt iterator starts at very close
        // #to the altmax... the object is a h symmetry then it knows its alt_min...
        if (sym->is_h_sym()) alt_iterator = delimiters["alt_min"];

        int tally = 0;
        while ( alt_iterator <= altmax ) {
                float h = get_az_delta(delta,alt_iterator, sym->get_max_csym() );

                // not sure what this does code taken from EMAN1 - FIXME original author add comments
                if ( (alt_iterator > 0) && ( (azmax/h) < 2.8f) ) h = azmax / 2.1f;
                else if (alt_iterator == 0) h = azmax;

                float az_iterator = 0.0f;

                float azmax_adjusted = azmax;
                bool d_odd_mirror_flag = false;
                get_az_max(sym,altmax, inc_mirror,alt_iterator, h,d_odd_mirror_flag, azmax_adjusted);
                if (alt_iterator<paltmin) { alt_iterator += delta; continue; }
                
                while ( az_iterator <= azmax_adjusted ) {
                        // FIXME: add an intelligent comment - this was copied from old code
//                      if ( az_iterator > 180.0 && alt_iterator > 180.0/(2.0-0.001) && alt_iterator < 180.0/(2.0+0.001) ) {
//                              az_iterator +=  h;
//                              continue;
//                      }

                        if (sym->is_platonic_sym()) {
                                if ( sym->is_in_asym_unit(alt_iterator, az_iterator,inc_mirror) == false ) {
                                        az_iterator += h;
                                        continue;
                                }
                        }

                        tally++;
                        if ( sym->is_h_sym() && inc_mirror && alt_iterator != (float) delimiters["alt_min"] ) {
                                tally++;
                        }
                        az_iterator += h;
                        if ( (az_iterator > azmax_adjusted) && d_odd_mirror_flag) {
                                azmax_adjusted = azmax;
                                az_iterator += azmax/2.0f;
                        }
                }
                alt_iterator += delta;
        }
        
        if (breaksym) return tally*sym->get_nsym();
        return tally;
}
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::EMObject::BOOL, EMAN::EMObject::FLOAT, EMAN::EMObject::INT, and EMAN::TypeDict::put().

                {
                        TypeDict d = OrientationGenerator::get_param_types();
                        d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument.");
                        d.put("perturb", EMObject::BOOL, "Whether or not to perturb the generated orientations in a small local area, default is true.");
                        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.");
                        d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
                        d.put("alt_min", EMObject::FLOAT, "Minimum altitude value to include (alt=0 is Z axis). Default=0");
                        d.put("alt_max", EMObject::FLOAT, "Maximum altitude value to include (alt=90 is X-Y plane). Default=no limit");
                        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.");
                        return d;
                }
static 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.

References EmanOrientationGenerator().

                {
                        return new EmanOrientationGenerator();
                }
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 1131 of file symmetry.h.

Referenced by get_name().


The documentation for this class was generated from the following files: