Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

fits_factory.h

Go to the documentation of this file.
00001 /*
00002 Arroyo - software for the simulation of electromagnetic wave propagation
00003 through turbulence and optics.
00004 
00005 Copyright (c) 2000-2004 California Institute of Technology.  Written by
00006 Dr. Matthew Britton.  For comments or questions about this software,
00007 please contact the author at mbritton@astro.caltech.edu.
00008 
00009 This program is free software; you can redistribute it and/or modify it
00010 under the terms of the GNU General Public License as  published by the
00011 Free Software Foundation; either version 2 of the License, or (at your
00012 option) any later version.
00013 
00014 This program is provided "as is" and distributed in the hope that it
00015 will be useful, but WITHOUT ANY WARRANTY; without even the implied
00016 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  In no
00017 event shall California Institute of Technology be liable to any party
00018 for direct, indirect, special, incidental or consequential damages,
00019 including lost profits, arising out of the use of this software and its
00020 documentation, even if the California Institute of Technology has been
00021 advised of the possibility of such damage.   The California Institute of
00022 Technology has no obligation to provide maintenance, support, updates,
00023 enhancements or modifications.  See the GNU General Public License for
00024 more details.
00025 
00026 You should have received a copy of the GNU General Public License along
00027 with this program; if not, write to the Free Software
00028 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00029 */
00030 
00031 #ifndef FITS_FACTORY_H
00032 #define FITS_FACTORY_H
00033 
00034 #include <map>
00035 #include <string>
00036 #include <vector>
00037 #include <iterator>
00038 #include <iostream>
00039 #include "iofits.h"
00040 
00041 namespace Arroyo {
00042 
00043   using std::string;
00044   using std::vector;
00045   using std::cerr;
00046   using std::cout;
00047   using std::endl;
00048 
00049   class iofits;
00050 
00051 
00056 
00057   class fits_keyval_entry {
00058 
00059   private:
00060 
00063     fits_keyval_entry(){};
00064 
00065   protected:
00066 
00068     int header_offset;
00069 
00070     string key;
00071     string val;
00072 
00073   public:
00074 
00077     fits_keyval_entry(const string & k, const string & v, int hdr_offset = 0) {
00078       if(hdr_offset<0){
00079         cerr << "fits_keyval_entry::fits_keyval_entry error - "
00080                   << "could not initialize fits_keyval_entry with header offset "
00081                   << hdr_offset << endl;
00082         throw(string("fits_keyval_entry::fits_keyval_entry"));
00083       }
00084       header_offset = hdr_offset;
00085       key = k;
00086       val = v;
00087     }
00088 
00091     fits_keyval_entry(const fits_keyval_entry & fkve) {
00092       this->operator=(fkve);
00093     }
00094 
00097     ~fits_keyval_entry(){};
00098 
00101     fits_keyval_entry & operator=(const fits_keyval_entry & fkve){
00102       if(this==&fkve) return(*this);
00103       header_offset = fkve.header_offset;
00104       key = fkve.key;
00105       val = fkve.val;
00106       return(*this);
00107     }
00108 
00111     int get_offset() const {return(header_offset);};
00112     
00115     string get_key() const {return(key);};
00116 
00119     string get_val() const {return(val);};
00120 
00123     void print(std::ostream & os) const {
00124       os << "\t" << key << "\t" << val
00125          << "\tHDU offset " << header_offset << "\t" 
00126          << endl;
00127     }
00128 
00132     friend bool operator<(const fits_keyval_entry & kve1, 
00133                           const fits_keyval_entry & kve2){
00134       if(kve1.header_offset<kve2.header_offset) return(true);
00135       return(false);
00136     }
00137 
00140     friend bool operator==(const fits_keyval_entry &f1, const fits_keyval_entry &f2){
00141       if(f1.header_offset!=f2.header_offset) return(false);
00142       if(f1.key!=f2.key) return(false);
00143       if(f1.val!=f2.val) return(false);
00144       return(true);
00145     }
00146   };
00147 
00148 
00151 
00152   class fits_keyval_set :
00153     public vector<fits_keyval_entry> {
00154 
00155   public:
00156 
00159     fits_keyval_set(){}
00160 
00163     fits_keyval_set(const fits_keyval_set & fkvs) {
00164       this->operator=(fkvs);
00165     }
00166 
00169     ~fits_keyval_set(){};
00170 
00173     fits_keyval_set & operator=(const fits_keyval_set & fkvs){
00174       if(this==&fkvs) return(*this);
00175       this->vector<fits_keyval_entry>::operator=(fkvs);
00176       return(*this);
00177     }
00178 
00181     void print(std::ostream & os) const {      
00182       for(int i=0; i<this->size(); i++)
00183         (*this)[i].print(os);
00184     };
00185 
00188     friend bool operator<(const fits_keyval_set & kvs1, 
00189                           const fits_keyval_set & kvs2){
00190       return(true);
00191       /*
00192       cout << "op<\n";
00193       if(kvs1.size()<kvs2.size()) return(true);
00194       for(int i=0; i<kvs1.size(); i++)
00195         if(kvs1[i]<kvs2[i]) return(true);
00196       return(false);
00197       */
00198     }
00199 
00202     friend bool operator==(const fits_keyval_set &s1, const fits_keyval_set &s2){
00203       s1.print(cout);
00204       cout << endl;
00205       s2.print(cout);
00206       cout << endl << endl;
00207 
00208       if(s1.size()!=s2.size()) return(false);
00209       for(int i=0; i<s1.size(); i++)
00210         if(!(s1[i]==s2[i])) return(false);
00211       return(true);
00212     }
00213   };
00214 
00260 
00261   template<class abstract_product>
00262   class fits_factory {
00263 
00264   private:
00265 
00268     fits_factory(){};
00269 
00272     ~fits_factory(){};
00273 
00274     static fits_factory &instance()
00275       {
00276         static fits_factory f;
00277         return f;
00278       };
00279   
00280     typedef std::map<fits_keyval_set, 
00281       abstract_product *(*)(const iofits &) > assoc_map;
00282 
00286     assoc_map creators_;
00287 
00288   public:
00289 
00290     static bool Register(const fits_keyval_set &fkvs, 
00291                          abstract_product *(*creator)(const iofits &) ) {
00292         
00293       //typedef std::pair<const std::map<const std::string, std::string>, abstract_product *(*)(const char * )> value_type;
00294       
00295       /*
00296         std::cout << "called register creator\n";
00297         assoc_map::const_iterator e = instance().creators_.end();
00298         assoc_map::const_iterator i = instance().creators_.find(fits_keyval_map);
00299         if(i!=e){
00300         cout << "keyval map already registered\n";
00301           throw(string("fits_factory::register"));
00302           }
00303       */
00304         
00305       //fits_keyval_entries entries(fkves);
00306       //std::sort(entries.begin(), entries.end());
00307 
00308       //cout << "REGISTERING\n";
00309       //fkvs.print(cout);
00310 
00311       if(!(instance().creators_.insert(typename assoc_map::value_type(fkvs, creator))).second){
00312         cerr << "fits_factory::Register error - could not register class\n";
00313         fkvs.print(cerr);
00314         throw(string("fits_factory::Register"));
00315       }
00316       /*
00317       cout << "REGISTERED\n";
00318       typename assoc_map::const_iterator i = instance().creators_.begin();
00319       while(i!=instance().creators_.end()){
00320         i->first.print(cout);
00321         cout << endl << endl;
00322         i++;
00323       } 
00324       */     
00325       return true;
00326     }
00327     
00328     static abstract_product *create(const iofits & iof) {
00329       // iterate through the entries in the assoc_map, 
00330       // checking for a match
00331       string val, comment;
00332       typename assoc_map::const_iterator i = instance().creators_.begin();
00333       bool match;
00334 
00335       //cout << "checking " << instance().creators_.size() << " entries\n";
00336 
00337       while(i!=instance().creators_.end()){
00338         match = true;
00339 
00340         //cout << "checking " << i->first.size() << " fits_keyval_entries\n";
00341 
00342         fits_keyval_set::const_iterator j = (i->first).begin();
00343         while(j!=(i->first).end()){
00344           iof.movrel_hdu(j->get_offset());
00345           /*
00346           cout << "checking key x" << j->get_key() << "x"
00347                << " val x" << j->get_val() << "x"
00348                << " hdu offset " << j->get_offset()
00349                << endl;
00350           */
00351           if(!iof.key_exists(j->get_key().c_str())){
00352             //cout << "\tcould not find key " << j->get_key() << endl;
00353             match = false;
00354             iof.movrel_hdu(-j->get_offset());
00355             break;
00356           }
00357           // Here if the second entry in the map is empty
00358           // we assume that the existence of the first
00359           // key in the header is what the user wants to test.
00360           // So we skip checking the value
00361           if(j->get_val().length()){
00362             iof.read_key(j->get_key().c_str(), val, comment);
00363             if(j->get_val()!=val){
00364               //cout << "\tfound val " << val << " rather than val " << j->get_val() << endl;
00365               match = false;
00366               iof.movrel_hdu(-j->get_offset());
00367               break;
00368             }
00369           }
00370           iof.movrel_hdu(-j->get_offset());
00371           j++;
00372         }
00373         if(match) return (i->second)(iof);
00374         i++;
00375       }
00376       cout << "fits_factory_create error - "
00377            << "could not find matching map in fits header - registered entries:\n\n";
00378       i = instance().creators_.begin();
00379       while(i!=instance().creators_.end()){
00380         i->first.print(cout);
00381         cout << endl << endl;
00382         i++;
00383       }
00384       throw string("fits_factory::create");
00385     }    
00386   };
00387 
00388 }
00389 #endif 
00390 

Generated on Thu Nov 29 17:16:29 2007 for arroyo by  doxygen 1.3.9.1