00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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.");
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"]; };
00523
00524
00525
00526
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; }
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
01292
01293
01294
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 }
01378
01379 #endif // eman__symmetry_h__
01380