EMAN2
emobject.cpp
Go to the documentation of this file.
00001 
00005 /*
00006  * Author: Steven Ludtke, 04/10/2003 (sludtke@bcm.edu)
00007  * Probable contributor: Liwei Peng (what dates?)
00008  * Contributing author: David Woolford 06/11/2007
00009  *
00010  * Copyright (c) 2000-2007 Baylor College of Medicine
00011  *
00012  * This software is issued under a joint BSD/GNU license. You may use the
00013  * source code in this file under either license. However, note that the
00014  * complete EMAN2 and SPARX software packages have some GPL dependencies,
00015  * so you are responsible for compliance with the licenses of these packages
00016  * if you opt to use BSD licensing. The warranty disclaimer below holds
00017  * in either instance.
00018  *
00019  * This complete copyright notice must be included in any revised version of the
00020  * source code. Additional authorship citations may be added, but existing
00021  * author citations must be preserved.
00022  *
00023  * This program is free software; you can redistribute it and/or modify
00024  * it under the terms of the GNU General Public License as published by
00025  * the Free Software Foundation; either version 2 of the License, or
00026  * (at your option) any later version.
00027  *
00028  * This program is distributed in the hope that it will be useful,
00029  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00030  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00031  * GNU General Public License for more details.
00032  *
00033  * You should have received a copy of the GNU General Public License
00034  * along with this program; if not, write to the Free Software
00035  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00036  *
00037  * */
00038 
00039 #include "emobject.h"
00040 #include <cmath>
00041 #ifdef WIN32
00042 #define M_PI 3.14159265358979323846f
00043 #endif
00044 
00045 #include <algorithm>
00046 // using copy
00047 
00048 #include "util.h"
00049 
00050 using namespace EMAN;
00051 
00052 #include <iostream>
00053 using std::cout;
00054 using std::cerr;
00055 using std::endl;
00056 
00057 const float EMConsts::I2G = (float) (4.0 / (M_PI*M_PI));
00058 const float EMConsts::I3G = (float) (6.4 / (M_PI*M_PI));
00059 const float EMConsts::I4G = (float) (8.8 / (M_PI*M_PI));
00060 const float EMConsts::I5G = (float) (10.4 / (M_PI*M_PI));
00061 // This stolen from wikipedia.org
00062 const double EMConsts::pi = 3.141592653589793238462643383279502884197169399;
00063 const double EMConsts::deg2rad = pi/180.0;
00064 const double EMConsts::rad2deg = 180.0/pi;
00065 
00066 
00067 #include <sstream>
00068 using std::stringstream;
00069 
00070 #include "transform.h"
00071 #include "ctf.h"
00072 
00073 #ifdef MEMDEBUG
00074 set<EMObject*> allemobjlist;
00075 #endif
00076 
00077 
00078 // Static init
00079 map< EMObject::ObjectType, string>  EMObject::type_registry = init();;
00080 
00081 //-------------------------------EMObjectTypes-----------------------------------------
00082 map< EMObject::ObjectType, string> EMObject::init()
00083 {
00084         map< EMObject::ObjectType, string> mymap;
00085         static bool first_construction = true;
00086         if ( first_construction )
00087         {
00088                 // Initialize the the type registry once and for all
00089                 mymap[BOOL] = "BOOL";
00090                 mymap[SHORT] = "SHORT";
00091                 mymap[INT] = "INT";
00092                 mymap[UNSIGNEDINT] = "UNSIGNEDINT";
00093                 mymap[FLOAT] = "FLOAT";
00094                 mymap[DOUBLE] = "DOUBLE";
00095                 mymap[STRING] = "STRING";
00096                 mymap[EMDATA] = "EMDATA";
00097                 mymap[XYDATA] = "XYDATA";
00098                 mymap[INTARRAY] = "INTARRAY";
00099                 mymap[FLOATARRAY] = "FLOATARRAY";
00100                 mymap[STRINGARRAY] = "STRINGARRAY";
00101                 mymap[TRANSFORM] = "TRANFORM";
00102                 mymap[CTF] = "CTF";
00103                 mymap[FLOAT_POINTER] = "FLOAT_POINTER";
00104                 mymap[INT_POINTER] = "INT_POINTER";
00105                 mymap[UNKNOWN] = "UNKNOWN";
00106                 mymap[VOID_POINTER] = "VOID_POINTER";
00107                 mymap[TRANSFORMARRAY] = "TRANSFORMARRAY";
00108                 first_construction = false;
00109         }
00110 
00111         return mymap;
00112 }
00113 
00114 //-------------------------------EMObject--------------------------------------------
00115 
00116 void EMObject::printInfo() const
00117 {
00118         cout << "The address of my type is " << &type << endl;
00119         cout << " Now printing the enumerated values in type_registry " << endl;
00120         for( map< ObjectType, string>::const_iterator it = type_registry.begin(); it != type_registry.end(); ++it )
00121         {
00122                 cout << it->first << " " << it->second << endl;
00123         }
00124         cout << "My type is " << to_str(type) << " and its enumerated value is " << type << endl;
00125         cout << "The address of the static type registry is " << &type_registry <<", it should be same for all EMObjects" << endl;
00126 }
00127 
00128 EMObject::~EMObject() {
00129 #ifdef MEMDEBUG
00130         allemobjlist.erase(this);
00131         printf("  -(%6d) %p\n",(int)allemobjlist.size(),this);
00132 #endif
00133 }
00134 
00135 EMObject::EMObject() :
00136         d(0), type(UNKNOWN)
00137 {
00138 #ifdef MEMDEBUG
00139         allemobjlist.insert(this);
00140         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00141 #endif
00142 }
00143 
00144 EMObject::EMObject(bool boolean) :
00145         b(boolean), type(BOOL)
00146 {
00147 #ifdef MEMDEBUG
00148         allemobjlist.insert(this);
00149         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00150 #endif
00151 }
00152 
00153 EMObject::EMObject(short sint) :
00154         si(sint), type(SHORT)
00155 {
00156 #ifdef MEMDEBUG
00157         allemobjlist.insert(this);
00158         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00159 #endif
00160 }
00161 
00162 EMObject::EMObject(int num) :
00163         n(num), type(INT)
00164 {
00165 #ifdef MEMDEBUG
00166         allemobjlist.insert(this);
00167         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00168 #endif
00169 }
00170 
00171 EMObject::EMObject(unsigned int num) :
00172         ui(num), type(UNSIGNEDINT)
00173 {
00174 #ifdef MEMDEBUG
00175         allemobjlist.insert(this);
00176         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00177 #endif
00178 }
00179 
00180 EMObject::EMObject(float ff) :
00181         type(FLOAT)
00182 {
00183 
00184 #ifdef MEMDEBUG
00185         allemobjlist.insert(this);
00186         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00187 #endif
00188         if(Util::goodf(&ff)) {
00189                 f = ff;
00190         }
00191         else{
00192                 f = 0.0f;
00193         }
00194 }
00195 
00196 EMObject::EMObject(double dd) :
00197         type(DOUBLE)
00198 {
00199 
00200 #ifdef MEMDEBUG
00201         allemobjlist.insert(this);
00202         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00203 #endif
00204         if(Util::goodf(&dd)) {
00205                 d = dd;
00206         }
00207         else{
00208                 d = 0.0;
00209         }
00210 }
00211 
00212 EMObject::EMObject(const char *s) :
00213         str(s), type(STRING)
00214 {
00215 #ifdef MEMDEBUG
00216         allemobjlist.insert(this);
00217         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00218 #endif
00219 }
00220 
00221 EMObject::EMObject(const string & s) :
00222         str(s), type(STRING)
00223 {
00224 #ifdef MEMDEBUG
00225         allemobjlist.insert(this);
00226         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00227 #endif
00228 }
00229 
00230 EMObject::EMObject(float *f) :
00231         fp(f), type(FLOAT_POINTER)
00232 {
00233 #ifdef MEMDEBUG
00234         allemobjlist.insert(this);
00235         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00236 #endif
00237 }
00238 
00239 EMObject::EMObject(int *i) :
00240         ip(i), type(INT_POINTER)
00241 {
00242 #ifdef MEMDEBUG
00243         allemobjlist.insert(this);
00244         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00245 #endif
00246 }
00247 
00248 EMObject::EMObject(void *v) :
00249         vp(v), type(VOID_POINTER)
00250 {
00251 #ifdef MEMDEBUG
00252         allemobjlist.insert(this);
00253         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00254 #endif
00255 }
00256 
00257 EMObject::EMObject(EMData * em) :
00258         emdata(em), type(EMDATA)
00259 {
00260 #ifdef MEMDEBUG
00261         allemobjlist.insert(this);
00262         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00263 #endif
00264 }
00265 
00266 EMObject::EMObject(XYData * xy) :
00267         xydata(xy), type(XYDATA)
00268 {
00269 #ifdef MEMDEBUG
00270         allemobjlist.insert(this);
00271         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00272 #endif
00273 }
00274 
00275 EMObject::EMObject(Transform* t) :
00276         farray(t->get_matrix()), type(TRANSFORM)
00277 {
00278 #ifdef MEMDEBUG
00279         allemobjlist.insert(this);
00280         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00281 #endif
00282 }
00283 
00284 EMObject::EMObject(Ctf * ctf) :
00285         str(ctf->to_string()), type(CTF)
00286 {
00287 #ifdef MEMDEBUG
00288         allemobjlist.insert(this);
00289         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00290 #endif
00291 }
00292 
00293 EMObject::EMObject(const vector< int >& v ) :
00294         iarray(v), type(INTARRAY)
00295 {
00296 #ifdef MEMDEBUG
00297         allemobjlist.insert(this);
00298         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00299 #endif
00300 }
00301 
00302 EMObject::EMObject(const vector < float >&v) :
00303         farray(v), type(FLOATARRAY)
00304 {
00305 #ifdef MEMDEBUG
00306         allemobjlist.insert(this);
00307         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00308 #endif
00309 }
00310 
00311 EMObject::EMObject(const vector <string>& sarray) :
00312         strarray(sarray), type(STRINGARRAY)
00313 {
00314 #ifdef MEMDEBUG
00315         allemobjlist.insert(this);
00316         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00317 #endif
00318 }
00319 
00320 EMObject::EMObject(const vector <Transform>& tarray) :
00321         transformarray(tarray), type(TRANSFORMARRAY)
00322 {
00323 #ifdef MEMDEBUG
00324         allemobjlist.insert(this);
00325         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00326 #endif
00327 }
00328 
00329 EMObject::operator bool () const
00330 {
00331         if (type == BOOL) {
00332                 return b;
00333         }
00334         else if (type == SHORT) {
00335                 return si != 0;
00336         }
00337         else if (type == INT) {
00338                 return n != 0;
00339         }
00340         else if (type == UNSIGNEDINT) {
00341                 return ui != 0;
00342         }
00343         else if (type == FLOAT) {
00344                 return f != 0;
00345         }
00346         else if (type == DOUBLE) {
00347                 return d != 0;
00348         }
00349         else if (type == EMDATA) {
00350                 return emdata != 0;
00351         }
00352         else if (type == XYDATA) {
00353                 return xydata != 0;
00354         }
00355         else if (type == FLOAT_POINTER) {
00356                 return fp != 0;
00357         }
00358         else if (type == INT_POINTER) {
00359                 return ip != 0;
00360         }
00361         else if (type == VOID_POINTER) {
00362                 return vp != 0;
00363         }
00364 //      else if (type == TRANSFORM) {
00365 //              return transform != 0;
00366 //      }
00367         // It seemed unconventional to return a boolean for the stl objects
00368         else {
00369                 if (type != UNKNOWN) {
00370                         throw TypeException("Cannot convert to bool this data type ",
00371                                                                 get_object_type_name(type));
00372                 }
00373         }
00374         return 0;
00375 }
00376 
00377 EMObject::operator short () const
00378 {
00379         if (type == SHORT) {
00380                 return si;
00381         }
00382         else {
00383         if (type != UNKNOWN) {
00384                                 throw TypeException("Cannot convert to int this data type ",
00385                                                                         get_object_type_name(type));
00386                         }
00387         }
00388         return 0;
00389 }
00390 
00391 EMObject::operator int () const
00392 {
00393         if (type == INT) {
00394                 return n;
00395         }
00396         else if (type == SHORT) {
00397                 return si;
00398         }
00399         else if (type == UNSIGNEDINT) {
00400                 return (int) ui;
00401         }
00402         else if (type == FLOAT) {
00403                 return (int) f;
00404         }
00405         else if (type == DOUBLE) {
00406                 return (int) d;
00407         }
00408         else if (type == BOOL) {
00409                 return b?1:0;
00410         }
00411         else {
00412                 if (type != UNKNOWN) {
00413                         throw TypeException("Cannot convert to int this data type ",
00414                                                                 get_object_type_name(type));
00415                 }
00416         }
00417         return 0;
00418 }
00419 
00420 EMObject::operator unsigned int () const
00421 {
00422         if (type == UNSIGNEDINT) {
00423                 return (unsigned int) ui;
00424         }
00425         else {
00426                 if (type != UNKNOWN) {
00427                         throw TypeException("Cannot convert to int this data type ",
00428                                                                 get_object_type_name(type));
00429                 }
00430         }
00431         return 0;
00432 }
00433 
00434 EMObject::operator float () const
00435 {
00436         if (type == BOOL) {
00437                 return b?1.0f:0.0f;
00438         }
00439         else if (type == FLOAT) {
00440                 return f;
00441         }
00442         else if (type == SHORT) {
00443                 return si;
00444         }
00445         else if (type == INT) {
00446                 return (float) n;
00447         }
00448         else if (type == UNSIGNEDINT) {
00449                 return (float) ui;
00450         }
00451         else if (type == DOUBLE) {
00452                 return (float) d;
00453         }
00454         else if (type == STRING) {
00455                 return (float)atof(str.c_str());
00456         }
00457         else {
00458                 if (type != UNKNOWN) {
00459                         throw TypeException("Cannot convert to float from this data type",
00460                                                                 get_object_type_name(type));
00461                 }
00462         }
00463 
00464         return 0;
00465 }
00466 
00467 EMObject::operator double () const
00468 {
00469         if (type == BOOL) {
00470         return b?1.0:0.0;
00471         }
00472         else if (type == DOUBLE) {
00473                 return d;
00474         }
00475         else if (type == SHORT) {
00476                 return si;
00477         }
00478         else if (type == INT) {
00479                 return (double) n;
00480         }
00481         else if (type == UNSIGNEDINT) {
00482                 return (double) ui;
00483         }
00484         else if (type == FLOAT) {
00485                 return (double) f;
00486         }
00487         else {
00488                 if (type != UNKNOWN) {
00489                         throw TypeException("Cannot convert to double from this data type",
00490                                                                 get_object_type_name(type));
00491                 }
00492         }
00493         return 0;
00494 }
00495 
00496 EMObject::operator int * () const
00497 {
00498         if (type != INT_POINTER)
00499         {
00500                 if (type != UNKNOWN)
00501                         throw TypeException("Cannot convert to float pointer from this data type",
00502                                                                 get_object_type_name(type));
00503 
00504                 return 0;
00505         }
00506 
00507         return ip;
00508 }
00509 
00510 
00511 EMObject::operator float * () const
00512 {
00513         if (type != FLOAT_POINTER)
00514         {
00515                 if (type != UNKNOWN)
00516                         throw TypeException("Cannot convert to float pointer from this data type",
00517                                                                 get_object_type_name(type));
00518 
00519                 return 0;
00520         }
00521 
00522         return fp;
00523 }
00524 
00525 // MAYBE REMOVE? FIXME
00526 EMObject::operator void * () const
00527 {
00528         if (type == VOID_POINTER) return vp;
00529         else if (type == FLOAT_POINTER) return (void *)fp;
00530         else if (type == INT_POINTER) return (void *)ip;
00531         else if (type == EMDATA) return (void *) emdata;
00532         else if (type == XYDATA) return (void *) xydata;
00533 //      else if (type == TRANSFORM) return (void *) transform;
00534         else throw TypeException("Cannot convert to void pointer from this data type", get_object_type_name(type));
00535 }
00536 
00537 EMObject::operator const char * () const
00538 {
00539         if (type != STRING && type != CTF) {
00540                 stringstream ss;
00541                 string return_string;
00542                 if ( type == INT )
00543                 {
00544                         ss << n;
00545                         ss >> return_string;
00546                         return return_string.c_str();
00547                 }
00548                 if ( type == UNSIGNEDINT )
00549                 {
00550                         ss << ui;
00551                         ss >> return_string;
00552                         return return_string.c_str();
00553                 }
00554                 else
00555                 if ( type == FLOAT )
00556                 {
00557                         ss << f;
00558                         ss >> return_string;
00559                         return return_string.c_str();
00560                 }
00561                 else
00562                 if ( type == DOUBLE )
00563                 {
00564                         ss << d;
00565                         ss >> return_string;
00566                         return return_string.c_str();
00567                 }
00568                 else if (type != UNKNOWN) {
00569                         throw TypeException("Cannot convert to string from this data type",
00570                                                                 get_object_type_name(type));
00571                 }
00572 
00573                 return "";
00574         }
00575         return str.c_str();
00576 }
00577 
00578 EMObject::operator EMData * () const
00579 {
00580         if (type != EMDATA) {
00581                 if (type != UNKNOWN) {
00582                         throw TypeException("Cannot convert to EMData* from this data type",
00583                                    get_object_type_name(type));
00584                 }
00585                 return 0;
00586         }
00587         return emdata;
00588 }
00589 
00590 EMObject::operator XYData * () const
00591 {
00592         if (type != XYDATA) {
00593                 if (type != UNKNOWN) {
00594                         throw TypeException("Cannot convert to XYData* from this data type",
00595                                    get_object_type_name(type));
00596                 }
00597                 return 0;
00598         }
00599         return xydata;
00600 }
00601 
00602 EMObject::operator Transform* () const
00603 {
00604         if(type != TRANSFORM) {
00605                 if(type != UNKNOWN) {
00606                         throw TypeException("Cannot convert to TRANSFORM* from this data type",
00607                                                                 get_object_type_name(type));
00608                 }
00609         }
00610         Transform * transform = new Transform();
00611         transform->set_matrix(farray);
00612         return transform;
00613 }
00614 
00615 EMObject::operator Ctf* () const
00616 {
00617 /*      if(type != CTF) {
00618                 if(type != CTF) {
00619                         throw TypeException("Cannot convert to TRANSFORM* from this data type",
00620                                                                 get_object_type_name(type));
00621                 }
00622         }*/
00623         Ctf * ctf = 0;
00624         if(str[0] == 'O') {
00625                 ctf = new EMAN1Ctf();
00626                 ctf->from_string(str);
00627         }
00628         else if(str[0] == 'E') {
00629                 ctf = new EMAN2Ctf();
00630                 ctf->from_string(str);
00631         }
00632         return ctf;
00633 }
00634 
00635 EMObject::operator vector<int>() const
00636 {
00637     if( type != INTARRAY )
00638     {
00639         if( type != UNKNOWN ) {
00640                 throw TypeException("Cannot convert to vector<int> from this data type", get_object_type_name(type) );
00641                 }
00642                 return vector<int>();
00643     }
00644     return iarray;
00645 }
00646 
00647 EMObject::operator vector < float > () const
00648 {
00649         if (type != FLOATARRAY) {
00650                 if (type != UNKNOWN) {
00651                         throw TypeException("Cannot convert to vector<float> from this data type",
00652                                                                 get_object_type_name(type));
00653                 }
00654                 return vector < float >();
00655         }
00656         return farray;
00657 }
00658 
00659 EMObject::operator vector<string> () const
00660 {
00661         if (type != STRINGARRAY) {
00662                 if (type != UNKNOWN) {
00663                         throw TypeException("Cannot convert to vector<string> from this data type",
00664                                                                 get_object_type_name(type));
00665                 }
00666                 return vector<string>();
00667         }
00668         return strarray;
00669 }
00670 
00671 EMObject::operator vector<Transform> () const
00672 {
00673         if(type != TRANSFORMARRAY) {
00674                 if (type != UNKNOWN) {
00675                         throw TypeException("Cannot convert to vector<string> from this data type",
00676                                                                 get_object_type_name(type));
00677                 }
00678                 return vector<Transform>();
00679         }
00680         return transformarray;
00681 }
00682 
00683 bool EMObject::is_null() const
00684 {
00685         return (type == UNKNOWN);
00686 }
00687 
00688 string EMObject::to_str() const
00689 {
00690         return to_str(type);
00691 }
00692 
00693 string EMObject::to_str(ObjectType argtype) const
00694 {
00695         if (argtype == STRING) {
00696                 return str;
00697         }
00698         else {
00699                 char tmp_str[32];
00700                 if (argtype == BOOL) {
00701                         if (b)
00702                                 sprintf(tmp_str, "true");
00703                         else
00704                                 sprintf(tmp_str, "false");
00705                 }
00706                 else if (argtype == SHORT) {
00707                         sprintf(tmp_str, "%hd", si);
00708                 }
00709                 else if (argtype == INT) {
00710                         sprintf(tmp_str, "%d", n);
00711                 }
00712                 else if (argtype == UNSIGNEDINT) {
00713                         sprintf(tmp_str, "%d", ui);
00714                 }
00715                 else if (argtype == FLOAT) {
00716                         sprintf(tmp_str, "%f", f);
00717                 }
00718                 else if (argtype == DOUBLE) {
00719                         sprintf(tmp_str, "%f", d);
00720                 }
00721                 else if (argtype == EMDATA) {
00722                         sprintf(tmp_str, "EMDATA");
00723                 }
00724                 else if (argtype == FLOAT_POINTER) {
00725                         sprintf(tmp_str, "FLOAT_POINTER");
00726                 }
00727                 else if (argtype == INT) {
00728                         sprintf(tmp_str, "INT_POINTER");
00729                 }
00730                 else if (argtype == VOID_POINTER) {
00731                         sprintf(tmp_str, "VOID_POINTER");
00732                 }
00733                 else if (argtype == XYDATA) {
00734                         sprintf(tmp_str, "XYDATA");
00735                 }
00736                 else if (argtype == INTARRAY) {
00737                         sprintf(tmp_str, "INTARRAY");
00738                 }
00739                 else if (argtype == FLOATARRAY) {
00740                         sprintf(tmp_str, "FLOATARRAY");
00741                 }
00742                 else if (argtype == STRINGARRAY) {
00743                         sprintf(tmp_str, "STRINGARRAY");
00744                 }
00745                 else if (argtype == TRANSFORM) {
00746                         sprintf(tmp_str, "TRANSFORM");
00747                 }
00748                 else if (argtype == TRANSFORMARRAY) {
00749                         sprintf(tmp_str, "TRANSFORMARRAY");
00750                 }
00751                 else if (argtype == CTF) {
00752                         sprintf(tmp_str, "CTF");
00753                 }
00754                 else if (argtype == UNKNOWN) {
00755                         sprintf(tmp_str, "UNKNOWN");
00756                 }
00757                 else {
00758                         LOGERR("No such EMObject defined");
00759                         throw NotExistingObjectException("EMObject", "unknown type");
00760                 }
00761                 return string(tmp_str);
00762         }
00763 }
00764 
00765 string EMObject::get_object_type_name(ObjectType t)
00766 {
00767 #ifdef _WIN32
00768         if (t == BOOL) {
00769                 return "BOOL";
00770         }else
00771         if ( t == SHORT) {
00772                 return "SHORT";
00773         }else
00774         if ( t == INT){
00775                 return "INT";
00776         }else
00777         if ( t == UNSIGNEDINT){
00778                 return "UNSIGNEDINT";
00779         } else
00780         if ( t == FLOAT){
00781                 return "FLOAT";
00782         } else
00783         if ( t == DOUBLE){
00784                 return "DOUBLE";
00785         }else
00786         if ( t == STRING){
00787                 return "STRING";
00788         }else
00789         if ( t == EMDATA){
00790                 return "EMDATA";
00791         }
00792         else
00793         if ( t == XYDATA){
00794                 return "XYDATA";
00795         }else
00796         if ( t == INTARRAY){
00797                 return "INTARRAY";
00798         }else
00799         if ( t == FLOATARRAY){
00800                 return "FLOATARRAY";
00801         } else
00802         if ( t == STRINGARRAY){
00803                 return "STRINGARRAY";
00804         }else
00805         if ( t == TRANSFORM){
00806                 return "TRANSFORM";
00807         }else
00808         if ( t == TRANSFORMARRAY){
00809                 return "TRANSFORMARRAY";
00810         }
00811         if ( t == CTF){
00812                 return "CTF";
00813         }else
00814         if ( t == FLOAT_POINTER){
00815                 return "FLOAT_POINTER";
00816         }else
00817         if ( t == INT_POINTER){
00818                 return "INT_POINTER";
00819         }else
00820         if ( t == UNKNOWN){
00821                 return "UNKNOWN";
00822         } else
00823         if ( t == VOID_POINTER){
00824                 return "VOID_POINTER";
00825         }
00826         else {
00827                 LOGERR("No such EMObject defined");
00828                 throw NotExistingObjectException("EMObject", "unknown type");
00829         }
00830 
00831 #else
00832 
00833         if  ( type_registry.find(t) != type_registry.end() )
00834                 return type_registry[t];
00835         else
00836                 LOGERR("No such EMObject defined");
00837                 throw NotExistingObjectException("EMObject", "unknown type");
00838 #endif  //_WIN32
00839 }
00840 
00841 bool EMAN::operator==(const EMObject &e1, const EMObject & e2)
00842 {
00843 
00844         if (e1.type != e2.type) {
00845                 return false;
00846         }
00847 
00848         switch (e1.type) {
00849         case  EMObject::BOOL:
00850                 return (e1.b == e2.b);
00851         break;
00852         case EMObject::SHORT:
00853                 return (e1.si == e2.si);
00854         break;
00855         case  EMObject::INT:
00856                 return (e1.n == e2.n);
00857         break;
00858         case  EMObject::UNSIGNEDINT:
00859                 return (e1.ui == e2.ui);
00860         break;
00861         case  EMObject::FLOAT:
00862                 return (e1.f == e2.f);
00863         break;
00864         case  EMObject::DOUBLE:
00865                 return (e1.d == e2.d);
00866         break;
00867         case EMObject::CTF:
00868         case  EMObject::STRING:
00869                 return (e1.str == e2.str);
00870         break;
00871         case  EMObject::FLOAT_POINTER:
00872                 return (e1.fp == e2.fp);
00873         break;
00874         case  EMObject::INT_POINTER:
00875                 return (e1.ip == e2.ip);
00876         break;
00877         case  EMObject::VOID_POINTER:
00878                 return (e1.vp == e2.vp);
00879         break;
00880         case  EMObject::EMDATA:
00881                 return (e1.emdata == e2.emdata);
00882         break;
00883         case  EMObject::XYDATA:
00884                 return (e1.xydata == e2.xydata);
00885         break;
00886         case  EMObject::TRANSFORM:
00887         case  EMObject::FLOATARRAY:
00888                 if (e1.farray.size() == e2.farray.size()) {
00889                         for (size_t i = 0; i < e1.farray.size(); i++) {
00890                                 if (e1.farray[i] != e2.farray[i]) {
00891                                         return false;
00892                                 }
00893                         }
00894                         return true;
00895                 }
00896                 else {
00897                         return false;
00898                 }
00899         break;
00900         case  EMObject::INTARRAY:
00901                 if (e1.iarray.size() == e2.iarray.size()) {
00902                         for (size_t i = 0; i < e1.iarray.size(); i++) {
00903                                 if (e1.iarray[i] != e2.iarray[i]) {
00904                                         return false;
00905                                 }
00906                         }
00907                         return true;
00908                 }
00909         break;
00910         case  EMObject::STRINGARRAY:
00911                 if (e1.strarray.size() == e2.strarray.size()) {
00912                         for (size_t i = 0; i < e1.strarray.size(); i++) {
00913                                 if (e1.strarray[i] != e2.strarray[i]) {
00914                                         return false;
00915                                 }
00916                         }
00917                         return true;
00918                 }
00919                 else {
00920                         return false;
00921                 }
00922         break;
00923         case EMObject::TRANSFORMARRAY:
00924                 if (e1.transformarray.size() == e2.transformarray.size()) {
00925                         for (size_t i = 0; i < e1.transformarray.size(); i++) {
00926                                 if (e1.transformarray[i] != e2.transformarray[i]) {
00927                                         return false;
00928                                 }
00929                         }
00930                 }
00931         break;
00932         case  EMObject::UNKNOWN:
00933                 // UNKNOWN really means "no type" and if two objects both have
00934                 // type UNKNOWN they really are the same
00935                 return (e1.type == e2.type);
00936         break;
00937         default:
00938                 return false;
00939         break;
00940         }
00941         return false;
00942 }
00943 
00944 bool EMAN::operator!=(const EMObject &e1, const EMObject & e2)
00945 {
00946         return !(e1 == e2);
00947 }
00948 
00949 // Copy constructor
00950 EMObject::EMObject(const EMObject& that)
00951 {
00952         // init isn't necessary because that must have already called it!
00953         *this = that;
00954 #ifdef MEMDEBUG
00955         allemobjlist.insert(this);
00956         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00957 #endif
00958 }
00959 
00960 
00961 // Assignment operator -  - copies only the variable associated with the type of the argument.
00962 // It would be possible just to do a dumb copy of everything, but that seems opposed to
00963 // the concept of an EMObject, which is always of a single type.
00964 EMObject& EMObject::operator=( const EMObject& that )
00965 {
00966 
00967 // This test breaks assignment when either the current or assigned values are (float)nan
00968 // it's also somewhat inherently stupid, since testing for equivalence may cost as much
00969 // as assignment.
00970 //      if ( *this != that )
00971         {
00972                 // First store the type of the input, At first I forgot to do this and it was a very
00973                 // difficult bug to track down
00974                 type = that.type;
00975 
00976 //              if ( type != this_type ) throw
00977 
00978 
00979                 switch (type)
00980                 {
00981                 case BOOL:
00982                         b = that.b;
00983                 break;
00984                 case SHORT:
00985                         si = that.si;
00986                 break;
00987                 case INT:
00988                         n = that.n;
00989                 break;
00990                 case UNSIGNEDINT:
00991                         ui = that.ui;
00992                 break;
00993                 case FLOAT:
00994                         f = that.f;
00995                 break;
00996                 case DOUBLE:
00997                         d = that.d;
00998                 break;
00999                 case CTF:
01000                 case STRING:
01001                         str = that.str;
01002                 break;
01003                 case FLOAT_POINTER:
01004                         // Warning - Pointer address copy.
01005                         fp = that.fp;
01006                 break;
01007                 case INT_POINTER:
01008                 // Warning - Pointer address copy.
01009                         ip = that.ip;
01010                 break;
01011                 case VOID_POINTER:
01012                         // Warning - Pointer address copy.
01013                         vp = that.vp;
01014                 break;
01015                 case EMDATA:
01016                         // Warning - Pointer address copy.
01017                         emdata = that.emdata;
01018                 break;
01019                 case XYDATA:
01020                         // Warning - Pointer address copy.
01021                         xydata = that.xydata;
01022                 break;
01023                 case TRANSFORM:
01024                 case FLOATARRAY:
01025                         farray = that.farray;
01026                 break;
01027                 case INTARRAY:
01028                         iarray = that.iarray;
01029                 break;
01030                 case STRINGARRAY:
01031                         strarray = that.strarray;
01032                 break;
01033                 case TRANSFORMARRAY:
01034                         transformarray = that.transformarray;
01035                 break;
01036                 case UNKNOWN:
01037                         // This is possible, nothing should happen
01038                         // The EMObject's default constructor has been called and
01039                         // as yet has no type - doing nothing is exactly as the
01040                         // the assignment operator should work.
01041                 break;
01042                 default:
01043                         LOGERR("No such EMObject defined");
01044                         throw NotExistingObjectException("EMObject", "unknown type");
01045                 break;
01046                 }
01047         }
01048 //      else
01049 //      {
01050 //              cerr << "Warning - attempt to assign EMObject onto itself. No action taken" << endl;
01051 //              cerr << "My type is " << get_object_type_name(type) << endl;
01052 //      }
01053 
01054         return *this;
01055 }
01056 
01057 //-------------------------------TypeDict--------------------------------------------
01058 
01059 void TypeDict::dump()
01060 {
01061         map < string, string >::iterator p;
01062         for (p = type_dict.begin(); p != type_dict.end(); p++) {
01063                 printf("\t%s    %s  %s\n",
01064                            p->first.c_str(), p->second.c_str(), desc_dict[p->first].c_str());
01065         }
01066 }
01067 
01068 //-------------------------------Dict--------------------------------------------
01069 
01070 Dict::Dict(const Dict& that)
01071 {
01072         *this = that;
01073 }
01074 
01075 Dict& Dict::operator=(const Dict& that)
01076 {
01077         if ( this != &that )
01078         {
01079                 dict.clear();
01080                 copy(that.begin(), that.end(), inserter(dict, dict.begin()));
01081                 // or use this
01082                 // dict.insert( that.begin(), that.end());
01083         }
01084         else
01085         {
01086                 cerr << "Warning - attempted to assign a Dict object to itself. No action taken" << endl;
01087         }
01088 
01089         return *this;
01090 }
01091 
01092 bool EMAN::operator==(const Dict& d1, const Dict& d2)
01093 {
01094         // Just make use of map's version of operator==
01095         return (d1.dict == d2.dict);
01096 }
01097 
01098 bool EMAN::operator!=(const Dict& d1, const Dict& d2)
01099 {
01100         return !(d1 == d2);
01101 }
01102 
01103 
01104 // Iterator support
01105 // This is just a wrapper, everything is inherited from the map<string,EMObject>::iterator
01106 // so the interface is the same as you would expect
01107 // iterator support added by d.woolford May 2007
01108 
01109 Dict::iterator Dict::begin( void )
01110 {
01111         return iterator( dict.begin() );
01112 }
01113 
01114 Dict::const_iterator Dict::begin( void ) const
01115 {
01116         return const_iterator( (map < string, EMObject >::const_iterator) dict.begin() );
01117 }
01118 
01119 // Wraps map.find(const string& key)
01120 Dict::iterator Dict::find( const string& key )
01121 {
01122         return iterator( dict.find(key) );
01123 }
01124 
01125 Dict::iterator Dict::end( void )
01126 {
01127         return iterator( dict.end() );
01128 }
01129 
01130 Dict::const_iterator Dict::end( void ) const
01131 {
01132         return const_iterator( (map < string, EMObject >::const_iterator)dict.end() );
01133 }
01134 
01135 Dict::const_iterator Dict::find( const string& key ) const
01136 {
01137         return const_iterator( (map < string, EMObject >::const_iterator)dict.find(key) );
01138 }
01139 
01140 //
01141 // iterator
01142 //
01143 Dict::iterator::iterator( map< string, EMObject >::iterator parent_it  ) :
01144         map< string, EMObject >::iterator( parent_it )
01145 {
01146 }
01147 
01148 
01149 Dict::iterator::iterator( const iterator& that ) :
01150         map < string, EMObject >::iterator( that )
01151 {
01152 }
01153 
01154 
01155 Dict::iterator& Dict::iterator::operator=( const iterator& that )
01156 {
01157         if( this != &that )
01158         {
01159                 map < string, EMObject >::iterator::operator=( that );
01160         }
01161         return *this;
01162 }
01163 
01164 //
01165 // const_iterator
01166 //
01167 
01168 Dict::const_iterator::const_iterator( const map < string, EMObject >::const_iterator parent_it  ) :
01169         map< string, EMObject >::const_iterator( parent_it )
01170 {
01171 }
01172 
01173 Dict::const_iterator::const_iterator( const Dict::iterator& it ) :
01174         map< string, EMObject >::const_iterator(it)
01175 {
01176 }
01177 
01178 Dict::const_iterator::const_iterator( const const_iterator& it ) :
01179         map< string, EMObject >::const_iterator(it)
01180 {
01181 }
01182 
01183 Dict::const_iterator& Dict::const_iterator::operator=( const const_iterator& that )
01184 {
01185         if( this != &that )
01186         {
01187                 map < string, EMObject >::const_iterator::operator=( that );
01188         }
01189         return *this;
01190 }
01191 
01192 EMObject Dict::get_ci(const string & key) const
01193 {
01194         string lower_key = Util::str_to_lower(key);
01195 
01196         for (map < string, EMObject >::const_iterator it = dict.begin(); it != dict.end(); ++it ) {
01197                 string lower = Util::str_to_lower(it->first);
01198                 if (lower == lower_key) return it->second;
01199         }
01200 
01201         throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
01202 }
01203 
01204 bool Dict::has_key_ci(const string & key) const
01205 {
01206         string lower_key = Util::str_to_lower(key);
01207 
01208         for (map < string, EMObject >::const_iterator it = dict.begin(); it != dict.end(); ++it ) {
01209                 string lower = Util::str_to_lower(it->first);
01210                 if (lower == lower_key) return true;
01211         }
01212         return false;
01213 }