EMAN2
symmetry.h
Go to the documentation of this file.
00001 
00002 /*
00003  * Author: David Woolford, 09/23/2008 (woolford@bcm.edu)
00004  * Copyright (c) 2000-2006 Baylor College of Medicine
00005  *
00006  * This software is issued under a joint BSD/GNU license. You may use the
00007  * source code in this file under either license. However, note that the
00008  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00009  * so you are responsible for compliance with the licenses of these packages
00010  * if you opt to use BSD licensing. The warranty disclaimer below holds
00011  * in either instance.
00012  *
00013  * This complete copyright notice must be included in any revised version of the
00014  * source code. Additional authorship citations may be added, but existing
00015  * author citations must be preserved.
00016  *
00017  * This program is free software; you can redistribute it and/or modify
00018  * it under the terms of the GNU General Public License as published by
00019  * the Free Software Foundation; either version 2 of the License, or
00020  * (at your option) any later version.
00021  *
00022  * This program is distributed in the hope that it will be useful,
00023  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00024  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00025  * GNU General Public License for more details.
00026  *
00027  * You should have received a copy of the GNU General Public License
00028  * along with this program; if not, write to the Free Software
00029  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00030  *
00031  * */
00032 #ifndef eman__symmetry_h__
00033 #define eman__symmetry_h__ 1
00034 
00035 
00036 #include "emobject.h"
00037 #include "vec3.h"
00038 #include "transform.h"
00039 
00040 namespace EMAN {
00041 
00056         class Symmetry3D : public FactoryBase
00057         {
00058         public:
00059                 typedef vector<vector<Vec3f> >::const_iterator cit;
00060                 typedef vector<vector<Vec3f> >::iterator ncit;
00061                 Symmetry3D();
00062                 virtual  ~Symmetry3D();
00063 
00069                 virtual Dict get_delimiters(const bool inc_mirror=false) const = 0;
00070 
00076                 virtual Transform get_sym(const int n) const = 0;
00077 
00081                 virtual int get_nsym() const = 0;
00082 
00086                 virtual float get_az_alignment_offset() const { return 0.0; }
00087 
00088 
00089 
00094                 virtual bool is_platonic_sym() const { return false; }
00095 
00100                 virtual bool is_h_sym() const { return false; }
00101 
00106                 virtual bool is_c_sym() const { return false; }
00107 
00112                 virtual bool is_d_sym() const { return false; }
00113 
00118                 virtual bool is_tet_sym() const { return false; }
00119 
00120 
00121 
00125                 virtual int get_max_csym() const = 0;
00126 
00136                 virtual vector<Vec3f> get_asym_unit_points(bool inc_mirror) const = 0;
00144                 vector<Transform> gen_orientations(const string& generatorname="eman", const Dict& parms=Dict());
00145 
00154                 virtual bool is_in_asym_unit(const float& altitude, const float& azimuth, const bool inc_mirror) const = 0;
00155 
00165                 virtual Transform reduce(const Transform& t3d, int n=0) const;
00166 
00167 
00174                 virtual int in_which_asym_unit(const Transform& t3d) const;
00175 
00183                 virtual int point_in_which_asym_unit(const Vec3f& v) const;
00184 
00189                 virtual vector<vector<Vec3f> > get_asym_unit_triangles(bool inc_mirror) const = 0;
00190 
00200                 virtual vector<Transform> get_touching_au_transforms(bool inc_mirror = true) const;
00201 
00202                 virtual vector<Transform> get_syms() const;
00203                 static vector<Transform> get_symmetries(const string& symmetry);
00204         protected:
00207                 mutable float** cached_au_planes;
00208 
00210                 mutable int cache_size;
00212                 mutable int num_triangles;
00214                 mutable vector< vector<Vec3f> > au_sym_triangles;
00217                 void cache_au_planes() const;
00218 
00221                 void delete_au_planes();
00222         private:
00224                 Symmetry3D(const Symmetry3D&);
00226                 Symmetry3D& operator=(const Symmetry3D&);
00227 };
00228 
00233         class CSym : public Symmetry3D
00234 {
00235         public:
00236                 CSym() {};
00237                 virtual  ~CSym() {};
00238 
00242                 static Symmetry3D *NEW()
00243                 {
00244                         return new CSym();
00245                 }
00246 
00250                 virtual string get_name() const { return NAME; }
00251 
00255                 virtual string get_desc() const { return "C symmetry support"; }
00256 
00260                 virtual TypeDict get_param_types() const
00261                 {
00262                         TypeDict d;
00263                         d.put("nsym", EMObject::INT, "The symmetry number");
00264                         return d;
00265                 }
00266 
00274                 virtual Dict get_delimiters(const bool inc_mirror=false) const;
00275 
00283                 virtual Transform get_sym(const int n) const;
00284 
00289                 virtual int get_nsym() const { return params["nsym"]; };
00290 
00291 
00296                 virtual int get_max_csym() const { return params["nsym"]; }
00297 
00299                 static const string NAME;
00300 
00305                 virtual vector<Vec3f> get_asym_unit_points(bool inc_mirror = false) const;
00306 
00315                 virtual bool is_in_asym_unit(const float& altitude, const float& azimuth, const bool inc_mirror) const;
00316 
00320                 virtual bool is_c_sym() const { return  true; }
00321 
00322 
00327                 virtual vector<vector<Vec3f> > get_asym_unit_triangles(bool inc_mirror) const;
00328         private:
00330                 CSym(const CSym&);
00332                 CSym& operator=(const CSym&);
00333 
00334 };
00335 
00340         class DSym : public Symmetry3D
00341 {
00342         public:
00343                 DSym() {};
00344                 virtual  ~DSym() {};
00345 
00349                 static Symmetry3D *NEW()
00350                 {
00351                         return new DSym();
00352                 }
00353 
00357                 virtual string get_name() const { return NAME; }
00358 
00362                 virtual string get_desc() const { return "D symmetry support"; }
00363 
00367                 virtual TypeDict get_param_types() const
00368                 {
00369                         TypeDict d;
00370                         d.put("nsym", EMObject::INT, "The symmetry number");
00371                         return d;
00372                 }
00373 
00381                 virtual Dict get_delimiters(const bool inc_mirror=false) const;
00382 
00391                 virtual Transform get_sym(const int n) const;
00392 
00397                 virtual int get_nsym() const { return 2*(int)params["nsym"]; };
00398 
00399 
00404                 virtual int get_max_csym() const { return params["nsym"]; }
00405 
00410                 virtual vector<Vec3f> get_asym_unit_points(bool inc_mirror = false) const;
00411 
00420                 virtual bool is_in_asym_unit(const float& altitude, const float& azimuth, const bool inc_mirror) const;
00421 
00423                 static const string NAME;
00424 
00428                 virtual bool is_d_sym() const { return  true; }
00429 
00434                 virtual vector<vector<Vec3f> > get_asym_unit_triangles(bool inc_mirror) const;
00435         private:
00437                 DSym(const DSym&);
00439                 DSym& operator=(const DSym&);
00440 };
00441 
00446         class HSym : public Symmetry3D
00447 {
00448         public:
00449                 HSym() {};
00450                 virtual  ~HSym() {};
00451 
00455                 static Symmetry3D *NEW()
00456                 {
00457                         return new HSym();
00458                 }
00459 
00463                 virtual string get_name() const { return NAME; }
00464 
00468                 virtual string get_desc() const { return "Helical symmetry, with support for N-start, pitch and limited tilt range. Specify as H<nsym>:<nstart>:<daz>:<tz in pix>[:<maxtilt>]"; }
00469 
00476                 virtual TypeDict get_param_types() const
00477                 {
00478                         TypeDict d;
00479                         d.put("nsym", EMObject::INT, "The number of asymmetric units to generate. This could be infinite for helical symmetry. Normally a multiple of nstart.");
00480                         d.put("nstart", EMObject::INT, "The Cn symmetry of a single Z-slice of the helix.");
00481                         d.put("tz", EMObject::FLOAT, "The translational distance (along z) between successive identical subunits in angstroms (default A/pix is 1)");
00482                         d.put("daz", EMObject::FLOAT, "The rotational angle (about z) between successive identical subunits in degrees");
00483                         d.put("apix", EMObject::FLOAT, "Angstroms per pixel, default is 1.0, used only for tz");
00484                         d.put("maxtilt", EMObject::FLOAT, "When generating projections, normally only 'side views' are created (3-D Z along Y in 2-D). This is the maximum out of plane tilt in degrees.");
00485                         return d;
00486                 }
00487 
00500                 virtual Dict get_delimiters(const bool inc_mirror=false) const;
00501 
00502 
00511                 virtual Transform get_sym(const int n) const;
00512 
00519                 virtual int get_nsym() const { return (int)params["nsym"]; }; 
00520                 /*virtual int get_nsym() const {
00521                         float daz = params.set_default("daz",0.0f);
00522                         if ( daz <= 0 ) throw InvalidValueException(daz,"Error, you must specify a positive non zero d_az");
00523                         return static_cast<int>(360.0/daz);
00524                 };*/
00525 
00530                 virtual int get_max_csym() const { return (int)params["nstart"]; }      // may not be 
00531 
00533                 static const string NAME;
00534 
00538                 virtual bool is_h_sym() const { return true; }
00539 
00548                 virtual bool is_in_asym_unit(const float& altitude, const float& azimuth, const bool inc_mirror) const;
00549 
00554                 virtual vector<Vec3f> get_asym_unit_points(bool inc_mirror = false) const;
00555 
00560                 virtual vector<vector<Vec3f> > get_asym_unit_triangles(bool inc_mirror) const;
00561         private:
00563                 HSym(const HSym&);
00565                 HSym& operator=(const HSym&);
00566 };
00567 
00581         class PlatonicSym : public Symmetry3D
00582 {
00583         public:
00584                 PlatonicSym() {};
00585                 virtual  ~PlatonicSym() {};
00586 
00591                 virtual TypeDict get_param_types() const
00592                 {
00593                         TypeDict d;
00594                         return d;
00595                 }
00596 
00612                 virtual Dict get_delimiters(const bool inc_mirror=false) const;
00613 
00622                 virtual bool is_in_asym_unit(const float& altitude, const float& azimuth, const bool inc_mirror) const;
00623 
00627                 virtual bool is_platonic_sym() const { return true; }
00628 
00629         protected:
00631                 Dict platonic_params;
00632 
00638                 void init();
00639 
00647                 float platonic_alt_lower_bound(const float& azimuth, const float& alpha) const;
00648 
00653                 virtual vector<Vec3f> get_asym_unit_points(bool inc_mirror = false) const;
00654 
00659                 virtual vector<vector<Vec3f> > get_asym_unit_triangles(bool inc_mirror) const;
00660         private:
00662                 PlatonicSym(const PlatonicSym&);
00664                 PlatonicSym& operator=(const PlatonicSym&);
00665 };
00666 
00675         class TetrahedralSym : public PlatonicSym
00676 {
00677         public:
00680                 TetrahedralSym()  {init();}
00681                 virtual  ~TetrahedralSym() {}
00682 
00686                 static Symmetry3D *NEW()
00687                 {
00688                         return new TetrahedralSym();
00689                 }
00690 
00694                 virtual string get_name() const { return NAME; }
00695 
00696 
00700                 virtual string get_desc() const { return "Tetrahedral symmetry support"; }
00701 
00706                 virtual int get_max_csym() const { return 3; }
00707 
00720                 virtual Transform get_sym(const int n) const;
00721 
00730                 virtual bool is_in_asym_unit(const float& altitude, const float& azimuth, const bool inc_mirror) const;
00731 
00736                 virtual int get_nsym() const { return 12; };
00737 
00744                 virtual float get_az_alignment_offset() const;
00745 
00747                 static const string NAME;
00748 
00753                 virtual vector<Vec3f> get_asym_unit_points(bool inc_mirror = false) const;
00754 
00758                 virtual bool is_tet_sym() const { return true; }
00759 
00760         private:
00762                 TetrahedralSym(const TetrahedralSym&);
00764                 TetrahedralSym& operator=(const TetrahedralSym&);
00765 
00766 
00767 };
00768 
00779         class OctahedralSym : public PlatonicSym
00780 {
00781         public:
00784                 OctahedralSym()  {init();}
00785                 virtual  ~OctahedralSym() {}
00786 
00790                 static Symmetry3D *NEW()
00791                 {
00792                         return new OctahedralSym();
00793                 }
00794 
00798                 virtual string get_name() const { return NAME; };
00799 
00803                 virtual string get_desc() const { return "Octahedral symmetry support"; }
00804 
00809                 virtual int get_max_csym() const { return 4; }
00810 
00828                 virtual Transform get_sym(const int n) const;
00829 
00834                 virtual int get_nsym() const { return 24; };
00835 
00837                 static const string NAME;
00838         private:
00840                 OctahedralSym(const OctahedralSym&);
00842                 OctahedralSym& operator=(const OctahedralSym&);
00843 };
00844 
00855         class IcosahedralSym : public PlatonicSym
00856 {
00857         public:
00860                 IcosahedralSym() {init(); }
00861                 virtual  ~IcosahedralSym() { }
00862 
00866                 static Symmetry3D *NEW()
00867                 {
00868                         return new IcosahedralSym();
00869                 }
00870 
00874                 virtual string get_name() const { return NAME; };
00875 
00879                 virtual string get_desc() const { return "Icosahedral symmetry support"; }
00880 
00885                 virtual int get_max_csym() const { return 5; }// 5 is the greatest symmetry
00886 
00893                 virtual Transform get_sym(const int n) const;
00894 
00899                 virtual int get_nsym() const { return 60; };
00900 
00907                 virtual float get_az_alignment_offset() const;
00908 
00910                 static const string NAME;
00911         private:
00913                 IcosahedralSym(const IcosahedralSym&);
00915                 IcosahedralSym& operator=(const IcosahedralSym&);
00916 };
00917 
00919 class Icosahedral2Sym : public PlatonicSym
00920 {
00921         public:
00924                 Icosahedral2Sym() { }
00925                 virtual  ~Icosahedral2Sym() { init(); }
00926 
00930                 static Symmetry3D *NEW()
00931                 {
00932                         return new Icosahedral2Sym();
00933                 }
00934 
00938                 virtual string get_name() const { return NAME; };
00939 
00943                 virtual string get_desc() const { return "Icosahedral 2 symmetry support"; }
00944 
00949                 virtual int get_max_csym() const { return 2; }
00950 
00957                 virtual Transform get_sym(const int n) const;
00958 
00963                 virtual int get_nsym() const { return 60; };
00964 
00971                 virtual float get_az_alignment_offset() const;
00972 
00974                 static const string NAME;
00975         private:
00977                 Icosahedral2Sym(const Icosahedral2Sym&);
00979                 Icosahedral2Sym& operator=(const Icosahedral2Sym&);
00980 };
00981 
00983         template <> Factory < Symmetry3D >::Factory();
00985         template <> Symmetry3D* Factory < Symmetry3D >::get(const string & instancename);
00987         void dump_symmetries();
00989         map<string, vector<string> > dump_symmetries_list();
00990 
00999         class OrientationGenerator : public FactoryBase
01000 {
01001         public:
01002                 OrientationGenerator() {};
01003                 virtual ~OrientationGenerator() {};
01004 
01009                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const  = 0;
01010 
01011                 virtual TypeDict get_param_types() const
01012                 {
01013                         TypeDict d;
01014                         d.put("phitoo", EMObject::FLOAT,  "Specifying a non zero value for this argument will cause phi rotations to be included. The value specified is the angular spacing of the phi rotations in degrees. The default for this value is 0, causing no extra phi rotations to be included.");
01015                         d.put("random_phi", EMObject::BOOL,  "Causes the orientations to have a random phi. This occurs before the phitoo parameter is considered.");
01016                         return d;
01017                 }
01018 
01035                 bool add_orientation(vector<Transform>& v, const float& az, const float& alt) const;
01036 
01037 
01038 
01052                 float get_optimal_delta(const Symmetry3D* const sym, const int& n) const;
01053 
01060                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const = 0;
01061 
01062         protected:
01063                 void get_az_max(const Symmetry3D* const sym, const float& altmax, const bool inc_mirror, const float& alt_iterator,const float& h,bool& d_odd_mirror_flag, float& azmax_adjusted) const;
01064 
01065         private:
01067                 OrientationGenerator(const OrientationGenerator&);
01069                 OrientationGenerator& operator=(const OrientationGenerator&);
01070 };
01071 
01072 
01073 
01083 class EmanOrientationGenerator : public OrientationGenerator
01084 {
01085         public:
01086                 EmanOrientationGenerator() {};
01087                 virtual  ~EmanOrientationGenerator() {};
01088 
01092                 static OrientationGenerator *NEW()
01093                 {
01094                         return new EmanOrientationGenerator();
01095                 }
01096 
01100                 virtual string get_name() const { return NAME; }
01101 
01105                 virtual string get_desc() const { return "Generate orientations distributed quasi-uniformaly over the asymmetric unit using an altitude-proportional strategy"; }
01106 
01111                 virtual TypeDict get_param_types() const
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                 }
01123 
01128                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01129 
01131                 static const string NAME;
01132         private:
01134                 EmanOrientationGenerator(const EmanOrientationGenerator&);
01136                 EmanOrientationGenerator& operator=(const EmanOrientationGenerator&);
01137 
01144                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const;
01145 
01146 
01155                 float get_az_delta(const float& delta,const float& altitude, const int maxcsym) const;
01156 
01157 };
01158 
01165 class RandomOrientationGenerator : public OrientationGenerator
01166 {
01167         public:
01168                 RandomOrientationGenerator() {}
01169                 virtual ~RandomOrientationGenerator() {}
01170 
01174                 static OrientationGenerator *NEW()
01175                 {
01176                         return new RandomOrientationGenerator();
01177                 }
01178 
01182                 virtual string get_name() const { return NAME; }
01183 
01187                 virtual string get_desc() const { return "Generate random orientations within an asymmetric unit"; }
01188 
01193                 virtual TypeDict get_param_types() const
01194                 {
01195                         TypeDict d;
01196                         d.put("n", EMObject::INT, "The number of orientations to generate.");
01197                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01198                         d.put("phitoo", EMObject::BOOL, "Makes phi random as well");
01199                         return d;
01200                 }
01201 
01206                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01207 
01209                 static const string NAME;
01210 
01211                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const { (void)sym; (void)delta; return 0; }
01212         private:
01214                 RandomOrientationGenerator(const RandomOrientationGenerator&);
01216                 RandomOrientationGenerator& operator=(const RandomOrientationGenerator&);
01217 };
01218 
01230         class EvenOrientationGenerator : public OrientationGenerator
01231 {
01232         public:
01233                 EvenOrientationGenerator() {}
01234                 virtual ~EvenOrientationGenerator() {}
01235 
01239                 static OrientationGenerator *NEW()
01240                 {
01241                         return new EvenOrientationGenerator();
01242                 }
01243 
01244 
01248                 virtual string get_name() const { return NAME; }
01249 
01253                 virtual string get_desc() const { return "Generate quasi-evenly distributed orientations within an asymmetric unit using Penczek's (94) approach"; }
01254 
01259                 virtual TypeDict get_param_types() const
01260                 {
01261                         TypeDict d = OrientationGenerator::get_param_types();
01262                         d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument.");
01263                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01264                         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.");
01265                         return d;
01266                 }
01267 
01272                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01273 
01275                 static const string NAME;
01276         private:
01278                 EvenOrientationGenerator(const EvenOrientationGenerator&);
01280                 EvenOrientationGenerator& operator=(const EvenOrientationGenerator&);
01287                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const;
01288 
01289 };
01290 
01296 class SaffOrientationGenerator : public OrientationGenerator
01297 {
01298         public:
01299                 SaffOrientationGenerator() {}
01300                 virtual ~SaffOrientationGenerator() {}
01301 
01305                 static OrientationGenerator *NEW()
01306                 {
01307                         return new SaffOrientationGenerator();
01308                 }
01309 
01313                 virtual string get_name() const { return NAME; }
01314 
01318                 virtual string get_desc() const { return "Generate quasi-evenly distributed orientations within an asymmetric unit using a spiraling method attributed to Saff"; }
01319 
01324                 virtual TypeDict get_param_types() const
01325                 {
01326                         TypeDict d = OrientationGenerator::get_param_types();
01327                         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.");
01328                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01329                         d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument.");
01330                         return d;
01331                 }
01332 
01337                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01338 
01340                 static const string NAME;
01341         private:
01343                 SaffOrientationGenerator(const SaffOrientationGenerator&);
01345                 SaffOrientationGenerator& operator=(const SaffOrientationGenerator&);
01352                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const;
01353 
01354                 // This was a function that paid special considerations to the overall algorithm in the
01355                 // case of the Platonic symmetries, which have non trivial asymmetric units. But unfortunately
01356                 // it was bug-prone, and the approach in place already seemed good enough
01357                 //vector<Transform> gen_platonic_orientations(const Symmetry3D* const sym, const float& delta) const;
01358 };
01359 
01360 
01369 class OptimumOrientationGenerator : public OrientationGenerator
01370 {
01371         public:
01372                 OptimumOrientationGenerator() {}
01373                 virtual ~OptimumOrientationGenerator() {}
01374 
01378                 static OrientationGenerator *NEW()
01379                 {
01380                         return new OptimumOrientationGenerator();
01381                 }
01382 
01386                 virtual string get_name() const { return NAME; }
01387 
01391                 virtual string get_desc() const { return "Generate optimally distributed orientations within an asymmetric using a basic optimization technique"; }
01392 
01397                 virtual TypeDict get_param_types() const
01398                 {
01399                         TypeDict d = OrientationGenerator::get_param_types();
01400                         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.");
01401                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01402                         d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument.");
01403                         d.put("use", EMObject::STRING, "The orientation generation technique used to generate the initial distribution on the unit sphere.");
01404                         return d;
01405                 }
01406 
01411                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01412 
01414                 static const string NAME;
01415         private:
01417                 OptimumOrientationGenerator(const OptimumOrientationGenerator&);
01419                 OptimumOrientationGenerator& operator=(const OptimumOrientationGenerator&);
01426                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const;
01427 
01428 
01431                 vector<Vec3f> optimize_distances(const vector<Transform>& v) const;
01432 };
01433 
01435         template <> Factory < OrientationGenerator >::Factory();
01437         void dump_orientgens();
01439         map<string, vector<string> > dump_orientgens_list();
01440 } // namespace EMAN
01441 
01442 #endif // eman__symmetry_h__
01443