Changeset 7278 for trunk/psModules/src/concepts/pmConceptsRead.c
- Timestamp:
- Jun 1, 2006, 2:55:23 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/concepts/pmConceptsRead.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/concepts/pmConceptsRead.c
r7017 r7278 1 1 #include <stdio.h> 2 #include <assert.h> 2 3 3 4 #include "pslib.h" … … 21 22 ) 22 23 { 24 assert(concept); 25 assert(pattern); 26 23 27 switch (pattern->type) { 24 28 case PS_DATA_STRING: { … … 53 57 ) 54 58 { 55 if (concept) { 56 psMetadataItem *parsed = NULL; // The parsed concept 57 if (spec->parse) { 58 parsed = spec->parse(concept, spec->blank, cameraFormat, fpa, chip, cell); 59 } else { 60 parsed = parsePlain(concept, spec->blank); 61 } 62 63 // Plug the parsed concept into a new psMetadataItem, so each "concept" has its own version that can 64 // be altered without affecting the others. Also, so that we maintain the template name and comment. 65 psMetadataItem *cleaned = NULL; // Item that's been cleaned up --- correct name and comment 66 switch (spec->blank->type) { 67 case PS_DATA_STRING: 68 cleaned = psMetadataItemAllocStr(spec->blank->name, spec->blank->comment, parsed->data.V); 69 break; 70 case PS_DATA_S32: 71 cleaned = psMetadataItemAllocS32(spec->blank->name, spec->blank->comment, parsed->data.S32); 72 break; 73 case PS_DATA_F32: 74 cleaned = psMetadataItemAllocF32(spec->blank->name, spec->blank->comment, parsed->data.F32); 75 break; 76 case PS_DATA_F64: 77 cleaned = psMetadataItemAllocF64(spec->blank->name, spec->blank->comment, parsed->data.F64); 78 break; 79 default: 80 cleaned = psMetadataItemAlloc(spec->blank->name, parsed->type, spec->blank->comment, 81 parsed->data.V); 82 } 83 psFree(parsed); 84 psMetadataAddItem(target, cleaned, PS_LIST_TAIL, PS_META_REPLACE); 85 psFree(cleaned); // Drop reference 86 return true; 87 } 88 89 return false; 59 assert(spec); 60 assert(cameraFormat); 61 assert(target); 62 63 if (!concept) { 64 return false; 65 } 66 67 psMetadataItem *parsed = NULL; // The parsed concept 68 if (spec->parse) { 69 parsed = spec->parse(concept, spec->blank, cameraFormat, fpa, chip, cell); 70 } else { 71 parsed = parsePlain(concept, spec->blank); 72 } 73 74 // Plug the parsed concept into a new psMetadataItem, so each "concept" has its own version that can 75 // be altered without affecting the others. Also, so that we maintain the template name and comment. 76 psMetadataItem *cleaned = NULL; // Item that's been cleaned up --- correct name and comment 77 switch (spec->blank->type) { 78 case PS_DATA_STRING: 79 cleaned = psMetadataItemAllocStr(spec->blank->name, spec->blank->comment, parsed->data.V); 80 break; 81 case PS_DATA_S32: 82 cleaned = psMetadataItemAllocS32(spec->blank->name, spec->blank->comment, parsed->data.S32); 83 break; 84 case PS_DATA_F32: 85 cleaned = psMetadataItemAllocF32(spec->blank->name, spec->blank->comment, parsed->data.F32); 86 break; 87 case PS_DATA_F64: 88 cleaned = psMetadataItemAllocF64(spec->blank->name, spec->blank->comment, parsed->data.F64); 89 break; 90 default: 91 cleaned = psMetadataItemAlloc(spec->blank->name, parsed->type, spec->blank->comment, 92 parsed->data.V); 93 } 94 psFree(parsed); 95 psMetadataAddItem(target, cleaned, PS_LIST_TAIL, PS_META_REPLACE); 96 psFree(cleaned); // Drop reference 97 return true; 90 98 } 91 99 … … 100 108 ) 101 109 { 102 if (cell) { 103 pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level 104 if (! hdu) { 105 return false; 106 } 107 psMetadata *cameraFormat = hdu->format; // The camera format 108 psMetadata *cellConfig = cell->config; // The camera configuration for this cell 109 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 110 psMetadataItem *specItem = NULL; // Item from the specs metadata 111 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 112 pmConceptSpec *spec = specItem->data.V; // The specification 113 psString name = specItem->name; // The concept name 114 psMetadataItem *conceptItem = psMetadataLookup(cellConfig, name); // The concept, or NULL 115 psMetadataItem *value = NULL; // The value of the concept 116 if (conceptItem) { 117 if (conceptItem->type == PS_DATA_STRING) { 118 // Check the SOURCE 119 psString nameSource = NULL; // String with the concept name and ".SOURCE" added 120 psStringAppend(&nameSource, "%s.SOURCE", name); 121 bool mdok = true; // Status of MD lookup 122 psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source 123 psFree(nameSource); 124 if (mdok && strlen(source) > 0 && strcasecmp(source, "VALUE") == 0) { 125 value = conceptItem; 126 conceptParse(spec, value, cameraFormat, target, NULL, NULL, cell); 127 } else if (source && (strlen(source) == 0 || strcasecmp(source, "HEADER") != 0)) { 128 // We leave "HEADER" to pmConceptsReadFromHeader 129 psError(PS_ERR_IO, true, "%s isn't HEADER or VALUE --- can't read %s\n", source, 130 name); 131 continue; 132 } 133 } else { 134 // Another type --- should be OK 135 conceptParse(spec, conceptItem, cameraFormat, target, NULL, NULL, cell); 110 PS_ASSERT_PTR_NON_NULL(specs, false); 111 PS_ASSERT_PTR_NON_NULL(target, false); 112 if (!cell) { 113 return false; 114 } 115 116 pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level 117 if (! hdu) { 118 return false; 119 } 120 psMetadata *cameraFormat = hdu->format; // The camera format 121 psMetadata *cellConfig = cell->config; // The camera configuration for this cell 122 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 123 psMetadataItem *specItem = NULL; // Item from the specs metadata 124 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 125 pmConceptSpec *spec = specItem->data.V; // The specification 126 psString name = specItem->name; // The concept name 127 psMetadataItem *conceptItem = psMetadataLookup(cellConfig, name); // The concept, or NULL 128 psMetadataItem *value = NULL; // The value of the concept 129 if (conceptItem) { 130 if (conceptItem->type == PS_DATA_STRING) { 131 // Check the SOURCE 132 psString nameSource = NULL; // String with the concept name and ".SOURCE" added 133 psStringAppend(&nameSource, "%s.SOURCE", name); 134 bool mdok = true; // Status of MD lookup 135 psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source 136 psFree(nameSource); 137 if (mdok && strlen(source) > 0 && strcasecmp(source, "VALUE") == 0) { 138 value = conceptItem; 139 conceptParse(spec, value, cameraFormat, target, NULL, NULL, cell); 140 } else if (source && (strlen(source) == 0 || strcasecmp(source, "HEADER") != 0)) { 141 // We leave "HEADER" to pmConceptsReadFromHeader 142 psError(PS_ERR_IO, true, "%s isn't HEADER or VALUE --- can't read %s\n", source, 143 name); 144 continue; 136 145 } 146 } else { 147 // Another type --- should be OK 148 conceptParse(spec, conceptItem, cameraFormat, target, NULL, NULL, cell); 137 149 } 138 150 } 139 psFree(specsIter); 140 return true; 141 } 142 return false; 151 } 152 psFree(specsIter); 153 return true; 143 154 } 144 155 … … 151 162 ) 152 163 { 164 PS_ASSERT_PTR_NON_NULL(specs, false); 165 PS_ASSERT_PTR_NON_NULL(target, false); 166 153 167 pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level 154 168 if (!hdu) { … … 158 172 bool mdok = true; // Status of MD lookup 159 173 psMetadata *defaults = psMetadataLookupMD(&mdok, cameraFormat, "DEFAULTS"); // The DEFAULTS spec 160 if (mdok && defaults) { 161 pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level 162 psMetadata *cameraFormat = hdu->format; // The camera format 163 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 164 psMetadataItem *specItem = NULL; // Item from the specs metadata 165 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 166 pmConceptSpec *spec = specItem->data.V; // The specification 167 psString name = specItem->name; // The concept name 168 psMetadataItem *conceptItem = psMetadataLookup(defaults, name); // The concept, or NULL 169 conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell); 170 } 171 psFree(specsIter); 172 return true; 173 } 174 return false; 174 if (!mdok || !defaults) { 175 return false; 176 } 177 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 178 psMetadataItem *specItem = NULL; // Item from the specs metadata 179 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 180 pmConceptSpec *spec = specItem->data.V; // The specification 181 psString name = specItem->name; // The concept name 182 psMetadataItem *conceptItem = psMetadataLookup(defaults, name); // The concept, or NULL 183 conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell); 184 } 185 psFree(specsIter); 186 return true; 175 187 } 176 188 … … 183 195 ) 184 196 { 197 PS_ASSERT_PTR_NON_NULL(specs, false); 198 PS_ASSERT_PTR_NON_NULL(target, false); 199 185 200 pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level 186 201 if (!hdu) { … … 190 205 bool mdok = true; // Status of MD lookup 191 206 psMetadata *transSpec = psMetadataLookupMD(&mdok, cameraFormat, "TRANSLATION"); // The TRANSLATION spec 192 if (mdok && transSpec) { 193 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 194 psMetadataItem *specItem = NULL; // Item from the specs metadata 195 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 196 pmConceptSpec *spec = specItem->data.V; // The specification 197 psString name = specItem->name; // The concept name 198 psMetadataItem *headerItem = NULL; // The value of the concept from the header 199 // First check the cell configuration 200 if (cell && cell->config) { 201 psMetadataItem *conceptItem = psMetadataLookup(cell->config, name); // The concept, or NULL 202 if (conceptItem) { 203 // Check the SOURCE 204 psString nameSource = NULL; // String with the concept name and ".SOURCE" added 205 psStringAppend(&nameSource, "%s.SOURCE", name); 206 psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source 207 psFree(nameSource); 208 if (mdok && strlen(source) && strcasecmp(source, "HEADER") == 0) { 209 headerItem = psMetadataLookup(hdu->header, conceptItem->data.V); 207 if (!mdok || !transSpec) { 208 return false; 209 } 210 211 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 212 psMetadataItem *specItem = NULL; // Item from the specs metadata 213 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 214 pmConceptSpec *spec = specItem->data.V; // The specification 215 psString name = specItem->name; // The concept name 216 psMetadataItem *headerItem = NULL; // The value of the concept from the header 217 // First check the cell configuration 218 if (cell && cell->config) { 219 psMetadataItem *conceptItem = psMetadataLookup(cell->config, name); // The concept, or NULL 220 if (conceptItem) { 221 // Check the SOURCE 222 psString nameSource = NULL; // String with the concept name and ".SOURCE" added 223 psStringAppend(&nameSource, "%s.SOURCE", name); 224 psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source 225 psFree(nameSource); 226 if (mdok && strlen(source) && strcasecmp(source, "HEADER") == 0) { 227 headerItem = psMetadataLookup(hdu->header, conceptItem->data.V); 228 } 229 // Leave the error handling to pmConceptsFromCamera, which should already have been called 230 } 231 } 232 if (! headerItem) { 233 psString keywords = psMetadataLookupStr(&mdok, transSpec, name); // The FITS keywords 234 if (mdok && strlen(keywords) > 0) { 235 // In case there are multiple headers 236 psList *keys = psStringSplit(keywords, " ,;", true); // List of keywords 237 if (keys->n == 1) { 238 // Only one key --- proceed as usual 239 headerItem = psMetadataLookup(hdu->header, keywords); 240 } else { 241 psListIterator *keysIter = psListIteratorAlloc(keys, PS_LIST_HEAD, false); // Iterator 242 psString key = NULL; // Item from iteration 243 psList *values = psListAlloc(NULL); // List containing the values 244 while ((key = psListGetAndIncrement(keysIter))) { 245 psMetadataItem *value = psMetadataLookup(hdu->header, key); 246 psListAdd(values, PS_LIST_TAIL, value); 210 247 } 211 // Leave the error handling to pmConceptsFromCamera, which should already have been called 248 psFree(keysIter); 249 headerItem = psMetadataItemAlloc(name, PS_DATA_LIST, specItem->comment, values); 250 psFree(values); 212 251 } 252 psFree(keys); 213 253 } 214 if (! headerItem) {215 psString keywords = psMetadataLookupStr(&mdok, transSpec, name); // The FITS keywords216 if (mdok && strlen(keywords) > 0) {217 // In case there are multiple headers218 psList *keys = psStringSplit(keywords, " ,;", true); // List of keywords219 if (keys->n == 1) {220 // Only one key --- proceed as usual221 headerItem = psMetadataLookup(hdu->header, keywords);222 } else {223 psListIterator *keysIter = psListIteratorAlloc(keys, PS_LIST_HEAD, false); // Iterator224 psString key = NULL; // Item from iteration225 psList *values = psListAlloc(NULL); // List containing the values226 while ((key = psListGetAndIncrement(keysIter))) {227 psMetadataItem *value = psMetadataLookup(hdu->header, key);228 psListAdd(values, PS_LIST_TAIL, value);229 }230 psFree(keysIter);231 headerItem = psMetadataItemAlloc(name, PS_DATA_LIST, specItem->comment, values);232 psFree(values);233 }234 psFree(keys);235 }236 }237 238 // This will also clean up the name239 conceptParse(spec, headerItem, cameraFormat, target, fpa, chip, cell);240 254 } 241 psFree(specsIter); 242 return true; 243 } 244 return false; 255 256 // This will also clean up the name 257 conceptParse(spec, headerItem, cameraFormat, target, fpa, chip, cell); 258 } 259 psFree(specsIter); 260 return true; 245 261 } 246 262 … … 255 271 ) 256 272 { 273 PS_ASSERT_PTR_NON_NULL(specs, false); 274 PS_ASSERT_PTR_NON_NULL(target, false); 275 257 276 #ifdef OMIT_PSDB 277 258 278 return false; 259 279 #else … … 266 286 bool mdok = true; // Status of MD lookup 267 287 psMetadata *dbSpec = psMetadataLookupMD(&mdok, cameraFormat, "DATABSE"); // The DATABASE spec 268 if (mdok && dbSpec) { 269 pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level 270 psMetadata *cameraFormat = hdu->format; // The camera format 271 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 272 psMetadataItem *specItem = NULL; // Item from the specs metadata 273 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 274 pmConceptSpec *spec = specItem->data.V; // The specification 275 psString name = specItem->name; // The concept name 276 277 psMetadata *dbLookup = psMetadataLookupMD(&mdok, dbSpec, name); 278 if (mdok && dbLookup) { 279 const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE"); // Table name 280 // Names of the "where" columns 281 const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL"); 282 // Values of the "where" columns 283 const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS"); 284 285 // Now, need to get the "given"s 286 if (strlen(givenCols) > 0 || strlen(givenPS) > 0) { 287 psList *cols = psStringSplit(givenCols, ",;", true); // List of column names 288 psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns 289 psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB 290 if (cols->n != values->n) { 288 if (!mdok || !dbSpec) { 289 return false; 290 } 291 292 psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator 293 psMetadataItem *specItem = NULL; // Item from the specs metadata 294 while ((specItem = psMetadataGetAndIncrement(specsIter))) { 295 pmConceptSpec *spec = specItem->data.V; // The specification 296 psString name = specItem->name; // The concept name 297 298 psMetadata *dbLookup = psMetadataLookupMD(&mdok, dbSpec, name); 299 if (mdok && dbLookup) { 300 const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE"); // Table name 301 // Names of the "where" columns 302 const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL"); 303 // Values of the "where" columns 304 const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS"); 305 306 // Now, need to get the "given"s 307 if (strlen(givenCols) > 0 || strlen(givenPS) > 0) { 308 psList *cols = psStringSplit(givenCols, ",;", true); // List of column names 309 psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns 310 psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB 311 if (cols->n != values->n) { 312 psLogMsg(__func__, PS_LOG_WARN, 313 "The GIVENDBCOL and GIVENPS entries for %s do not have " 314 "the same number of entries --- ignored.\n", name); 315 } else { 316 // Iterators for the lists 317 psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false); 318 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); 319 char *column = NULL; // Name of the column 320 while ((column = psListGetAndIncrement(colsIter))) { 321 char *dependName = psListGetAndIncrement(valuesIter); // Name for the value 322 if (!strlen(column) || !strlen(name)) { 323 psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is " 324 " empty --- ignored.\n", name); 325 } else { 326 // Search for the value name 327 psMetadataItem *item = NULL; // The value 328 if (!item && cell) { 329 item = psMetadataLookup(cell->concepts, dependName); 330 } 331 if (!item && chip) { 332 item = psMetadataLookup(chip->concepts, dependName); 333 } 334 if (!item && fpa) { 335 item = psMetadataLookup(fpa->concepts, dependName); 336 } 337 if (! item) { 338 psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB" 339 " lookup on %s --- ignored.\n", dependName, name); 340 } else { 341 // We need to create a new psMetadataItem. I don't think we can't 342 // simply hack the existing one, since that could conceivably cause 343 // memory leaks 344 psMetadataItem *newItem = psMetadataItemAlloc(name, item->type, 345 item->comment, 346 item->data.V); 347 psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE); 348 psFree(newItem); 349 } 350 } 351 psFree(dependName); 352 psFree(column); 353 } // Iterating through the columns 354 psFree(colsIter); 355 psFree(valuesIter); 356 357 psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result 358 // Note that we use limit=2 in order to test if there are multiple rows returned 359 360 psMetadataItem *conceptItem = NULL; // The final result of the DB lookup 361 if (dbResult->n == 0) { 291 362 psLogMsg(__func__, PS_LOG_WARN, 292 "The GIVENDBCOL and GIVENPS entries for %s do not have " 293 "the same number of entries --- ignored.\n", name); 363 "Unable to find any rows in DB for %s --- ignored\n", name); 294 364 } else { 295 // Iterators for the lists 296 psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false); 297 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); 298 char *column = NULL; // Name of the column 299 while ((column = psListGetAndIncrement(colsIter))) { 300 char *dependName = psListGetAndIncrement(valuesIter); // Name for the value 301 if (!strlen(column) || !strlen(name)) { 302 psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is " 303 " empty --- ignored.\n", name); 304 } else { 305 // Search for the value name 306 psMetadataItem *item = NULL; // The value 307 if (!item && cell) { 308 item = psMetadataLookup(cell->concepts, dependName); 309 } 310 if (!item && chip) { 311 item = psMetadataLookup(chip->concepts, dependName); 312 } 313 if (!item && fpa) { 314 item = psMetadataLookup(fpa->concepts, dependName); 315 } 316 if (! item) { 317 psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB" 318 " lookup on %s --- ignored.\n", dependName, name); 319 } else { 320 // We need to create a new psMetadataItem. I don't think we can't 321 // simply hack the existing one, since that could conceivably cause 322 // memory leaks 323 psMetadataItem *newItem = psMetadataItemAlloc(name, item->type, 324 item->comment, 325 item->data.V); 326 psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE); 327 psFree(newItem); 328 } 329 } 330 psFree(dependName); 331 psFree(column); 332 } // Iterating through the columns 333 psFree(colsIter); 334 psFree(valuesIter); 335 336 psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result 337 // Note that we use limit=2 in order to test if there are multiple rows returned 338 339 psMetadataItem *conceptItem = NULL; // The final result of the DB lookup 340 if (dbResult->n == 0) { 365 if (dbResult-> n > 1) { 341 366 psLogMsg(__func__, PS_LOG_WARN, 342 "Unable to find any rows in DB for %s --- ignored\n", name); 343 } else { 344 if (dbResult-> n > 1) { 345 psLogMsg(__func__, PS_LOG_WARN, 346 "Multiple rows returned in DB lookup for %s --- " 347 " using the first one only.\n", name); 348 } 349 conceptItem = (psMetadataItem*)dbResult->data[0]; 367 "Multiple rows returned in DB lookup for %s --- " 368 " using the first one only.\n", name); 350 369 } 351 352 // Now we have the result 353 conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell); 354 370 conceptItem = (psMetadataItem*)dbResult->data[0]; 355 371 } 356 psFree(cols); 357 psFree(values); 372 373 // Now we have the result 374 conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell); 375 358 376 } 359 } // Doing the "given"s. 360 361 } // Iterating through the concept specifications 362 psFree(specsIter); 363 364 return true; 365 } 366 return false; 377 psFree(cols); 378 psFree(values); 379 } 380 } // Doing the "given"s. 381 382 } // Iterating through the concept specifications 383 psFree(specsIter); 384 385 return true; 367 386 #endif 368 387 } 369 388 370 389 371 372 373 #ifdef OLD374 375 psMetadataItem *pmConceptReadFromCamera(pmCell *cell, // The cell376 const char *concept // Name of concept377 )378 {379 if (cell) {380 psMetadata *camera = cell->config; // Camera configuration381 psMetadataItem *item = psMetadataLookup(camera, concept);382 return item;383 }384 return NULL;385 }386 387 psMetadataItem *pmConceptReadFromHeader(pmFPA *fpa, // The FPA that contains the chip388 pmChip *chip, // The chip that contains the cell389 pmCell *cell, // The cell390 const char *concept // Name of concept391 )392 {393 bool mdStatus = true; // Status of MD lookup394 psMetadata *translation = psMetadataLookupMD(&mdStatus, fpa->camera, "TRANSLATION"); // FITS translation395 if (! mdStatus) {396 psError(PS_ERR_IO, false, "Unable to find TRANSLATION in camera configuration.\n");397 return NULL;398 }399 400 // Look for how to translate the concept into a FITS header name401 const char *keyword = psMetadataLookupStr(&mdStatus, translation, concept);402 if (mdStatus && strlen(keyword) > 0) {403 // We have a FITS header to look up --- search each level404 if (cell && cell->hdu) {405 psMetadataItem *cellItem = psMetadataLookup(cell->hdu->header, keyword);406 if (cellItem) {407 // XXX: Need to clean up before returning408 return cellItem;409 }410 }411 412 if (chip && chip->hdu) {413 psMetadataItem *chipItem = psMetadataLookup(chip->hdu->header, keyword);414 if (chipItem) {415 // XXX: Need to clean up before returning416 return chipItem;417 }418 }419 420 if (fpa->hdu) {421 psMetadataItem *fpaItem = psMetadataLookup(fpa->hdu->header, keyword);422 if (fpaItem) {423 // XXX: Need to clean up before returning424 return fpaItem;425 }426 }427 }428 429 // No header value430 return NULL;431 }432 433 434 // Look for a default435 psMetadataItem *pmConceptReadFromDefault(pmFPA *fpa, // The FPA that contains the chip436 pmChip *chip, // The chip that contains the cell437 pmCell *cell, // The cell438 const char *concept // Name of concept439 )440 {441 bool mdOK = true; // Status of MD lookup442 psMetadata *defaults = psMetadataLookupMD(&mdOK, fpa->camera, "DEFAULTS");443 if (! mdOK) {444 psError(PS_ERR_IO, false, "Unable to find DEFAULTS in camera configuration.\n");445 return NULL;446 }447 448 psMetadataItem *defItem = psMetadataLookup(defaults, concept);449 if (defItem) {450 if (defItem->type == PS_DATA_METADATA) {451 // A dependent default452 psTrace(__func__, 7, "Evaluating dependent default....\n");453 psMetadata *dependents = defItem->data.V; // The list of dependents454 // Find out what it depends on455 psString dependName = psStringCopy(concept);456 psStringAppend(&dependName, ".DEPEND");457 psString dependsOn = psMetadataLookupStr(&mdOK, defaults, dependName);458 if (! mdOK) {459 psError(PS_ERR_IO, false, "Unable to find %s in camera configuration for dependent default"460 " --- ignored\n", dependName);461 // XXX: Need to clean up before returning462 return NULL;463 }464 psFree(dependName);465 // Find the value of the dependent concept466 psMetadataItem *depItem = pmConceptReadFromHeader(fpa, chip, cell, dependsOn);467 if (! depItem) {468 psError(PS_ERR_IO, true, "Unable to find value for %s (required for %s)\n", dependsOn,469 concept);470 return NULL;471 }472 if (depItem->type != PS_DATA_STRING) {473 psError(PS_ERR_IO, true, "Value of %s is not of type string, as required for dependency"474 " --- ignored.\n", dependsOn);475 }476 477 defItem = psMetadataLookup(dependents, depItem->data.V); // This is now what we were after478 }479 }480 481 // XXX: Need to clean up before returning482 return defItem; // defItem is either NULL or points to what was desired483 }484 485 486 // Look for a database lookup487 // XXX: Not tested488 psMetadataItem *pmConceptReadFromDB(pmFPA *fpa, // The FPA that contains the chip489 pmChip *chip, // The chip that contains the cell490 pmCell *cell, // The cell491 psDB *db, // DB handle492 const char *concept // Name of concept493 )494 {495 if (! db) {496 // No database initialised497 return NULL;498 }499 500 bool mdStatus = true; // Status of MD lookup501 psMetadata *database = psMetadataLookupMD(&mdStatus, fpa->camera, "DATABASE");502 if (! mdStatus) {503 // No error, because not everyone needs to use the DB504 return NULL;505 }506 507 psMetadata *dbLookup = psMetadataLookupMD(&mdStatus, database, concept);508 if (dbLookup) {509 const char *tableName = psMetadataLookupStr(&mdStatus, dbLookup, "TABLE"); // Name of the table510 // const char *colName = psMetadataLookupStr(&mdStatus, dbLookup, "COLUMN"); // Name of the column511 const char *givenCols = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENDBCOL"); // Name of "where"512 // columns513 const char *givenPS = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENPS"); // Values for "where"514 // columns515 516 // Now, need to get the "given"s517 if (strlen(givenCols) || strlen(givenPS)) {518 psList *cols = psStringSplit(givenCols, ",;", true); // List of column names519 psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns520 psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB521 if (cols->n != values->n) {522 psLogMsg(__func__, PS_LOG_WARN, "The GIVENDBCOL and GIVENPS entries for %s do not have "523 "the same number of entries --- ignored.\n", concept);524 } else {525 // Iterators for the lists526 psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);527 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);528 char *column = NULL; // Name of the column529 while ((column = psListGetAndIncrement(colsIter))) {530 char *name = psListGetAndIncrement(valuesIter); // Name for the value531 if (!strlen(column) || !strlen(name)) {532 psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "533 " empty --- ignored.\n", concept);534 } else {535 // Search for the value name536 psMetadataItem *item = pmConceptReadFromHeader(fpa, chip, cell, name);537 if (! item) {538 item = pmConceptReadFromDefault(fpa, chip, cell, name);539 }540 if (! item) {541 psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB "542 " lookup on %s --- ignored.\n", name, concept);543 } else {544 // We need to create a new psMetadataItem. I don't think we can't simply hack545 // the existing one, since that could conceivably cause memory leaks546 psMetadataItem *newItem = psMetadataItemAlloc(concept, item->type,547 item->comment, item->data.V);548 psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);549 psFree(newItem);550 }551 }552 psFree(name);553 psFree(column);554 } // Iterating through the columns555 psFree(colsIter);556 psFree(valuesIter);557 558 psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result559 // Note that we use limit=2 in order to test if there are multiple rows returned560 561 psMetadataItem *result = NULL; // The final result of the DB lookup562 if (dbResult->n == 0) {563 psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- ignored\n",564 concept);565 } else {566 if (dbResult-> n > 1) {567 psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s --- "568 " using the first one only.\n", concept);569 }570 result = (psMetadataItem*)dbResult->data[0];571 }572 // XXX: Need to clean up before returning573 return result;574 }575 psFree(cols);576 psFree(values);577 }578 } // Doing the "given"s.579 580 psAbort(__func__, "Shouldn't ever get here.\n");581 return NULL;582 }583 584 585 // Concept lookup586 psMetadataItem *pmConceptRead(pmFPA *fpa, // The FPA587 pmChip *chip,// The chip588 pmCell *cell, // The cell589 psDB *db, // DB handle590 const char *name // Concept name591 )592 {593 // Try headers, database, defaults in order594 psMetadataItem *item = pmConceptReadFromCamera(cell, name);595 if (! item) {596 item = pmConceptReadFromHeader(fpa, chip, cell, name);597 }598 if (! item) {599 item = pmConceptReadFromDB(fpa, chip, cell, db, name);600 }601 if (! item) {602 item = pmConceptReadFromDefault(fpa, chip, cell, name);603 }604 return item; // item is either NULL, or points to what was desired605 }606 607 608 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
