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 <vector>
00043 using std::vector;
00044 
00045 #include <string>
00046 using std::string;
00047 
00048 #include <utility>
00049 using std::pair;
00050 
00051 #include <algorithm>
00052 // using copy
00053 
00054 #include <iterator>
00055 
00056 #include "log.h"
00057 #include "exception.h"
00058 
00059 // #include "transform.h" // Trnasform3D::EulerType
00060 
00061 // debug
00062 #include <iostream>
00063 using std::cout;
00064 using std::endl;
00065 
00066 #include <cctype> // tolower
00067 #include <algorithm> //tolower
00068 namespace EMAN
00069 {
00070         class EMConsts {
00071         public:
00072                 static const float I2G; // 2 interpolation
00073                 static const float I3G; // used for 3 and 5x5x5 interpolation
00074                 static const float I4G; // used for 4 interpolation
00075                 static const float I5G; // used for 5x5x5 interpolation
00076 
00077                 static const double rad2deg; // radians to degree constant factor
00078                 static const double deg2rad; // degrees to radians constant factor
00079                 static const double pi; // degrees to radians constant factor
00080         };
00081 
00082         class EMData;
00083         class XYData;
00084         class Aligner;
00085         class Averager;
00086         class Cmp;
00087         class Processor;
00088         class Projector;
00089         class Reconstructor;
00090         class Analyzer;
00091         class Transform;
00092         class Ctf;
00093 
00094         enum MapInfoType {
00095                 NORMAL,
00096                 ICOS2F_FIRST_OCTANT,
00097                 ICOS2F_FULL,
00098                 ICOS2F_HALF,
00099                 ICOS3F_HALF,
00100                 ICOS3F_FULL,
00101                 ICOS5F_HALF,
00102                 ICOS5F_FULL,
00103                 ICOS_UNKNOWN
00104         };
00105 
00122         class EMObject
00123         {
00124         public:
00125                 enum ObjectType {
00126                         UNKNOWN,
00127                         BOOL,
00128                         UNSIGNEDINT,
00129                         INT,
00130                         FLOAT,
00131                         DOUBLE,
00132                         STRING,
00133                         EMDATA,
00134                         XYDATA,
00135                         INTARRAY,
00136                         FLOATARRAY,
00137                         STRINGARRAY,
00138                         TRANSFORM,
00139                         CTF,
00140                         FLOAT_POINTER,
00141                         INT_POINTER,
00142                         VOID_POINTER
00143                 };
00144 
00145 
00150                 EMObject();
00151                 EMObject(bool boolean);
00152                 EMObject(int num);
00153                 EMObject(unsigned int num);
00154                 EMObject(float ff);
00155                 EMObject(double dd);
00156                 EMObject(const char *s);
00157                 EMObject(const string & s);
00158                 EMObject(float * fp);
00159                 EMObject(int * ip);
00160                 EMObject(void * vp);
00161                 EMObject(EMData * em);
00162                 EMObject(XYData * xy);
00163                 EMObject(Transform * t);
00164                 EMObject(Ctf * ctf);
00165                 EMObject(const vector< int >& v );
00166                 EMObject(const vector < float >&v);
00167                 EMObject(const vector <string>& sarray);
00168 
00173                 EMObject(const EMObject& that);
00174 
00179                 EMObject& operator=(const EMObject& that);
00180 
00184                 ~EMObject();
00187                 operator bool () const;
00188                 operator int () const;
00189                 operator unsigned int () const;
00190                 operator float () const;
00191                 operator double () const;
00192                 operator const char *() const;
00193                 operator float * () const;
00194                 operator int * () const;
00195                 operator void * () const;
00196                 operator EMData *() const;
00197                 operator XYData *() const;
00198                 operator Transform *() const;
00199                 operator Ctf *() const;
00200                 operator vector < int > () const;
00201                 operator vector < float > () const;
00202                 operator vector<string> () const;
00203 
00208                 bool is_null() const;
00209 
00212                 string to_str() const;
00213 
00218                 ObjectType get_type() const { return type; }
00219 
00224                 string get_type_string() const { return get_object_type_name(type); }
00225 
00226 
00232                 string to_str(ObjectType type) const;
00233 
00237                 static string get_object_type_name(ObjectType t);
00238 
00242                 friend bool operator==(const EMObject &e1, const EMObject & e2);
00243 
00247                 friend bool operator!=(const EMObject &e1, const EMObject & e2);
00248 
00249         private:
00250                 union
00251                 {
00252                         bool b;
00253                         int n;
00254                         unsigned int ui;
00255                         float f;
00256                         double d;
00257                         float * fp;
00258                         int * ip;
00259                         void * vp;
00260                         EMData *emdata;
00261                         XYData *xydata;
00262                 };
00263 
00264                 string str;
00265                 vector < int > iarray;
00266                 vector < float >farray;
00267                 vector < string> strarray;
00268                 ObjectType type;
00269 
00272                 void printInfo() const;
00273 
00274 //              void init();
00275                 
00276                 static map< ObjectType, string> init();
00277                 static map< ObjectType, string> type_registry;
00278 
00279         };
00280 
00281         bool operator==(const EMObject &e1, const EMObject & e2);
00282         bool operator!=(const EMObject &e1, const EMObject & e2);
00283 
00295         class TypeDict
00296         {
00297                 public:
00298                         TypeDict()
00299                         {
00300                         }
00301 
00302                         ~TypeDict()
00303                         {
00304                         }
00305 
00306                         vector < string > keys() const
00307                         {
00308                                 vector < string > result;
00309                                 map < string, string >::const_iterator p;
00310 
00311                                 for (p = type_dict.begin(); p != type_dict.end(); p++) {
00312                                         result.push_back(p->first);
00313                                 }
00314 
00315                                 return result;
00316                         }
00317 
00318                         size_t size() const
00319                         {
00320                                 return type_dict.size();
00321                         }
00322 
00323                         void put(const string& key, EMObject::ObjectType o, const string& desc = "")
00324                         {
00325                                 type_dict[key] = EMObject::get_object_type_name(o);
00326                                 desc_dict[key] = desc;
00327                         }
00328 
00329                         string get_type(const string& key)
00330                         {
00331                                 return type_dict[key];
00332                         }
00333 
00334                         string get_desc(const string& key)
00335                         {
00336                                 return desc_dict[key];
00337                         }
00338 
00339                         string operator[] (const string & key)
00340                         {
00341                                 return type_dict[key];
00342                         }
00343 
00344                         void dump();
00345 
00346                         inline bool find_type( const string& type ) {  if ( type_dict.find(type) != type_dict.end() ) return true; return false; }
00347 
00348                 private:
00349                         map < string, string > type_dict;
00350                         map < string, string > desc_dict;
00351         };
00352 
00353 
00377         class Dict
00378         {
00379         public:
00380                 Dict()
00381                 {
00382                 }
00383 
00388                 Dict(const string & key1, EMObject val1)
00389                 {
00390                         dict[key1] = val1;
00391                 }
00392 
00395                 Dict(const string & key1, EMObject val1,
00396                          const string & key2, EMObject val2)
00397                 {
00398                         dict[key1] = val1;
00399                         dict[key2] = val2;
00400                 }
00401 
00404                 Dict(const string & key1, EMObject val1,
00405                          const string & key2, EMObject val2,
00406                          const string & key3, EMObject val3)
00407                 {
00408                         dict[key1] = val1;
00409                         dict[key2] = val2;
00410                         dict[key3] = val3;
00411                 }
00412 
00415                 Dict(const string & key1, EMObject val1,
00416                          const string & key2, EMObject val2,
00417                          const string & key3, EMObject val3,
00418                          const string & key4, EMObject val4)
00419                 {
00420                         dict[key1] = val1;
00421                         dict[key2] = val2;
00422                         dict[key3] = val3;
00423                         dict[key4] = val4;
00424                 }
00425 
00429                 Dict(const map < string, EMObject > &d)
00430                 {
00431                         copy(d.begin(), d.end(), inserter(dict, dict.begin()));
00432                         // Or use
00433                         // dict.insert(d.begin(), d.end());
00434                 }
00435 
00439                 ~Dict() {}
00440 
00444                 Dict( const Dict& that);
00445 
00449                 Dict& operator=(const Dict& that);
00450 
00453                 vector < string > keys()const
00454                 {
00455                         vector < string > result;
00456 
00457                         map < string, EMObject >::const_iterator p;
00458                         for (p = dict.begin(); p != dict.end(); p++) {
00459                                 result.push_back(p->first);
00460                         }
00461 
00462                         return result;
00463                 }
00464 
00467                 vector < EMObject > values()const
00468                 {
00469                         vector < EMObject > result;
00470 
00471                         map < string, EMObject >::const_iterator p;
00472                         for (p = dict.begin(); p != dict.end(); p++) {
00473                                 result.push_back(p->second);
00474                         }
00475 
00476                         return result;
00477                 }
00478 
00482                 bool has_key_ci(const string & key) const;
00483 
00487                 bool has_key(const string & key) const
00488                 {
00489                         map < string, EMObject >::const_iterator p = dict.find(key);
00490                         if (p != dict.end()) {
00491                                 return true;
00492                         }
00493                         return false;
00494                 }
00495 
00498                 size_t size() const
00499                 {
00500                         return dict.size();
00501                 }
00502 
00506                 EMObject get(const string & key) const
00507                 {
00508                         if( has_key(key) ) {
00509                                 return dict[key];
00510                         }
00511                         else {
00512                                 LOGERR("No such key exist in this Dict");
00513                                 throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00514                         }
00515                 }
00516 
00520                 EMObject get_ci(const string & key) const;
00524                 void put(const string & key, EMObject val)
00525                 {
00526                         dict[key] = val;
00527                 }
00528 
00531                 void erase(const string & key)
00532                 {
00533                         dict.erase(key);
00534                 }
00535 
00539                 void clear()
00540                 {
00541                         dict.clear();
00542                 }
00543 
00547                 template<typename type>
00548                 type set_default(const string & key, type val)
00549                 {
00550                         if (!has_key(key)) {
00551                                 dict[key] = val;
00552                         }
00553                         return dict[key];
00554                 }
00555 
00556                 Dict copy_exclude_keys(const vector<string>& excluded_keys) const
00557                 {
00558                         Dict ret(*this);
00559 
00560                         for ( vector<string>::const_iterator it = excluded_keys.begin(); it != excluded_keys.end(); ++it ) {
00561                                 if (ret.has_key(*it)) ret.erase(*it);
00562                         }
00563 
00564                         return ret;
00565                 }
00566 
00567                 Dict copy_exclusive_keys(const vector<string>& exclusive_keys) const
00568                 {
00569                         Dict ret;
00570                         for ( vector<string>::const_iterator it = exclusive_keys.begin(); it != exclusive_keys.end(); ++it ) {
00571                                 if (has_key(*it)) ret[*it] = (*this)[*it];
00572                         }
00573 
00574                         return ret;
00575                 }
00576 
00577                 Dict copy_keys_in( const TypeDict& tdict ) const {
00578                         vector<string> keys = tdict.keys();
00579                         return copy_exclusive_keys(keys);
00580                 }
00581 
00582                 EMObject & operator[] (const string & key)
00583                 {
00584 //                      static EMObject nullreturn;
00585 //                      if( has_key(key) )  return dict[key];
00586 //                      else return nullreturn;
00587 
00588 //                      if( has_key(key) ) {
00589                                 return dict[key];
00590 //                      }
00591 //                      else {
00592 //                              LOGERR("No such key exist in this Dict");
00593 //                              throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00594 //                      }
00595                 }
00596 
00597                 EMObject operator[] (const string & key) const
00598                 {
00599 //                      if( has_key(key) )  return dict[key];
00600 //                      else return EMObject();
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 
00612                 friend bool operator==(const Dict& d1, const Dict& d2);
00613 
00617                 friend bool operator!=(const Dict& d1, const Dict& d2);
00618 
00619         private:
00620                 mutable map < string, EMObject > dict;
00621 
00622         public:
00630                 class iterator : public map < string, EMObject >::iterator
00631                 {
00632                 public:
00633                         typedef std::bidirectional_iterator_tag iterator_category;
00634                         typedef pair<string, EMObject> value_type;
00635 
00636                 public:
00637                         iterator( map < string, EMObject >::iterator parent_it );
00638                         virtual ~iterator(){}
00639 
00640                         iterator( const iterator& that );
00641                         iterator& operator=( const iterator& that );
00642                 };
00643 
00651                 class const_iterator :  public map < string, EMObject >::const_iterator
00652                 {
00653                 public:
00654                         typedef std::bidirectional_iterator_tag iterator_category;
00655                         typedef pair<string, EMObject> value_type; // Note that value_type should NOT be const even though the container elements are const
00656                 public:
00657                         const_iterator( const map < string, EMObject >::const_iterator parent_it);
00658                         virtual ~const_iterator(){}
00659                         const_iterator( const Dict::iterator& it );
00660 
00661                         const_iterator( const const_iterator& that );
00662                         const_iterator& operator=( const const_iterator& that );
00663                 };
00664 
00665                 // Iterator support
00666                 iterator begin( void );
00667                 const_iterator begin( void ) const;
00668 
00669                 iterator end( void );
00670                 const_iterator end( void ) const;
00671 
00672                 // Wraps map.find(const string& key)
00673                 iterator find( const string& key );
00674                 const_iterator find( const string& key ) const;
00675         };
00676 
00677         // These operators were originally added for the purposes of making testing code but might come in handy for other things
00678         // operator== simply wraps map<string, EMObject>::operator==
00679         bool operator==(const Dict &d1, const Dict& d2);
00680         bool operator!=(const Dict &d1, const Dict& d2);
00681 
00682 
00701         template < class T > class Factory
00702         {
00703         public:
00704                 typedef T *(*InstanceType) ();
00705 
00706                 template <class ClassType> static void add();
00707                 static T *get(const string & instance_name);
00708                 static T *get(const string & instance_name, const Dict & params);
00709                 static vector < string > get_list();
00710 
00711         private:
00712                 Factory();
00713                 Factory(const Factory < T > &);
00714                 ~Factory();
00715                 static void init();
00716                 template <class ClassType> void force_add();
00717 
00718                 static Factory < T > *my_instance;
00719                 map < string, InstanceType > my_dict;
00720         };
00721 
00722         template < class T > Factory < T > *Factory < T >::my_instance = 0;
00723 
00724         template < class T > void Factory < T >::init()
00725         {
00726                 if (!my_instance) {
00727                         my_instance = new Factory < T > ();
00728                 }
00729         }
00730 
00731         template < class T > 
00732         template < class ClassType > 
00733         void Factory < T >::force_add()
00734         {
00735                 string name = ClassType::NAME;
00736                 my_dict[name] = &ClassType::NEW;
00737         }
00738 
00739 
00740         template < class T > 
00741         template < class ClassType >
00742         void Factory < T >::add()
00743         {
00744                 init();
00745 
00746                 string name = ClassType::NAME;
00747                 typename map < string, InstanceType >::iterator fi =
00748                         my_instance->my_dict.find(name);
00749 
00750                 if (fi == my_instance->my_dict.end()) {
00751                         my_instance->my_dict[name] = &ClassType::NEW;
00752                 }
00753         }
00754 
00755         template < class T > T * Factory < T >::get(const string & instancename)
00756         {
00757                 init();
00758                 typename map < string, InstanceType >::iterator fi =
00759                         my_instance->my_dict.find(instancename);
00760                 if (fi != my_instance->my_dict.end()) {
00761                         return my_instance->my_dict[instancename] ();
00762                 }
00763 
00764                 string lower = instancename;
00765                 for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00766 
00767                 fi = my_instance->my_dict.find(lower);
00768                 if (fi != my_instance->my_dict.end()) {
00769                         return my_instance->my_dict[lower] ();
00770                 }
00771 
00772                 throw NotExistingObjectException(instancename, "The named object doesn't exist");
00773         }
00774 
00775         template < class T > T * Factory < T >::get(const string & instancename,
00776                                                                                                 const Dict & params)
00777         {
00778                 init();
00779 
00780                 typename map < string, InstanceType >::iterator fi =
00781                         my_instance->my_dict.find(instancename);
00782 
00783                 string lower = instancename;
00784                 if (fi == my_instance->my_dict.end()) {
00785                         for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00786                         fi = my_instance->my_dict.find(lower);
00787                 }
00788 
00789                 if (fi != my_instance->my_dict.end()) {
00790                         T *i = my_instance->my_dict[lower] ();
00791 
00792                         const vector<string> para_keys = params.keys();
00793 //                      std::cout << "the number of keys is " << para_keys.size() << std::endl; // PRB May 19th
00794                         const vector<string> valid_keys = i->get_param_types().keys();
00795                         typename vector<string>::const_iterator it;
00796                         for(it=para_keys.begin(); it!=para_keys.end(); ++it) {
00797 //                              std::cout << "the iterator  is " << *it << std::endl; // PRB May 19th
00798                                 if( find(valid_keys.begin(), valid_keys.end(), *it) == valid_keys.end() ) {
00799                                         throw InvalidParameterException(*it);
00800                                 }
00801                         }
00802 
00803                         i->set_params(params);
00804                         return i;
00805                 }
00806 
00807 
00808                 throw NotExistingObjectException(instancename, "No such an instance existing");
00809         }
00810 
00811         template < class T > vector < string > Factory < T >::get_list() {
00812                 init();
00813                 vector < string > result;
00814                 typename map < string, InstanceType >::const_iterator p;
00815                 for (p = my_instance->my_dict.begin(); p != my_instance->my_dict.end(); p++) {
00816                         result.push_back(p->first);
00817                 }
00818 
00819                 return result;
00820         }
00821 
00822         template < class T > void dump_factory()
00823         {
00824                 vector < string > item_names = Factory < T >::get_list();
00825 
00826                 for (size_t i = 0; i < item_names.size(); i++) {
00827                         T *item = Factory < T >::get(item_names[i]);
00828                         printf("%s :  %s\n", item->get_name().c_str(),item->get_desc().c_str());
00829                         TypeDict td = item->get_param_types();
00830                         td.dump();
00831                 }
00832         }
00833 
00834         template < class T > map<string, vector<string> > dump_factory_list()
00835         {
00836                 vector < string > item_names = Factory < T >::get_list();
00837                 map<string, vector<string> >    factory_list;
00838 
00839                 typename vector<string>::const_iterator p;
00840                 for(p = item_names.begin(); p !=item_names.end(); ++p) {
00841                         T *item = Factory<T>::get(*p);
00842 
00843                         string name = item->get_name();
00844 
00845                         vector<string> content;
00846                         content.push_back(item->get_desc());
00847                         TypeDict td = item->get_param_types();
00848                         vector<string> keys = td.keys();
00849                         for(unsigned int i=0; i<td.size(); ++i) {
00850                                 content.push_back(keys[i]);
00851                                 content.push_back( td.get_type(keys[i]) );
00852                                 content.push_back( td.get_desc(keys[i]) );
00853                         }
00854                         factory_list[name] = content;
00855                 }
00856 
00857                 return factory_list;
00858         }
00859 
00866         class FactoryBase
00867         {
00868         public:
00869                 FactoryBase() {}
00870                 virtual ~FactoryBase() {};
00871 
00875                 virtual string get_name() const = 0;
00876 
00880                 virtual string get_desc() const = 0;
00881 
00885                 Dict get_params() const { return params; }
00886 
00890                 void set_params(const Dict & new_params)
00891                 {
00892                         params.clear();
00893                         insert_params(new_params);
00894                 }
00895                 
00896                 inline void set_param(const string key,const EMObject val) { params[key]=val; }
00897                 
00900                 virtual TypeDict get_param_types() const = 0;
00901 
00905                 void insert_params(const Dict & new_params)
00906                 {
00907                 // this is really inserting OR individually replacing...
00908                 // the old data will be kept if it is not written over
00909                         TypeDict permissable_params = get_param_types();
00910                         for ( Dict::const_iterator it = new_params.begin(); it != new_params.end(); ++it )
00911                         {
00912 
00913                                 if ( !permissable_params.find_type(it->first) )
00914                                 {
00915                                         throw InvalidParameterException(it->first);
00916                                 }
00917                                 params[it->first] = it->second;
00918                         }
00919                 }
00920 
00921                 Dict copy_relevant_params(const FactoryBase* const that) const
00922                 {
00923                         return params.copy_keys_in(that->get_param_types());
00924 
00925                 }
00926 
00927                 protected:
00929                 mutable Dict params;
00930         };
00931 }
00932 
00933 #endif

Generated on Tue May 25 17:13:32 2010 for EMAN2 by  doxygen 1.4.7