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 "H symmetry support"; }
00469 
00476                 virtual TypeDict get_param_types() const
00477                 {
00478                         TypeDict d;
00479                         d.put("nsym", EMObject::INT, "The symmetry number of the helix, around the equator.");
00480                         d.put("nstart", EMObject::INT, "The symmetry number of the implicit C symmetry.");//ming add
00481                         d.put("equator_range", EMObject::FLOAT, "The amount altitude angles are allowed to vary above and below the equator. Default is 5");
00482                         d.put("tz", EMObject::FLOAT, "The translational distance (along z) between successive identical subunits in angstrom (default a/pix is 1)");
00483                         d.put("daz", EMObject::FLOAT, "The rotational angle (about z) between successive identical subunits in degrees");
00484                         d.put("apix", EMObject::FLOAT, "Angstrom per pixel, default is one.");
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 
00522                 virtual int get_nsym() const { return (int)params["nsym"]; }; // ming, this is the number of helix turns
00523                 /*virtual int get_nsym() const {
00524                         float daz = params.set_default("daz",0.0f);
00525                         if ( daz <= 0 ) throw InvalidValueException(daz,"Error, you must specify a positive non zero d_az");
00526                         return static_cast<int>(360.0/daz);
00527                 };*/
00528 
00533                 virtual int get_max_csym() const { return params["nsym"]; }
00534 
00536                 static const string NAME;
00537 
00541                 virtual bool is_h_sym() const { return true; }
00542 
00551                 virtual bool is_in_asym_unit(const float& altitude, const float& azimuth, const bool inc_mirror) const;
00552 
00557                 virtual vector<Vec3f> get_asym_unit_points(bool inc_mirror = false) const;
00558 
00563                 virtual vector<vector<Vec3f> > get_asym_unit_triangles(bool inc_mirror) const;
00564         private:
00566                 HSym(const HSym&);
00568                 HSym& operator=(const HSym&);
00569 };
00570 
00584         class PlatonicSym : public Symmetry3D
00585 {
00586         public:
00587                 PlatonicSym() {};
00588                 virtual  ~PlatonicSym() {};
00589 
00594                 virtual TypeDict get_param_types() const
00595                 {
00596                         TypeDict d;
00597                         return d;
00598                 }
00599 
00615                 virtual Dict get_delimiters(const bool inc_mirror=false) const;
00616 
00625                 virtual bool is_in_asym_unit(const float& altitude, const float& azimuth, const bool inc_mirror) const;
00626 
00630                 virtual bool is_platonic_sym() const { return true; }
00631 
00632         protected:
00634                 Dict platonic_params;
00635 
00641                 void init();
00642 
00650                 float platonic_alt_lower_bound(const float& azimuth, const float& alpha) const;
00651 
00656                 virtual vector<Vec3f> get_asym_unit_points(bool inc_mirror = false) const;
00657 
00662                 virtual vector<vector<Vec3f> > get_asym_unit_triangles(bool inc_mirror) const;
00663         private:
00665                 PlatonicSym(const PlatonicSym&);
00667                 PlatonicSym& operator=(const PlatonicSym&);
00668 };
00669 
00678         class TetrahedralSym : public PlatonicSym
00679 {
00680         public:
00683                 TetrahedralSym()  {init();}
00684                 virtual  ~TetrahedralSym() {}
00685 
00689                 static Symmetry3D *NEW()
00690                 {
00691                         return new TetrahedralSym();
00692                 }
00693 
00697                 virtual string get_name() const { return NAME; }
00698 
00699 
00703                 virtual string get_desc() const { return "Tetrahedral symmetry support"; }
00704 
00709                 virtual int get_max_csym() const { return 3; }
00710 
00723                 virtual Transform get_sym(const int n) const;
00724 
00733                 virtual bool is_in_asym_unit(const float& altitude, const float& azimuth, const bool inc_mirror) const;
00734 
00739                 virtual int get_nsym() const { return 12; };
00740 
00747                 virtual float get_az_alignment_offset() const;
00748 
00750                 static const string NAME;
00751 
00756                 virtual vector<Vec3f> get_asym_unit_points(bool inc_mirror = false) const;
00757 
00761                 virtual bool is_tet_sym() const { return true; }
00762 
00763         private:
00765                 TetrahedralSym(const TetrahedralSym&);
00767                 TetrahedralSym& operator=(const TetrahedralSym&);
00768 
00769 
00770 };
00771 
00782         class OctahedralSym : public PlatonicSym
00783 {
00784         public:
00787                 OctahedralSym()  {init();}
00788                 virtual  ~OctahedralSym() {}
00789 
00793                 static Symmetry3D *NEW()
00794                 {
00795                         return new OctahedralSym();
00796                 }
00797 
00801                 virtual string get_name() const { return NAME; };
00802 
00806                 virtual string get_desc() const { return "Octahedral symmetry support"; }
00807 
00812                 virtual int get_max_csym() const { return 4; }
00813 
00831                 virtual Transform get_sym(const int n) const;
00832 
00837                 virtual int get_nsym() const { return 24; };
00838 
00840                 static const string NAME;
00841         private:
00843                 OctahedralSym(const OctahedralSym&);
00845                 OctahedralSym& operator=(const OctahedralSym&);
00846 };
00847 
00858         class IcosahedralSym : public PlatonicSym
00859 {
00860         public:
00863                 IcosahedralSym() {init(); }
00864                 virtual  ~IcosahedralSym() { }
00865 
00869                 static Symmetry3D *NEW()
00870                 {
00871                         return new IcosahedralSym();
00872                 }
00873 
00877                 virtual string get_name() const { return NAME; };
00878 
00882                 virtual string get_desc() const { return "Icosahedral symmetry support"; }
00883 
00888                 virtual int get_max_csym() const { return 5; }// 5 is the greatest symmetry
00889 
00896                 virtual Transform get_sym(const int n) const;
00897 
00902                 virtual int get_nsym() const { return 60; };
00903 
00910                 virtual float get_az_alignment_offset() const;
00911 
00913                 static const string NAME;
00914         private:
00916                 IcosahedralSym(const IcosahedralSym&);
00918                 IcosahedralSym& operator=(const IcosahedralSym&);
00919 };
00921         template <> Factory < Symmetry3D >::Factory();
00923         template <> Symmetry3D* Factory < Symmetry3D >::get(const string & instancename);
00925         void dump_symmetries();
00927         map<string, vector<string> > dump_symmetries_list();
00928 
00937         class OrientationGenerator : public FactoryBase
00938 {
00939         public:
00940                 OrientationGenerator() {};
00941                 virtual ~OrientationGenerator() {};
00942 
00947                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const  = 0;
00948 
00949                 virtual TypeDict get_param_types() const
00950                 {
00951                         TypeDict d;
00952                         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.");
00953                         d.put("random_phi", EMObject::BOOL,  "Causes the orientations to have a random phi. This occurs before the phitoo parameter is considered.");
00954                         return d;
00955                 }
00956 
00973                 bool add_orientation(vector<Transform>& v, const float& az, const float& alt) const;
00974 
00975 
00976 
00990                 float get_optimal_delta(const Symmetry3D* const sym, const int& n) const;
00991 
00998                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const = 0;
00999 
01000         protected:
01001                 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;
01002 
01003         private:
01005                 OrientationGenerator(const OrientationGenerator&);
01007                 OrientationGenerator& operator=(const OrientationGenerator&);
01008 };
01009 
01010 
01011 
01021 class EmanOrientationGenerator : public OrientationGenerator
01022 {
01023         public:
01024                 EmanOrientationGenerator() {};
01025                 virtual  ~EmanOrientationGenerator() {};
01026 
01030                 static OrientationGenerator *NEW()
01031                 {
01032                         return new EmanOrientationGenerator();
01033                 }
01034 
01038                 virtual string get_name() const { return NAME; }
01039 
01043                 virtual string get_desc() const { return "Generate orientations distributed quasi-uniformaly over the asymmetric unit using an altitude-proportional strategy"; }
01044 
01049                 virtual TypeDict get_param_types() const
01050                 {
01051                         TypeDict d = OrientationGenerator::get_param_types();
01052                         d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument.");
01053                         d.put("perturb", EMObject::BOOL, "Whether or not to perturb the generated orientations in a small local area, default is true.");
01054                         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.");
01055                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01056                         d.put("alt_min", EMObject::FLOAT, "Minimum altitude value to include (alt=0 is Z axis). Default=0");
01057                         d.put("alt_max", EMObject::FLOAT, "Maximum altitude value to include (alt=90 is X-Y plane). Default=no limit");
01058                         return d;
01059                 }
01060 
01065                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01066 
01068                 static const string NAME;
01069         private:
01071                 EmanOrientationGenerator(const EmanOrientationGenerator&);
01073                 EmanOrientationGenerator& operator=(const EmanOrientationGenerator&);
01074 
01081                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const;
01082 
01083 
01092                 float get_az_delta(const float& delta,const float& altitude, const int maxcsym) const;
01093 
01094 };
01095 
01102 class RandomOrientationGenerator : public OrientationGenerator
01103 {
01104         public:
01105                 RandomOrientationGenerator() {}
01106                 virtual ~RandomOrientationGenerator() {}
01107 
01111                 static OrientationGenerator *NEW()
01112                 {
01113                         return new RandomOrientationGenerator();
01114                 }
01115 
01119                 virtual string get_name() const { return NAME; }
01120 
01124                 virtual string get_desc() const { return "Generate random orientations within an asymmetric unit"; }
01125 
01130                 virtual TypeDict get_param_types() const
01131                 {
01132                         TypeDict d;
01133                         d.put("n", EMObject::INT, "The number of orientations to generate.");
01134                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01135                         d.put("phitoo", EMObject::BOOL, "Makes phi random as well");
01136                         return d;
01137                 }
01138 
01143                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01144 
01146                 static const string NAME;
01147 
01148                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const { (void)sym; (void)delta; return 0; }
01149         private:
01151                 RandomOrientationGenerator(const RandomOrientationGenerator&);
01153                 RandomOrientationGenerator& operator=(const RandomOrientationGenerator&);
01154 };
01155 
01167         class EvenOrientationGenerator : public OrientationGenerator
01168 {
01169         public:
01170                 EvenOrientationGenerator() {}
01171                 virtual ~EvenOrientationGenerator() {}
01172 
01176                 static OrientationGenerator *NEW()
01177                 {
01178                         return new EvenOrientationGenerator();
01179                 }
01180 
01181 
01185                 virtual string get_name() const { return NAME; }
01186 
01190                 virtual string get_desc() const { return "Generate quasi-evenly distributed orientations within an asymmetric unit using Penczek's (94) approach"; }
01191 
01196                 virtual TypeDict get_param_types() const
01197                 {
01198                         TypeDict d = OrientationGenerator::get_param_types();
01199                         d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument.");
01200                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01201                         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.");
01202                         return d;
01203                 }
01204 
01209                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01210 
01212                 static const string NAME;
01213         private:
01215                 EvenOrientationGenerator(const EvenOrientationGenerator&);
01217                 EvenOrientationGenerator& operator=(const EvenOrientationGenerator&);
01224                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const;
01225 
01226 };
01227 
01233 class SaffOrientationGenerator : public OrientationGenerator
01234 {
01235         public:
01236                 SaffOrientationGenerator() {}
01237                 virtual ~SaffOrientationGenerator() {}
01238 
01242                 static OrientationGenerator *NEW()
01243                 {
01244                         return new SaffOrientationGenerator();
01245                 }
01246 
01250                 virtual string get_name() const { return NAME; }
01251 
01255                 virtual string get_desc() const { return "Generate quasi-evenly distributed orientations within an asymmetric unit using a spiraling method attributed to Saff"; }
01256 
01261                 virtual TypeDict get_param_types() const
01262                 {
01263                         TypeDict d = OrientationGenerator::get_param_types();
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                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01266                         d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument.");
01267                         return d;
01268                 }
01269 
01274                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01275 
01277                 static const string NAME;
01278         private:
01280                 SaffOrientationGenerator(const SaffOrientationGenerator&);
01282                 SaffOrientationGenerator& operator=(const SaffOrientationGenerator&);
01289                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const;
01290 
01291                 // This was a function that paid special considerations to the overall algorithm in the
01292                 // case of the Platonic symmetries, which have non trivial asymmetric units. But unfortunately
01293                 // it was bug-prone, and the approach in place already seemed good enough
01294                 //vector<Transform> gen_platonic_orientations(const Symmetry3D* const sym, const float& delta) const;
01295 };
01296 
01297 
01306 class OptimumOrientationGenerator : public OrientationGenerator
01307 {
01308         public:
01309                 OptimumOrientationGenerator() {}
01310                 virtual ~OptimumOrientationGenerator() {}
01311 
01315                 static OrientationGenerator *NEW()
01316                 {
01317                         return new OptimumOrientationGenerator();
01318                 }
01319 
01323                 virtual string get_name() const { return NAME; }
01324 
01328                 virtual string get_desc() const { return "Generate optimally distributed orientations within an asymmetric using a basic optimization technique"; }
01329 
01334                 virtual TypeDict get_param_types() const
01335                 {
01336                         TypeDict d = OrientationGenerator::get_param_types();
01337                         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.");
01338                         d.put("inc_mirror", EMObject::BOOL, "Indicates whether or not to include the mirror portion of the asymmetric unit. Default is false.");
01339                         d.put("delta", EMObject::FLOAT, "The angular separation of orientations in degrees. This option is mutually exclusively of the n argument.");
01340                         d.put("use", EMObject::STRING, "The orientation generation technique used to generate the initial distribution on the unit sphere.");
01341                         return d;
01342                 }
01343 
01348                 virtual vector<Transform> gen_orientations(const Symmetry3D* const sym) const;
01349 
01351                 static const string NAME;
01352         private:
01354                 OptimumOrientationGenerator(const OptimumOrientationGenerator&);
01356                 OptimumOrientationGenerator& operator=(const OptimumOrientationGenerator&);
01363                 virtual int get_orientations_tally(const Symmetry3D* const sym, const float& delta) const;
01364 
01365 
01368                 vector<Vec3f> optimize_distances(const vector<Transform>& v) const;
01369 };
01370 
01372         template <> Factory < OrientationGenerator >::Factory();
01374         void dump_orientgens();
01376         map<string, vector<string> > dump_orientgens_list();
01377 } // namespace EMAN
01378 
01379 #endif // eman__symmetry_h__
01380 

Generated on Mon Jul 19 12:40:14 2010 for EMAN2 by  doxygen 1.4.7