| [2820] | 1 | #include "machdefs.h" | 
|---|
|  | 2 | #include "sopnamsp.h" | 
|---|
|  | 3 |  | 
|---|
|  | 4 | #include <stdio.h> | 
|---|
|  | 5 | #include <string.h> | 
|---|
|  | 6 | #include <iostream> | 
|---|
|  | 7 | #include <typeinfo> | 
|---|
|  | 8 |  | 
|---|
|  | 9 | #include "fitsmanager.h" | 
|---|
|  | 10 | #include "fitshandler.h" | 
|---|
|  | 11 |  | 
|---|
|  | 12 | struct hand_list_el { | 
|---|
|  | 13 | FitsHandlerInterface * fhi; | 
|---|
| [2895] | 14 | int glev; | 
|---|
|  | 15 | string desc; | 
|---|
| [2820] | 16 | }; | 
|---|
|  | 17 |  | 
|---|
|  | 18 | typedef list<hand_list_el> HandlerList; | 
|---|
|  | 19 |  | 
|---|
|  | 20 | static HandlerList * hlistp = NULL; | 
|---|
|  | 21 |  | 
|---|
|  | 22 | static inline void ChkHLP() | 
|---|
|  | 23 | { | 
|---|
| [2843] | 24 | if (hlistp == NULL) hlistp = new HandlerList; | 
|---|
| [2820] | 25 | } | 
|---|
| [2895] | 26 | /*! | 
|---|
| [2932] | 27 | Generic handlers (ImageHDU, TableHDU) will have a higher global priority level | 
|---|
|  | 28 | than specific handlers. Use glev=0 for specific handlers and glev=1 for generic | 
|---|
|  | 29 | handlers. | 
|---|
| [2895] | 30 | \param fhi : handler object pointer (created by new) which will be kept in the | 
|---|
|  | 31 | handler list | 
|---|
|  | 32 | \param glev : global priority level associated with the handler. Used when different | 
|---|
|  | 33 | handlers return the same value for CheckHandling() or CheckReadability(). | 
|---|
|  | 34 | \param desc : classe name description associated with the handler | 
|---|
|  | 35 | */ | 
|---|
|  | 36 | int FitsManager::RegisterHandler(FitsHandlerInterface * fhi, int glev, string desc) | 
|---|
| [2820] | 37 | { | 
|---|
| [2864] | 38 | ChkHLP(); | 
|---|
| [2820] | 39 | if (fhi == NULL) | 
|---|
|  | 40 | throw NullPtrError("FitsManager::RegisterHandler() fhi=NULL "); | 
|---|
|  | 41 | HandlerList::iterator it; | 
|---|
|  | 42 | for(it = hlistp->begin(); it != hlistp->end(); it++) { | 
|---|
|  | 43 | if (typeid(*((*it).fhi)) == typeid(*fhi)) | 
|---|
|  | 44 | throw DuplicateIdExc("FitsManager::RegisterHandler() Already registered handler"); | 
|---|
|  | 45 | } | 
|---|
|  | 46 | hand_list_el hle; | 
|---|
|  | 47 | hle.fhi = fhi; | 
|---|
| [2895] | 48 | hle.glev = glev; | 
|---|
|  | 49 | hle.desc = desc; | 
|---|
| [2820] | 50 | hlistp->push_back(hle); | 
|---|
|  | 51 | return hlistp->size(); | 
|---|
|  | 52 | } | 
|---|
|  | 53 |  | 
|---|
|  | 54 | int FitsManager::ListHandlers() | 
|---|
|  | 55 | { | 
|---|
| [2864] | 56 | ChkHLP(); | 
|---|
| [2820] | 57 | int kk=0; | 
|---|
|  | 58 | cout << "---- FitsManager::ListHandlers()  NbHandlers= " << hlistp->size() | 
|---|
|  | 59 | << endl; | 
|---|
|  | 60 | HandlerList::iterator it; | 
|---|
|  | 61 | for(it = hlistp->begin(); it != hlistp->end(); it++) { | 
|---|
|  | 62 | kk++; | 
|---|
| [2895] | 63 | cout << kk << "- " << (*it).desc << " : " | 
|---|
|  | 64 | << typeid(*((*it).fhi)).name() << " glev= " <<(*it).glev << endl; | 
|---|
| [2820] | 65 | } | 
|---|
|  | 66 | return hlistp->size(); | 
|---|
|  | 67 | } | 
|---|
|  | 68 |  | 
|---|
| [2901] | 69 | /*! | 
|---|
|  | 70 | Return a NULL pointer if no handler is registered for object \b o . | 
|---|
|  | 71 | The returned pointer should not be used directly and should NOT | 
|---|
|  | 72 | be deleted. For read/write operations, the Clone() method should | 
|---|
|  | 73 | be called on the returned object. | 
|---|
|  | 74 | */ | 
|---|
| [2820] | 75 | FitsHandlerInterface* FitsManager::FindHandler(AnyDataObj & o) | 
|---|
|  | 76 | { | 
|---|
| [2864] | 77 | ChkHLP(); | 
|---|
| [2820] | 78 | FitsHandlerInterface * fhi = NULL; | 
|---|
|  | 79 | HandlerList::iterator it; | 
|---|
| [2864] | 80 | int hfg = 0; | 
|---|
|  | 81 | int bhfg = 0; | 
|---|
| [2895] | 82 | int clev = 0; | 
|---|
|  | 83 | int blev = 0; | 
|---|
| [2864] | 84 | for(it = hlistp->begin(); it != hlistp->end(); it++) { | 
|---|
|  | 85 | hfg = (*it).fhi->CheckHandling(o); | 
|---|
| [2898] | 86 | if (hfg < 1) continue; | 
|---|
| [2895] | 87 | if ( ( hfg > bhfg ) || ( (hfg == bhfg) && ((*it).glev > blev) ) ) { | 
|---|
|  | 88 | fhi = (*it).fhi;  bhfg = hfg;  blev = (*it).glev; | 
|---|
| [2820] | 89 | } | 
|---|
| [2864] | 90 | } | 
|---|
| [2901] | 91 | return fhi ; | 
|---|
|  | 92 | } | 
|---|
|  | 93 |  | 
|---|
|  | 94 | /*! | 
|---|
|  | 95 | Throws an exception ( NotFoundExc ) if the write operation can not be performed. | 
|---|
|  | 96 | */ | 
|---|
|  | 97 | void FitsManager::Write(FitsInOutFile& os, AnyDataObj & o) | 
|---|
|  | 98 | { | 
|---|
|  | 99 | FitsHandlerInterface * fhi = FindHandler(o); | 
|---|
| [2820] | 100 | if (fhi == NULL) { | 
|---|
| [2901] | 101 | string msg = "FitsManager::Write()/FindHandler() Handler not found for "; | 
|---|
| [2820] | 102 | msg += typeid(o).name(); | 
|---|
|  | 103 | throw NotFoundExc(msg); | 
|---|
|  | 104 | } | 
|---|
| [2901] | 105 | FitsHandlerInterface * fhi2 = fhi->Clone(); | 
|---|
| [2820] | 106 | fhi2->SetDataObj(o); | 
|---|
|  | 107 | fhi2->Write(os); | 
|---|
| [2901] | 108 | delete fhi2 ; | 
|---|
| [2820] | 109 | return; | 
|---|
|  | 110 | } | 
|---|
|  | 111 |  | 
|---|
| [2901] | 112 | /*! | 
|---|
|  | 113 | Throws an exception ( NotFoundExc ) if the read operation can not be performed. | 
|---|
|  | 114 | */ | 
|---|
| [2864] | 115 | void FitsManager::Read(FitsInOutFile& is, AnyDataObj & o) | 
|---|
| [2820] | 116 | { | 
|---|
| [2901] | 117 | FitsHandlerInterface * fhi = FindHandler(o); | 
|---|
|  | 118 | if (fhi == NULL) { | 
|---|
|  | 119 | string msg = "FitsManager::Read()/FindHandler() Handler not found for "; | 
|---|
|  | 120 | msg += typeid(o).name(); | 
|---|
|  | 121 | throw NotFoundExc(msg); | 
|---|
|  | 122 | } | 
|---|
|  | 123 | FitsHandlerInterface * fhi2 = fhi->Clone(); | 
|---|
| [2820] | 124 | fhi2->SetDataObj(o); | 
|---|
| [2864] | 125 | fhi2->Read(is); | 
|---|
|  | 126 | delete fhi2; | 
|---|
| [2820] | 127 | return; | 
|---|
|  | 128 | } | 
|---|
| [2864] | 129 |  | 
|---|
| [2901] | 130 | /*! | 
|---|
|  | 131 | Return a NULL pointer if no handler is found capable of reading | 
|---|
|  | 132 | the current HDU. | 
|---|
|  | 133 | The returned pointer should not be used directly and should NOT | 
|---|
|  | 134 | be deleted. For read/write operations, the Clone() method should | 
|---|
|  | 135 | be called on the returned object. | 
|---|
|  | 136 | */ | 
|---|
| [2864] | 137 | FitsHandlerInterface * FitsManager::FindReader(FitsInOutFile& is) | 
|---|
|  | 138 | { | 
|---|
|  | 139 | ChkHLP(); | 
|---|
|  | 140 | FitsHandlerInterface * fhi = NULL; | 
|---|
|  | 141 | HandlerList::iterator it; | 
|---|
|  | 142 | int hfg = 0; | 
|---|
|  | 143 | int bhfg = 0; | 
|---|
| [2895] | 144 | int blev = 0; | 
|---|
| [2864] | 145 | for(it = hlistp->begin(); it != hlistp->end(); it++) { | 
|---|
|  | 146 | hfg = (*it).fhi->CheckReadability(is); | 
|---|
| [2898] | 147 | if (hfg < 1) continue; | 
|---|
| [2895] | 148 | if ( ( hfg > bhfg ) || ( (hfg == bhfg) && ((*it).glev > blev) ) ) { | 
|---|
|  | 149 | fhi = (*it).fhi;  bhfg = hfg;  blev = (*it).glev; | 
|---|
| [2864] | 150 | } | 
|---|
|  | 151 | } | 
|---|
| [2901] | 152 | return fhi; | 
|---|
|  | 153 | } | 
|---|
|  | 154 |  | 
|---|
|  | 155 | /*! | 
|---|
|  | 156 | Throws an exception ( NotFoundExc ) if the read operation can not be performed. | 
|---|
|  | 157 | In case of success, the calling function is responsible for deleting | 
|---|
|  | 158 | the returned FitsHandlerInterface object, when the correspondind data object | 
|---|
|  | 159 | is not needed any more. | 
|---|
|  | 160 | */ | 
|---|
|  | 161 | FitsHandlerInterface * FitsManager::Read(FitsInOutFile& is) | 
|---|
|  | 162 | { | 
|---|
|  | 163 | FitsHandlerInterface * fhi = FindReader(is); | 
|---|
| [2864] | 164 | if (fhi == NULL) { | 
|---|
| [2901] | 165 | string msg = "FitsManager::Read()/FindReader() Reader/Handler not found  "; | 
|---|
| [2864] | 166 | msg += is.FileName(); | 
|---|
|  | 167 | char buff[64]; | 
|---|
|  | 168 | sprintf(buff, " HDU= %d Type= %d", (int)(is.CurrentHDU()), | 
|---|
|  | 169 | (int)(is.CurrentHDUType()) ); | 
|---|
|  | 170 | msg += buff; | 
|---|
|  | 171 | throw NotFoundExc(msg); | 
|---|
|  | 172 | } | 
|---|
|  | 173 | FitsHandlerInterface * fhi2 = FindReader(is)->Clone(); | 
|---|
|  | 174 | fhi2->Read(is); | 
|---|
|  | 175 | return fhi2; | 
|---|
|  | 176 | } | 
|---|
| [2898] | 177 |  | 
|---|
|  | 178 | /*! | 
|---|
|  | 179 | \param filename : FITS file name to be scanned | 
|---|
|  | 180 | \param os : infomation will be sent to formatted stream os | 
|---|
|  | 181 | \param slev : scan level , bit 0 (1/3) print HDU keywords, | 
|---|
|  | 182 | bit 2 (2,3) try to read HDU data using the appropraite handler | 
|---|
|  | 183 | \param Rc : return number of scanned HDU's | 
|---|
|  | 184 | */ | 
|---|
|  | 185 | int FitsManager::ScanFile(string filename, ostream& os, int slev) | 
|---|
|  | 186 | { | 
|---|
|  | 187 | FitsInOutFile is(filename, FitsInOutFile::Fits_RO); | 
|---|
|  | 188 | os << "=== FitsManager::ScanFile( " << filename << " ) NbHDUs= " | 
|---|
|  | 189 | << is.NbHDUs() << endl; | 
|---|
|  | 190 | int rc = 0; | 
|---|
|  | 191 | for(int k=0; k<is.NbHDUs(); k++) { | 
|---|
|  | 192 | os << " ------ HDU No " << is.CurrentHDU() << " Type= " | 
|---|
|  | 193 | << is.CurrentHDUTypeStr() << endl; | 
|---|
|  | 194 | int hdutyp = is.CurrentHDUType(); | 
|---|
|  | 195 | if (hdutyp == IMAGE_HDU) { | 
|---|
|  | 196 | long naxes[5] = {0,0,0,0,0}; | 
|---|
|  | 197 | int naxis=5; | 
|---|
|  | 198 | int imgtyp = is.GetImageHDUInfo(naxis, naxes); | 
|---|
|  | 199 | os << ">> IMAGE_HDU:  naxis= " << naxis << " : "; | 
|---|
|  | 200 | for(int i=0; i<naxis; i++) { | 
|---|
|  | 201 | if (i>0) os << " x " ; | 
|---|
|  | 202 | os << naxes[i]; | 
|---|
|  | 203 | } | 
|---|
|  | 204 | os << endl; | 
|---|
|  | 205 | } | 
|---|
|  | 206 | else { | 
|---|
|  | 207 | vector<string> colnames; | 
|---|
|  | 208 | vector<int> coltypes; | 
|---|
|  | 209 | vector<long> repcnt; | 
|---|
|  | 210 | vector<long> width; | 
|---|
|  | 211 | int ncols = is.GetColInfo(colnames, coltypes, repcnt, width); | 
|---|
|  | 212 | if (hdutyp == BINARY_TBL) os << ">> BINARY_TBL :  NRows= " << is.GetNbRows(); | 
|---|
|  | 213 | else os << ">> ASCII_TBL :  NRows= " << is.GetNbRows(); | 
|---|
|  | 214 | os << " x NCols= " << ncols << endl; | 
|---|
|  | 215 | for(int kk=0; kk<colnames.size(); kk++) { | 
|---|
|  | 216 | os << "Col[" << kk+1 << "]  Name= " << colnames[kk] | 
|---|
|  | 217 | << " Type= " << FitsTypes::DataTypeToTypeString(coltypes[kk]) | 
|---|
|  | 218 | << " Repeat= " << repcnt[kk] | 
|---|
|  | 219 | << " W= " << width[kk] << endl; | 
|---|
|  | 220 | } | 
|---|
|  | 221 | } | 
|---|
|  | 222 | // Fin the appropriate handler : | 
|---|
|  | 223 | ChkHLP(); | 
|---|
|  | 224 | FitsHandlerInterface * fhi = NULL; | 
|---|
|  | 225 | HandlerList::iterator it; | 
|---|
|  | 226 | string hdesc; | 
|---|
|  | 227 | int hfg = 0; | 
|---|
|  | 228 | int bhfg = 0; | 
|---|
|  | 229 | int blev = 0; | 
|---|
|  | 230 | for(it = hlistp->begin(); it != hlistp->end(); it++) { | 
|---|
|  | 231 | hfg = (*it).fhi->CheckReadability(is); | 
|---|
|  | 232 | if (hfg < 1) continue; | 
|---|
|  | 233 | if ( ( hfg > bhfg ) || ( (hfg == bhfg) && ((*it).glev > blev) ) ) { | 
|---|
|  | 234 | fhi = (*it).fhi;  bhfg = hfg;  blev = (*it).glev; hdesc = (*it).desc; | 
|---|
|  | 235 | } | 
|---|
|  | 236 | } | 
|---|
|  | 237 | if (fhi == NULL) | 
|---|
|  | 238 | os << ">>> Warning : No handler found for this HDU ... " << endl; | 
|---|
|  | 239 | else | 
|---|
|  | 240 | os << ">>> Reader/handler: " <<  hdesc << " : " | 
|---|
|  | 241 | << typeid(*fhi).name() << " HandLevel= " << blev << ", "  << bhfg << endl; | 
|---|
|  | 242 | if (fhi && (slev >= 2)) { | 
|---|
|  | 243 | os << ">>> Trying to read HDU data using the handler ..." << endl; | 
|---|
|  | 244 | FitsHandlerInterface* fhic = fhi->Clone(); | 
|---|
|  | 245 | fhic->Read(is); | 
|---|
|  | 246 | os << " FitsHandler.Read() OK " << endl; | 
|---|
|  | 247 | } | 
|---|
|  | 248 | if ( (slev == 1) || (slev == 3) ) { | 
|---|
|  | 249 | os << ">>>> HDU keywords list :  " <<  endl; | 
|---|
|  | 250 | DVList dvl; | 
|---|
|  | 251 | is.GetHeaderRecords(dvl); | 
|---|
|  | 252 | os << dvl; | 
|---|
|  | 253 | } | 
|---|
|  | 254 | os << "               --------------------- " << endl; | 
|---|
|  | 255 | is.MoveToNextHDU(); | 
|---|
|  | 256 | rc++; | 
|---|
|  | 257 | } | 
|---|
|  | 258 | os << "===================================================" << endl; | 
|---|
|  | 259 | return rc; | 
|---|
|  | 260 | } | 
|---|