Changeset 6734
- Timestamp:
- Mar 30, 2006, 10:08:30 AM (20 years ago)
- Location:
- branches/rel10_ifa/psModules/src
- Files:
-
- 14 edited
-
astrom/pmConcepts.c (modified) (3 diffs)
-
astrom/pmConceptsStandard.c (modified) (3 diffs)
-
astrom/pmConceptsStandard.h (modified) (1 diff)
-
astrom/pmConceptsWrite.c (modified) (6 diffs)
-
astrom/pmFPAConstruct.c (modified) (5 diffs)
-
astrom/pmFPAConstruct.h (modified) (1 diff)
-
astrom/pmFPACopy.c (modified) (17 diffs)
-
astrom/pmFPAWrite.c (modified) (3 diffs)
-
astrom/pmHDU.c (modified) (2 diffs)
-
astrom/pmHDUUtils.c (modified) (1 diff)
-
config/pmConfig.c (modified) (2 diffs)
-
config/pmConfig.h (modified) (2 diffs)
-
pslib/psImageFlip.c (modified) (2 diffs)
-
psmodules.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/rel10_ifa/psModules/src/astrom/pmConcepts.c
r6618 r6734 76 76 77 77 // Set all registered concepts to blank value for the specified level 78 static bool conceptsBlank(psMetadata **specs, // One of the concepts specifications78 static bool conceptsBlank(psMetadata **specs, // One of the concepts specifications 79 79 psMetadata *target // Place to install the concepts 80 80 ) … … 89 89 pmConceptSpec *spec = specItem->data.V; // The specification 90 90 psMetadataItem *blank = spec->blank; // The concept 91 psMetadataAddItem(target, blank, PS_LIST_TAIL, PS_META_REPLACE); 91 psMetadataItem *copy = NULL; // Copy of the blank concept 92 // Trap the lists, which can't be copied in the ordinary way without a warning 93 if (blank->type == PS_DATA_LIST) { 94 copy = psMetadataItemAlloc(blank->name, PS_DATA_LIST, blank->comment, blank->data.V); 95 } else { 96 copy = psMetadataItemCopy(blank); 97 } 98 if (!psMetadataAddItem(target, copy, PS_LIST_TAIL, PS_META_REPLACE)) { 99 psLogMsg(__func__, PS_LOG_WARN, "Unable to add blank version of concept %s\n", blank->name); 100 } 92 101 } 93 102 psFree(specsIter); … … 158 167 } 159 168 160 #if 0 161 bool pmConceptsRead(pmFPAview *view, 162 pmFPAlevel levels, 163 pmConceptSource source, 164 psDB *db 165 ) 166 { 167 pmFPA *fpa = view->fpa; // The FPA 168 169 #endif 170 171 // Set the concepts for a given FPA to blanks 172 bool pmConceptsBlankFPA(pmFPA *fpa // FPA for which to set blank concepts 173 ) { 174 psTrace("psModule.concepts", 5, "Blanking FPA concepts: %x %x\n", conceptsFPA, fpa->concepts); 175 return conceptsBlank(&conceptsFPA, fpa->concepts); 176 } 177 178 // Read the concepts for a given FPA 179 bool pmConceptsReadFPA(pmFPA *fpa, // FPA for which to read concepts 180 pmConceptSource source, // The source of the concepts to read 181 psDB *db // Database handle 182 ) { 183 psTrace("psModule.concepts", 5, "Reading FPA concepts: %x %x\n", conceptsFPA, fpa->concepts); 184 return conceptsRead(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts); 185 } 186 187 // Read the concepts for a given FPA 188 bool pmConceptsWriteFPA(pmFPA *fpa, // FPA for which to write concepts 189 pmConceptSource source, // The source of the concepts to read 190 psDB *db // Database handle 191 ) { 192 psTrace("psModule.concepts", 5, "Writing FPA concepts: %x %x\n", conceptsFPA, fpa->concepts); 193 return conceptsWrite(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts); 194 } 195 196 // Set the concepts for a given chip to blanks 197 bool pmConceptsBlankChip(pmChip *chip // FPA for which to set blank concepts 198 ) { 199 psTrace("psModule.concepts", 5, "Blanking chip concepts: %x %x\n", conceptsChip, chip->concepts); 200 return conceptsBlank(&conceptsChip, chip->concepts); 201 } 202 203 // Read the concepts for a given FPA 204 bool pmConceptsReadChip(pmChip *chip, // Chip for which to read concepts 205 pmConceptSource source, // The source of the concepts to read 206 bool propagate, // Propagate to higher levels as well? 207 psDB *db // Database handle 208 ) { 209 psTrace("psModule.concepts", 5, "Reading chip concepts: %x %x\n", conceptsChip, chip->concepts); 210 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 211 return conceptsRead(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts) && 212 ((propagate && conceptsRead(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts)) || 213 !propagate); 214 } 215 216 // Read the concepts for a given FPA 217 bool pmConceptsWriteChip(pmChip *chip, // Chip for which to write concepts 218 pmConceptSource source, // The source of the concepts to read 219 bool propagate,// Propagate to higher levels as well? 220 psDB *db // Database handle 221 ) { 222 psTrace("psModule.concepts", 5, "Writing chip concepts: %x %x\n", conceptsChip, chip->concepts); 223 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 224 return conceptsWrite(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts) && 225 ((propagate && conceptsWrite(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts)) || 226 !propagate); 227 } 228 229 // Set the concepts for a given chip to blanks 230 bool pmConceptsBlankCell(pmCell *cell // Cell for which to set blank concepts 231 ) { 232 psTrace("psModule.concepts", 5, "Blanking cell concepts: %x %x\n", conceptsCell, cell->concepts); 233 return conceptsBlank(&conceptsCell, cell->concepts); 234 } 235 236 // Read the concepts for a given FPA 237 bool pmConceptsReadCell(pmCell *cell, // Cell for which to read concepts 238 pmConceptSource source, // The source of the concepts to read 239 bool propagate,// Propagate to higher levels as well? 240 psDB *db // Database handle 241 ) { 242 psTrace("psModule.concepts", 5, "Reading cell concepts: %x %x\n", conceptsCell, cell->concepts); 243 pmChip *chip = cell->parent; // Chip to which the cell belongs 244 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 245 return conceptsRead(&conceptsCell, fpa, chip, cell, source, db, cell->concepts) && 246 ((propagate && conceptsRead(&conceptsChip, fpa, chip, cell, source, db, chip->concepts) && 247 conceptsRead(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts)) || !propagate); 248 } 249 250 // Read the concepts for a given FPA 251 bool pmConceptsWriteCell(pmCell *cell, // FPA for which to write concepts 252 pmConceptSource source, // The source of the concepts to read 253 bool propagate,// Propagate to higher levels as well? 254 psDB *db // Database handle 255 ) { 256 psTrace("psModule.concepts", 5, "Writing cell concepts: %x %x\n", conceptsCell, cell->concepts); 257 pmChip *chip = cell->parent; // Chip to which the cell belongs 258 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 259 return conceptsWrite(&conceptsCell, fpa, chip, cell, source, db, cell->concepts) && 260 ((propagate && conceptsWrite(&conceptsChip, fpa, chip, cell, source, db, chip->concepts) && 261 conceptsWrite(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts)) || !propagate); 262 } 263 264 265 bool pmConceptsInit(void) { 266 bool init = false; // Did we initialise anything? 267 if (! conceptsFPA) { 268 conceptsFPA = psMetadataAlloc(); 269 init = true; 270 271 // Install the standard concepts 272 273 #if 0 274 // FPA.NAME 275 { 276 psMetadataItem *fpaName = psMetadataItemAllocStr("FPA.NAME", "Name of FPA", ""); 277 pmConceptRegister(fpaName, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 278 psFree(fpaName); 279 } 280 #endif 281 282 // FPA.AIRMASS 283 { 284 psMetadataItem *fpaAirmass = psMetadataItemAllocF32("FPA.AIRMASS", "Airmass at boresight", 0.0); 285 pmConceptRegister(fpaAirmass, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 286 psFree(fpaAirmass); 287 } 288 289 // FPA.FILTER 290 { 291 psMetadataItem *fpaFilter = psMetadataItemAllocStr("FPA.FILTER", "Filter used", ""); 292 pmConceptRegister(fpaFilter, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 293 psFree(fpaFilter); 294 } 295 296 // FPA.POSANGLE 297 { 298 psMetadataItem *fpaPosangle = psMetadataItemAllocF32("FPA.POSANGLE", 299 "Position angle of instrument", 0.0); 300 pmConceptRegister(fpaPosangle, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 301 psFree(fpaPosangle); 302 } 303 304 // FPA.RADECSYS 305 { 306 psMetadataItem *fpaRadecsys = psMetadataItemAllocStr("FPA.RADECSYS", 307 "Celestial coordinate system", ""); 308 pmConceptRegister(fpaRadecsys, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 309 psFree(fpaRadecsys); 310 } 311 312 // FPA.RA 313 { 314 psMetadataItem *fpaRa = psMetadataItemAllocF64("FPA.RA", "Right Ascension of boresight", NAN); 315 pmConceptRegister(fpaRa, (pmConceptParseFunc)pmConceptParse_FPA_Coords, 316 (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA); 317 psFree(fpaRa); 318 } 319 320 // FPA.DEC 321 { 322 psMetadataItem *fpaDec = psMetadataItemAllocF64("FPA.DEC", "Declination of boresight", NAN); 323 pmConceptRegister(fpaDec, (pmConceptParseFunc)pmConceptParse_FPA_Coords, 324 (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA); 325 psFree(fpaDec); 326 } 327 328 // Done with FPA level concepts 329 } 330 if (! conceptsChip) { 331 conceptsChip = psMetadataAlloc(); 332 init = true; 333 // There are no standard concepts at the chip level to be installed 334 } 335 if (! conceptsCell) { 336 conceptsCell = psMetadataAlloc(); 337 init = true; 338 339 // Install the standard concepts 340 341 // CELL.GAIN 342 { 343 psMetadataItem *cellGain = psMetadataItemAllocF32("CELL.GAIN", "CCD gain (e/count)", NAN); 344 pmConceptRegister(cellGain, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 345 psFree(cellGain); 346 } 347 348 // CELL.READNOISE 349 { 350 psMetadataItem *cellReadnoise = psMetadataItemAllocF32("CELL.READNOISE", 351 "CCD read noise (e)", NAN); 352 pmConceptRegister(cellReadnoise, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 353 psFree(cellReadnoise); 354 } 355 356 // CELL.SATURATION 357 { 358 psMetadataItem *cellSaturation = psMetadataItemAllocF32("CELL.SATURATION", 359 "Saturation level (counts)", NAN); 360 pmConceptRegister(cellSaturation, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 361 psFree(cellSaturation); 362 } 363 364 // CELL.BAD 365 { 366 psMetadataItem *cellBad = psMetadataItemAllocF32("CELL.BAD", "Bad level (counts)", NAN); 367 pmConceptRegister(cellBad, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 368 psFree(cellBad); 369 } 370 371 // CELL.XPARITY 372 { 373 psMetadataItem *cellXparity = psMetadataItemAllocS32("CELL.XPARITY", 374 "Orientation in x compared to the rest of the FPA", 0); 375 pmConceptRegister(cellXparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 376 psFree(cellXparity); 377 } 378 379 // CELL.YPARITY 380 { 381 psMetadataItem *cellYparity = psMetadataItemAllocS32("CELL.YPARITY", 382 "Orientation in x compared to the rest of the FPA", 0); 383 pmConceptRegister(cellYparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 384 psFree(cellYparity); 385 } 386 387 // CELL.READDIR 388 { 389 psMetadataItem *cellReaddir = psMetadataItemAllocS32("CELL.READDIR", 390 "Read direction, rows=1, cols=2", 1); 391 pmConceptRegister(cellReaddir, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 392 psFree(cellReaddir); 393 } 394 395 396 // These (CELL.EXPOSURE and CELL.DARKTIME) used to be READOUT.EXPOSURE and READOUT.DARKTIME, but that 397 // doesn't really make sense at the moment. Maybe we need to add a "parent" link to the readouts. 398 // But then how are the exposure times REALLY derived? They're not in the FITS headers, because a 399 // readout is a plane in a 3D image. We'll have to dream up some additional suffix to specify these, 400 // but for now.... 401 402 // CELL.EXPOSURE 403 { 404 psMetadataItem *cellExposure = psMetadataItemAllocF32("CELL.EXPOSURE", 405 "Exposure time (sec)", NAN); 406 pmConceptRegister(cellExposure, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 407 psFree(cellExposure); 408 } 409 410 // CELL.DARKTIME 411 { 412 psMetadataItem *cellDarktime = psMetadataItemAllocF32("CELL.DARKTIME", 413 "Time since flush (sec)", NAN); 414 pmConceptRegister(cellDarktime, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 415 psFree(cellDarktime); 416 } 417 418 // CELL.TRIMSEC 419 { 420 psRegion *trimsec = psAlloc(sizeof(psRegion)); // Blank trimsec 421 trimsec->x0 = trimsec->y0 = trimsec->x1 = trimsec->y1 = NAN; 422 psMetadataItem *cellTrimsec = psMetadataItemAllocPtr("CELL.TRIMSEC", PS_DATA_UNKNOWN, 423 "Trim section", trimsec); 424 psFree(trimsec); 425 pmConceptRegister(cellTrimsec, (pmConceptParseFunc)pmConceptParse_CELL_TRIMSEC, 426 (pmConceptFormatFunc)pmConceptFormat_CELL_TRIMSEC, PM_CONCEPT_LEVEL_CELL); 427 psFree(cellTrimsec); 428 } 429 430 // CELL.BIASSEC 431 { 432 psList *biassecs = psListAlloc(NULL); // Blank biassecs 433 psMetadataItem *cellBiassec = psMetadataItemAllocPtr("CELL.BIASSEC", PS_DATA_LIST, 434 "Bias sections", biassecs); 435 psFree(biassecs); 436 pmConceptRegister(cellBiassec, (pmConceptParseFunc)pmConceptParse_CELL_BIASSEC, 437 (pmConceptFormatFunc)pmConceptFormat_CELL_BIASSEC, PM_CONCEPT_LEVEL_CELL); 438 psFree(cellBiassec); 439 } 440 441 // CELL.XBIN 442 { 443 psMetadataItem *cellXbin = psMetadataItemAllocS32("CELL.XBIN", "Binning in x", 0); 444 pmConceptRegister(cellXbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning, 445 (pmConceptFormatFunc)pmConceptFormat_CELL_XBIN, PM_CONCEPT_LEVEL_CELL); 446 psFree(cellXbin); 447 } 448 449 // CELL.YBIN 450 { 451 psMetadataItem *cellYbin = psMetadataItemAllocS32("CELL.YBIN", "Binning in y", 0); 452 pmConceptRegister(cellYbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning, 453 (pmConceptFormatFunc)pmConceptFormat_CELL_YBIN, PM_CONCEPT_LEVEL_CELL); 454 psFree(cellYbin); 455 } 456 457 // CELL.TIMESYS 458 { 459 psMetadataItem *cellTimesys = psMetadataItemAllocS32("CELL.TIMESYS", "Time system", -1); 460 pmConceptRegister(cellTimesys, (pmConceptParseFunc)pmConceptParse_CELL_TIMESYS, 461 (pmConceptFormatFunc)pmConceptFormat_CELL_TIMESYS, PM_CONCEPT_LEVEL_CELL); 462 psFree(cellTimesys); 463 } 464 465 // CELL.TIME 466 { 467 psTime *time = psTimeAlloc(PS_TIME_TAI); // Blank time 468 // Not particularly distinguishing, but should be good enough 469 time->sec = 0; 470 time->nsec = 0; 471 psMetadataItem *cellTime = psMetadataItemAlloc("CELL.TIME", PS_DATA_TIME, 472 "Time of exposure", time); 473 psFree(time); 474 pmConceptRegister(cellTime, (pmConceptParseFunc)pmConceptParse_CELL_TIME, 475 (pmConceptFormatFunc)pmConceptFormat_CELL_TIME, PM_CONCEPT_LEVEL_CELL); 476 psFree(cellTime); 477 } 478 479 // CELL.X0 480 { 481 psMetadataItem *cellX0 = psMetadataItemAllocS32("CELL.X0", "Position of (0,0) on the chip", 0); 482 pmConceptRegister(cellX0, (pmConceptParseFunc)pmConceptParse_CELL_Positions, 483 (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL); 484 psFree(cellX0); 485 } 486 487 // CELL.Y0 488 { 489 psMetadataItem *cellY0 = psMetadataItemAllocS32("CELL.Y0", "Position of (0,0) on the chip", 0); 490 pmConceptRegister(cellY0, (pmConceptParseFunc)pmConceptParse_CELL_Positions, 491 (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL); 492 psFree(cellY0); 493 } 494 495 } 496 497 conceptsInitialised = true; 498 499 return init; 500 } 501 502 void pmConceptsDone(void) { 503 psFree(conceptsFPA); 504 psFree(conceptsChip); 505 psFree(conceptsCell); 506 } 507 508 509 // Copy concepts from one FPA to another 510 bool pmFPACopyConcepts(pmFPA *target, // The target FPA 511 pmFPA *source // The target FPA 512 ) { 513 // Copy FPA concepts 514 target->concepts = psMetadataCopy(target->concepts, source->concepts); 515 516 // Copy chip concepts 517 psArray *targetChips = target->chips; // Chips in target 518 psArray *sourceChips = source->chips; // Chips in source 519 if (targetChips->n != sourceChips->n) { 520 psError(PS_ERR_IO, true, "Number of chips in target (%d) and source (%d) differ --- unable to copy " 521 "concepts.\n", targetChips->n, sourceChips->n); 169 // Set the concepts for a given FPA to blanks 170 bool pmConceptsBlankFPA(pmFPA *fpa // FPA for which to set blank concepts 171 ) 172 { 173 psTrace("psModule.concepts", 5, "Blanking FPA concepts: %x %x\n", conceptsFPA, fpa->concepts); 174 return conceptsBlank(&conceptsFPA, fpa->concepts); 175 } 176 177 178 // Read the concepts for a given FPA 179 bool pmConceptsReadFPA(pmFPA *fpa, // FPA for which to read concepts 180 pmConceptSource source, // The source of the concepts to read 181 psDB *db // Database handle 182 ) 183 { 184 psTrace("psModule.concepts", 5, "Reading FPA concepts: %x %x\n", conceptsFPA, fpa->concepts); 185 return conceptsRead(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts); 186 } 187 188 // Read the concepts for a given FPA 189 bool pmConceptsWriteFPA(pmFPA *fpa, // FPA for which to write concepts 190 pmConceptSource source, // The source of the concepts to read 191 psDB *db // Database handle 192 ) 193 { 194 psTrace("psModule.concepts", 5, "Writing FPA concepts: %x %x\n", conceptsFPA, fpa->concepts); 195 return conceptsWrite(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts); 196 } 197 198 // Set the concepts for a given chip to blanks 199 bool pmConceptsBlankChip(pmChip *chip // FPA for which to set blank concepts 200 ) 201 { 202 psTrace("psModule.concepts", 5, "Blanking chip concepts: %x %x\n", conceptsChip, chip->concepts); 203 return conceptsBlank(&conceptsChip, chip->concepts); 204 } 205 206 // Read the concepts for a given FPA 207 bool pmConceptsReadChip(pmChip *chip, // Chip for which to read concepts 208 pmConceptSource source, // The source of the concepts to read 209 bool propagate, // Propagate to higher levels as well? 210 psDB *db // Database handle 211 ) 212 { 213 psTrace("psModule.concepts", 5, "Reading chip concepts: %x %x\n", conceptsChip, chip->concepts); 214 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 215 return conceptsRead(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts) && 216 ((propagate && conceptsRead(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts)) || 217 !propagate); 218 } 219 220 // Read the concepts for a given FPA 221 bool pmConceptsWriteChip(pmChip *chip, // Chip for which to write concepts 222 pmConceptSource source, // The source of the concepts to read 223 bool propagate,// Propagate to higher levels as well? 224 psDB *db // Database handle 225 ) 226 { 227 psTrace("psModule.concepts", 5, "Writing chip concepts: %x %x\n", conceptsChip, chip->concepts); 228 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 229 return conceptsWrite(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts) && 230 ((propagate && conceptsWrite(&conceptsFPA, fpa, chip, NULL, source, db, fpa->concepts)) || 231 !propagate); 232 } 233 234 // Set the concepts for a given chip to blanks 235 bool pmConceptsBlankCell(pmCell *cell // Cell for which to set blank concepts 236 ) 237 { 238 psTrace("psModule.concepts", 5, "Blanking cell concepts: %x %x\n", conceptsCell, cell->concepts); 239 return conceptsBlank(&conceptsCell, cell->concepts); 240 } 241 242 // Read the concepts for a given FPA 243 bool pmConceptsReadCell(pmCell *cell, // Cell for which to read concepts 244 pmConceptSource source, // The source of the concepts to read 245 bool propagate,// Propagate to higher levels as well? 246 psDB *db // Database handle 247 ) 248 { 249 psTrace("psModule.concepts", 5, "Reading cell concepts: %x %x\n", conceptsCell, cell->concepts); 250 pmChip *chip = cell->parent; // Chip to which the cell belongs 251 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 252 return conceptsRead(&conceptsCell, fpa, chip, cell, source, db, cell->concepts) && 253 ((propagate && conceptsRead(&conceptsChip, fpa, chip, cell, source, db, chip->concepts) && 254 conceptsRead(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts)) || !propagate); 255 } 256 257 // Read the concepts for a given FPA 258 bool pmConceptsWriteCell(pmCell *cell, // FPA for which to write concepts 259 pmConceptSource source, // The source of the concepts to read 260 bool propagate,// Propagate to higher levels as well? 261 psDB *db // Database handle 262 ) 263 { 264 psTrace("psModule.concepts", 5, "Writing cell concepts: %x %x\n", conceptsCell, cell->concepts); 265 pmChip *chip = cell->parent; // Chip to which the cell belongs 266 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 267 return conceptsWrite(&conceptsCell, fpa, chip, cell, source, db, cell->concepts) && 268 ((propagate && conceptsWrite(&conceptsChip, fpa, chip, cell, source, db, chip->concepts) && 269 conceptsWrite(&conceptsFPA, fpa, chip, cell, source, db, fpa->concepts)) || !propagate); 270 } 271 272 273 bool pmConceptsInit(void) 274 { 275 bool init = false; // Did we initialise anything? 276 if (! conceptsFPA) { 277 conceptsFPA = psMetadataAlloc(); 278 init = true; 279 280 // Install the standard concepts 281 282 #if 0 283 // FPA.NAME 284 { 285 psMetadataItem *fpaName = psMetadataItemAllocStr("FPA.NAME", "Name of FPA", ""); 286 pmConceptRegister(fpaName, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 287 psFree(fpaName); 288 } 289 #endif 290 291 // FPA.AIRMASS 292 { 293 psMetadataItem *fpaAirmass = psMetadataItemAllocF32("FPA.AIRMASS", "Airmass at boresight", 0.0); 294 pmConceptRegister(fpaAirmass, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 295 psFree(fpaAirmass); 296 } 297 298 // FPA.FILTER 299 { 300 psMetadataItem *fpaFilter = psMetadataItemAllocStr("FPA.FILTER", "Filter used", ""); 301 pmConceptRegister(fpaFilter, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 302 psFree(fpaFilter); 303 } 304 305 // FPA.POSANGLE 306 { 307 psMetadataItem *fpaPosangle = psMetadataItemAllocF32("FPA.POSANGLE", 308 "Position angle of instrument", 0.0); 309 pmConceptRegister(fpaPosangle, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 310 psFree(fpaPosangle); 311 } 312 313 // FPA.RADECSYS 314 { 315 psMetadataItem *fpaRadecsys = psMetadataItemAllocStr("FPA.RADECSYS", 316 "Celestial coordinate system", ""); 317 pmConceptRegister(fpaRadecsys, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 318 psFree(fpaRadecsys); 319 } 320 321 // FPA.RA 322 { 323 psMetadataItem *fpaRa = psMetadataItemAllocF64("FPA.RA", "Right Ascension of boresight", NAN); 324 pmConceptRegister(fpaRa, (pmConceptParseFunc)pmConceptParse_FPA_Coords, 325 (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA); 326 psFree(fpaRa); 327 } 328 329 // FPA.DEC 330 { 331 psMetadataItem *fpaDec = psMetadataItemAllocF64("FPA.DEC", "Declination of boresight", NAN); 332 pmConceptRegister(fpaDec, (pmConceptParseFunc)pmConceptParse_FPA_Coords, 333 (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA); 334 psFree(fpaDec); 335 } 336 337 // Done with FPA level concepts 338 } 339 if (! conceptsChip) { 340 conceptsChip = psMetadataAlloc(); 341 init = true; 342 // There are no standard concepts at the chip level to be installed 343 } 344 if (! conceptsCell) { 345 conceptsCell = psMetadataAlloc(); 346 init = true; 347 348 // Install the standard concepts 349 350 // CELL.GAIN 351 { 352 psMetadataItem *cellGain = psMetadataItemAllocF32("CELL.GAIN", "CCD gain (e/count)", NAN); 353 pmConceptRegister(cellGain, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 354 psFree(cellGain); 355 } 356 357 // CELL.READNOISE 358 { 359 psMetadataItem *cellReadnoise = psMetadataItemAllocF32("CELL.READNOISE", 360 "CCD read noise (e)", NAN); 361 pmConceptRegister(cellReadnoise, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 362 psFree(cellReadnoise); 363 } 364 365 // CELL.SATURATION 366 { 367 psMetadataItem *cellSaturation = psMetadataItemAllocF32("CELL.SATURATION", 368 "Saturation level (counts)", NAN); 369 pmConceptRegister(cellSaturation, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 370 psFree(cellSaturation); 371 } 372 373 // CELL.BAD 374 { 375 psMetadataItem *cellBad = psMetadataItemAllocF32("CELL.BAD", "Bad level (counts)", NAN); 376 pmConceptRegister(cellBad, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 377 psFree(cellBad); 378 } 379 380 // CELL.XPARITY 381 { 382 psMetadataItem *cellXparity = psMetadataItemAllocS32("CELL.XPARITY", 383 "Orientation in x compared to the rest of the FPA", 0); 384 pmConceptRegister(cellXparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 385 psFree(cellXparity); 386 } 387 388 // CELL.YPARITY 389 { 390 psMetadataItem *cellYparity = psMetadataItemAllocS32("CELL.YPARITY", 391 "Orientation in x compared to the rest of the FPA", 0); 392 pmConceptRegister(cellYparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 393 psFree(cellYparity); 394 } 395 396 // CELL.READDIR 397 { 398 psMetadataItem *cellReaddir = psMetadataItemAllocS32("CELL.READDIR", 399 "Read direction, rows=1, cols=2", 1); 400 pmConceptRegister(cellReaddir, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 401 psFree(cellReaddir); 402 } 403 404 405 // These (CELL.EXPOSURE and CELL.DARKTIME) used to be READOUT.EXPOSURE and READOUT.DARKTIME, but that 406 // doesn't really make sense at the moment. Maybe we need to add a "parent" link to the readouts. 407 // But then how are the exposure times REALLY derived? They're not in the FITS headers, because a 408 // readout is a plane in a 3D image. We'll have to dream up some additional suffix to specify these, 409 // but for now.... 410 411 // CELL.EXPOSURE 412 { 413 psMetadataItem *cellExposure = psMetadataItemAllocF32("CELL.EXPOSURE", 414 "Exposure time (sec)", NAN); 415 pmConceptRegister(cellExposure, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 416 psFree(cellExposure); 417 } 418 419 // CELL.DARKTIME 420 { 421 psMetadataItem *cellDarktime = psMetadataItemAllocF32("CELL.DARKTIME", 422 "Time since flush (sec)", NAN); 423 pmConceptRegister(cellDarktime, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 424 psFree(cellDarktime); 425 } 426 427 // CELL.TRIMSEC 428 { 429 psRegion *trimsec = psAlloc(sizeof(psRegion)); // Blank trimsec 430 trimsec->x0 = trimsec->y0 = trimsec->x1 = trimsec->y1 = NAN; 431 psMetadataItem *cellTrimsec = psMetadataItemAllocPtr("CELL.TRIMSEC", PS_DATA_REGION, 432 "Trim section", trimsec); 433 psFree(trimsec); 434 pmConceptRegister(cellTrimsec, (pmConceptParseFunc)pmConceptParse_CELL_TRIMSEC, 435 #if 0 436 (pmConceptFormatFunc)pmConceptFormat_CELL_TRIMSEC, 437 #else 438 NULL, 439 #endif 440 PM_CONCEPT_LEVEL_CELL); 441 psFree(cellTrimsec); 442 } 443 444 // CELL.BIASSEC 445 { 446 psList *biassecs = psListAlloc(NULL); // Blank biassecs 447 psMetadataItem *cellBiassec = psMetadataItemAllocPtr("CELL.BIASSEC", PS_DATA_LIST, 448 "Bias sections", biassecs); 449 psFree(biassecs); 450 pmConceptRegister(cellBiassec, (pmConceptParseFunc)pmConceptParse_CELL_BIASSEC, 451 (pmConceptFormatFunc)pmConceptFormat_CELL_BIASSEC, PM_CONCEPT_LEVEL_CELL); 452 psFree(cellBiassec); 453 } 454 455 // CELL.XBIN 456 { 457 psMetadataItem *cellXbin = psMetadataItemAllocS32("CELL.XBIN", "Binning in x", 0); 458 pmConceptRegister(cellXbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning, 459 (pmConceptFormatFunc)pmConceptFormat_CELL_XBIN, PM_CONCEPT_LEVEL_CELL); 460 psFree(cellXbin); 461 } 462 463 // CELL.YBIN 464 { 465 psMetadataItem *cellYbin = psMetadataItemAllocS32("CELL.YBIN", "Binning in y", 0); 466 pmConceptRegister(cellYbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning, 467 (pmConceptFormatFunc)pmConceptFormat_CELL_YBIN, PM_CONCEPT_LEVEL_CELL); 468 psFree(cellYbin); 469 } 470 471 // CELL.TIMESYS 472 { 473 psMetadataItem *cellTimesys = psMetadataItemAllocS32("CELL.TIMESYS", "Time system", -1); 474 pmConceptRegister(cellTimesys, (pmConceptParseFunc)pmConceptParse_CELL_TIMESYS, 475 (pmConceptFormatFunc)pmConceptFormat_CELL_TIMESYS, PM_CONCEPT_LEVEL_CELL); 476 psFree(cellTimesys); 477 } 478 479 // CELL.TIME 480 { 481 psTime *time = psTimeAlloc(PS_TIME_TAI); // Blank time 482 // Not particularly distinguishing, but should be good enough 483 time->sec = 0; 484 time->nsec = 0; 485 psMetadataItem *cellTime = psMetadataItemAlloc("CELL.TIME", PS_DATA_TIME, 486 "Time of exposure", time); 487 psFree(time); 488 pmConceptRegister(cellTime, (pmConceptParseFunc)pmConceptParse_CELL_TIME, 489 (pmConceptFormatFunc)pmConceptFormat_CELL_TIME, PM_CONCEPT_LEVEL_CELL); 490 psFree(cellTime); 491 } 492 493 // CELL.X0 494 { 495 psMetadataItem *cellX0 = psMetadataItemAllocS32("CELL.X0", "Position of (0,0) on the chip", 0); 496 pmConceptRegister(cellX0, (pmConceptParseFunc)pmConceptParse_CELL_Positions, 497 (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL); 498 psFree(cellX0); 499 } 500 501 // CELL.Y0 502 { 503 psMetadataItem *cellY0 = psMetadataItemAllocS32("CELL.Y0", "Position of (0,0) on the chip", 0); 504 pmConceptRegister(cellY0, (pmConceptParseFunc)pmConceptParse_CELL_Positions, 505 (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL); 506 psFree(cellY0); 507 } 508 509 } 510 511 conceptsInitialised = true; 512 513 return init; 514 } 515 516 void pmConceptsDone(void) 517 { 518 psFree(conceptsFPA); 519 psFree(conceptsChip); 520 psFree(conceptsCell); 521 } 522 523 524 // Copy concepts from one FPA to another 525 bool pmFPACopyConcepts(pmFPA *target, // The target FPA 526 pmFPA *source // The target FPA 527 ) 528 { 529 // Copy FPA concepts 530 target->concepts = psMetadataCopy(target->concepts, source->concepts); 531 532 // Copy chip concepts 533 psArray *targetChips = target->chips; // Chips in target 534 psArray *sourceChips = source->chips; // Chips in source 535 if (targetChips->n != sourceChips->n) { 536 psError(PS_ERR_IO, true, "Number of chips in target (%d) and source (%d) differ --- unable to copy " 537 "concepts.\n", targetChips->n, sourceChips->n); 538 return false; 539 } 540 for (int i = 0; i < targetChips->n; i++) { 541 pmChip *targetChip = targetChips->data[i]; // Target chip of interest 542 pmChip *sourceChip = sourceChips->data[i]; // Source chip of interest 543 if (! targetChip || ! sourceChip) { 544 continue; 545 } 546 targetChip->concepts = psMetadataCopy(targetChip->concepts, sourceChip->concepts); 547 548 // Copy cell concepts 549 psArray *targetCells = targetChip->cells; // Cells in target 550 psArray *sourceCells = sourceChip->cells; // Cells in source 551 if (targetCells->n != sourceCells->n) { 552 psError(PS_ERR_IO, true, "Number of cells in target (%d) and source (%d) differ for chip %d ---" 553 " unable to copy concepts.\n", targetCells->n, sourceCells->n, i); 522 554 return false; 523 555 } 524 for (int i = 0; i < targetChips->n; i++) {525 pmC hip *targetChip = targetChips->data[i]; // Target chip of interest526 pmC hip *sourceChip = sourceChips->data[i]; // Source chip of interest527 if (! targetC hip || ! sourceChip) {556 for (int j = 0; j < targetCells->n; j++) { 557 pmCell *targetCell = targetCells->data[j]; // Target chip of interest 558 pmCell *sourceCell = sourceCells->data[j]; // Source chip of interest 559 if (! targetCell || ! sourceCell) { 528 560 continue; 529 561 } 530 targetChip->concepts = psMetadataCopy(targetChip->concepts, sourceChip->concepts); 531 532 // Copy cell concepts 533 psArray *targetCells = targetChip->cells; // Cells in target 534 psArray *sourceCells = sourceChip->cells; // Cells in source 535 if (targetCells->n != sourceCells->n) { 536 psError(PS_ERR_IO, true, "Number of cells in target (%d) and source (%d) differ for chip %d ---" 537 " unable to copy concepts.\n", targetCells->n, sourceCells->n, i); 538 return false; 539 } 540 for (int j = 0; j < targetCells->n; j++) { 541 pmCell *targetCell = targetCells->data[j]; // Target chip of interest 542 pmCell *sourceCell = sourceCells->data[j]; // Source chip of interest 543 if (! targetCell || ! sourceCell) { 544 continue; 545 } 546 targetCell->concepts = psMetadataCopy(targetCell->concepts, sourceCell->concepts); 547 } 548 } 549 550 return true; 551 } 562 targetCell->concepts = psMetadataCopy(targetCell->concepts, sourceCell->concepts); 563 } 564 } 565 566 return true; 567 } -
branches/rel10_ifa/psModules/src/astrom/pmConceptsStandard.c
r6663 r6734 156 156 } 157 157 158 psMetadataItem *item = psMetadataItemAllocPtr(pattern->name, PS_DATA_ UNKNOWN, pattern->comment, trimsec);158 psMetadataItem *item = psMetadataItemAllocPtr(pattern->name, PS_DATA_REGION, pattern->comment, trimsec); 159 159 psFree(trimsec); 160 160 return item; … … 434 434 435 435 436 436 #if 0 437 437 psMetadataItem *pmConceptFormat_CELL_TRIMSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell) 438 438 { … … 446 446 return formatted; 447 447 } 448 449 450 bool pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell) 451 { 448 #endif 449 450 psMetadataItem *pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell) 451 { 452 // Return a metadata item containing a list of metadata items of region strings 452 453 psList *biassecs = concept->data.V; // The biassecs region list 453 psString biassecString = NULL; // String containing the biassecs454 454 psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator 455 455 psRegion *region = NULL; // Region from iteration 456 bool first = true; // Are we on the first one?456 psList *new = psListAlloc(NULL); // New list containing metadatas 457 457 while ((region = psListGetAndIncrement(biassecsIter))) { 458 458 psString regionString = psRegionToString(*region); // The string region "[x0:x1,y0:y1]" 459 if (first) { 460 psStringAppend(&biassecString, "%s", regionString); 461 first = false; 462 } else { 463 psStringAppend(&biassecString, ";%s", regionString); // Put in a semi-colon 464 } 465 psFree(regionString); 459 psMetadataItem *item = psMetadataItemAllocStr(concept->name, concept->comment, regionString); 460 psFree(regionString); // Drop reference 461 psListAdd(new, PS_LIST_TAIL, item); 462 psFree(item); // Drop reference 466 463 } 467 464 psFree(biassecsIter); 468 psMetadataItem *formatted = psMetadataItemAlloc Str(concept->name, concept->comment, biassecString);469 psFree( biassecString);// Drop reference465 psMetadataItem *formatted = psMetadataItemAllocPtr(concept->name, PS_DATA_LIST, concept->comment, new); 466 psFree(new); // Drop reference 470 467 return formatted; 471 468 } 472 473 469 474 470 // This function actually does both CELL.XBIN and CELL.YBIN if CELL.XBIN and CELL.YBIN are specified by the -
branches/rel10_ifa/psModules/src/astrom/pmConceptsStandard.h
r6575 r6734 14 14 psMetadataItem *pmConceptParse_CELL_TIME(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell); 15 15 psMetadataItem *pmConceptParse_CELL_Positions(psMetadataItem *concept, psMetadataItem *pattern, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell); 16 #if 0 16 17 psMetadataItem *pmConceptFormat_CELL_TRIMSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell); 17 bool pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell); 18 #endif 19 psMetadataItem *pmConceptFormat_CELL_BIASSEC(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell); 18 20 psMetadataItem *pmConceptFormat_CELL_XBIN(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell); 19 21 psMetadataItem *pmConceptFormat_CELL_YBIN(psMetadataItem *concept, psMetadata *cameraFormat, pmFPA *fpa, pmChip *chip, pmCell *cell); -
branches/rel10_ifa/psModules/src/astrom/pmConceptsWrite.c
r6663 r6734 95 95 } 96 96 97 static bool writeHeader(pmHDU *hdu, // HDU for which to add to the header 98 const char *keyword, // Keyword to add 99 psMetadataItem *item // Item to add to the header 100 ) 97 // Write a single value to a header 98 static bool writeSingleHeader(pmHDU *hdu, // HDU for which to add to the header 99 const char *keyword, // Keyword to add 100 psMetadataItem *item // Item to add to the header 101 ) 101 102 { 102 103 switch (item->type) { … … 113 114 return psMetadataAddF64(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment, 114 115 item->data.F64); 116 case PS_DATA_REGION: { 117 psString region = psRegionToString(*(psRegion*)item->data.V); 118 bool result = psMetadataAddStr(hdu->header, PS_LIST_TAIL, keyword, PS_META_REPLACE, item->comment, 119 region); 120 psFree(region); 121 return result; 122 } 115 123 default: 116 124 psLogMsg(__func__, PS_LOG_WARN, "Type of %s is not suitable for a FITS header --- not added.\n", … … 118 126 return false; 119 127 } 128 } 129 130 131 // Write potentially multiple values to a header 132 static bool writeHeader(pmHDU *hdu, // HDU for which to add to the header 133 const char *keywords, // Keywords to add 134 psMetadataItem *item // Item to add to the header 135 ) 136 { 137 bool status = true; // Status of writing headers, to be returned 138 if (item->type == PS_DATA_LIST) { 139 psList *values = item->data.V; // List of outputs 140 psList *keys = psStringSplit(keywords, " ,;"); // List of keywords 141 if (keys->n != values->n) { 142 psLogMsg(__func__, PS_LOG_WARN, "Number of keywords (%d) does not match number of values (%d).\n", 143 keys->n, values->n); 144 } 145 psListIterator *keysIter = psListIteratorAlloc(keys, PS_LIST_HEAD, false); // Iterator for keywords 146 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator for values 147 psString key = NULL; // Keyword from iteration 148 psMetadataItem *value = NULL; // Value from iteration 149 while ((key = psListGetAndIncrement(keysIter)) && (value = psListGetAndIncrement(valuesIter))) { 150 status |= writeSingleHeader(hdu, key, value); 151 } 152 psFree(keysIter); 153 psFree(valuesIter); 154 psFree(keys); 155 } else { 156 status = writeSingleHeader(hdu, keywords, item); 157 } 158 return status; 120 159 } 121 160 … … 156 195 psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source 157 196 if (mdok && strlen(source) > 0) { 197 psTrace(__func__, 8, "%s is %s\n", nameSource, source); 158 198 if (strcasecmp(source, "HEADER") == 0) { 159 199 if (cameraItem->type != PS_DATA_STRING) { … … 162 202 continue; 163 203 } 204 psTrace(__func__, 8, "Writing %s to header %s\n", name, cameraItem->data.V); 164 205 writeHeader(hdu, cameraItem->data.V, formatted); 165 206 continue; 166 207 } 167 208 if (strcasecmp(source, "VALUE") == 0) { 209 psTrace(__func__, 8, "Checking %s against camera format.\n", name); 168 210 if (! compareConcepts(cameraItem, formatted)) { 169 211 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera " 170 "format, but the values don't match.\n" );212 "format, but the values don't match.\n", name); 171 213 } 172 214 continue; … … 179 221 if (! compareConcepts(cameraItem, formatted)) { 180 222 psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera " 181 "format, but the values don't match.\n" );223 "format, but the values don't match.\n", name); 182 224 } 183 225 } -
branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.c
r6713 r6734 682 682 // Print out the focal plane structure 683 683 void pmFPAPrint(pmFPA *fpa, // FPA to print 684 bool header, // Print headers? 684 685 bool concepts // Print concepts? 685 686 ) … … 703 704 if (chip->hdu) { 704 705 psTrace(__func__, 4, "---> Chip is extension %s.\n", chip->hdu->extname); 706 if (chip->hdu->header && header) { 707 psTrace(__func__, 4, "---> Header:\n"); 708 psMetadataPrint(chip->hdu->header, 8); 709 } 705 710 if (! chip->hdu->images) { 706 711 psTrace(__func__, 4, "---> NO PIXELS read in for extension %s\n", chip->hdu->extname); … … 718 723 if (cell->hdu) { 719 724 psTrace(__func__, 6, "---> Cell is extension %s.\n", cell->hdu->extname); 725 if (cell->hdu->header && header) { 726 psTrace(__func__, 4, "---> Header:\n"); 727 psMetadataPrint(cell->hdu->header, 8); 728 } 720 729 if (! cell->hdu->images) { 721 730 psTrace(__func__, 6, "---> NO PIXELS read in for extension %s\n", cell->hdu->extname); … … 731 740 pmReadout *readout = readouts->data[k]; // The readout 732 741 psImage *image = readout->image; // The image 742 psList *bias = readout->bias; // The list of bias images 733 743 if (image) { 734 744 psTrace(__func__, 8, "Image: [%d:%d,%d:%d] (%dx%d)\n", image->col0, image->col0 + … … 736 746 image->numRows); 737 747 } 748 if (bias) { 749 psListIterator *biasIter = psListIteratorAlloc(bias, PS_LIST_HEAD, false); // Iterator 750 psImage *biasImage = NULL; // Bias image from iteration 751 while ((biasImage = psListGetAndIncrement(biasIter))) { 752 psTrace(__func__, 8, "Bias: [%d:%d,%d:%d] (%dx%d)\n", biasImage->col0, 753 biasImage->col0 + biasImage->numCols, biasImage->row0, 754 biasImage->row0 + biasImage->numRows, biasImage->numCols, biasImage->numRows); 755 } 756 psFree(biasIter); 757 } 738 758 } // Iterating over cell 739 759 } // Iterating over chip -
branches/rel10_ifa/psModules/src/astrom/pmFPAConstruct.h
r6618 r6734 17 17 // Print out the FPA 18 18 void pmFPAPrint(pmFPA *fpa, // FPA to print 19 bool header, // Print headers? 19 20 bool concepts // Print concepts? 20 21 ); 21 22 22 23 23 #endif -
branches/rel10_ifa/psModules/src/astrom/pmFPACopy.c
r6720 r6734 117 117 *xSize = MAX(trimsec->x1, *xSize); 118 118 *ySize = MAX(trimsec->y1, *ySize); 119 } else { 120 psFree(cellsIter); 121 return false; 119 122 } 120 123 psList *biassecs = psMetadataLookupPtr(&mdok, cell->concepts, "CELL.BIASSEC"); // Bias sections … … 126 129 *xSize = MAX(biassec->x1, *xSize); 127 130 *ySize = MAX(biassec->y1, *ySize); 131 } else { 132 psFree(biassecsIter); 133 psFree(cellsIter); 134 return false; 128 135 } 129 136 } … … 133 140 psFree(cellsIter); 134 141 135 return (*xSize == 0 || *ySize == 0);142 return (*xSize != 0 && *ySize != 0); 136 143 } 137 144 … … 145 152 switch (readdir) { 146 153 case 1: // Read direction is rows 147 region = psRegionSet(*position, image->row0, *position + image->numCols,154 region = psRegionSet(*position, *position + image->numCols, image->row0, 148 155 image->row0 + image->numRows); 149 156 *position += image->numCols; 150 157 break; 151 158 case 2: // Read direction is columns 152 region = psRegionSet(image->col0, *position, image->col0 + image->numCols,159 region = psRegionSet(image->col0, image->col0 + image->numCols, *position, 153 160 *position + image->numRows); 154 161 *position += image->numRows; … … 209 216 int numCells = targets->n; // Number of cells 210 217 int cellNum = 0; // The cell number 211 int position ;// Position on the image218 int position = 0; // Position on the image 212 219 bool mdok = true; // Status of MD lookup 213 220 … … 218 225 while ((target = psListGetAndIncrement(targetsIter)) && (source = psListGetAndIncrement(sourcesIter)) && 219 226 !done) { 220 if (cellNum < numCells/2) {227 if (cellNum <= numCells/2 - 1) { 221 228 doBiasSections(&position, target, source); 229 cellNum++; 222 230 } else { 223 231 done = true; … … 249 257 250 258 // A final run through to do the RHS biases 251 psListIteratorSet(targetsIter, numCells/2);252 psListIteratorSet(sourcesIter, numCells/2);259 psListIteratorSet(targetsIter, cellNum); 260 psListIteratorSet(sourcesIter, cellNum); 253 261 while ((target = psListGetAndIncrement(targetsIter)) && (source = psListGetAndIncrement(sourcesIter))) { 254 262 doBiasSections(&position, target, source); … … 299 307 // Get the size of the HDU, either from existing trimsec and biassec, or generate these and try again 300 308 int xSize = 0, ySize = 0; // Size of HDU 301 if (!sizeHDU(&xSize, &ySize, targetCells) || !(generateTrimBias(targetCells, sourceCells) && 309 #if 1 310 311 if (!sizeHDU(&xSize, &ySize, targetCells) && !(generateTrimBias(targetCells, sourceCells) && 302 312 sizeHDU(&xSize, &ySize, targetCells))) { 303 313 psError(PS_ERR_IO, true, "Unable to determine size of HDU!\n"); 304 314 return false; 305 315 } 316 #else 317 if (!sizeHDU(&xSize, &ySize, targetCells)) { 318 if (generateTrimBias(targetCells, sourceCells)) { 319 if (!sizeHDU(&xSize, &ySize, targetCells)) { 320 psError(PS_ERR_IO, true, "Unable to determine size of HDU!\n"); 321 return false; 322 } 323 } else { 324 psError(PS_ERR_IO, true, "Unable to determine size of HDU!\n"); 325 return false; 326 } 327 } 328 #endif 306 329 307 330 hdu->images = psArrayAlloc(numReadouts); … … 314 337 return true; 315 338 } 316 317 318 #define UPDATE_CASE(TYPENAME,TYPE) \319 case TYPENAME: targetItem->data.TYPE = sourceItem->data.TYPE; \320 break;321 322 // Update a particular "concept" for the target cell from the source cell323 static bool updateConcept(pmCell *target, // Target cell324 const pmCell *source, // Source cell325 const char *concept // Concept name326 )327 {328 psMetadataItem *targetItem = psMetadataLookup(target->concepts, concept); // Concept from the target329 psMetadataItem *sourceItem = psMetadataLookup(source->concepts, concept); // Concept from the source330 331 switch (targetItem->type) {332 UPDATE_CASE(PS_TYPE_S32, S32);333 UPDATE_CASE(PS_TYPE_F32, F32);334 UPDATE_CASE(PS_TYPE_F64, F64);335 UPDATE_CASE(PS_DATA_STRING, V);336 default:337 psLogMsg(__func__, PS_LOG_WARN, "Unsupported type (%x) for concept %s --- ignored.\n",338 targetItem->type, concept);339 return false;340 }341 return true;342 }343 344 339 345 340 // Copy pixels from a target image to a source image, with flips … … 386 381 return false; 387 382 } 383 384 #if 1 385 // Copy any headers 386 if (target->hdu && !target->hdu->phu) { 387 pmHDU *sourceHDU = pmHDUFromFPA(source); 388 target->hdu->header = psMetadataCopy(target->hdu->header, sourceHDU->header); 389 } 390 #endif 388 391 389 392 int numChips = 0; // Number of chips copied … … 400 403 } 401 404 405 // Update the concepts 406 psMetadataCopy(target->concepts, source->concepts); 407 402 408 return numChips; 403 409 } … … 417 423 return false; 418 424 } 425 426 #if 1 427 // Copy any headers 428 if (target->hdu && !target->hdu->phu) { 429 pmHDU *sourceHDU = pmHDUFromChip(source); 430 target->hdu->header = psMetadataCopy(target->hdu->header, sourceHDU->header); 431 } 432 #endif 419 433 420 434 int numCells = 0; // Number of cells copied … … 431 445 } 432 446 447 // Update the concepts 448 psMetadataCopy(target->concepts, source->concepts); 449 433 450 return numCells; 434 451 … … 442 459 assert(source); 443 460 444 psArray *targetReadouts = target->readouts; // The target readouts445 461 psArray *sourceReadouts = source->readouts; // The source readouts 446 if (targetReadouts->n != sourceReadouts->n) { 447 psError(PS_ERR_IO, true, "Number of source readouts (%d) differs from the number of target readouts " 448 "(%d)\n", sourceReadouts->n, targetReadouts->n); 449 return false; 450 } 451 int numReadouts = targetReadouts->n; // Number of readouts copied 462 int numReadouts = sourceReadouts->n; // Number of readouts copied 463 464 #if 1 465 // Copy any headers 466 if (target->hdu && !target->hdu->phu) { 467 pmHDU *sourceHDU = pmHDUFromCell(source); 468 target->hdu->header = psMetadataCopy(target->hdu->header, sourceHDU->header); 469 } 470 #endif 452 471 453 472 pmHDU *hdu = pmHDUFromCell(target); // The target HDU; we need to fix this up 454 if (! hdu->images) {473 if (!hdu->images) { 455 474 generateHDU(target, source); 456 475 } 457 458 // Need to check CELL.X0, CELL.Y0, CELL.XBIN, CELL.YBIN should be unchanged; we can check this by 459 // setting the values and leaving it to the pmConceptWrite functions to do the checking against the 460 // camera configuration when it comes time to write them out. 461 updateConcept(target, source, "CELL.X0"); 462 updateConcept(target, source, "CELL.Y0"); 463 updateConcept(target, source, "CELL.XBIN"); 464 updateConcept(target, source, "CELL.YBIN"); 476 if (!hdu->header) { 477 hdu->header = psMetadataAlloc(); 478 } 465 479 466 480 // Need to check/change CELL.XPARITY and CELL.YPARITY 467 481 bool xFlip = (psMetadataLookupS32(NULL, target->concepts, "CELL.XPARITY") != 468 psMetadataLookupS32(NULL, target->concepts, "CELL.XPARITY")); // Switch parity in x?482 psMetadataLookupS32(NULL, source->concepts, "CELL.XPARITY")); // Switch parity in x? 469 483 bool yFlip = (psMetadataLookupS32(NULL, target->concepts, "CELL.YPARITY") != 470 psMetadataLookupS32(NULL, target->concepts, "CELL.YPARITY")); // Switch parity in y?484 psMetadataLookupS32(NULL, source->concepts, "CELL.YPARITY")); // Switch parity in y? 471 485 472 486 bool mdok = true; // Status of MD lookup … … 482 496 } 483 497 484 for (int i = 0; i < targetReadouts->n; i++) {498 for (int i = 0; i < numReadouts; i++) { 485 499 pmReadout *sourceReadout = sourceReadouts->data[i]; // The source readout 486 500 psImage *sourceImage = sourceReadout->image; // The source image 487 pmReadout *targetReadout = targetReadouts->data[i]; // The target readout501 pmReadout *targetReadout = pmReadoutAlloc(target); // The target readout; this adds it to the cell 488 502 if (sourceImage->numCols != trimsec->x1 - trimsec->x0 || 489 503 sourceImage->numRows != trimsec->y1 - trimsec->y0) { … … 500 514 psListIterator *biassecsIter = psListIteratorAlloc(biassecs, PS_LIST_HEAD, false); // Iterator 501 515 psRegion *biassec = NULL; // Bias section from iteration 502 while ((biassec = psListGetAndIncrement(biassecsIter))) { 516 psListIterator *biasIter = psListIteratorAlloc(sourceReadout->bias, PS_LIST_HEAD, false); // Iterator 517 psImage *bias = NULL; // Bias image from iteration 518 while ((biassec = psListGetAndIncrement(biassecsIter)) && (bias = psListGetAndIncrement(biasIter))) { 503 519 if (psRegionIsBad(*biassec)) { 504 520 psString biassecString = psRegionToString(*biassec); // String for bias section … … 507 523 continue; 508 524 } 509 if ( sourceImage->numCols != biassec->x1 - biassec->x0 ||510 sourceImage->numRows != biassec->y1 - biassec->y0) {525 if (bias->numCols != biassec->x1 - biassec->x0 || 526 bias->numRows != biassec->y1 - biassec->y0) { 511 527 psString biassecString = psRegionToString(*biassec); // String with the bias section 512 528 psLogMsg(__func__, PS_LOG_WARN, "Source image size (%dx%d) for readout %d doesn't match " 513 "CELL.BIASSEC for target (%s) -- ignored.\n", sourceImage->numCols,514 sourceImage->numRows, i,biassecString);529 "CELL.BIASSEC for target (%s) -- ignored.\n", bias->numCols, bias->numRows, i, 530 biassecString); 515 531 psFree(biassecString); 516 532 } else { 517 copyPixels(hdu->images->data[i], sourceImage, *biassec, xFlip, yFlip);518 psImage * bias = psMemIncrRefCounter(psImageSubset(hdu->images->data[i], *biassec));519 psListAdd(targetReadout->bias, PS_LIST_TAIL, bias);520 psFree( bias);// Drop reference533 copyPixels(hdu->images->data[i], bias, *biassec, xFlip, yFlip); 534 psImage *newBias = psMemIncrRefCounter(psImageSubset(hdu->images->data[i], *biassec)); 535 psListAdd(targetReadout->bias, PS_LIST_TAIL, newBias); 536 psFree(newBias); // Drop reference 521 537 } 522 538 } 523 539 psFree(biassecsIter); 524 540 psFree(biasIter); 541 } 542 543 // Copy the remaining "concepts" over 544 psMetadataIterator *conceptsIter = psMetadataIteratorAlloc(source->concepts, PS_LIST_HEAD, NULL); 545 psMetadataItem *conceptItem = NULL; // Item from iteration 546 while ((conceptItem = psMetadataGetAndIncrement(conceptsIter))) { 547 psString name = conceptItem->name; // Name of concept 548 if (strcmp(name, "CELL.TRIMSEC") != 0 && strcmp(name, "CELL.BIASSEC") != 0 && 549 strcmp(name, "CELL.XPARITY") != 0 && strcmp(name, "CELL.YPARITY") != 0) { 550 psMetadataAddItem(target->concepts, conceptItem, PS_LIST_TAIL, PS_META_REPLACE); 551 } 552 } 553 554 // Need to update CELL.X0 and CELL.Y0 if we flipped 555 if (xFlip) { 556 psMetadataItem *xZero = psMetadataLookup(target->concepts, "CELL.X0"); // CELL.X0 557 pmReadout *readout = target->readouts->data[0]; // A representative readout 558 xZero->data.S32 -= readout->image->numCols - 1; 559 } 560 if (yFlip) { 561 psMetadataItem *yZero = psMetadataLookup(target->concepts, "CELL.Y0"); // CELL.Y0 562 pmReadout *readout = target->readouts->data[0]; // A representative readout 563 yZero->data.S32 -= readout->image->numRows - 1; 525 564 } 526 565 -
branches/rel10_ifa/psModules/src/astrom/pmFPAWrite.c
r6663 r6734 13 13 ) 14 14 { 15 pmConceptsWriteCell(cell, PM_CONCEPT_SOURCE_HEADER, false, NULL); 15 pmConceptsWriteCell(cell, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, 16 false, NULL); 16 17 17 18 pmHDU *hdu = cell->hdu; // The HDU … … 30 31 ) 31 32 { 32 pmConceptsWriteChip(chip, PM_CONCEPT_SOURCE_HEADER, false, NULL); 33 pmConceptsWriteChip(chip, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, 34 false, NULL); 33 35 34 36 pmHDU *hdu = chip->hdu; // The HDU … … 56 58 ) 57 59 { 58 pmConceptsWriteFPA(fpa, PM_CONCEPT_SOURCE_HEADER, NULL); 60 pmConceptsWriteFPA(fpa, PM_CONCEPT_SOURCE_HEADER | PM_CONCEPT_SOURCE_CAMERA | PM_CONCEPT_SOURCE_DEFAULTS, 61 NULL); 59 62 60 63 pmHDU *hdu = fpa->hdu; // The HDU -
branches/rel10_ifa/psModules/src/astrom/pmHDU.c
r6726 r6734 4 4 #include "pslib.h" 5 5 #include "pmFPA.h" 6 #include "psAdditionals.h" 6 7 7 8 … … 35 36 hdu->extname = psStringCopy(extname); 36 37 } 37 hdu->format = NULL; 38 hdu->header = NULL; 39 hdu->images = NULL; 40 hdu->table = NULL; 38 hdu->format = NULL; 39 hdu->header = NULL; 40 hdu->images = NULL; 41 hdu->table = NULL; 42 hdu->weights = NULL; 43 hdu->masks = NULL; 41 44 42 45 return hdu; -
branches/rel10_ifa/psModules/src/astrom/pmHDUUtils.c
r6713 r6734 59 59 } 60 60 61 -
branches/rel10_ifa/psModules/src/config/pmConfig.c
r6713 r6734 3 3 * @author PAP, IfA 4 4 * 5 * @version $Revision: 1.7.4. 6$ $Name: not supported by cvs2svn $6 * @date $Date: 2006-03- 28 02:16:26$5 * @version $Revision: 1.7.4.7 $ $Name: not supported by cvs2svn $ 6 * @date $Date: 2006-03-30 20:08:30 $ 7 7 * 8 8 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 539 539 return(psDBInit(dbServer, dbUsername, dbPassword, dbName)); 540 540 } 541 542 543 bool pmConfigConformHeader(psMetadata *header, // Header to conform 544 const psMetadata *format // Camera format 545 ) 546 { 547 bool mdok = true; // Status of MD lookup 548 psMetadata *rules = psMetadataLookupMD(&mdok, format, "RULE"); // How to identify this format 549 if (!mdok || !rules) { 550 psError(PS_ERR_IO, false, "Unable to find RULE in camer format.\n"); 551 return false; 552 } 553 554 psMetadataIterator *rulesIter = psMetadataIteratorAlloc(rules, PS_LIST_HEAD, NULL); // Iterator for rules 555 psMetadataItem *rulesItem = NULL; // Item from iteration 556 while ((rulesItem = psMetadataGetAndIncrement(rulesIter))) { 557 psMetadataItem *newItem = psMetadataItemCopy(rulesItem); // Copy of item 558 psMetadataAddItem(header, newItem, PS_LIST_TAIL, PS_META_REPLACE); 559 psFree(newItem); // Drop reference 560 } 561 psFree(rulesIter); 562 563 return true; 564 } -
branches/rel10_ifa/psModules/src/config/pmConfig.h
r6713 r6734 3 3 * @author PAP, IfA 4 4 * 5 * @version $Revision: 1.3.4. 4$ $Name: not supported by cvs2svn $6 * @date $Date: 2006-03- 28 02:16:26$5 * @version $Revision: 1.3.4.5 $ $Name: not supported by cvs2svn $ 6 * @date $Date: 2006-03-30 20:08:30 $ 7 7 * 8 8 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 100 100 ); 101 101 102 /** pmConfigConformHeader 103 * 104 * Make the supplied header conform to the nominated camera format. 105 */ 106 bool pmConfigConformHeader(psMetadata *header, // Header to conform 107 const psMetadata *format // Camera format 108 ); 109 102 110 103 111 #endif -
branches/rel10_ifa/psModules/src/pslib/psImageFlip.c
r6721 r6734 36 36 } 37 37 38 return image;38 return output; 39 39 } 40 40 … … 73 73 } 74 74 75 return image;75 return output; 76 76 } -
branches/rel10_ifa/psModules/src/psmodules.h
r6723 r6734 7 7 // the following headers are from psModule:pslib 8 8 #include <psImageJpeg.h> 9 #include <psImageFlip.h> 9 10 #include <psLine.h> 10 11 #include <psPolynomialUtils.h>
Note:
See TracChangeset
for help on using the changeset viewer.
