00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00193
00194
00195
00196
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
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
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
00318
00319
00320
00321
00322
00323
00324
00325 return true;
00326 }
00327
00328 static abstract_product *create(const iofits & iof) {
00329
00330
00331 string val, comment;
00332 typename assoc_map::const_iterator i = instance().creators_.begin();
00333 bool match;
00334
00335
00336
00337 while(i!=instance().creators_.end()){
00338 match = true;
00339
00340
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
00347
00348
00349
00350
00351 if(!iof.key_exists(j->get_key().c_str())){
00352
00353 match = false;
00354 iof.movrel_hdu(-j->get_offset());
00355 break;
00356 }
00357
00358
00359
00360
00361 if(j->get_val().length()){
00362 iof.read_key(j->get_key().c_str(), val, comment);
00363 if(j->get_val()!=val){
00364
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