Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

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 <iostream>
00066 using std::cout;
00067 using std::endl;
00068 
00069 #include <cctype> // tolower
00070 #include <algorithm> //tolower
00071 namespace EMAN
00072 {
00073         class EMConsts {
00074         public:
00075                 static const float I2G; // 2 interpolation
00076                 static const float I3G; // used for 3 and 5x5x5 interpolation
00077                 static const float I4G; // used for 4 interpolation
00078                 static const float I5G; // used for 5x5x5 interpolation
00079 
00080                 static const double rad2deg; // radians to degree constant factor
00081                 static const double deg2rad; // degrees to radians constant factor
00082                 static const double pi; // degrees to radians constant factor
00083         };
00084 
00085         class EMData;
00086         class XYData;
00087         class Aligner;
00088         class Averager;
00089         class Cmp;
00090         class Processor;
00091         class Projector;
00092         class Reconstructor;
00093         class Analyzer;
00094         class Transform;
00095         class Ctf;
00096 
00097         enum MapInfoType {
00098                 NORMAL,
00099                 ICOS2F_FIRST_OCTANT,
00100                 ICOS2F_FULL,
00101                 ICOS2F_HALF,
00102                 ICOS3F_HALF,
00103                 ICOS3F_FULL,
00104                 ICOS5F_HALF,
00105                 ICOS5F_FULL,
00106                 ICOS_UNKNOWN
00107         };
00108 
00125         class EMObject
00126         {
00127         public:
00128                 enum ObjectType {
00129                         UNKNOWN,
00130                         BOOL,
00131                         UNSIGNEDINT,
00132                         INT,
00133                         FLOAT,
00134                         DOUBLE,
00135                         STRING,
00136                         EMDATA,
00137                         XYDATA,
00138                         INTARRAY,
00139                         FLOATARRAY,
00140                         STRINGARRAY,
00141                         TRANSFORM,
00142                         CTF,
00143                         FLOAT_POINTER,
00144                         INT_POINTER,
00145                         VOID_POINTER,
00146                         TRANSFORMARRAY
00147                 };
00148 
00149 
00154                 EMObject();
00155                 EMObject(bool boolean);
00156                 EMObject(int num);
00157                 EMObject(unsigned int num);
00158                 EMObject(float ff);
00159                 EMObject(double dd);
00160                 EMObject(const char *s);
00161                 EMObject(const string & s);
00162                 EMObject(float * fp);
00163                 EMObject(int * ip);
00164                 EMObject(void * vp);
00165                 EMObject(EMData * em);
00166                 EMObject(XYData * xy);
00167                 EMObject(Transform * t);
00168                 EMObject(Ctf * ctf);
00169                 EMObject(const vector< int >& v );
00170                 EMObject(const vector < float >&v);
00171                 EMObject(const vector <string>& sarray);
00172                 EMObject(const vector <Transform>& tarray);
00173 
00178                 EMObject(const EMObject& that);
00179 
00184                 EMObject& operator=(const EMObject& that);
00185 
00189                 ~EMObject();
00192                 operator bool () const;
00193                 operator int () const;
00194                 operator unsigned int () const;
00195                 operator float () const;
00196                 operator double () const;
00197                 operator const char *() const;
00198                 operator float * () const;
00199                 operator int * () const;
00200                 operator void * () const;
00201                 operator EMData *() const;
00202                 operator XYData *() const;
00203                 operator Transform *() const;
00204                 operator Ctf *() const;
00205                 operator vector < int > () const;
00206                 operator vector < float > () const;
00207                 operator vector<string> () const;
00208                 operator vector<Transform> () const;
00209 
00214                 bool is_null() const;
00215 
00218                 string to_str() const;
00219 
00224                 ObjectType get_type() const { return type; }
00225 
00230                 string get_type_string() const { return get_object_type_name(type); }
00231 
00232 
00238                 string to_str(ObjectType type) const;
00239 
00243                 static string get_object_type_name(ObjectType t);
00244 
00248                 friend bool operator==(const EMObject &e1, const EMObject & e2);
00249 
00253                 friend bool operator!=(const EMObject &e1, const EMObject & e2);
00254 
00255         private:
00256                 union
00257                 {
00258                         bool b;
00259                         int n;
00260                         unsigned int ui;
00261                         float f;
00262                         double d;
00263                         float * fp;
00264                         int * ip;
00265                         void * vp;
00266                         EMData *emdata;
00267                         XYData *xydata;
00268                 };
00269 
00270                 string str;
00271                 vector <int> iarray;
00272                 vector <float> farray;
00273                 vector <string> strarray;
00274                 vector <Transform> transformarray;
00275                 ObjectType type;
00276 
00279                 void printInfo() const;
00280 
00281 //              void init();
00282                 
00283                 static map< ObjectType, string> init();
00284                 static map< ObjectType, string> type_registry;
00285                 
00286         };
00287 
00288         bool operator==(const EMObject &e1, const EMObject & e2);
00289         bool operator!=(const EMObject &e1, const EMObject & e2);
00290 
00302         class TypeDict
00303         {
00304                 public:
00305                         TypeDict()
00306                         {
00307                         }
00308 
00309                         ~TypeDict()
00310                         {
00311                         }
00312 
00313                         vector < string > keys() const
00314                         {
00315                                 vector < string > result;
00316                                 map < string, string >::const_iterator p;
00317 
00318                                 for (p = type_dict.begin(); p != type_dict.end(); p++) {
00319                                         result.push_back(p->first);
00320                                 }
00321 
00322                                 return result;
00323                         }
00324 
00325                         size_t size() const
00326                         {
00327                                 return type_dict.size();
00328                         }
00329 
00330                         void put(const string& key, EMObject::ObjectType o, const string& desc = "")
00331                         {
00332                                 type_dict[key] = EMObject::get_object_type_name(o);
00333                                 desc_dict[key] = desc;
00334                         }
00335 
00336                         string get_type(const string& key)
00337                         {
00338                                 return type_dict[key];
00339                         }
00340 
00341                         string get_desc(const string& key)
00342                         {
00343                                 return desc_dict[key];
00344                         }
00345 
00346                         string operator[] (const string & key)
00347                         {
00348                                 return type_dict[key];
00349                         }
00350 
00351                         void dump();
00352 
00353                         inline bool find_type( const string& type ) {  if ( type_dict.find(type) != type_dict.end() ) return true; return false; }
00354 
00355                 private:
00356                         map < string, string > type_dict;
00357                         map < string, string > desc_dict;
00358         };
00359 
00360 
00384         class Dict
00385         {
00386         public:
00387                 Dict()
00388                 {
00389                 }
00390 
00395                 Dict(const string & key1, EMObject val1)
00396                 {
00397                         dict[key1] = val1;
00398                 }
00399 
00402                 Dict(const string & key1, EMObject val1,
00403                          const string & key2, EMObject val2)
00404                 {
00405                         dict[key1] = val1;
00406                         dict[key2] = val2;
00407                 }
00408 
00411                 Dict(const string & key1, EMObject val1,
00412                          const string & key2, EMObject val2,
00413                          const string & key3, EMObject val3)
00414                 {
00415                         dict[key1] = val1;
00416                         dict[key2] = val2;
00417                         dict[key3] = val3;
00418                 }
00419 
00422                 Dict(const string & key1, EMObject val1,
00423                          const string & key2, EMObject val2,
00424                          const string & key3, EMObject val3,
00425                          const string & key4, EMObject val4)
00426                 {
00427                         dict[key1] = val1;
00428                         dict[key2] = val2;
00429                         dict[key3] = val3;
00430                         dict[key4] = val4;
00431                 }
00432 
00436                 Dict(const map < string, EMObject > &d)
00437                 {
00438                         copy(d.begin(), d.end(), inserter(dict, dict.begin()));
00439                         // Or use
00440                         // dict.insert(d.begin(), d.end());
00441                 }
00442 
00446                 ~Dict() {}
00447 
00451                 Dict( const Dict& that);
00452 
00456                 Dict& operator=(const Dict& that);
00457 
00460                 vector < string > keys()const
00461                 {
00462                         vector < string > result;
00463 
00464                         map < string, EMObject >::const_iterator p;
00465                         for (p = dict.begin(); p != dict.end(); p++) {
00466                                 result.push_back(p->first);
00467                         }
00468 
00469                         return result;
00470                 }
00471 
00474                 vector < EMObject > values()const
00475                 {
00476                         vector < EMObject > result;
00477 
00478                         map < string, EMObject >::const_iterator p;
00479                         for (p = dict.begin(); p != dict.end(); p++) {
00480                                 result.push_back(p->second);
00481                         }
00482 
00483                         return result;
00484                 }
00485 
00489                 bool has_key_ci(const string & key) const;
00490 
00494                 bool has_key(const string & key) const
00495                 {
00496                         map < string, EMObject >::const_iterator p = dict.find(key);
00497                         if (p != dict.end()) {
00498                                 return true;
00499                         }
00500                         return false;
00501                 }
00502 
00505                 size_t size() const
00506                 {
00507                         return dict.size();
00508                 }
00509 
00513                 EMObject get(const string & key) const
00514                 {
00515                         if( has_key(key) ) {
00516                                 return dict[key];
00517                         }
00518                         else {
00519                                 LOGERR("No such key exist in this Dict");
00520                                 throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00521                         }
00522                 }
00523 
00527                 EMObject get_ci(const string & key) const;
00531                 void put(const string & key, EMObject val)
00532                 {
00533                         dict[key] = val;
00534                 }
00535 
00538                 void erase(const string & key)
00539                 {
00540                         dict.erase(key);
00541                 }
00542 
00546                 void clear()
00547                 {
00548                         dict.clear();
00549                 }
00550 
00554                 template<typename type>
00555                 type set_default(const string & key, type val)
00556                 {
00557                         if (!has_key(key)) {
00558                                 dict[key] = val;
00559                         }
00560                         return dict[key];
00561                 }
00562 
00563                 Dict copy_exclude_keys(const vector<string>& excluded_keys) const
00564                 {
00565                         Dict ret(*this);
00566 
00567                         for ( vector<string>::const_iterator it = excluded_keys.begin(); it != excluded_keys.end(); ++it ) {
00568                                 if (ret.has_key(*it)) ret.erase(*it);
00569                         }
00570 
00571                         return ret;
00572                 }
00573 
00574                 Dict copy_exclusive_keys(const vector<string>& exclusive_keys) const
00575                 {
00576                         Dict ret;
00577                         for ( vector<string>::const_iterator it = exclusive_keys.begin(); it != exclusive_keys.end(); ++it ) {
00578                                 if (has_key(*it)) ret[*it] = (*this)[*it];
00579                         }
00580 
00581                         return ret;
00582                 }
00583 
00584                 Dict copy_keys_in( const TypeDict& tdict ) const {
00585                         vector<string> keys = tdict.keys();
00586                         return copy_exclusive_keys(keys);
00587                 }
00588 
00589                 EMObject & operator[] (const string & key)
00590                 {
00591 //                      static EMObject nullreturn;
00592 //                      if( has_key(key) )  return dict[key];
00593 //                      else return nullreturn;
00594 
00595 //                      if( has_key(key) ) {
00596                                 return dict[key];
00597 //                      }
00598 //                      else {
00599 //                              LOGERR("No such key exist in this Dict");
00600 //                              throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00601 //                      }
00602                 }
00603 
00604                 EMObject operator[] (const string & key) const
00605                 {
00606 //                      if( has_key(key) )  return dict[key];
00607 //                      else return EMObject();
00608                         return dict[key];
00609 
00610 //                      else {
00611 //                              LOGERR("No such key exist in this Dict");
00612 //                              throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00613 //                      }
00614                 }
00615 
00619                 friend bool operator==(const Dict& d1, const Dict& d2);
00620 
00624                 friend bool operator!=(const Dict& d1, const Dict& d2);
00625 
00626         private:
00627                 mutable map < string, EMObject > dict;
00628 
00629         public:
00637                 class iterator : public map < string, EMObject >::iterator
00638                 {
00639                 public:
00640                         typedef std::bidirectional_iterator_tag iterator_category;
00641                         typedef pair<string, EMObject> value_type;
00642 
00643                 public:
00644                         iterator( map < string, EMObject >::iterator parent_it );
00645                         virtual ~iterator(){}
00646 
00647                         iterator( const iterator& that );
00648                         iterator& operator=( const iterator& that );
00649                 };
00650 
00658                 class const_iterator :  public map < string, EMObject >::const_iterator
00659                 {
00660                 public:
00661                         typedef std::bidirectional_iterator_tag iterator_category;
00662                         typedef pair<string, EMObject> value_type; // Note that value_type should NOT be const even though the container elements are const
00663                 public:
00664                         const_iterator( const map < string, EMObject >::const_iterator parent_it);
00665                         virtual ~const_iterator(){}
00666                         const_iterator( const Dict::iterator& it );
00667 
00668                         const_iterator( const const_iterator& that );
00669                         const_iterator& operator=( const const_iterator& that );
00670                 };
00671 
00672                 // Iterator support
00673                 iterator begin( void );
00674                 const_iterator begin( void ) const;
00675 
00676                 iterator end( void );
00677                 const_iterator end( void ) const;
00678 
00679                 // Wraps map.find(const string& key)
00680                 iterator find( const string& key );
00681                 const_iterator find( const string& key ) const;
00682         };
00683 
00684         // These operators were originally added for the purposes of making testing code but might come in handy for other things
00685         // operator== simply wraps map<string, EMObject>::operator==
00686         bool operator==(const Dict &d1, const Dict& d2);
00687         bool operator!=(const Dict &d1, const Dict& d2);
00688 
00689 
00708         template < class T > class Factory
00709         {
00710         public:
00711                 typedef T *(*InstanceType) ();
00712 
00713                 template <class ClassType> static void add();
00714                 static T *get(const string & instance_name);
00715                 static T *get(const string & instance_name, const Dict & params);
00716                 static vector < string > get_list();
00717 
00718         private:
00719                 Factory();
00720                 Factory(const Factory < T > &);
00721                 ~Factory();
00722                 static void init();
00723                 template <class ClassType> void force_add();
00724 
00725                 static Factory < T > *my_instance;
00726                 map < string, InstanceType > my_dict;
00727         };
00728 
00729         template < class T > Factory < T > *Factory < T >::my_instance = 0;
00730 
00731         template < class T > void Factory < T >::init()
00732         {
00733                 if (!my_instance) {
00734                         my_instance = new Factory < T > ();
00735                 }
00736         }
00737 
00738         template < class T > 
00739         template < class ClassType > 
00740         void Factory < T >::force_add()
00741         {
00742                 string name = ClassType::NAME;
00743                 my_dict[name] = &ClassType::NEW;
00744         }
00745 
00746 
00747         template < class T > 
00748         template < class ClassType >
00749         void Factory < T >::add()
00750         {
00751                 init();
00752 
00753                 string name = ClassType::NAME;
00754                 typename map < string, InstanceType >::iterator fi =
00755                         my_instance->my_dict.find(name);
00756 
00757                 if (fi == my_instance->my_dict.end()) {
00758                         my_instance->my_dict[name] = &ClassType::NEW;
00759                 }
00760         }
00761 
00762         template < class T > T * Factory < T >::get(const string & instancename)
00763         {
00764                 init();
00765                 typename map < string, InstanceType >::iterator fi =
00766                         my_instance->my_dict.find(instancename);
00767                 if (fi != my_instance->my_dict.end()) {
00768                         return my_instance->my_dict[instancename] ();
00769                 }
00770 
00771                 string lower = instancename;
00772                 for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00773 
00774                 fi = my_instance->my_dict.find(lower);
00775                 if (fi != my_instance->my_dict.end()) {
00776                         return my_instance->my_dict[lower] ();
00777                 }
00778 
00779                 throw NotExistingObjectException(instancename, "The named object doesn't exist");
00780         }
00781 
00782         template < class T > T * Factory < T >::get(const string & instancename,
00783                                                                                                 const Dict & params)
00784         {
00785                 init();
00786 
00787                 typename map < string, InstanceType >::iterator fi =
00788                         my_instance->my_dict.find(instancename);
00789 
00790                 string lower = instancename;
00791                 if (fi == my_instance->my_dict.end()) {
00792                         for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00793                         fi = my_instance->my_dict.find(lower);
00794                 }
00795 
00796                 if (fi != my_instance->my_dict.end()) {
00797                         T *i = my_instance->my_dict[lower] ();
00798 
00799                         const vector<string> para_keys = params.keys();
00800 //                      std::cout << "the number of keys is " << para_keys.size() << std::endl; // PRB May 19th
00801                         const vector<string> valid_keys = i->get_param_types().keys();
00802                         typename vector<string>::const_iterator it;
00803                         for(it=para_keys.begin(); it!=para_keys.end(); ++it) {
00804 //                              std::cout << "the iterator  is " << *it << std::endl; // PRB May 19th
00805                                 if( find(valid_keys.begin(), valid_keys.end(), *it) == valid_keys.end() ) {
00806                                         throw InvalidParameterException(*it);
00807                                 }
00808                         }
00809 
00810                         i->set_params(params);
00811                         return i;
00812                 }
00813 
00814 
00815                 throw NotExistingObjectException(instancename, "No such an instance existing");
00816         }
00817 
00818         template < class T > vector < string > Factory < T >::get_list() {
00819                 init();
00820                 vector < string > result;
00821                 typename map < string, InstanceType >::const_iterator p;
00822                 for (p = my_instance->my_dict.begin(); p != my_instance->my_dict.end(); p++) {
00823                         result.push_back(p->first);
00824                 }
00825 
00826                 return result;
00827         }
00828 
00829         template < class T > void dump_factory()
00830         {
00831                 vector < string > item_names = Factory < T >::get_list();
00832 
00833                 for (size_t i = 0; i < item_names.size(); i++) {
00834                         T *item = Factory < T >::get(item_names[i]);
00835                         printf("%s :  %s\n", item->get_name().c_str(),item->get_desc().c_str());
00836                         TypeDict td = item->get_param_types();
00837                         td.dump();
00838                 }
00839         }
00840 
00841         template < class T > map<string, vector<string> > dump_factory_list()
00842         {
00843                 vector < string > item_names = Factory < T >::get_list();
00844                 map<string, vector<string> >    factory_list;
00845 
00846                 typename vector<string>::const_iterator p;
00847                 for(p = item_names.begin(); p !=item_names.end(); ++p) {
00848                         T *item = Factory<T>::get(*p);
00849 
00850                         string name = item->get_name();
00851 
00852                         vector<string> content;
00853                         content.push_back(item->get_desc());
00854                         TypeDict td = item->get_param_types();
00855                         vector<string> keys = td.keys();
00856                         for(unsigned int i=0; i<td.size(); ++i) {
00857                                 content.push_back(keys[i]);
00858                                 content.push_back( td.get_type(keys[i]) );
00859                                 content.push_back( td.get_desc(keys[i]) );
00860                         }
00861                         factory_list[name] = content;
00862                 }
00863 
00864                 return factory_list;
00865         }
00866 
00873         class FactoryBase
00874         {
00875         public:
00876                 FactoryBase() {}
00877                 virtual ~FactoryBase() {};
00878 
00882                 virtual string get_name() const = 0;
00883 
00887                 virtual string get_desc() const = 0;
00888 
00892                 Dict get_params() const { return params; }
00893 
00897                 void set_params(const Dict & new_params)
00898                 {
00899                         params.clear();
00900                         insert_params(new_params);
00901                 }
00902                 
00903                 inline void set_param(const string key,const EMObject val) { params[key]=val; }
00904                 
00907                 virtual TypeDict get_param_types() const = 0;
00908 
00912                 void insert_params(const Dict & new_params)
00913                 {
00914                 // this is really inserting OR individually replacing...
00915                 // the old data will be kept if it is not written over
00916                         TypeDict permissable_params = get_param_types();
00917                         for ( Dict::const_iterator it = new_params.begin(); it != new_params.end(); ++it )
00918                         {
00919 
00920                                 if ( !permissable_params.find_type(it->first) )
00921                                 {
00922                                         throw InvalidParameterException(it->first);
00923                                 }
00924                                 params[it->first] = it->second;
00925                         }
00926                 }
00927 
00928                 Dict copy_relevant_params(const FactoryBase* const that) const
00929                 {
00930                         return params.copy_keys_in(that->get_param_types());
00931 
00932                 }
00933 
00934                 protected:
00936                 mutable Dict params;
00937         };
00938 }
00939 
00940 #endif

Generated on Tue Jul 12 13:48:58 2011 for EMAN2 by  doxygen 1.3.9.1