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[INT] = "INT";
00091                 mymap[UNSIGNEDINT] = "UNSIGNEDINT";
00092                 mymap[FLOAT] = "FLOAT";
00093                 mymap[DOUBLE] = "DOUBLE";
00094                 mymap[STRING] = "STRING";
00095                 mymap[EMDATA] = "EMDATA";
00096                 mymap[XYDATA] = "XYDATA";
00097                 mymap[INTARRAY] = "INTARRAY";
00098                 mymap[FLOATARRAY] = "FLOATARRAY";
00099                 mymap[STRINGARRAY] = "STRINGARRAY";
00100                 mymap[TRANSFORM] = "TRANFORM";
00101                 mymap[CTF] = "CTF";
00102                 mymap[FLOAT_POINTER] = "FLOAT_POINTER";
00103                 mymap[INT_POINTER] = "INT_POINTER";
00104                 mymap[UNKNOWN] = "UNKNOWN";
00105                 mymap[VOID_POINTER] = "VOID_POINTER";
00106                 first_construction = false;
00107         }
00108         
00109         return mymap;
00110 }
00111 
00112 //-------------------------------EMObject--------------------------------------------
00113 
00114 void EMObject::printInfo() const
00115 {
00116         cout << "The address of my type is " << &type << endl;
00117         cout << " Now printing the enumerated values in type_registry " << endl;
00118         for( map< ObjectType, string>::const_iterator it = type_registry.begin(); it != type_registry.end(); ++it )
00119         {
00120                 cout << it->first << " " << it->second << endl;
00121         }
00122         cout << "My type is " << to_str(type) << " and its enumerated value is " << type << endl;
00123         cout << "The address of the static type registry is " << &type_registry <<", it should be same for all EMObjects" << endl;
00124 }
00125 
00126 EMObject::~EMObject() {
00127 #ifdef MEMDEBUG
00128         allemobjlist.erase(this);
00129         printf("  -(%6d) %p\n",(int)allemobjlist.size(),this);
00130 #endif
00131 }
00132 
00133 EMObject::EMObject() :
00134         d(0), type(UNKNOWN)
00135 {
00136 #ifdef MEMDEBUG
00137         allemobjlist.insert(this);
00138         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00139 #endif
00140 }
00141 
00142 EMObject::EMObject(bool boolean) :
00143         b(boolean), type(BOOL)
00144 {
00145 #ifdef MEMDEBUG
00146         allemobjlist.insert(this);
00147         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00148 #endif
00149 }
00150 
00151 EMObject::EMObject(int num) :
00152         n(num), type(INT)
00153 {
00154 #ifdef MEMDEBUG
00155         allemobjlist.insert(this);
00156         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00157 #endif
00158 }
00159 
00160 EMObject::EMObject(unsigned int num) :
00161         ui(num), type(UNSIGNEDINT)
00162 {
00163 #ifdef MEMDEBUG
00164         allemobjlist.insert(this);
00165         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00166 #endif
00167 }
00168 
00169 EMObject::EMObject(float ff) :
00170         type(FLOAT)
00171 {
00172 
00173 #ifdef MEMDEBUG
00174         allemobjlist.insert(this);
00175         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00176 #endif
00177         if(Util::goodf(&ff)) {
00178                 f = ff;
00179         }
00180         else{
00181                 f = 0.0f;
00182         }
00183 }
00184 
00185 EMObject::EMObject(double dd) :
00186         type(DOUBLE)
00187 {
00188 
00189 #ifdef MEMDEBUG
00190         allemobjlist.insert(this);
00191         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00192 #endif
00193         if(Util::goodf(&dd)) {
00194                 d = dd;
00195         }
00196         else{
00197                 d = 0.0;
00198         }
00199 }
00200 
00201 EMObject::EMObject(const char *s) :
00202         str(s), type(STRING)
00203 {
00204 #ifdef MEMDEBUG
00205         allemobjlist.insert(this);
00206         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00207 #endif
00208 }
00209 
00210 EMObject::EMObject(const string & s) :
00211         str(s), type(STRING)
00212 {
00213 #ifdef MEMDEBUG
00214         allemobjlist.insert(this);
00215         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00216 #endif
00217 }
00218 
00219 EMObject::EMObject(float *f) :
00220         fp(f), type(FLOAT_POINTER)
00221 {
00222 #ifdef MEMDEBUG
00223         allemobjlist.insert(this);
00224         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00225 #endif
00226 }
00227 
00228 EMObject::EMObject(int *i) :
00229         ip(i), type(INT_POINTER)
00230 {
00231 #ifdef MEMDEBUG
00232         allemobjlist.insert(this);
00233         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00234 #endif
00235 }
00236 
00237 EMObject::EMObject(void *v) :
00238         vp(v), type(VOID_POINTER)
00239 {
00240 #ifdef MEMDEBUG
00241         allemobjlist.insert(this);
00242         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00243 #endif
00244 }
00245 
00246 EMObject::EMObject(EMData * em) :
00247         emdata(em), type(EMDATA)
00248 {
00249 #ifdef MEMDEBUG
00250         allemobjlist.insert(this);
00251         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00252 #endif
00253 }
00254 
00255 EMObject::EMObject(XYData * xy) :
00256         xydata(xy), type(XYDATA)
00257 {
00258 #ifdef MEMDEBUG
00259         allemobjlist.insert(this);
00260         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00261 #endif
00262 }
00263 
00264 EMObject::EMObject(Transform* t) :
00265         farray(t->get_matrix()), type(TRANSFORM)
00266 {
00267 #ifdef MEMDEBUG
00268         allemobjlist.insert(this);
00269         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00270 #endif
00271 }
00272 
00273 EMObject::EMObject(Ctf * ctf) :
00274         str(ctf->to_string()), type(CTF)
00275 {
00276 #ifdef MEMDEBUG
00277         allemobjlist.insert(this);
00278         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00279 #endif
00280 }
00281 
00282 EMObject::EMObject(const vector< int >& v ) :
00283         iarray(v), type(INTARRAY)
00284 {
00285 #ifdef MEMDEBUG
00286         allemobjlist.insert(this);
00287         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00288 #endif
00289 }
00290 
00291 EMObject::EMObject(const vector < float >&v) :
00292         farray(v), type(FLOATARRAY)
00293 {
00294 #ifdef MEMDEBUG
00295         allemobjlist.insert(this);
00296         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00297 #endif
00298 }
00299 
00300 EMObject:: EMObject(const vector <string>& sarray) :
00301         strarray(sarray), type(STRINGARRAY)
00302 {
00303 #ifdef MEMDEBUG
00304         allemobjlist.insert(this);
00305         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00306 #endif
00307 }
00308 
00309 EMObject::operator bool () const
00310 {
00311         if (type == BOOL) {
00312                 return b;
00313         }
00314         else if (type == INT) {
00315                 return n != 0;
00316         }
00317         else if (type == UNSIGNEDINT) {
00318                 return ui != 0;
00319         }
00320         else if (type == FLOAT) {
00321                 return f != 0;
00322         }
00323         else if (type == DOUBLE) {
00324                 return d != 0;
00325         }
00326         else if (type == EMDATA) {
00327                 return emdata != 0;
00328         }
00329         else if (type == XYDATA) {
00330                 return xydata != 0;
00331         }
00332         else if (type == FLOAT_POINTER) {
00333                 return fp != 0;
00334         }
00335         else if (type == INT_POINTER) {
00336                 return ip != 0;
00337         }
00338         else if (type == VOID_POINTER) {
00339                 return vp != 0;
00340         }
00341 //      else if (type == TRANSFORM) {
00342 //              return transform != 0;
00343 //      }
00344         // It seemed unconventional to return a boolean for the stl objects
00345         else {
00346                 if (type != UNKNOWN) {
00347                         throw TypeException("Cannot convert to bool this data type ",
00348                                                                 get_object_type_name(type));
00349                 }
00350         }
00351         return 0;
00352 }
00353 
00354 EMObject::operator int () const
00355 {
00356         if (type == INT) {
00357                 return n;
00358         }
00359         else if (type == UNSIGNEDINT) {
00360                 return (int) ui;
00361         }
00362         else if (type == FLOAT) {
00363                 return (int) f;
00364         }
00365         else if (type == DOUBLE) {
00366                 return (int) d;
00367         }
00368         else if (type == BOOL) {
00369                 return b?1:0;
00370         }
00371         else {
00372                 if (type != UNKNOWN) {
00373                         throw TypeException("Cannot convert to int this data type ",
00374                                                                 get_object_type_name(type));
00375                 }
00376         }
00377         return 0;
00378 }
00379 
00380 EMObject::operator unsigned int () const
00381 {
00382         if (type == UNSIGNEDINT) {
00383                 return (unsigned int) ui;
00384         }
00385         else {
00386                 if (type != UNKNOWN) {
00387                         throw TypeException("Cannot convert to int this data type ",
00388                                                                 get_object_type_name(type));
00389                 }
00390         }
00391         return 0;
00392 }
00393 
00394 EMObject::operator float () const
00395 {
00396         if (type == BOOL) {
00397                 return b?1.0f:0.0f;
00398         }
00399         else if (type == FLOAT) {
00400                 return f;
00401         }
00402         else if (type == INT) {
00403                 return (float) n;
00404         }
00405         else if (type == UNSIGNEDINT) {
00406                 return (float) ui;
00407         }
00408         else if (type == DOUBLE) {
00409                 return (float) d;
00410         }
00411         else {
00412                 if (type != UNKNOWN) {
00413                         throw TypeException("Cannot convert to float from this data type",
00414                                                                 get_object_type_name(type));
00415                 }
00416         }
00417 
00418         return 0;
00419 }
00420 
00421 EMObject::operator double () const
00422 {
00423         if (type == BOOL) {
00424         return b?1.0:0.0;
00425         }
00426         else if (type == DOUBLE) {
00427                 return d;
00428         }
00429         else if (type == INT) {
00430                 return (double) n;
00431         }
00432         else if (type == UNSIGNEDINT) {
00433                 return (double) ui;
00434         }
00435         else if (type == FLOAT) {
00436                 return (double) f;
00437         }
00438         else {
00439                 if (type != UNKNOWN) {
00440                         throw TypeException("Cannot convert to double from this data type",
00441                                                                 get_object_type_name(type));
00442                 }
00443         }
00444         return 0;
00445 }
00446 
00447 EMObject::operator int * () const
00448 {
00449         if (type != INT_POINTER)
00450         {
00451                 if (type != UNKNOWN)
00452                         throw TypeException("Cannot convert to float pointer from this data type",
00453                                                                 get_object_type_name(type));
00454 
00455                 return 0;
00456         }
00457 
00458         return ip;
00459 }
00460 
00461 
00462 EMObject::operator float * () const
00463 {
00464         if (type != FLOAT_POINTER)
00465         {
00466                 if (type != UNKNOWN)
00467                         throw TypeException("Cannot convert to float pointer from this data type",
00468                                                                 get_object_type_name(type));
00469 
00470                 return 0;
00471         }
00472 
00473         return fp;
00474 }
00475 
00476 // MAYBE REMOVE? FIXME
00477 EMObject::operator void * () const
00478 {
00479         if (type == VOID_POINTER) return vp;
00480         else if (type == FLOAT_POINTER) return (void *)fp;
00481         else if (type == INT_POINTER) return (void *)ip;
00482         else if (type == EMDATA) return (void *) emdata;
00483         else if (type == XYDATA) return (void *) xydata;
00484 //      else if (type == TRANSFORM) return (void *) transform;
00485         else throw TypeException("Cannot convert to void pointer from this data type", get_object_type_name(type));
00486 }
00487 
00488 EMObject::operator const char * () const
00489 {
00490         if (type != STRING && type != CTF) {
00491                 stringstream ss;
00492                 string return_string;
00493                 if ( type == INT )
00494                 {
00495                         ss << n;
00496                         ss >> return_string;
00497                         return return_string.c_str();
00498                 }
00499                 if ( type == UNSIGNEDINT )
00500                 {
00501                         ss << ui;
00502                         ss >> return_string;
00503                         return return_string.c_str();
00504                 }
00505                 else
00506                 if ( type == FLOAT )
00507                 {
00508                         ss << f;
00509                         ss >> return_string;
00510                         return return_string.c_str();
00511                 }
00512                 else
00513                 if ( type == DOUBLE )
00514                 {
00515                         ss << d;
00516                         ss >> return_string;
00517                         return return_string.c_str();
00518                 }
00519                 else if (type != UNKNOWN) {
00520                         throw TypeException("Cannot convert to string from this data type",
00521                                                                 get_object_type_name(type));
00522                 }
00523 
00524                 return "";
00525         }
00526         return str.c_str();
00527 }
00528 
00529 EMObject::operator EMData * () const
00530 {
00531         if (type != EMDATA) {
00532                 if (type != UNKNOWN) {
00533                         throw TypeException("Cannot convert to EMData* from this data type",
00534                                    get_object_type_name(type));
00535                 }
00536                 return 0;
00537         }
00538         return emdata;
00539 }
00540 
00541 EMObject::operator XYData * () const
00542 {
00543         if (type != XYDATA) {
00544                 if (type != UNKNOWN) {
00545                         throw TypeException("Cannot convert to XYData* from this data type",
00546                                    get_object_type_name(type));
00547                 }
00548                 return 0;
00549         }
00550         return xydata;
00551 }
00552 
00553 EMObject::operator Transform* () const
00554 {
00555         if(type != TRANSFORM) {
00556                 if(type != UNKNOWN) {
00557                         throw TypeException("Cannot convert to TRANSFORM* from this data type",
00558                                                                 get_object_type_name(type));
00559                 }
00560         }
00561         Transform * transform = new Transform();
00562         transform->set_matrix(farray);
00563         return transform;
00564 }
00565 
00566 EMObject::operator Ctf* () const
00567 {
00568 /*      if(type != CTF) {
00569                 if(type != CTF) {
00570                         throw TypeException("Cannot convert to TRANSFORM* from this data type",
00571                                                                 get_object_type_name(type));
00572                 }
00573         }*/
00574         Ctf * ctf = 0;
00575         if(str[0] == 'O') {
00576                 ctf = new EMAN1Ctf();
00577                 ctf->from_string(str);
00578         }
00579         else if(str[0] == 'E') {
00580                 ctf = new EMAN2Ctf();
00581                 ctf->from_string(str);
00582         }
00583         return ctf;
00584 }
00585 
00586 EMObject::operator vector<int>() const
00587 {
00588     if( type != INTARRAY )
00589     {
00590         if( type != UNKNOWN ) {
00591                 throw TypeException("Cannot convert to vector<int> from this data type", get_object_type_name(type) );
00592                 }
00593                 return vector<int>();
00594     }
00595     return iarray;
00596 }
00597 
00598 EMObject::operator vector < float > () const
00599 {
00600         if (type != FLOATARRAY) {
00601                 if (type != UNKNOWN) {
00602                         throw TypeException("Cannot convert to vector<float> from this data type",
00603                                                                 get_object_type_name(type));
00604                 }
00605                 return vector < float >();
00606         }
00607         return farray;
00608 }
00609 
00610 EMObject::operator vector<string> () const
00611 {
00612         if (type != STRINGARRAY) {
00613                 if (type != UNKNOWN) {
00614                         throw TypeException("Cannot convert to vector<string> from this data type",
00615                                                                 get_object_type_name(type));
00616                 }
00617                 return vector<string>();
00618         }
00619         return strarray;
00620 }
00621 
00622 bool EMObject::is_null() const
00623 {
00624         return (type == UNKNOWN);
00625 }
00626 
00627 string EMObject::to_str() const
00628 {
00629         return to_str(type);
00630 }
00631 
00632 string EMObject::to_str(ObjectType argtype) const
00633 {
00634         if (argtype == STRING) {
00635                 return str;
00636         }
00637         else {
00638                 char tmp_str[32];
00639                 if (argtype == BOOL) {
00640                         if (b)
00641                                 sprintf(tmp_str, "true");
00642                         else
00643                                 sprintf(tmp_str, "false");
00644                 }
00645                 else if (argtype == INT) {
00646                         sprintf(tmp_str, "%d", n);
00647                 }
00648                 else if (argtype == UNSIGNEDINT) {
00649                         sprintf(tmp_str, "%d", ui);
00650                 }
00651                 else if (argtype == FLOAT) {
00652                         sprintf(tmp_str, "%f", f);
00653                 }
00654                 else if (argtype == DOUBLE) {
00655                         sprintf(tmp_str, "%f", d);
00656                 }
00657                 else if (argtype == EMDATA) {
00658                         sprintf(tmp_str, "EMDATA");
00659                 }
00660                 else if (argtype == FLOAT_POINTER) {
00661                         sprintf(tmp_str, "FLOAT_POINTER");
00662                 }
00663                 else if (argtype == INT) {
00664                         sprintf(tmp_str, "INT_POINTER");
00665                 }
00666                 else if (argtype == VOID_POINTER) {
00667                         sprintf(tmp_str, "VOID_POINTER");
00668                 }
00669                 else if (argtype == XYDATA) {
00670                         sprintf(tmp_str, "XYDATA");
00671                 }
00672                 else if (argtype == INTARRAY) {
00673                         sprintf(tmp_str, "INTARRAY");
00674                 }
00675                 else if (argtype == FLOATARRAY) {
00676                         sprintf(tmp_str, "FLOATARRAY");
00677                 }
00678                 else if (argtype == STRINGARRAY) {
00679                         sprintf(tmp_str, "STRINGARRAY");
00680                 }
00681                 else if (argtype == TRANSFORM) {
00682                         sprintf(tmp_str, "TRANSFORMD");
00683                 }
00684                 else if (argtype == CTF) {
00685                         sprintf(tmp_str, "CTF");
00686                 }
00687                 else if (argtype == UNKNOWN) {
00688                         sprintf(tmp_str, "UNKNOWN");
00689                 }
00690                 else {
00691                         LOGERR("No such EMObject defined");
00692                         throw NotExistingObjectException("EMObject", "unknown type");
00693                 }
00694                 return string(tmp_str);
00695         }
00696 }
00697 
00698 string EMObject::get_object_type_name(ObjectType t)
00699 {
00700 #ifdef _WIN32
00701         if (t == BOOL) {
00702                 return "BOOL";
00703         }else
00704         if ( t == INT){
00705                 return "INT";
00706         }else
00707         if ( t == UNSIGNEDINT){
00708                 return "UNSIGNEDINT";
00709         } else
00710         if ( t == FLOAT){
00711                 return "FLOAT";
00712         } else
00713         if ( t == DOUBLE){
00714                 return "DOUBLE";
00715         }else
00716         if ( t == STRING){
00717                 return "STRING";
00718         }else
00719         if ( t == EMDATA){
00720                 return "EMDATA";
00721         }
00722         else
00723         if ( t == XYDATA){
00724                 return "XYDATA";
00725         }else
00726         if ( t == INTARRAY){
00727                 return "INTARRAY";
00728         }else
00729         if ( t == FLOATARRAY){
00730                 return "FLOATARRAY";
00731         } else
00732         if ( t == STRINGARRAY){
00733                 return "STRINGARRAY";
00734         }else
00735         if ( t == TRANSFORM){
00736                 return "TRANSFORM";
00737         }else
00738         if ( t == CTF){
00739                 return "CTF";
00740         }else
00741         if ( t == FLOAT_POINTER){
00742                 return "FLOAT_POINTER";
00743         }else
00744         if ( t == INT_POINTER){
00745                 return "INT_POINTER";
00746         }else
00747         if ( t == UNKNOWN){
00748                 return "UNKNOWN";
00749         } else
00750         if ( t == VOID_POINTER){
00751                 return "VOID_POINTER";
00752         }
00753         else {
00754                 LOGERR("No such EMObject defined");
00755                 throw NotExistingObjectException("EMObject", "unknown type");
00756         }
00757 
00758 #else
00759 
00760         if  ( type_registry.find(t) != type_registry.end() )
00761                 return type_registry[t];
00762         else
00763                 LOGERR("No such EMObject defined");
00764                 throw NotExistingObjectException("EMObject", "unknown type");
00765 #endif  //_WIN32
00766 }
00767 
00768 bool EMAN::operator==(const EMObject &e1, const EMObject & e2)
00769 {
00770 
00771         if (e1.type != e2.type) {
00772                 return false;
00773         }
00774 
00775         switch (e1.type) {
00776         case  EMObject::BOOL:
00777                 return (e1.b == e2.b);
00778         break;
00779         case  EMObject::INT:
00780                 return (e1.n == e2.n);
00781         break;
00782         case  EMObject::UNSIGNEDINT:
00783                 return (e1.ui == e2.ui);
00784         break;
00785         case  EMObject::FLOAT:
00786                 return (e1.f == e2.f);
00787         break;
00788         case  EMObject::DOUBLE:
00789                 return (e1.d == e2.d);
00790         break;
00791         case EMObject::CTF:
00792         case  EMObject::STRING:
00793                 return (e1.str == e2.str);
00794         break;
00795         case  EMObject::FLOAT_POINTER:
00796                 return (e1.fp == e2.fp);
00797         break;
00798         case  EMObject::INT_POINTER:
00799                 return (e1.ip == e2.ip);
00800         break;
00801         case  EMObject::VOID_POINTER:
00802                 return (e1.vp == e2.vp);
00803         break;
00804         case  EMObject::EMDATA:
00805                 return (e1.emdata == e2.emdata);
00806         break;
00807         case  EMObject::XYDATA:
00808                 return (e1.xydata == e2.xydata);
00809         break;
00810         case  EMObject::TRANSFORM:
00811         case  EMObject::FLOATARRAY:
00812                 if (e1.farray.size() == e2.farray.size()) {
00813                         for (size_t i = 0; i < e1.farray.size(); i++) {
00814                                 if (e1.farray[i] != e2.farray[i]) {
00815                                         return false;
00816                                 }
00817                         }
00818                         return true;
00819                 }
00820                 else {
00821                         return false;
00822                 }
00823         break;
00824         case  EMObject::INTARRAY:
00825                 if (e1.iarray.size() == e2.iarray.size()) {
00826                         for (size_t i = 0; i < e1.iarray.size(); i++) {
00827                                 if (e1.iarray[i] != e2.iarray[i]) {
00828                                         return false;
00829                                 }
00830                         }
00831                         return true;
00832                 }
00833         break;
00834         case  EMObject::STRINGARRAY:
00835                 if (e1.strarray.size() == e2.strarray.size()) {
00836                         for (size_t i = 0; i < e1.strarray.size(); i++) {
00837                                 if (e1.strarray[i] != e2.strarray[i]) {
00838                                         return false;
00839                                 }
00840                         }
00841                         return true;
00842                 }
00843                 else {
00844                         return false;
00845                 }
00846         break;
00847         case  EMObject::UNKNOWN:
00848                 // UNKNOWN really means "no type" and if two objects both have
00849                 // type UNKNOWN they really are the same
00850                 return (e1.type == e2.type);
00851         break;
00852         default:
00853                 return false;
00854         break;
00855         }
00856         return false;
00857 }
00858 
00859 bool EMAN::operator!=(const EMObject &e1, const EMObject & e2)
00860 {
00861         return !(e1 == e2);
00862 }
00863 
00864 // Copy constructor
00865 EMObject::EMObject(const EMObject& that)
00866 {
00867         // init isn't necessary because that must have already called it!
00868         *this = that;
00869 #ifdef MEMDEBUG
00870         allemobjlist.insert(this);
00871         printf("  +(%6d) %p\n",(int)allemobjlist.size(),this);
00872 #endif
00873 }
00874 
00875 
00876 // Assignment operator -  - copies only the variable associated with the type of the argument.
00877 // It would be possible just to do a dumb copy of everything, but that seems opposed to
00878 // the concept of an EMObject, which is always of a single type.
00879 EMObject& EMObject::operator=( const EMObject& that )
00880 {
00881 
00882 // This test breaks assignment when either the current or assigned values are (float)nan
00883 // it's also somewhat inherently stupid, since testing for equivalence may cost as much
00884 // as assignment.
00885 //      if ( *this != that )
00886         {
00887                 // First store the type of the input, At first I forgot to do this and it was a very
00888                 // difficult bug to track down
00889                 type = that.type;
00890 
00891 //              if ( type != this_type ) throw
00892 
00893 
00894                 switch (type)
00895                 {
00896                 case BOOL:
00897                         b = that.b;
00898                 break;
00899                 case INT:
00900                         n = that.n;
00901                 break;
00902                 case UNSIGNEDINT:
00903                         ui = that.ui;
00904                 break;
00905                 case FLOAT:
00906                         f = that.f;
00907                 break;
00908                 case DOUBLE:
00909                         d = that.d;
00910                 break;
00911                 case CTF:
00912                 case STRING:
00913                         str = that.str;
00914                 break;
00915                 case FLOAT_POINTER:
00916                         // Warning - Pointer address copy.
00917                         fp = that.fp;
00918                 break;
00919                 case INT_POINTER:
00920                 // Warning - Pointer address copy.
00921                         ip = that.ip;
00922                 break;
00923                 case VOID_POINTER:
00924                         // Warning - Pointer address copy.
00925                         vp = that.vp;
00926                 break;
00927                 case EMDATA:
00928                         // Warning - Pointer address copy.
00929                         emdata = that.emdata;
00930                 break;
00931                 case XYDATA:
00932                         // Warning - Pointer address copy.
00933                         xydata = that.xydata;
00934                 break;
00935                 case TRANSFORM:
00936                 case FLOATARRAY:
00937                         farray = that.farray;
00938                 break;
00939                 case INTARRAY:
00940                         iarray = that.iarray;
00941                 break;
00942                 case STRINGARRAY:
00943                         strarray = that.strarray;
00944                 break;
00945                 case UNKNOWN:
00946                         // This is possible, nothing should happen
00947                         // The EMObject's default constructor has been called and
00948                         // as yet has no type - doing nothing is exactly as the
00949                         // the assignment operator should work.
00950                 break;
00951                 default:
00952                         LOGERR("No such EMObject defined");
00953                         throw NotExistingObjectException("EMObject", "unknown type");
00954                 break;
00955                 }
00956         }
00957 //      else
00958 //      {
00959 //              cerr << "Warning - attempt to assign EMObject onto itself. No action taken" << endl;
00960 //              cerr << "My type is " << get_object_type_name(type) << endl;
00961 //      }
00962 
00963         return *this;
00964 }
00965 
00966 //-------------------------------TypeDict--------------------------------------------
00967 
00968 void TypeDict::dump()
00969 {
00970         map < string, string >::iterator p;
00971         for (p = type_dict.begin(); p != type_dict.end(); p++) {
00972                 printf("\t%s    %s  %s\n",
00973                            p->first.c_str(), p->second.c_str(), desc_dict[p->first].c_str());
00974         }
00975 }
00976 
00977 //-------------------------------Dict--------------------------------------------
00978 
00979 Dict::Dict(const Dict& that)
00980 {
00981         *this = that;
00982 }
00983 
00984 Dict& Dict::operator=(const Dict& that)
00985 {
00986         if ( this != &that )
00987         {
00988                 dict.clear();
00989                 copy(that.begin(), that.end(), inserter(dict, dict.begin()));
00990                 // or use this
00991                 // dict.insert( that.begin(), that.end());
00992         }
00993         else
00994         {
00995                 cerr << "Warning - attempted to assign a Dict object to itself. No action taken" << endl;
00996         }
00997 
00998         return *this;
00999 }
01000 
01001 bool EMAN::operator==(const Dict& d1, const Dict& d2)
01002 {
01003         // Just make use of map's version of operator==
01004         return (d1.dict == d2.dict);
01005 }
01006 
01007 bool EMAN::operator!=(const Dict& d1, const Dict& d2)
01008 {
01009         return !(d1 == d2);
01010 }
01011 
01012 
01013 // Iterator support
01014 // This is just a wrapper, everything is inherited from the map<string,EMObject>::iterator
01015 // so the interface is the same as you would expect
01016 // iterator support added by d.woolford May 2007
01017 
01018 Dict::iterator Dict::begin( void )
01019 {
01020         return iterator( dict.begin() );
01021 }
01022 
01023 Dict::const_iterator Dict::begin( void ) const
01024 {
01025         return const_iterator( (map < string, EMObject >::const_iterator) dict.begin() );
01026 }
01027 
01028 // Wraps map.find(const string& key)
01029 Dict::iterator Dict::find( const string& key )
01030 {
01031         return iterator( dict.find(key) );
01032 }
01033 
01034 Dict::iterator Dict::end( void )
01035 {
01036         return iterator( dict.end() );
01037 }
01038 
01039 Dict::const_iterator Dict::end( void ) const
01040 {
01041         return const_iterator( (map < string, EMObject >::const_iterator)dict.end() );
01042 }
01043 
01044 Dict::const_iterator Dict::find( const string& key ) const
01045 {
01046         return const_iterator( (map < string, EMObject >::const_iterator)dict.find(key) );
01047 }
01048 
01049 //
01050 // iterator
01051 //
01052 Dict::iterator::iterator( map< string, EMObject >::iterator parent_it  ) :
01053         map< string, EMObject >::iterator( parent_it )
01054 {
01055 }
01056 
01057 
01058 Dict::iterator::iterator( const iterator& that ) :
01059         map < string, EMObject >::iterator( that )
01060 {
01061 }
01062 
01063 
01064 Dict::iterator& Dict::iterator::operator=( const iterator& that )
01065 {
01066         if( this != &that )
01067         {
01068                 map < string, EMObject >::iterator::operator=( that );
01069         }
01070         return *this;
01071 }
01072 
01073 //
01074 // const_iterator
01075 //
01076 
01077 Dict::const_iterator::const_iterator( const map < string, EMObject >::const_iterator parent_it  ) :
01078         map< string, EMObject >::const_iterator( parent_it )
01079 {
01080 }
01081 
01082 Dict::const_iterator::const_iterator( const Dict::iterator& it ) :
01083         map< string, EMObject >::const_iterator(it)
01084 {
01085 }
01086 
01087 Dict::const_iterator::const_iterator( const const_iterator& it ) :
01088         map< string, EMObject >::const_iterator(it)
01089 {
01090 }
01091 
01092 Dict::const_iterator& Dict::const_iterator::operator=( const const_iterator& that )
01093 {
01094         if( this != &that )
01095         {
01096                 map < string, EMObject >::const_iterator::operator=( that );
01097         }
01098         return *this;
01099 }
01100 
01101 EMObject Dict::get_ci(const string & key) const
01102 {
01103         string lower_key = Util::str_to_lower(key);
01104 
01105         for (map < string, EMObject >::const_iterator it = dict.begin(); it != dict.end(); ++it ) {
01106                 string lower = Util::str_to_lower(it->first);
01107                 if (lower == lower_key) return it->second;
01108         }
01109 
01110         throw NotExistingObjectException("EMObject", "Nonexisting key (" + key + ") in Dict");
01111 }
01112 
01113 bool Dict::has_key_ci(const string & key) const
01114 {
01115         string lower_key = Util::str_to_lower(key);
01116 
01117         for (map < string, EMObject >::const_iterator it = dict.begin(); it != dict.end(); ++it ) {
01118                 string lower = Util::str_to_lower(it->first);
01119                 if (lower == lower_key) return true;
01120         }
01121         return false;
01122 }

Generated on Mon Jul 19 12:40:10 2010 for EMAN2 by  doxygen 1.4.7