- Timestamp:
- Mar 10, 2006, 5:20:10 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/rel10_ifa/psModules/src/astrom/pmConceptsWrite.c
r6552 r6570 7 7 #include "psAdditionals.h" 8 8 9 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 10 // File-static functions 11 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 9 12 10 13 static bool compareConcepts(psMetadataItem *item1, // First item to compare … … 67 70 } 68 71 72 // Format a single concept 73 static psMetadataItem *conceptFormat(pmConceptSpec *spec, // The concept specification 74 psMetadataItem *concept, // The concept to parse 75 psMetadata *cameraFormat, // The camera format 76 pmFPA *fpa, // The FPA 77 pmChip *chip, // The chip 78 pmCell *cell // The cell 79 ) 80 { 81 if (concept) { 82 psMetadataItem *formatted = NULL; // The formatted concept 83 if (spec->format) { 84 formatted = spec->format(concept, cameraFormat, fpa, chip, cell); 85 } else { 86 formatted = psMemIncrRefCounter(concept); 87 } 88 89 return formatted; 90 } 91 } 92 93 static bool writeHeader(pmHDU *hdu, // HDU for which to add to the header 94 const char *keyword, // Keyword to add 95 psMetadataItem *item // Item to add to the header 96 ) 97 { 98 switch (item->type) { 99 case PS_DATA_STRING: 100 return psMetadataAddStr(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment, 101 item->data.V); 102 case PS_DATA_S32: 103 return psMetadataAddS32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment, 104 item->data.S32); 105 case PS_DATA_F32: 106 return psMetadataAddF32(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment, 107 item->data.F32); 108 case PS_DATA_F64: 109 return psMetadataAddF64(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment, 110 item->data.F64); 111 default: 112 psLogMsg(__func__, PS_LOG_WARN, "Type of %s is not suitable for a FITS header --- not added.\n", 113 item->name); 114 return false; 115 } 116 } 117 118 119 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 120 // Public functions 121 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 122 123 bool pmConceptsWriteToCamera(psMetadata *specs, // The concept specifications 124 pmCell *cell, // The cell 125 psMetadata *concepts // The concepts 126 ) 127 { 128 if (cell) { 129 pmHDU *hdu = getLowestHDU(NULL, NULL, cell); // The HDU at the lowest level 130 psMetadata *cameraFormat = hdu->format; // The camera format 131 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 132 psMetadataItem *specItem = NULL; // Item from the specs metadata 133 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 134 pmConceptSpec *spec = specItem->data.V; // The specification 135 psString name = specItem->name; // The concept name 136 psMetadataItem *cameraItem = psMetadataLookup(cell->config, name); // The concept from the camera, 137 // or NULL 138 if (cameraItem) { 139 // Grab the concept 140 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The concept 141 // Formatted version 142 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, NULL, NULL, cell); 143 psString nameSource = NULL; // String with the concept name and ".SOURCE" added 144 psStringAppend(nameSource, "%s.SOURCE", name); 145 bool mdok = true; // Status of MD lookup 146 psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source 147 if (mdok && strlen(source) > 0) { 148 if (strcasecmp(source, "HEADER") == 0) { 149 if (cameraItem->type != PS_DATA_STRING) { 150 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by header, but is not " 151 "of type STR --- ignored.\n", conceptItem->name) 152 continue; 153 } 154 writeHeader(hdu, cameraItem->data.V, formatted); 155 continue; 156 } 157 if (strcasecmp(source, "VALUE") == 0) { 158 if (! compareConcepts(cameraItem, formatted)) { 159 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera " 160 "format, but the values don't match.\n"); 161 } 162 continue; 163 } 164 psLogMsg(__func__, PS_LOG_WARN, "Concept source %s isn't HEADER or VALUE --- can't " 165 "write\n", nameSource); 166 continue; 167 } 168 // Assume it's specified by value 169 if (! compareConcepts(cameraItem, formatted)) { 170 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera " 171 "format, but the values don't match.\n"); 172 } 173 } 174 175 } 176 psFree(specsIter); 177 return true; 178 } 179 return false; 180 } 181 182 183 bool pmConceptsWriteToDefault(psMetadata *specs, // The concept specifications 184 pmFPA *fpa, // The FPA 185 pmChip *chip, // The chip 186 pmCell *cell, // The cell 187 psMetadata *concepts // The concepts 188 ) 189 { 190 bool mdok = true; // Status of MD lookup 191 psMetadata *defaults = psMetadataLookupMD(&mdok, cameraFormat, "DEFAULTS"); // The DEFAULTS spec 192 if (mdok && defaults) { 193 pmHDU *hdu = getLowestHDU(fpa, chip, cell); // The HDU at the lowest level 194 psMetadata *cameraFormat = hdu->format; // The camera format 195 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 196 psMetadataItem *specItem = NULL; // Item from the specs metadata 197 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 198 pmConceptSpec *spec = specItem->data.V; // The specification 199 psString name = specItem->name; // The concept name 200 psMetadataItem *defaultItem = psMetadataLookup(defaults, name); // The item from the DEFAULTS 201 if (defaultItem) { 202 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts 203 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell); 204 if (! compareConcepts(cameraItem, formatted)) { 205 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by the DEFAULTS in the camera " 206 "format, but the values don't match.\n"); 207 } 208 } 209 } 210 psFree(specsIter); 211 return true; 212 } 213 return false; 214 } 215 216 // XXX need to write multiple headers if I get a list 217 bool pmConceptsWriteToHeader(psMetadata *specs, // The concept specifications 218 pmFPA *fpa, // The FPA 219 pmChip *chip, // The chip 220 pmCell *cell, // The cell 221 psMetadata *concepts // The concepts 222 ) 223 { 224 bool mdok = true; // Status of MD lookup 225 psMetadata *translation = psMetadataLookupMD(&mdok, cameraFormat, "TRANSLATION"); // The TRANSLATION spec 226 if (mdok && translation) { 227 pmHDU *hdu = getLowestHDU(fpa, chip, cell); // The HDU at the lowest level 228 psMetadata *cameraFormat = hdu->format; // The camera format 229 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 230 psMetadataItem *specItem = NULL; // Item from the specs metadata 231 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 232 pmConceptSpec *spec = specItem->data.V; // The specification 233 psString name = specItem->name; // The concept name 234 psMetadataItem *headerItem = psMetadataLookup(translation, name); // The item from the TRANSLATION 235 if (headerItem) { 236 if (headerItem->type != PS_DATA_STRING) { 237 psLogMsg(__func__, PS_LOG_WARN, "TRANSLATION keyword for concept %s isn't of type STR ---" 238 " ignored.", name); 239 continue; 240 } 241 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts 242 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell); 243 psList *keywords = psStringSplit(headerItem->data.V, " ,;"); // List of header keywords 244 if (formatted->type == PS_DATA_LIST) { 245 psList *values = formatted->data.V; // The values for the headers 246 if (values->n != keywords->n) { 247 psLogMsg(__func__, PS_LOG_WARN, "Number of headers specified does not match number " 248 "of values for concept %s.\n", name); 249 } 250 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator 251 psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false); 252 psMetadataItem *valuesItem = NULL; // Item from list 253 while ((valuesItem = psListGetAndIncrement(valuesIter))) { 254 psString keyword = psListGetAndIncrement(keywordsIter); // Keyword from the list 255 if (strlen(keyword) > 0) { 256 writeHeader(hdu, keyword, formatted); 257 } 258 } 259 psFree(valuesIter); 260 psFree(keywordsIter); 261 } else { 262 psString keyword = psListGet(keywords, PS_LIST_HEAD); // The keyword 263 writeHeader(hdu, keyword, formatted); 264 } 265 } 266 } 267 psFree(specsIter); 268 return true; 269 } 270 return false; 271 } 272 273 274 bool pmConceptsWriteToDatabase(psMetadata *specs, // The concept specifications 275 pmFPA *fpa, // The FPA 276 pmChip *chip, // The chip 277 pmCell *cell, // The cell 278 psDB *db,// The database handle 279 psMetadata *concepts // The concepts 280 ) 281 { 282 bool mdok = true; // Status of MD lookup 283 psMetadata *database = psMetadataLookupMD(&mdok, cameraFormat, "DATABASE"); // The DATABASE spec 284 if (mdok && database) { 285 pmHDU *hdu = getLowestHDU(fpa, chip, cell); // The HDU at the lowest level 286 psMetadata *cameraFormat = hdu->format; // The camera format 287 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 288 psMetadataItem *specItem = NULL; // Item from the specs metadata 289 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 290 pmConceptSpec *spec = specItem->data.V; // The specification 291 psString name = specItem->name; // The concept name 292 293 psMetadataItem *dbItem = psMetadataLookup(&mdok, database, name); // The item from the DATABASE 294 if (dbItem) { 295 if (dbItem->type != PS_DATA_METADATA) { 296 psLogMsg(__func__, PS_LOG_WARN, "DATABASE keyword for concept %s isn't of type METADATA " 297 "--- ignored.\n", name); 298 continue; 299 } 300 301 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts 302 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell); 303 304 psMetadata *dbLookup = dbItem->data.V; // How to look up the value of interest 305 // Name of the table 306 const char *tableName = psMetadataLookupStr(&mdStatus, dbLookup, "TABLE"); 307 // Name of "where" columns 308 const char *givenCols = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENDBCOL"); 309 // Values for "where" columns 310 const char *givenPS = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENPS"); 311 312 // Now, need to get the "given"s 313 if (strlen(givenCols) || strlen(givenPS)) { 314 psList *cols = psStringSplit(givenCols, ",;"); // List of column names 315 psList *values = psStringSplit(givenPS, ",;"); // List of value names for the columns 316 psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB 317 if (cols->n != values->n) { 318 psLogMsg(__func__, PS_LOG_WARN, 319 "The GIVENDBCOL and GIVENPS entries for %s do not have " 320 "the same number of entries --- ignored.\n", concept); 321 } else { 322 // Iterators for the lists 323 psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false); 324 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); 325 char *column = NULL; // Name of the column 326 while ((column = psListGetAndIncrement(colsIter))) { 327 char *name = psListGetAndIncrement(valuesIter); // Name for the value 328 if (!strlen(column) || !strlen(name)) { 329 psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is " 330 " empty --- ignored.\n", concept); 331 } else { 332 // Search for the value name 333 psMetadataItem *item = pmConceptReadFromHeader(fpa, chip, cell, name); 334 if (! item) { 335 item = pmConceptReadFromDefault(fpa, chip, cell, name); 336 } 337 if (! item) { 338 psLogMsg(__func__, PS_LOG_ERROR, 339 "Unable to find the value name %s for DB " 340 " lookup on %s --- ignored.\n", name, concept); 341 } else { 342 // We need to create a new psMetadataItem. I don't think we can't simply 343 // hack the existing one, since that could conceivably cause memory leaks 344 psMetadataAddItem(selection, formatted, PS_LIST_TAIL, PS_META_REPLACE); 345 psFree(formatted); 346 } 347 } 348 psFree(name); 349 psFree(column); 350 } // Iterating through the columns 351 psFree(colsIter); 352 psFree(valuesIter); 353 354 // Check first to make sure we're only going to touch one row 355 psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result 356 // Note that we use limit=2 in order to test if there are multiple rows returned 357 if (! dbResult || dbResult->n == 0) { 358 psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- " 359 "ignored\n", concept->name); 360 return false; 361 } else { 362 if (dbResult->n > 1) { 363 psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s " 364 "--- ignored.\n", concept->name); 365 } 366 // Update the DB 367 psMetadata *update = psMetadataAlloc(); 368 psMetadataAddItem(update, concept, PS_LIST_HEAD, 0); 369 psDBUpdateRows(db, tableName, selection, update); 370 psFree(update); 371 return true; 372 } 373 } 374 psFree(cols); 375 psFree(values); 376 } // Doing the "given"s. 377 } 378 } 379 psFree(specsIter); 380 return true; 381 } 382 return false; 383 } 384 385 386 387 388 #if 0 69 389 70 390 // Well, not really "write", but check to make sure it's there and matches … … 368 688 } 369 689 690 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
