emobject.h

Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Copyright (c) 2000-2007 Baylor College of Medicine
00008  *
00009  * This software is issued under a joint BSD/GNU license. You may use the
00010  * source code in this file under either license. However, note that the
00011  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00012  * so you are responsible for compliance with the licenses of these packages
00013  * if you opt to use BSD licensing. The warranty disclaimer below holds
00014  * in either instance.
00015  *
00016  * This complete copyright notice must be included in any revised version of the
00017  * source code. Additional authorship citations may be added, but existing
00018  * author citations must be preserved.
00019  *
00020  * This program is free software; you can redistribute it and/or modify
00021  * it under the terms of the GNU General Public License as published by
00022  * the Free Software Foundation; either version 2 of the License, or
00023  * (at your option) any later version.
00024  *
00025  * This program is distributed in the hope that it will be useful,
00026  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00027  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00028  * GNU General Public License for more details.
00029  *
00030  * You should have received a copy of the GNU General Public License
00031  * along with this program; if not, write to the Free Software
00032  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00033  *
00034  * */
00035 
00036 #ifndef eman__object__h__
00037 #define eman__object__h__ 1
00038 
00039 #include <map>
00040 using std::map;
00041 
00042 #include <set>
00043 using std::set;
00044 
00045 #include <vector>
00046 using std::vector;
00047 
00048 #include <string>
00049 using std::string;
00050 
00051 #include <utility>
00052 using std::pair;
00053 
00054 #include <algorithm>
00055 // using copy
00056 
00057 #include <iterator>
00058 
00059 #include "log.h"
00060 #include "exception.h"
00061 
00062 // #include "transform.h" // Trnasform3D::EulerType
00063 
00064 // debug
00065 #include <cstdio>
00066 #include <iostream>
00067 using std::cout;
00068 using std::endl;
00069 
00070 #include <cctype> // tolower
00071 #include <algorithm> //tolower
00072 namespace EMAN
00073 {
00074         class EMConsts {
00075         public:
00076                 static const float I2G; // 2 interpolation
00077                 static const float I3G; // used for 3 and 5x5x5 interpolation
00078                 static const float I4G; // used for 4 interpolation
00079                 static const float I5G; // used for 5x5x5 interpolation
00080 
00081                 static const double rad2deg; // radians to degree constant factor
00082                 static const double deg2rad; // degrees to radians constant factor
00083                 static const double pi; // degrees to radians constant factor
00084         };
00085 
00086         class EMData;
00087         class XYData;
00088         class Aligner;
00089         class Averager;
00090         class Cmp;
00091         class Processor;
00092         class Projector;
00093         class Reconstructor;
00094         class Analyzer;
00095         class Transform;
00096         class Ctf;
00097 
00098         enum MapInfoType {
00099                 NORMAL,
00100                 ICOS2F_FIRST_OCTANT,
00101                 ICOS2F_FULL,
00102                 ICOS2F_HALF,
00103                 ICOS3F_HALF,
00104                 ICOS3F_FULL,
00105                 ICOS5F_HALF,
00106                 ICOS5F_FULL,
00107                 ICOS_UNKNOWN
00108         };
00109 
00126         class EMObject
00127         {
00128         public:
00129                 enum ObjectType {
00130                         UNKNOWN,
00131                         BOOL,
00132                         SHORT,
00133                         UNSIGNEDINT,
00134                         INT,
00135                         FLOAT,
00136                         DOUBLE,
00137                         STRING,
00138                         EMDATA,
00139                         XYDATA,
00140                         INTARRAY,
00141                         FLOATARRAY,
00142                         STRINGARRAY,
00143                         TRANSFORM,
00144                         CTF,
00145                         FLOAT_POINTER,
00146                         INT_POINTER,
00147                         VOID_POINTER,
00148                         TRANSFORMARRAY
00149                 };
00150 
00151 
00156                 EMObject();
00157                 EMObject(bool boolean);
00158                 EMObject(short);
00159                 EMObject(int num);
00160                 EMObject(unsigned int num);
00161                 EMObject(float ff);
00162                 EMObject(double dd);
00163                 EMObject(const char *s);
00164                 EMObject(const string & s);
00165                 EMObject(float * fp);
00166                 EMObject(int * ip);
00167                 EMObject(void * vp);
00168                 EMObject(EMData * em);
00169                 EMObject(XYData * xy);
00170                 EMObject(Transform * t);
00171                 EMObject(Ctf * ctf);
00172                 EMObject(const vector< int >& v );
00173                 EMObject(const vector < float >&v);
00174                 EMObject(const vector <string>& sarray);
00175                 EMObject(const vector <Transform>& tarray);
00176 
00181                 EMObject(const EMObject& that);
00182 
00187                 EMObject& operator=(const EMObject& that);
00188 
00192                 ~EMObject();
00195                 operator bool () const;
00196                 operator short () const;
00197                 operator int () const;
00198                 operator unsigned int () const;
00199                 operator float () const;
00200                 operator double () const;
00201                 operator const char *() const;
00202                 operator float * () const;
00203                 operator int * () const;
00204                 operator void * () const;
00205                 operator EMData *() const;
00206                 operator XYData *() const;
00207                 operator Transform *() const;
00208                 operator Ctf *() const;
00209                 operator vector < int > () const;
00210                 operator vector < float > () const;
00211                 operator vector<string> () const;
00212                 operator vector<Transform> () const;
00213 
00218                 bool is_null() const;
00219 
00222                 string to_str() const;
00223 
00228                 ObjectType get_type() const { return type; }
00229 
00234                 string get_type_string() const { return get_object_type_name(type); }
00235 
00236 
00242                 string to_str(ObjectType type) const;
00243 
00247                 static string get_object_type_name(ObjectType t);
00248 
00252                 friend bool operator==(const EMObject &e1, const EMObject & e2);
00253 
00257                 friend bool operator!=(const EMObject &e1, const EMObject & e2);
00258 
00259         private:
00260                 union
00261                 {
00262                         bool b;
00263                         short si;
00264                         int n;
00265                         unsigned int ui;
00266                         float f;
00267                         double d;
00268                         float * fp;
00269                         int * ip;
00270                         void * vp;
00271                         EMData *emdata;
00272                         XYData *xydata;
00273                 };
00274 
00275                 string str;
00276                 vector <int> iarray;
00277                 vector <float> farray;
00278                 vector <string> strarray;
00279                 vector <Transform> transformarray;
00280                 ObjectType type;
00281 
00284                 void printInfo() const;
00285 
00286 //              void init();
00287                 
00288                 static map< ObjectType, string> init();
00289                 static map< ObjectType, string> type_registry;
00290                 
00291         };
00292 
00293         bool operator==(const EMObject &e1, const EMObject & e2);
00294         bool operator!=(const EMObject &e1, const EMObject & e2);
00295 
00307         class TypeDict
00308         {
00309                 public:
00310                         TypeDict()
00311                         {
00312                         }
00313 
00314                         ~TypeDict()
00315                         {
00316                         }
00317 
00318                         vector < string > keys() const
00319                         {
00320                                 vector < string > result;
00321                                 map < string, string >::const_iterator p;
00322 
00323                                 for (p = type_dict.begin(); p != type_dict.end(); p++) {
00324                                         result.push_back(p->first);
00325                                 }
00326 
00327                                 return result;
00328                         }
00329 
00330                         size_t size() const
00331                         {
00332                                 return type_dict.size();
00333                         }
00334 
00335                         void put(const string& key, EMObject::ObjectType o, const string& desc = "")
00336                         {
00337                                 type_dict[key] = EMObject::get_object_type_name(o);
00338                                 desc_dict[key] = desc;
00339                         }
00340 
00341                         string get_type(const string& key)
00342                         {
00343                                 return type_dict[key];
00344                         }
00345 
00346                         string get_desc(const string& key)
00347                         {
00348                                 return desc_dict[key];
00349                         }
00350 
00351                         string operator[] (const string & key)
00352                         {
00353                                 return type_dict[key];
00354                         }
00355 
00356                         void dump();
00357 
00358                         inline bool find_type( const string& type ) {  if ( type_dict.find(type) != type_dict.end() ) return true; return false; }
00359 
00360                 private:
00361                         map < string, string > type_dict;
00362                         map < string, string > desc_dict;
00363         };
00364 
00365 
00389         class Dict
00390         {
00391         public:
00392                 Dict()
00393                 {
00394                 }
00395 
00400                 Dict(const string & key1, EMObject val1)
00401                 {
00402                         dict[key1] = val1;
00403                 }
00404 
00407                 Dict(const string & key1, EMObject val1,
00408                          const string & key2, EMObject val2)
00409                 {
00410                         dict[key1] = val1;
00411                         dict[key2] = val2;
00412                 }
00413 
00416                 Dict(const string & key1, EMObject val1,
00417                          const string & key2, EMObject val2,
00418                          const string & key3, EMObject val3)
00419                 {
00420                         dict[key1] = val1;
00421                         dict[key2] = val2;
00422                         dict[key3] = val3;
00423                 }
00424 
00427                 Dict(const string & key1, EMObject val1,
00428                          const string & key2, EMObject val2,
00429                          const string & key3, EMObject val3,
00430                          const string & key4, EMObject val4)
00431                 {
00432                         dict[key1] = val1;
00433                         dict[key2] = val2;
00434                         dict[key3] = val3;
00435                         dict[key4] = val4;
00436                 }
00437 
00441                 Dict(const map < string, EMObject > &d)
00442                 {
00443                         copy(d.begin(), d.end(), inserter(dict, dict.begin()));
00444                         // Or use
00445                         // dict.insert(d.begin(), d.end());
00446                 }
00447 
00451                 ~Dict() {}
00452 
00456                 Dict( const Dict& that);
00457 
00461                 Dict& operator=(const Dict& that);
00462 
00465                 vector < string > keys()const
00466                 {
00467                         vector < string > result;
00468 
00469                         map < string, EMObject >::const_iterator p;
00470                         for (p = dict.begin(); p != dict.end(); p++) {
00471                                 result.push_back(p->first);
00472                         }
00473 
00474                         return result;
00475                 }
00476 
00479                 vector < EMObject > values()const
00480                 {
00481                         vector < EMObject > result;
00482 
00483                         map < string, EMObject >::const_iterator p;
00484                         for (p = dict.begin(); p != dict.end(); p++) {
00485                                 result.push_back(p->second);
00486                         }
00487 
00488                         return result;
00489                 }
00490 
00494                 bool has_key_ci(const string & key) const;
00495 
00499                 bool has_key(const string & key) const
00500                 {
00501                         map < string, EMObject >::const_iterator p = dict.find(key);
00502                         if (p != dict.end()) {
00503                                 return true;
00504                         }
00505                         return false;
00506                 }
00507 
00510                 size_t size() const
00511                 {
00512                         return dict.size();
00513                 }
00514 
00518                 EMObject get(const string & key) const
00519                 {
00520                         if( has_key(key) ) {
00521                                 return dict[key];
00522                         }
00523                         else {
00524                                 LOGERR("No such key exist in this Dict");
00525                                 throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00526                         }
00527                 }
00528 
00532                 EMObject get_ci(const string & key) const;
00536                 void put(const string & key, EMObject val)
00537                 {
00538                         dict[key] = val;
00539                 }
00540 
00543                 void erase(const string & key)
00544                 {
00545                         dict.erase(key);
00546                 }
00547 
00551                 void clear()
00552                 {
00553                         dict.clear();
00554                 }
00555 
00559                 template<typename type>
00560                 type set_default(const string & key, type val)
00561                 {
00562                         if (!has_key(key)) {
00563                                 dict[key] = val;
00564                         }
00565                         return dict[key];
00566                 }
00567 
00568                 Dict copy_exclude_keys(const vector<string>& excluded_keys) const
00569                 {
00570                         Dict ret(*this);
00571 
00572                         for ( vector<string>::const_iterator it = excluded_keys.begin(); it != excluded_keys.end(); ++it ) {
00573                                 if (ret.has_key(*it)) ret.erase(*it);
00574                         }
00575 
00576                         return ret;
00577                 }
00578 
00579                 Dict copy_exclusive_keys(const vector<string>& exclusive_keys) const
00580                 {
00581                         Dict ret;
00582                         for ( vector<string>::const_iterator it = exclusive_keys.begin(); it != exclusive_keys.end(); ++it ) {
00583                                 if (has_key(*it)) ret[*it] = (*this)[*it];
00584                         }
00585 
00586                         return ret;
00587                 }
00588 
00589                 Dict copy_keys_in( const TypeDict& tdict ) const {
00590                         vector<string> keys = tdict.keys();
00591                         return copy_exclusive_keys(keys);
00592                 }
00593 
00594                 EMObject & operator[] (const string & key)
00595                 {
00596 //                      static EMObject nullreturn;
00597 //                      if( has_key(key) )  return dict[key];
00598 //                      else return nullreturn;
00599 
00600 //                      if( has_key(key) ) {
00601                                 return dict[key];
00602 //                      }
00603 //                      else {
00604 //                              LOGERR("No such key exist in this Dict");
00605 //                              throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00606 //                      }
00607                 }
00608 
00609                 EMObject operator[] (const string & key) const
00610                 {
00611 //                      if( has_key(key) )  return dict[key];
00612 //                      else return EMObject();
00613                         return dict[key];
00614 
00615 //                      else {
00616 //                              LOGERR("No such key exist in this Dict");
00617 //                              throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00618 //                      }
00619                 }
00620 
00624                 friend bool operator==(const Dict& d1, const Dict& d2);
00625 
00629                 friend bool operator!=(const Dict& d1, const Dict& d2);
00630 
00631         private:
00632                 mutable map < string, EMObject > dict;
00633 
00634         public:
00642                 class iterator : public map < string, EMObject >::iterator
00643                 {
00644                 public:
00645                         typedef std::bidirectional_iterator_tag iterator_category;
00646                         typedef pair<string, EMObject> value_type;
00647 
00648                 public:
00649                         iterator( map < string, EMObject >::iterator parent_it );
00650                         virtual ~iterator(){}
00651 
00652                         iterator( const iterator& that );
00653                         iterator& operator=( const iterator& that );
00654                 };
00655 
00663                 class const_iterator :  public map < string, EMObject >::const_iterator
00664                 {
00665                 public:
00666                         typedef std::bidirectional_iterator_tag iterator_category;
00667                         typedef pair<string, EMObject> value_type; // Note that value_type should NOT be const even though the container elements are const
00668                 public:
00669                         const_iterator( const map < string, EMObject >::const_iterator parent_it);
00670                         virtual ~const_iterator(){}
00671                         const_iterator( const Dict::iterator& it );
00672 
00673                         const_iterator( const const_iterator& that );
00674                         const_iterator& operator=( const const_iterator& that );
00675                 };
00676 
00677                 // Iterator support
00678                 iterator begin( void );
00679                 const_iterator begin( void ) const;
00680 
00681                 iterator end( void );
00682                 const_iterator end( void ) const;
00683 
00684                 // Wraps map.find(const string& key)
00685                 iterator find( const string& key );
00686                 const_iterator find( const string& key ) const;
00687         };
00688 
00689         // These operators were originally added for the purposes of making testing code but might come in handy for other things
00690         // operator== simply wraps map<string, EMObject>::operator==
00691         bool operator==(const Dict &d1, const Dict& d2);
00692         bool operator!=(const Dict &d1, const Dict& d2);
00693 
00694 
00713         template < class T > class Factory
00714         {
00715         public:
00716                 typedef T *(*InstanceType) ();
00717 
00718                 template <class ClassType> static void add();
00719                 static T *get(const string & instance_name);
00720                 static T *get(const string & instance_name, const Dict & params);
00721                 static vector < string > get_list();
00722 
00723         private:
00724                 Factory();
00725                 Factory(const Factory < T > &);
00726                 ~Factory();
00727                 static void init();
00728                 template <class ClassType> void force_add();
00729 
00730                 static Factory < T > *my_instance;
00731                 map < string, InstanceType > my_dict;
00732         };
00733 
00734         template < class T > Factory < T > *Factory < T >::my_instance = 0;
00735 
00736         template < class T > void Factory < T >::init()
00737         {
00738                 if (!my_instance) {
00739                         my_instance = new Factory < T > ();
00740                 }
00741         }
00742 
00743         template < class T > 
00744         template < class ClassType > 
00745         void Factory < T >::force_add()
00746         {
00747                 string name = ClassType::NAME;
00748                 my_dict[name] = &ClassType::NEW;
00749         }
00750 
00751 
00752         template < class T > 
00753         template < class ClassType >
00754         void Factory < T >::add()
00755         {
00756                 init();
00757 
00758                 string name = ClassType::NAME;
00759                 typename map < string, InstanceType >::iterator fi =
00760                         my_instance->my_dict.find(name);
00761 
00762                 if (fi == my_instance->my_dict.end()) {
00763                         my_instance->my_dict[name] = &ClassType::NEW;
00764                 }
00765         }
00766 
00767         template < class T > T * Factory < T >::get(const string & instancename)
00768         {
00769                 init();
00770                 typename map < string, InstanceType >::iterator fi =
00771                         my_instance->my_dict.find(instancename);
00772                 if (fi != my_instance->my_dict.end()) {
00773                         return my_instance->my_dict[instancename] ();
00774                 }
00775 
00776                 string lower = instancename;
00777                 for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00778 
00779                 fi = my_instance->my_dict.find(lower);
00780                 if (fi != my_instance->my_dict.end()) {
00781                         return my_instance->my_dict[lower] ();
00782                 }
00783 
00784                 throw NotExistingObjectException(instancename, "The named object doesn't exist");
00785         }
00786 
00787         template < class T > T * Factory < T >::get(const string & instancename,
00788                                                                                                 const Dict & params)
00789         {
00790                 init();
00791 
00792                 typename map < string, InstanceType >::iterator fi =
00793                         my_instance->my_dict.find(instancename);
00794 
00795                 string lower = instancename;
00796                 if (fi == my_instance->my_dict.end()) {
00797                         for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00798                         fi = my_instance->my_dict.find(lower);
00799                 }
00800 
00801                 if (fi != my_instance->my_dict.end()) {
00802                         T *i = my_instance->my_dict[lower] ();
00803 
00804                         const vector<string> para_keys = params.keys();
00805 //                      std::cout << "the number of keys is " << para_keys.size() << std::endl; // PRB May 19th
00806                         const vector<string> valid_keys = i->get_param_types().keys();
00807                         typename vector<string>::const_iterator it;
00808                         for(it=para_keys.begin(); it!=para_keys.end(); ++it) {
00809 //                              std::cout << "the iterator  is " << *it << std::endl; // PRB May 19th
00810                                 if( find(valid_keys.begin(), valid_keys.end(), *it) == valid_keys.end() ) {
00811                                         throw InvalidParameterException(*it);
00812                                 }
00813                         }
00814 
00815                         i->set_params(params);
00816                         return i;
00817                 }
00818 
00819 
00820                 throw NotExistingObjectException(instancename, "No such an instance existing");
00821         }
00822 
00823         template < class T > vector < string > Factory < T >::get_list() {
00824                 init();
00825                 vector < string > result;
00826                 typename map < string, InstanceType >::const_iterator p;
00827                 for (p = my_instance->my_dict.begin(); p != my_instance->my_dict.end(); p++) {
00828                         result.push_back(p->first);
00829                 }
00830 
00831                 return result;
00832         }
00833 
00834         template < class T > void dump_factory()
00835         {
00836                 vector < string > item_names = Factory < T >::get_list();
00837 
00838                 for (size_t i = 0; i < item_names.size(); i++) {
00839                         T *item = Factory < T >::get(item_names[i]);
00840                         printf("%s :  %s\n", item->get_name().c_str(),item->get_desc().c_str());
00841                         TypeDict td = item->get_param_types();
00842                         td.dump();
00843                 }
00844         }
00845 
00846         template < class T > map<string, vector<string> > dump_factory_list()
00847         {
00848                 vector < string > item_names = Factory < T >::get_list();
00849                 map<string, vector<string> >    factory_list;
00850 
00851                 typename vector<string>::const_iterator p;
00852                 for(p = item_names.begin(); p !=item_names.end(); ++p) {
00853                         T *item = Factory<T>::get(*p);
00854 
00855                         string name = item->get_name();
00856 
00857                         vector<string> content;
00858                         content.push_back(item->get_desc());
00859                         TypeDict td = item->get_param_types();
00860                         vector<string> keys = td.keys();
00861                         for(unsigned int i=0; i<td.size(); ++i) {
00862                                 content.push_back(keys[i]);
00863                                 content.push_back( td.get_type(keys[i]) );
00864                                 content.push_back( td.get_desc(keys[i]) );
00865                         }
00866                         factory_list[name] = content;
00867                 }
00868 
00869                 return factory_list;
00870         }
00871 
00878         class FactoryBase
00879         {
00880         public:
00881                 FactoryBase() {}
00882                 virtual ~FactoryBase() {};
00883 
00887                 virtual string get_name() const = 0;
00888 
00892                 virtual string get_desc() const = 0;
00893 
00897                 Dict get_params() const { return params; }
00898 
00902                 void set_params(const Dict & new_params)
00903                 {
00904                         params.clear();
00905                         insert_params(new_params);
00906                 }
00907                 
00908                 inline void set_param(const string key,const EMObject val) { params[key]=val; }
00909                 
00912                 virtual TypeDict get_param_types() const = 0;
00913 
00917                 void insert_params(const Dict & new_params)
00918                 {
00919                 // this is really inserting OR individually replacing...
00920                 // the old data will be kept if it is not written over
00921                         TypeDict permissable_params = get_param_types();
00922                         for ( Dict::const_iterator it = new_params.begin(); it != new_params.end(); ++it )
00923                         {
00924 
00925                                 if ( !permissable_params.find_type(it->first) )
00926                                 {
00927                                         throw InvalidParameterException(it->first);
00928                                 }
00929                                 params[it->first] = it->second;
00930                         }
00931                 }
00932 
00933                 Dict copy_relevant_params(const FactoryBase* const that) const
00934                 {
00935                         return params.copy_keys_in(that->get_param_types());
00936 
00937                 }
00938 
00939                 protected:
00941                 mutable Dict params;
00942         };
00943 }
00944 
00945 #endif

Generated on Tue Jun 11 12:40:22 2013 for EMAN2 by  doxygen 1.4.7