EMAN2
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 
00440                 Dict(const string & key1, EMObject val1,
00441                          const string & key2, EMObject val2,
00442                          const string & key3, EMObject val3,
00443                          const string & key4, EMObject val4,
00444                          const string & key5, EMObject val5)
00445                 {
00446                         dict[key1] = val1;
00447                         dict[key2] = val2;
00448                         dict[key3] = val3;
00449                         dict[key4] = val4;
00450                         dict[key5] = val5;
00451                 }
00452 
00456                 Dict(const map < string, EMObject > &d)
00457                 {
00458                         copy(d.begin(), d.end(), inserter(dict, dict.begin()));
00459                         // Or use
00460                         // dict.insert(d.begin(), d.end());
00461                 }
00462 
00466                 ~Dict() {}
00467 
00471                 Dict( const Dict& that);
00472 
00476                 Dict& operator=(const Dict& that);
00477 
00480                 vector < string > keys()const
00481                 {
00482                         vector < string > result;
00483 
00484                         map < string, EMObject >::const_iterator p;
00485                         for (p = dict.begin(); p != dict.end(); p++) {
00486                                 result.push_back(p->first);
00487                         }
00488 
00489                         return result;
00490                 }
00491 
00494                 vector < EMObject > values()const
00495                 {
00496                         vector < EMObject > result;
00497 
00498                         map < string, EMObject >::const_iterator p;
00499                         for (p = dict.begin(); p != dict.end(); p++) {
00500                                 result.push_back(p->second);
00501                         }
00502 
00503                         return result;
00504                 }
00505 
00509                 bool has_key_ci(const string & key) const;
00510 
00514                 bool has_key(const string & key) const
00515                 {
00516                         map < string, EMObject >::const_iterator p = dict.find(key);
00517                         if (p != dict.end()) {
00518                                 return true;
00519                         }
00520                         return false;
00521                 }
00522 
00525                 size_t size() const
00526                 {
00527                         return dict.size();
00528                 }
00529 
00533                 EMObject get(const string & key) const
00534                 {
00535                         if( has_key(key) ) {
00536                                 return dict[key];
00537                         }
00538                         else {
00539                                 LOGERR("No such key exist in this Dict");
00540                                 throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00541                         }
00542                 }
00543 
00547                 EMObject get_ci(const string & key) const;
00551                 void put(const string & key, EMObject val)
00552                 {
00553                         dict[key] = val;
00554                 }
00555 
00558                 void erase(const string & key)
00559                 {
00560                         dict.erase(key);
00561                 }
00562 
00566                 void clear()
00567                 {
00568                         dict.clear();
00569                 }
00570 
00574                 template<typename type>
00575                 type set_default(const string & key, type val)
00576                 {
00577                         if (!has_key(key)) {
00578                                 dict[key] = val;
00579                         }
00580                         return dict[key];
00581                 }
00582 
00583                 Dict copy_exclude_keys(const vector<string>& excluded_keys) const
00584                 {
00585                         Dict ret(*this);
00586 
00587                         for ( vector<string>::const_iterator it = excluded_keys.begin(); it != excluded_keys.end(); ++it ) {
00588                                 if (ret.has_key(*it)) ret.erase(*it);
00589                         }
00590 
00591                         return ret;
00592                 }
00593 
00594                 Dict copy_exclusive_keys(const vector<string>& exclusive_keys) const
00595                 {
00596                         Dict ret;
00597                         for ( vector<string>::const_iterator it = exclusive_keys.begin(); it != exclusive_keys.end(); ++it ) {
00598                                 if (has_key(*it)) ret[*it] = (*this)[*it];
00599                         }
00600 
00601                         return ret;
00602                 }
00603 
00604                 Dict copy_keys_in( const TypeDict& tdict ) const {
00605                         vector<string> keys = tdict.keys();
00606                         return copy_exclusive_keys(keys);
00607                 }
00608 
00609                 EMObject & operator[] (const string & key)
00610                 {
00611 //                      static EMObject nullreturn;
00612 //                      if( has_key(key) )  return dict[key];
00613 //                      else return nullreturn;
00614 
00615 //                      if( has_key(key) ) {
00616                                 return dict[key];
00617 //                      }
00618 //                      else {
00619 //                              LOGERR("No such key exist in this Dict");
00620 //                              throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00621 //                      }
00622                 }
00623 
00624                 EMObject operator[] (const string & key) const
00625                 {
00626 //                      if( has_key(key) )  return dict[key];
00627 //                      else return EMObject();
00628                         return dict[key];
00629 
00630 //                      else {
00631 //                              LOGERR("No such key exist in this Dict");
00632 //                              throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
00633 //                      }
00634                 }
00635 
00639                 friend bool operator==(const Dict& d1, const Dict& d2);
00640 
00644                 friend bool operator!=(const Dict& d1, const Dict& d2);
00645 
00646         private:
00647                 mutable map < string, EMObject > dict;
00648 
00649         public:
00657                 class iterator : public map < string, EMObject >::iterator
00658                 {
00659                 public:
00660                         typedef std::bidirectional_iterator_tag iterator_category;
00661                         typedef pair<string, EMObject> value_type;
00662 
00663                 public:
00664                         iterator( map < string, EMObject >::iterator parent_it );
00665                         virtual ~iterator(){}
00666 
00667                         iterator( const iterator& that );
00668                         iterator& operator=( const iterator& that );
00669                 };
00670 
00678                 class const_iterator :  public map < string, EMObject >::const_iterator
00679                 {
00680                 public:
00681                         typedef std::bidirectional_iterator_tag iterator_category;
00682                         typedef pair<string, EMObject> value_type; // Note that value_type should NOT be const even though the container elements are const
00683                 public:
00684                         const_iterator( const map < string, EMObject >::const_iterator parent_it);
00685                         virtual ~const_iterator(){}
00686                         const_iterator( const Dict::iterator& it );
00687 
00688                         const_iterator( const const_iterator& that );
00689                         const_iterator& operator=( const const_iterator& that );
00690                 };
00691 
00692                 // Iterator support
00693                 iterator begin( void );
00694                 const_iterator begin( void ) const;
00695 
00696                 iterator end( void );
00697                 const_iterator end( void ) const;
00698 
00699                 // Wraps map.find(const string& key)
00700                 iterator find( const string& key );
00701                 const_iterator find( const string& key ) const;
00702         };
00703 
00704         // These operators were originally added for the purposes of making testing code but might come in handy for other things
00705         // operator== simply wraps map<string, EMObject>::operator==
00706         bool operator==(const Dict &d1, const Dict& d2);
00707         bool operator!=(const Dict &d1, const Dict& d2);
00708 
00709 
00728         template < class T > class Factory
00729         {
00730         public:
00731                 typedef T *(*InstanceType) ();
00732 
00733                 template <class ClassType> static void add();
00734                 static T *get(const string & instance_name);
00735                 static T *get(const string & instance_name, const Dict & params);
00736                 static vector < string > get_list();
00737 
00738         private:
00739                 Factory();
00740                 Factory(const Factory < T > &);
00741                 ~Factory();
00742                 static void init();
00743                 template <class ClassType> void force_add();
00744 
00745                 static Factory < T > *my_instance;
00746                 map < string, InstanceType > my_dict;
00747         };
00748 
00749         template < class T > Factory < T > *Factory < T >::my_instance = 0;
00750 
00751         template < class T > void Factory < T >::init()
00752         {
00753                 if (!my_instance) {
00754                         my_instance = new Factory < T > ();
00755                 }
00756         }
00757 
00758         template < class T > 
00759         template < class ClassType > 
00760         void Factory < T >::force_add()
00761         {
00762                 string name = ClassType::NAME;
00763                 my_dict[name] = &ClassType::NEW;
00764         }
00765 
00766 
00767         template < class T > 
00768         template < class ClassType >
00769         void Factory < T >::add()
00770         {
00771                 init();
00772 
00773                 string name = ClassType::NAME;
00774                 typename map < string, InstanceType >::iterator fi =
00775                         my_instance->my_dict.find(name);
00776 
00777                 if (fi == my_instance->my_dict.end()) {
00778                         my_instance->my_dict[name] = &ClassType::NEW;
00779                 }
00780         }
00781 
00782         template < class T > T * Factory < T >::get(const string & instancename)
00783         {
00784                 init();
00785                 typename map < string, InstanceType >::iterator fi =
00786                         my_instance->my_dict.find(instancename);
00787                 if (fi != my_instance->my_dict.end()) {
00788                         return my_instance->my_dict[instancename] ();
00789                 }
00790 
00791                 string lower = instancename;
00792                 for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00793 
00794                 fi = my_instance->my_dict.find(lower);
00795                 if (fi != my_instance->my_dict.end()) {
00796                         return my_instance->my_dict[lower] ();
00797                 }
00798 
00799                 throw NotExistingObjectException(instancename, "The named object doesn't exist");
00800         }
00801 
00802         template < class T > T * Factory < T >::get(const string & instancename,
00803                                                                                                 const Dict & params)
00804         {
00805                 init();
00806 
00807                 typename map < string, InstanceType >::iterator fi =
00808                         my_instance->my_dict.find(instancename);
00809 
00810                 string lower = instancename;
00811                 if (fi == my_instance->my_dict.end()) {
00812                         for (unsigned int i=0; i<lower.length(); i++) lower[i]=tolower(lower[i]);
00813                         fi = my_instance->my_dict.find(lower);
00814                 }
00815 
00816                 if (fi != my_instance->my_dict.end()) {
00817                         T *i = my_instance->my_dict[lower] ();
00818 
00819                         const vector<string> para_keys = params.keys();
00820 //                      std::cout << "the number of keys is " << para_keys.size() << std::endl; // PRB May 19th
00821                         const vector<string> valid_keys = i->get_param_types().keys();
00822                         typename vector<string>::const_iterator it;
00823                         for(it=para_keys.begin(); it!=para_keys.end(); ++it) {
00824 //                              std::cout << "the iterator  is " << *it << std::endl; // PRB May 19th
00825                                 if( find(valid_keys.begin(), valid_keys.end(), *it) == valid_keys.end() ) {
00826                                         throw InvalidParameterException(*it);
00827                                 }
00828                         }
00829 
00830                         i->set_params(params);
00831                         return i;
00832                 }
00833 
00834 
00835                 throw NotExistingObjectException(instancename, "No such an instance existing");
00836         }
00837 
00838         template < class T > vector < string > Factory < T >::get_list() {
00839                 init();
00840                 vector < string > result;
00841                 typename map < string, InstanceType >::const_iterator p;
00842                 for (p = my_instance->my_dict.begin(); p != my_instance->my_dict.end(); p++) {
00843                         result.push_back(p->first);
00844                 }
00845 
00846                 return result;
00847         }
00848 
00849         template < class T > void dump_factory()
00850         {
00851                 vector < string > item_names = Factory < T >::get_list();
00852 
00853                 for (size_t i = 0; i < item_names.size(); i++) {
00854                         T *item = Factory < T >::get(item_names[i]);
00855                         printf("%s :  %s\n", item->get_name().c_str(),item->get_desc().c_str());
00856                         TypeDict td = item->get_param_types();
00857                         td.dump();
00858                 }
00859         }
00860 
00861         template < class T > map<string, vector<string> > dump_factory_list()
00862         {
00863                 vector < string > item_names = Factory < T >::get_list();
00864                 map<string, vector<string> >    factory_list;
00865 
00866                 typename vector<string>::const_iterator p;
00867                 for(p = item_names.begin(); p !=item_names.end(); ++p) {
00868                         T *item = Factory<T>::get(*p);
00869 
00870                         string name = item->get_name();
00871 
00872                         vector<string> content;
00873                         content.push_back(item->get_desc());
00874                         TypeDict td = item->get_param_types();
00875                         vector<string> keys = td.keys();
00876                         for(unsigned int i=0; i<td.size(); ++i) {
00877                                 content.push_back(keys[i]);
00878                                 content.push_back( td.get_type(keys[i]) );
00879                                 content.push_back( td.get_desc(keys[i]) );
00880                         }
00881                         factory_list[name] = content;
00882                 }
00883 
00884                 return factory_list;
00885         }
00886 
00893         class FactoryBase
00894         {
00895         public:
00896                 FactoryBase() {}
00897                 virtual ~FactoryBase() {};
00898 
00902                 virtual string get_name() const = 0;
00903 
00907                 virtual string get_desc() const = 0;
00908 
00912                 Dict get_params() const { return params; }
00913 
00917                 void set_params(const Dict & new_params)
00918                 {
00919                         params.clear();
00920                         insert_params(new_params);
00921                 }
00922                 
00923                 inline void set_param(const string key,const EMObject val) { params[key]=val; }
00924                 
00927                 virtual TypeDict get_param_types() const = 0;
00928 
00932                 void insert_params(const Dict & new_params)
00933                 {
00934                 // this is really inserting OR individually replacing...
00935                 // the old data will be kept if it is not written over
00936                         TypeDict permissable_params = get_param_types();
00937                         for ( Dict::const_iterator it = new_params.begin(); it != new_params.end(); ++it )
00938                         {
00939 
00940                                 if ( !permissable_params.find_type(it->first) )
00941                                 {
00942                                         throw InvalidParameterException(it->first);
00943                                 }
00944                                 params[it->first] = it->second;
00945                         }
00946                 }
00947 
00948                 Dict copy_relevant_params(const FactoryBase* const that) const
00949                 {
00950                         return params.copy_keys_in(that->get_param_types());
00951 
00952                 }
00953 
00954                 protected:
00956                 mutable Dict params;
00957         };
00958 }
00959 
00960 #endif