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                 };
00147 
00148 
00153                 EMObject();
00154                 EMObject(bool boolean);
00155                 EMObject(int num);
00156                 EMObject(unsigned int num);
00157                 EMObject(float ff);
00158                 EMObject(double dd);
00159                 EMObject(const char *s);
00160                 EMObject(const string & s);
00161                 EMObject(float * fp);
00162                 EMObject(int * ip);
00163                 EMObject(void * vp);
00164                 EMObject(EMData * em);
00165                 EMObject(XYData * xy);
00166                 EMObject(Transform * t);
00167                 EMObject(Ctf * ctf);
00168                 EMObject(const vector< int >& v );
00169                 EMObject(const vector < float >&v);
00170                 EMObject(const vector <string>& sarray);
00171 
00176                 EMObject(const EMObject& that);
00177 
00182                 EMObject& operator=(const EMObject& that);
00183 
00187                 ~EMObject();
00190                 operator bool () const;
00191                 operator int () const;
00192                 operator unsigned int () const;
00193                 operator float () const;
00194                 operator double () const;
00195                 operator const char *() const;
00196                 operator float * () const;
00197                 operator int * () const;
00198                 operator void * () const;
00199                 operator EMData *() const;
00200                 operator XYData *() const;
00201                 operator Transform *() const;
00202                 operator Ctf *() const;
00203                 operator vector < int > () const;
00204                 operator vector < float > () const;
00205                 operator vector<string> () const;
00206 
00211                 bool is_null() const;
00212 
00215                 string to_str() const;
00216 
00221                 ObjectType get_type() const { return type; }
00222 
00227                 string get_type_string() const { return get_object_type_name(type); }
00228 
00229 
00235                 string to_str(ObjectType type) const;
00236 
00240                 static string get_object_type_name(ObjectType t);
00241 
00245                 friend bool operator==(const EMObject &e1, const EMObject & e2);
00246 
00250                 friend bool operator!=(const EMObject &e1, const EMObject & e2);
00251 
00252         private:
00253                 union
00254                 {
00255                         bool b;
00256                         int n;
00257                         unsigned int ui;
00258                         float f;
00259                         double d;
00260                         float * fp;
00261                         int * ip;
00262                         void * vp;
00263                         EMData *emdata;
00264                         XYData *xydata;
00265                 };
00266 
00267                 string str;
00268                 vector < int > iarray;
00269                 vector < float >farray;
00270                 vector < string> strarray;
00271                 ObjectType type;
00272 
00275                 void printInfo() const;
00276 
00277 //              void init();
00278                 
00279                 static map< ObjectType, string> init();
00280                 static map< ObjectType, string> type_registry;
00281                 
00282         };
00283 
00284         bool operator==(const EMObject &e1, const EMObject & e2);
00285         bool operator!=(const EMObject &e1, const EMObject & e2);
00286 
00298         class TypeDict
00299         {
00300                 public:
00301                         TypeDict()
00302                         {
00303                         }
00304 
00305                         ~TypeDict()
00306                         {
00307                         }
00308 
00309                         vector < string > keys() const
00310                         {
00311                                 vector < string > result;
00312                                 map < string, string >::const_iterator p;
00313 
00314                                 for (p = type_dict.begin(); p != type_dict.end(); p++) {
00315                                         result.push_back(p->first);
00316                                 }
00317 
00318                                 return result;
00319                         }
00320 
00321                         size_t size() const
00322                         {
00323                                 return type_dict.size();
00324                         }
00325 
00326                         void put(const string& key, EMObject::ObjectType o, const string& desc = "")
00327                         {
00328                                 type_dict[key] = EMObject::get_object_type_name(o);
00329                                 desc_dict[key] = desc;
00330                         }
00331 
00332                         string get_type(const string& key)
00333                         {
00334                                 return type_dict[key];
00335                         }
00336 
00337                         string get_desc(const string& key)
00338                         {
00339                                 return desc_dict[key];
00340                         }
00341 
00342                         string operator[] (const string & key)
00343                         {
00344                                 return type_dict[key];
00345                         }
00346 
00347                         void dump();
00348 
00349                         inline bool find_type( const string& type ) {  if ( type_dict.find(type) != type_dict.end() ) return true; return false; }
00350 
00351                 private:
00352                         map < string, string > type_dict;
00353                         map < string, string > desc_dict;
00354         };
00355 
00356 
00380         class Dict
00381         {
00382         public:
00383                 Dict()
00384                 {
00385                 }
00386 
00391                 Dict(const string & key1, EMObject val1)
00392                 {
00393                         dict[key1] = val1;
00394                 }
00395 
00398                 Dict(const string & key1, EMObject val1,
00399                          const string & key2, EMObject val2)
00400                 {
00401                         dict[key1] = val1;
00402                         dict[key2] = val2;
00403                 }
00404 
00407                 Dict(const string & key1, EMObject val1,
00408                          const string & key2, EMObject val2,
00409                          const string & key3, EMObject val3)
00410                 {
00411                         dict[key1] = val1;
00412                         dict[key2] = val2;
00413                         dict[key3] = val3;
00414                 }
00415 
00418                 Dict(const string & key1, EMObject val1,
00419                          const string & key2, EMObject val2,
00420                          const string & key3, EMObject val3,
00421                          const string & key4, EMObject val4)
00422                 {
00423                         dict[key1] = val1;
00424                         dict[key2] = val2;
00425                         dict[key3] = val3;
00426                         dict[key4] = val4;
00427                 }
00428 
00432                 Dict(const map < string, EMObject > &d)
00433                 {
00434                         copy(d.begin(), d.end(), inserter(dict, dict.begin()));
00435                         // Or use
00436                         // dict.insert(d.begin(), d.end());
00437                 }
00438 
00442                 ~Dict() {}
00443 
00447                 Dict( const Dict& that);
00448 
00452                 Dict& operator=(const Dict& that);
00453 
00456                 vector < string > keys()const
00457                 {
00458                         vector < string > result;
00459 
00460                         map < string, EMObject >::const_iterator p;
00461                         for (p = dict.begin(); p != dict.end(); p++) {
00462                                 result.push_back(p->first);
00463                         }
00464 
00465                         return result;
00466                 }
00467 
00470                 vector < EMObject > values()const
00471                 {
00472                         vector < EMObject > result;
00473 
00474                         map < string, EMObject >::const_iterator p;
00475                         for (p = dict.begin(); p != dict.end(); p++) {
00476                                 result.push_back(p->second);
00477                         }
00478 
00479                         return result;
00480                 }
00481 
00485                 bool has_key_ci(const string & key) const;
00486 
00490                 bool has_key(const string & key) const
00491                 {
00492                         map < string, EMObject >::const_iterator p = dict.find(key);
00493                         if (p != dict.end()) {
00494                                 return true;
00495                         }
00496                         return false;
00497                 }
00498 
00501                 size_t size() const
00502                 {
00503                         return dict.size();
00504                 }
00505 
00509                 EMObject get(const string & key) const
00510                 {
00511                         if( has_key(key) ) {
00512                                 return dict[key];
00513                         }
00514                         else {
00515                                 LOGERR("No such key exist in this Dict");
00516                                 throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00517                         }
00518                 }
00519 
00523                 EMObject get_ci(const string & key) const;
00527                 void put(const string & key, EMObject val)
00528                 {
00529                         dict[key] = val;
00530                 }
00531 
00534                 void erase(const string & key)
00535                 {
00536                         dict.erase(key);
00537                 }
00538 
00542                 void clear()
00543                 {
00544                         dict.clear();
00545                 }
00546 
00550                 template<typename type>
00551                 type set_default(const string & key, type val)
00552                 {
00553                         if (!has_key(key)) {
00554                                 dict[key] = val;
00555                         }
00556                         return dict[key];
00557                 }
00558 
00559                 Dict copy_exclude_keys(const vector<string>& excluded_keys) const
00560                 {
00561                         Dict ret(*this);
00562 
00563                         for ( vector<string>::const_iterator it = excluded_keys.begin(); it != excluded_keys.end(); ++it ) {
00564                                 if (ret.has_key(*it)) ret.erase(*it);
00565                         }
00566 
00567                         return ret;
00568                 }
00569 
00570                 Dict copy_exclusive_keys(const vector<string>& exclusive_keys) const
00571                 {
00572                         Dict ret;
00573                         for ( vector<string>::const_iterator it = exclusive_keys.begin(); it != exclusive_keys.end(); ++it ) {
00574                                 if (has_key(*it)) ret[*it] = (*this)[*it];
00575                         }
00576 
00577                         return ret;
00578                 }
00579 
00580                 Dict copy_keys_in( const TypeDict& tdict ) const {
00581                         vector<string> keys = tdict.keys();
00582                         return copy_exclusive_keys(keys);
00583                 }
00584 
00585                 EMObject & operator[] (const string & key)
00586                 {
00587 //                      static EMObject nullreturn;
00588 //                      if( has_key(key) )  return dict[key];
00589 //                      else return nullreturn;
00590 
00591 //                      if( has_key(key) ) {
00592                                 return dict[key];
00593 //                      }
00594 //                      else {
00595 //                              LOGERR("No such key exist in this Dict");
00596 //                              throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00597 //                      }
00598                 }
00599 
00600                 EMObject operator[] (const string & key) const
00601                 {
00602 //                      if( has_key(key) )  return dict[key];
00603 //                      else return EMObject();
00604                         return dict[key];
00605 
00606 //                      else {
00607 //                              LOGERR("No such key exist in this Dict");
00608 //                              throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00609 //                      }
00610                 }
00611 
00615                 friend bool operator==(const Dict& d1, const Dict& d2);
00616 
00620                 friend bool operator!=(const Dict& d1, const Dict& d2);
00621 
00622         private:
00623                 mutable map < string, EMObject > dict;
00624 
00625         public:
00633                 class iterator : public map < string, EMObject >::iterator
00634                 {
00635                 public:
00636                         typedef std::bidirectional_iterator_tag iterator_category;
00637                         typedef pair<string, EMObject> value_type;
00638 
00639                 public:
00640                         iterator( map < string, EMObject >::iterator parent_it );
00641                         virtual ~iterator(){}
00642 
00643                         iterator( const iterator& that );
00644                         iterator& operator=( const iterator& that );
00645                 };
00646 
00654                 class const_iterator :  public map < string, EMObject >::const_iterator
00655                 {
00656                 public:
00657                         typedef std::bidirectional_iterator_tag iterator_category;
00658                         typedef pair<string, EMObject> value_type; // Note that value_type should NOT be const even though the container elements are const
00659                 public:
00660                         const_iterator( const map < string, EMObject >::const_iterator parent_it);
00661                         virtual ~const_iterator(){}
00662                         const_iterator( const Dict::iterator& it );
00663 
00664                         const_iterator( const const_iterator& that );
00665                         const_iterator& operator=( const const_iterator& that );
00666                 };
00667 
00668                 // Iterator support
00669                 iterator begin( void );
00670                 const_iterator begin( void ) const;
00671 
00672                 iterator end( void );
00673                 const_iterator end( void ) const;
00674 
00675                 // Wraps map.find(const string& key)
00676                 iterator find( const string& key );
00677                 const_iterator find( const string& key ) const;
00678         };
00679 
00680         // These operators were originally added for the purposes of making testing code but might come in handy for other things
00681         // operator== simply wraps map<string, EMObject>::operator==
00682         bool operator==(const Dict &d1, const Dict& d2);
00683         bool operator!=(const Dict &d1, const Dict& d2);
00684 
00685 
00704         template < class T > class Factory
00705         {
00706         public:
00707                 typedef T *(*InstanceType) ();
00708 
00709                 template <class ClassType> static void add();
00710                 static T *get(const string & instance_name);
00711                 static T *get(const string & instance_name, const Dict & params);
00712                 static vector < string > get_list();
00713 
00714         private:
00715                 Factory();
00716                 Factory(const Factory < T > &);
00717                 ~Factory();
00718                 static void init();
00719                 template <class ClassType> void force_add();
00720 
00721                 static Factory < T > *my_instance;
00722                 map < string, InstanceType > my_dict;
00723         };
00724 
00725         template < class T > Factory < T > *Factory < T >::my_instance = 0;
00726 
00727         template < class T > void Factory < T >::init()
00728         {
00729                 if (!my_instance) {
00730                         my_instance = new Factory < T > ();
00731                 }
00732         }
00733 
00734         template < class T > 
00735         template < class ClassType > 
00736         void Factory < T >::force_add()
00737         {
00738                 string name = ClassType::NAME;
00739                 my_dict[name] = &ClassType::NEW;
00740         }
00741 
00742 
00743         template < class T > 
00744         template < class ClassType >
00745         void Factory < T >::add()
00746         {
00747                 init();
00748 
00749                 string name = ClassType::NAME;
00750                 typename map < string, InstanceType >::iterator fi =
00751                         my_instance->my_dict.find(name);
00752 
00753                 if (fi == my_instance->my_dict.end()) {
00754                         my_instance->my_dict[name] = &ClassType::NEW;
00755                 }
00756         }
00757 
00758         template < class T > T * Factory < T >::get(const string & instancename)
00759         {
00760                 init();
00761                 typename map < string, InstanceType >::iterator fi =
00762                         my_instance->my_dict.find(instancename);
00763                 if (fi != my_instance->my_dict.end()) {
00764                         return my_instance->my_dict[instancename] ();
00765                 }
00766 
00767                 string lower = instancename;
00768                 for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00769 
00770                 fi = my_instance->my_dict.find(lower);
00771                 if (fi != my_instance->my_dict.end()) {
00772                         return my_instance->my_dict[lower] ();
00773                 }
00774 
00775                 throw NotExistingObjectException(instancename, "The named object doesn't exist");
00776         }
00777 
00778         template < class T > T * Factory < T >::get(const string & instancename,
00779                                                                                                 const Dict & params)
00780         {
00781                 init();
00782 
00783                 typename map < string, InstanceType >::iterator fi =
00784                         my_instance->my_dict.find(instancename);
00785 
00786                 string lower = instancename;
00787                 if (fi == my_instance->my_dict.end()) {
00788                         for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00789                         fi = my_instance->my_dict.find(lower);
00790                 }
00791 
00792                 if (fi != my_instance->my_dict.end()) {
00793                         T *i = my_instance->my_dict[lower] ();
00794 
00795                         const vector<string> para_keys = params.keys();
00796 //                      std::cout << "the number of keys is " << para_keys.size() << std::endl; // PRB May 19th
00797                         const vector<string> valid_keys = i->get_param_types().keys();
00798                         typename vector<string>::const_iterator it;
00799                         for(it=para_keys.begin(); it!=para_keys.end(); ++it) {
00800 //                              std::cout << "the iterator  is " << *it << std::endl; // PRB May 19th
00801                                 if( find(valid_keys.begin(), valid_keys.end(), *it) == valid_keys.end() ) {
00802                                         throw InvalidParameterException(*it);
00803                                 }
00804                         }
00805 
00806                         i->set_params(params);
00807                         return i;
00808                 }
00809 
00810 
00811                 throw NotExistingObjectException(instancename, "No such an instance existing");
00812         }
00813 
00814         template < class T > vector < string > Factory < T >::get_list() {
00815                 init();
00816                 vector < string > result;
00817                 typename map < string, InstanceType >::const_iterator p;
00818                 for (p = my_instance->my_dict.begin(); p != my_instance->my_dict.end(); p++) {
00819                         result.push_back(p->first);
00820                 }
00821 
00822                 return result;
00823         }
00824 
00825         template < class T > void dump_factory()
00826         {
00827                 vector < string > item_names = Factory < T >::get_list();
00828 
00829                 for (size_t i = 0; i < item_names.size(); i++) {
00830                         T *item = Factory < T >::get(item_names[i]);
00831                         printf("%s :  %s\n", item->get_name().c_str(),item->get_desc().c_str());
00832                         TypeDict td = item->get_param_types();
00833                         td.dump();
00834                 }
00835         }
00836 
00837         template < class T > map<string, vector<string> > dump_factory_list()
00838         {
00839                 vector < string > item_names = Factory < T >::get_list();
00840                 map<string, vector<string> >    factory_list;
00841 
00842                 typename vector<string>::const_iterator p;
00843                 for(p = item_names.begin(); p !=item_names.end(); ++p) {
00844                         T *item = Factory<T>::get(*p);
00845 
00846                         string name = item->get_name();
00847 
00848                         vector<string> content;
00849                         content.push_back(item->get_desc());
00850                         TypeDict td = item->get_param_types();
00851                         vector<string> keys = td.keys();
00852                         for(unsigned int i=0; i<td.size(); ++i) {
00853                                 content.push_back(keys[i]);
00854                                 content.push_back( td.get_type(keys[i]) );
00855                                 content.push_back( td.get_desc(keys[i]) );
00856                         }
00857                         factory_list[name] = content;
00858                 }
00859 
00860                 return factory_list;
00861         }
00862 
00869         class FactoryBase
00870         {
00871         public:
00872                 FactoryBase() {}
00873                 virtual ~FactoryBase() {};
00874 
00878                 virtual string get_name() const = 0;
00879 
00883                 virtual string get_desc() const = 0;
00884 
00888                 Dict get_params() const { return params; }
00889 
00893                 void set_params(const Dict & new_params)
00894                 {
00895                         params.clear();
00896                         insert_params(new_params);
00897                 }
00898                 
00899                 inline void set_param(const string key,const EMObject val) { params[key]=val; }
00900                 
00903                 virtual TypeDict get_param_types() const = 0;
00904 
00908                 void insert_params(const Dict & new_params)
00909                 {
00910                 // this is really inserting OR individually replacing...
00911                 // the old data will be kept if it is not written over
00912                         TypeDict permissable_params = get_param_types();
00913                         for ( Dict::const_iterator it = new_params.begin(); it != new_params.end(); ++it )
00914                         {
00915 
00916                                 if ( !permissable_params.find_type(it->first) )
00917                                 {
00918                                         throw InvalidParameterException(it->first);
00919                                 }
00920                                 params[it->first] = it->second;
00921                         }
00922                 }
00923 
00924                 Dict copy_relevant_params(const FactoryBase* const that) const
00925                 {
00926                         return params.copy_keys_in(that->get_param_types());
00927 
00928                 }
00929 
00930                 protected:
00932                 mutable Dict params;
00933         };
00934 }
00935 
00936 #endif

Generated on Mon Jul 19 13:03:43 2010 for EMAN2 by  doxygen 1.4.4