Changeset 6618 for branches/rel10_ifa/psModules/src/astrom/pmConcepts.c
- Timestamp:
- Mar 16, 2006, 3:47:44 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/rel10_ifa/psModules/src/astrom/pmConcepts.c
r6580 r6618 158 158 } 159 159 160 161 // Set the concepts for a given FPA to blanks 162 bool pmConceptsBlankFPA(pmFPA *fpa // FPA for which to set blank concepts 163 ) 164 { 165 psTrace("psModule.concepts", 5, "Blanking FPA concepts: %x %x\n", conceptsFPA, fpa->concepts); 166 return conceptsBlank(&conceptsFPA, fpa->concepts); 167 } 168 169 // Read the concepts for a given FPA 170 bool pmConceptsReadFPA(pmFPA *fpa, // FPA for which to read concepts 171 pmConceptSource source, // The source of the concepts to read 172 psDB *db // Database handle 173 ) 174 { 175 psTrace("psModule.concepts", 5, "Reading FPA concepts: %x %x\n", conceptsFPA, fpa->concepts); 176 return conceptsRead(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts); 177 } 178 179 // Read the concepts for a given FPA 180 bool pmConceptsWriteFPA(pmFPA *fpa, // FPA for which to write concepts 181 pmConceptSource source, // The source of the concepts to read 182 psDB *db // Database handle 183 ) 184 { 185 psTrace("psModule.concepts", 5, "Writing FPA concepts: %x %x\n", conceptsFPA, fpa->concepts); 186 return conceptsWrite(&conceptsFPA, fpa, NULL, NULL, source, db, fpa->concepts); 187 } 188 189 // Set the concepts for a given chip to blanks 190 bool pmConceptsBlankChip(pmChip *chip // FPA for which to set blank concepts 191 ) 192 { 193 psTrace("psModule.concepts", 5, "Blanking chip concepts: %x %x\n", conceptsChip, chip->concepts); 194 return conceptsBlank(&conceptsChip, chip->concepts); 195 } 196 197 // Read the concepts for a given FPA 198 bool pmConceptsReadChip(pmChip *chip, // Chip for which to read concepts 199 pmConceptSource source, // The source of the concepts to read 200 psDB *db // Database handle 201 ) 202 { 203 psTrace("psModule.concepts", 5, "Reading chip concepts: %x %x\n", conceptsChip, chip->concepts); 204 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 205 return conceptsRead(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts); 206 } 207 208 // Read the concepts for a given FPA 209 bool pmConceptsWriteChip(pmChip *chip, // Chip for which to write concepts 210 pmConceptSource source, // The source of the concepts to read 211 psDB *db // Database handle 212 ) 213 { 214 psTrace("psModule.concepts", 5, "Writing chip concepts: %x %x\n", conceptsChip, chip->concepts); 215 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 216 return conceptsWrite(&conceptsChip, fpa, chip, NULL, source, db, chip->concepts); 217 } 218 219 // Set the concepts for a given chip to blanks 220 bool pmConceptsBlankCell(pmCell *cell // Cell for which to set blank concepts 221 ) 222 { 223 psTrace("psModule.concepts", 5, "Blanking cell concepts: %x %x\n", conceptsCell, cell->concepts); 224 return conceptsBlank(&conceptsCell, cell->concepts); 225 } 226 227 // Read the concepts for a given FPA 228 bool pmConceptsReadCell(pmCell *cell, // Cell for which to read concepts 229 pmConceptSource source, // The source of the concepts to read 230 psDB *db // Database handle 231 ) 232 { 233 psTrace("psModule.concepts", 5, "Writing cell concepts: %x %x\n", conceptsCell, cell->concepts); 234 pmChip *chip = cell->parent; // Chip to which the cell belongs 235 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 236 return conceptsRead(&conceptsCell, fpa, chip, cell, source, db, cell->concepts); 237 } 238 239 // Read the concepts for a given FPA 240 bool pmConceptsWriteCell(pmCell *cell, // FPA for which to write concepts 241 pmConceptSource source, // The source of the concepts to read 242 psDB *db // Database handle 243 ) 244 { 245 psTrace("psModule.concepts", 5, "Writing cell concepts: %x %x\n", conceptsCell, cell->concepts); 246 pmChip *chip = cell->parent; // Chip to which the cell belongs 247 pmFPA *fpa = chip->parent; // FPA to which the chip belongs 248 return conceptsWrite(&conceptsCell, fpa, chip, cell, source, db, cell->concepts); 249 } 250 251 252 bool pmConceptsInit(void) 253 { 254 bool init = false; // Did we initialise anything? 255 if (! conceptsFPA) { 256 conceptsFPA = psMetadataAlloc(); 257 init = true; 258 259 // Install the standard concepts 260 261 #if 0 262 // FPA.NAME 263 { 264 psMetadataItem *fpaName = psMetadataItemAllocStr("FPA.NAME", "Name of FPA", ""); 265 pmConceptRegister(fpaName, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 266 psFree(fpaName); 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 267 329 } 268 #endif 269 270 // FPA.AIRMASS 271 { 272 psMetadataItem *fpaAirmass = psMetadataItemAllocF32("FPA.AIRMASS", "Airmass at boresight", 0.0); 273 pmConceptRegister(fpaAirmass, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 274 psFree(fpaAirmass); 330 if (! conceptsChip) { 331 conceptsChip = psMetadataAlloc(); 332 init = true; 333 // There are no standard concepts at the chip level to be installed 275 334 } 276 277 // FPA.FILTER 278 { 279 psMetadataItem *fpaFilter = psMetadataItemAllocStr("FPA.FILTER", "Filter used", ""); 280 pmConceptRegister(fpaFilter, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 281 psFree(fpaFilter); 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 282 495 } 283 496 284 // FPA.POSANGLE 285 { 286 psMetadataItem *fpaPosangle = psMetadataItemAllocF32("FPA.POSANGLE", 287 "Position angle of instrument", 0.0); 288 pmConceptRegister(fpaPosangle, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 289 psFree(fpaPosangle); 290 } 291 292 // FPA.RADECSYS 293 { 294 psMetadataItem *fpaRadecsys = psMetadataItemAllocStr("FPA.RADECSYS", 295 "Celestial coordinate system", ""); 296 pmConceptRegister(fpaRadecsys, NULL, NULL, PM_CONCEPT_LEVEL_FPA); 297 psFree(fpaRadecsys); 298 } 299 300 // FPA.RA 301 { 302 psMetadataItem *fpaRa = psMetadataItemAllocF64("FPA.RA", "Right Ascension of boresight", NAN); 303 pmConceptRegister(fpaRa, (pmConceptParseFunc)pmConceptParse_FPA_Coords, 304 (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA); 305 psFree(fpaRa); 306 } 307 308 // FPA.DEC 309 { 310 psMetadataItem *fpaDec = psMetadataItemAllocF64("FPA.DEC", "Declination of boresight", NAN); 311 pmConceptRegister(fpaDec, (pmConceptParseFunc)pmConceptParse_FPA_Coords, 312 (pmConceptFormatFunc)pmConceptFormat_FPA_Coords, PM_CONCEPT_LEVEL_FPA); 313 psFree(fpaDec); 314 } 315 316 // Done with FPA level concepts 317 } 318 if (! conceptsChip) { 319 conceptsChip = psMetadataAlloc(); 320 init = true; 321 // There are no standard concepts at the chip level to be installed 322 } 323 if (! conceptsCell) { 324 conceptsCell = psMetadataAlloc(); 325 init = true; 326 327 // Install the standard concepts 328 329 // CELL.GAIN 330 { 331 psMetadataItem *cellGain = psMetadataItemAllocF32("CELL.GAIN", "CCD gain (e/count)", NAN); 332 pmConceptRegister(cellGain, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 333 psFree(cellGain); 334 } 335 336 // CELL.READNOISE 337 { 338 psMetadataItem *cellReadnoise = psMetadataItemAllocF32("CELL.READNOISE", 339 "CCD read noise (e)", NAN); 340 pmConceptRegister(cellReadnoise, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 341 psFree(cellReadnoise); 342 } 343 344 // CELL.SATURATION 345 { 346 psMetadataItem *cellSaturation = psMetadataItemAllocF32("CELL.SATURATION", 347 "Saturation level (counts)", NAN); 348 pmConceptRegister(cellSaturation, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 349 psFree(cellSaturation); 350 } 351 352 // CELL.BAD 353 { 354 psMetadataItem *cellBad = psMetadataItemAllocF32("CELL.BAD", "Bad level (counts)", NAN); 355 pmConceptRegister(cellBad, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 356 psFree(cellBad); 357 } 358 359 // CELL.XPARITY 360 { 361 psMetadataItem *cellXparity = psMetadataItemAllocS32("CELL.XPARITY", 362 "Orientation in x compared to the rest of the FPA", 0); 363 pmConceptRegister(cellXparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 364 psFree(cellXparity); 365 } 366 367 // CELL.YPARITY 368 { 369 psMetadataItem *cellYparity = psMetadataItemAllocS32("CELL.YPARITY", 370 "Orientation in x compared to the rest of the FPA", 0); 371 pmConceptRegister(cellYparity, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 372 psFree(cellYparity); 373 } 374 375 // CELL.READDIR 376 { 377 psMetadataItem *cellReaddir = psMetadataItemAllocS32("CELL.READDIR", 378 "Read direction, rows=1, cols=2", 1); 379 pmConceptRegister(cellReaddir, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 380 psFree(cellReaddir); 381 } 382 383 384 // These (CELL.EXPOSURE and CELL.DARKTIME) used to be READOUT.EXPOSURE and READOUT.DARKTIME, but that 385 // doesn't really make sense at the moment. Maybe we need to add a "parent" link to the readouts. 386 // But then how are the exposure times REALLY derived? They're not in the FITS headers, because a 387 // readout is a plane in a 3D image. We'll have to dream up some additional suffix to specify these, 388 // but for now.... 389 390 // CELL.EXPOSURE 391 { 392 psMetadataItem *cellExposure = psMetadataItemAllocF32("CELL.EXPOSURE", 393 "Exposure time (sec)", NAN); 394 pmConceptRegister(cellExposure, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 395 psFree(cellExposure); 396 } 397 398 // CELL.DARKTIME 399 { 400 psMetadataItem *cellDarktime = psMetadataItemAllocF32("CELL.DARKTIME", 401 "Time since flush (sec)", NAN); 402 pmConceptRegister(cellDarktime, NULL, NULL, PM_CONCEPT_LEVEL_CELL); 403 psFree(cellDarktime); 404 } 405 406 // CELL.TRIMSEC 407 { 408 psRegion *trimsec = psAlloc(sizeof(psRegion)); // Blank trimsec 409 trimsec->x0 = trimsec->y0 = trimsec->x1 = trimsec->y1 = NAN; 410 psMetadataItem *cellTrimsec = psMetadataItemAllocPtr("CELL.TRIMSEC", PS_DATA_UNKNOWN, 411 "Trim section", trimsec); 412 psFree(trimsec); 413 pmConceptRegister(cellTrimsec, (pmConceptParseFunc)pmConceptParse_CELL_TRIMSEC, 414 (pmConceptFormatFunc)pmConceptFormat_CELL_TRIMSEC, PM_CONCEPT_LEVEL_CELL); 415 psFree(cellTrimsec); 416 } 417 418 // CELL.BIASSEC 419 { 420 psList *biassecs = psListAlloc(NULL); // Blank biassecs 421 psMetadataItem *cellBiassec = psMetadataItemAllocPtr("CELL.BIASSEC", PS_DATA_LIST, 422 "Bias sections", biassecs); 423 psFree(biassecs); 424 pmConceptRegister(cellBiassec, (pmConceptParseFunc)pmConceptParse_CELL_BIASSEC, 425 (pmConceptFormatFunc)pmConceptFormat_CELL_BIASSEC, PM_CONCEPT_LEVEL_CELL); 426 psFree(cellBiassec); 427 } 428 429 // CELL.XBIN 430 { 431 psMetadataItem *cellXbin = psMetadataItemAllocS32("CELL.XBIN", "Binning in x", 0); 432 pmConceptRegister(cellXbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning, 433 (pmConceptFormatFunc)pmConceptFormat_CELL_XBIN, PM_CONCEPT_LEVEL_CELL); 434 psFree(cellXbin); 435 } 436 437 // CELL.YBIN 438 { 439 psMetadataItem *cellYbin = psMetadataItemAllocS32("CELL.YBIN", "Binning in y", 0); 440 pmConceptRegister(cellYbin, (pmConceptParseFunc)pmConceptParse_CELL_Binning, 441 (pmConceptFormatFunc)pmConceptFormat_CELL_YBIN, PM_CONCEPT_LEVEL_CELL); 442 psFree(cellYbin); 443 } 444 445 // CELL.TIMESYS 446 { 447 psMetadataItem *cellTimesys = psMetadataItemAllocS32("CELL.TIMESYS", "Time system", -1); 448 pmConceptRegister(cellTimesys, (pmConceptParseFunc)pmConceptParse_CELL_TIMESYS, 449 (pmConceptFormatFunc)pmConceptFormat_CELL_TIMESYS, PM_CONCEPT_LEVEL_CELL); 450 psFree(cellTimesys); 451 } 452 453 // CELL.TIME 454 { 455 psTime *time = psTimeAlloc(PS_TIME_TAI); // Blank time 456 // Not particularly distinguishing, but should be good enough 457 time->sec = 0; 458 time->nsec = 0; 459 psMetadataItem *cellTime = psMetadataItemAlloc("CELL.TIME", PS_DATA_TIME, 460 "Time of exposure", time); 461 psFree(time); 462 pmConceptRegister(cellTime, (pmConceptParseFunc)pmConceptParse_CELL_TIME, 463 (pmConceptFormatFunc)pmConceptFormat_CELL_TIME, PM_CONCEPT_LEVEL_CELL); 464 psFree(cellTime); 465 } 466 467 // CELL.X0 468 { 469 psMetadataItem *cellX0 = psMetadataItemAllocS32("CELL.X0", "Position of (0,0) on the chip", 0); 470 pmConceptRegister(cellX0, (pmConceptParseFunc)pmConceptParse_CELL_Positions, 471 (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL); 472 psFree(cellX0); 473 } 474 475 // CELL.Y0 476 { 477 psMetadataItem *cellY0 = psMetadataItemAllocS32("CELL.Y0", "Position of (0,0) on the chip", 0); 478 pmConceptRegister(cellY0, (pmConceptParseFunc)pmConceptParse_CELL_Positions, 479 (pmConceptFormatFunc)pmConceptFormat_CELL_Positions, PM_CONCEPT_LEVEL_CELL); 480 psFree(cellY0); 481 } 482 483 } 484 485 conceptsInitialised = true; 486 487 return init; 488 } 489 490 void pmConceptsDone(void) 491 { 492 psFree(conceptsFPA); 493 psFree(conceptsChip); 494 psFree(conceptsCell); 495 } 496 497 498 // Copy concepts from one FPA to another 499 bool pmFPACopyConcepts(pmFPA *target, // The target FPA 500 pmFPA *source // The target FPA 501 ) 502 { 503 // Copy FPA concepts 504 target->concepts = psMetadataCopy(target->concepts, source->concepts); 505 506 // Copy chip concepts 507 psArray *targetChips = target->chips; // Chips in target 508 psArray *sourceChips = source->chips; // Chips in source 509 if (targetChips->n != sourceChips->n) { 510 psError(PS_ERR_IO, true, "Number of chips in target (%d) and source (%d) differ --- unable to copy " 511 "concepts.\n", targetChips->n, sourceChips->n); 512 return false; 513 } 514 for (int i = 0; i < targetChips->n; i++) { 515 pmChip *targetChip = targetChips->data[i]; // Target chip of interest 516 pmChip *sourceChip = sourceChips->data[i]; // Source chip of interest 517 if (! targetChip || ! sourceChip) { 518 continue; 519 } 520 targetChip->concepts = psMetadataCopy(targetChip->concepts, sourceChip->concepts); 521 522 // Copy cell concepts 523 psArray *targetCells = targetChip->cells; // Cells in target 524 psArray *sourceCells = sourceChip->cells; // Cells in source 525 if (targetCells->n != sourceCells->n) { 526 psError(PS_ERR_IO, true, "Number of cells in target (%d) and source (%d) differ for chip %d ---" 527 " unable to copy concepts.\n", targetCells->n, sourceCells->n, i); 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); 528 522 return false; 529 523 } 530 for (int j = 0; j < targetCells->n; j++) {531 pmC ell *targetCell = targetCells->data[j]; // Target chip of interest532 pmC ell *sourceCell = sourceCells->data[j]; // Source chip of interest533 if (! targetC ell || ! sourceCell) {524 for (int i = 0; i < targetChips->n; i++) { 525 pmChip *targetChip = targetChips->data[i]; // Target chip of interest 526 pmChip *sourceChip = sourceChips->data[i]; // Source chip of interest 527 if (! targetChip || ! sourceChip) { 534 528 continue; 535 529 } 536 targetCell->concepts = psMetadataCopy(targetCell->concepts, sourceCell->concepts); 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 } 537 548 } 538 } 539 540 return true; 541 } 549 550 return true; 551 }
Note:
See TracChangeset
for help on using the changeset viewer.
