Changeset 22699 for trunk/psModules/src/concepts/pmConcepts.c
- Timestamp:
- Feb 26, 2009, 2:45:31 PM (17 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/concepts/pmConcepts.c (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/concepts/pmConcepts.c
r20951 r22699 19 19 #include "pmConceptsWrite.h" 20 20 #include "pmConceptsStandard.h" 21 #include "pmConceptsUpdate.h"22 21 23 22 static bool conceptsInitialised = false;// Have concepts been read? … … 49 48 50 49 pmConceptSpec *pmConceptSpecAlloc(psMetadataItem *blank, pmConceptParseFunc parse, 51 pmConceptFormatFunc format, bool required) 50 pmConceptFormatFunc format, pmConceptCopyFunc copy, 51 bool required) 52 52 { 53 53 pmConceptSpec *spec = psAlloc(sizeof(pmConceptSpec)); … … 57 57 spec->parse = parse; 58 58 spec->format = format; 59 spec->copy = copy; 59 60 spec->required = required; 60 61 … … 86 87 } 87 88 89 psMetadata *pmConceptsSpecs(pmFPALevel level) 90 { 91 if (!conceptsInitialised) { 92 pmConceptsInit(); 93 } 94 95 // Get the appropriate concepts 96 psMetadata *concepts = conceptsFromLevel(level); // Metadata of concepts specs 97 if (!concepts) { 98 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Invalid concept level provided: %d\n", level); 99 return NULL; 100 } 101 102 return concepts; 103 } 104 88 105 bool pmConceptGetRequired(const char *name, pmFPALevel level) 89 106 { … … 129 146 130 147 bool pmConceptRegister(psMetadataItem *blank, pmConceptParseFunc parse, 131 pmConceptFormatFunc format, bool required, pmFPALevel level) 148 pmConceptFormatFunc format, pmConceptCopyFunc copy, 149 bool required, pmFPALevel level) 132 150 { 133 151 PS_ASSERT_PTR_NON_NULL(blank, false); … … 144 162 } 145 163 146 pmConceptSpec *spec = pmConceptSpecAlloc(blank, parse, format, required); // The concept specification164 pmConceptSpec *spec = pmConceptSpecAlloc(blank, parse, format, copy, required); // Concept specification 147 165 psMetadataAdd(target, PS_LIST_TAIL, blank->name, PS_DATA_UNKNOWN | PS_META_REPLACE, 148 166 "Concepts specification", spec); … … 188 206 189 207 190 191 // Read all registered concepts for the specified level192 static bool conceptsRead(psMetadata **specs, // One of the concepts specifications193 pmFPA *fpa, // The FPA194 pmChip *chip, // The chip195 pmCell *cell, // The cell196 unsigned int *read, // What's already been read197 pmConceptSource source, // The source of the concepts to read198 pmConfig *config, // Configuration199 psMetadata *target // Place into which to read the concepts200 )201 {202 assert(specs);203 assert(read);204 assert(target);205 206 if (!conceptsInitialised) {207 pmConceptsInit();208 }209 210 // At least one HDU is required for the reading functions211 pmHDU *hduLow = pmHDUGetLowest(fpa, chip, cell); // Lowest HDU.212 if (!hduLow) {213 // Can't do anything --- don't record any success, but don't return an error either214 return true;215 }216 pmHDU *hduHigh = pmHDUGetHighest(fpa, chip, cell); // Highest HDU217 218 if (cell && (cell->conceptsRead == PM_CONCEPT_SOURCE_NONE)) {219 pmConceptsBlankCell(cell);220 cell->conceptsRead = PM_CONCEPT_SOURCE_BLANK;221 }222 if (chip && (chip->conceptsRead == PM_CONCEPT_SOURCE_NONE)) {223 pmConceptsBlankChip(chip);224 chip->conceptsRead = PM_CONCEPT_SOURCE_BLANK;225 }226 if (fpa && (fpa->conceptsRead == PM_CONCEPT_SOURCE_NONE)) {227 pmConceptsBlankFPA(fpa);228 fpa->conceptsRead = PM_CONCEPT_SOURCE_BLANK;229 }230 231 bool success = true; // Success in reading concepts?232 if (source & PM_CONCEPT_SOURCE_CELLS && !(*read & PM_CONCEPT_SOURCE_CELLS) && cell) {233 if (p_pmConceptsReadFromCells(target, *specs, cell)) {234 *read |= PM_CONCEPT_SOURCE_CELLS;235 } else {236 psError(PS_ERR_UNKNOWN, false, "Error reading concepts from camera configuration.\n");237 success = false;238 }239 }240 241 if (source & PM_CONCEPT_SOURCE_DEFAULTS && !(*read & PM_CONCEPT_SOURCE_DEFAULTS)) {242 if (p_pmConceptsReadFromDefaults(target, *specs, fpa, chip, cell)) {243 *read |= PM_CONCEPT_SOURCE_DEFAULTS;244 } else {245 psError(PS_ERR_UNKNOWN, false, "Error reading concepts from defaults.\n");246 success = false;247 }248 }249 250 if (source & PM_CONCEPT_SOURCE_PHU && !(*read & PM_CONCEPT_SOURCE_PHU) && hduHigh->header) {251 if (p_pmConceptsReadFromHeader(target, *specs, fpa, chip, cell)) {252 *read |= PM_CONCEPT_SOURCE_PHU;253 } else {254 psError(PS_ERR_UNKNOWN, false, "Error reading concepts from PHU.\n");255 success = false;256 }257 }258 259 // If there are multiple HDUs, then it may be that one of them hasn't been read yet (hdu->header not set)260 if (source & PM_CONCEPT_SOURCE_HEADER && !(*read & PM_CONCEPT_SOURCE_HEADER) &&261 hduLow != hduHigh && hduLow->header) {262 if (p_pmConceptsReadFromHeader(target, *specs, fpa, chip, cell)) {263 *read |= PM_CONCEPT_SOURCE_HEADER;264 } else {265 psError(PS_ERR_UNKNOWN, false, "Error reading concepts from header.\n");266 success = false;267 }268 }269 270 #ifdef HAVE_PSDB271 if (source & PM_CONCEPT_SOURCE_DATABASE && !(*read & PM_CONCEPT_SOURCE_DATABASE)) {272 if (p_pmConceptsReadFromDatabase(target, *specs, fpa, chip, cell, config)) {273 *read |= PM_CONCEPT_SOURCE_DATABASE;274 } else {275 psError(PS_ERR_UNKNOWN, false, "Error reading concepts from database.\n");276 success = false;277 }278 }279 #endif280 281 pmConceptsUpdate(fpa, chip, cell);282 283 return success;284 }285 286 // Write all registered concepts for the specified level287 static bool conceptsWrite(psMetadata **specs, // One of the concepts specifications288 const pmFPA *fpa, // The FPA289 const pmChip *chip, // The chip290 const pmCell *cell, // The cell291 pmConceptSource source, // The source of the concepts to write292 pmConfig *config, // Configuration293 const psMetadata *concepts // The concepts to write out294 )295 {296 assert(specs);297 assert(concepts);298 299 if (!conceptsInitialised) {300 pmConceptsInit();301 }302 303 psTrace("psModules.concepts", 3, "Writing concepts (%p %p %p): %d\n", fpa, chip, cell, source);304 305 if (source & PM_CONCEPT_SOURCE_CELLS) {306 p_pmConceptsWriteToCells(*specs, cell, concepts);307 }308 if (source & PM_CONCEPT_SOURCE_DEFAULTS) {309 p_pmConceptsWriteToDefaults(*specs, fpa, chip, cell, concepts);310 }311 if (source & (PM_CONCEPT_SOURCE_PHU | PM_CONCEPT_SOURCE_HEADER)) {312 p_pmConceptsWriteToHeader(*specs, fpa, chip, cell, concepts);313 }314 if (source & PM_CONCEPT_SOURCE_DATABASE) {315 p_pmConceptsWriteToDatabase(*specs, fpa, chip, cell, config, concepts);316 }317 318 return true;319 }320 321 322 bool pmConceptsRead(pmFPA *fpa, pmChip *chip, pmCell *cell, pmConceptSource source, pmConfig *config)323 {324 PS_ASSERT_PTR_NON_NULL(fpa, false);325 bool success = conceptsRead(&conceptsFPA, fpa, chip, cell, &fpa->conceptsRead, source,326 config, fpa->concepts);327 if (chip) {328 success &= conceptsRead(&conceptsChip, fpa, chip, cell, &chip->conceptsRead, source,329 config, chip->concepts);330 }331 if (cell) {332 success &= conceptsRead(&conceptsCell, fpa, chip, cell, &cell->conceptsRead, source,333 config, cell->concepts);334 }335 336 return success;337 }338 339 340 208 bool pmConceptsBlankFPA(pmFPA *fpa) 341 209 { … … 345 213 } 346 214 347 348 bool pmConceptsReadFPA(pmFPA *fpa, pmConceptSource source, bool propagateDown, pmConfig *config)349 {350 PS_ASSERT_PTR_NON_NULL(fpa, false);351 psTrace("psModules.concepts", 5, "Reading FPA concepts: %p %p\n", conceptsFPA, fpa->concepts);352 bool success = conceptsRead(&conceptsFPA, fpa, NULL, NULL, &fpa->conceptsRead, source,353 config, fpa->concepts);354 if (propagateDown) {355 psArray *chips = fpa->chips; // Array of chips356 for (long i = 0; i < chips->n; i++) {357 pmChip *chip = chips->data[i]; // Chip of interest358 if (chip) {359 success &= pmConceptsReadChip(chip, source, false, true, config);360 }361 }362 }363 364 return success;365 }366 367 bool pmConceptsWriteFPA(const pmFPA *fpa, pmConceptSource source, bool propagateDown, pmConfig *config)368 {369 PS_ASSERT_PTR_NON_NULL(fpa, false);370 psTrace("psModules.concepts", 5, "Writing FPA concepts: %p %p\n", conceptsFPA, fpa->concepts);371 bool success = conceptsWrite(&conceptsFPA, fpa, NULL, NULL, source, config, fpa->concepts);372 if (propagateDown) {373 psArray *chips = fpa->chips; // Array of chips374 for (long i = 0; i < chips->n; i++) {375 pmChip *chip = chips->data[i]; // Chip of interest376 if (chip && !chip->hdu) {377 success &= pmConceptsWriteChip(chip, source, false, true, config);378 }379 }380 }381 return success;382 }383 384 215 bool pmConceptsBlankChip(pmChip *chip) 385 216 { … … 389 220 } 390 221 391 bool pmConceptsReadChip(pmChip *chip, pmConceptSource source, bool propagateUp,392 bool propagateDown, pmConfig *config)393 {394 PS_ASSERT_PTR_NON_NULL(chip, false);395 psTrace("psModules.concepts", 5, "Reading chip concepts: %p %p\n", conceptsChip, chip->concepts);396 pmFPA *fpa = chip->parent; // FPA to which the chip belongs397 bool success = conceptsRead(&conceptsChip, fpa, chip, NULL, &chip->conceptsRead, source, config,398 chip->concepts);399 if (propagateUp) {400 success &= conceptsRead(&conceptsFPA, fpa, chip, NULL, &fpa->conceptsRead, source,401 config, fpa->concepts);402 }403 if (propagateDown) {404 psArray *cells = chip->cells; // Array of cells405 for (long i = 0; i < cells->n; i++) {406 pmCell *cell = cells->data[i]; // Cell of interest407 if (cell) {408 success &= pmConceptsReadCell(cell, source, false, config);409 }410 }411 }412 return success;413 }414 415 bool pmConceptsWriteChip(const pmChip *chip, pmConceptSource source, bool propagateUp,416 bool propagateDown, pmConfig *config)417 {418 PS_ASSERT_PTR_NON_NULL(chip, false);419 psTrace("psModules.concepts", 5, "Writing chip concepts: %p %p\n", conceptsChip, chip->concepts);420 pmFPA *fpa = chip->parent; // FPA to which the chip belongs421 bool success = conceptsWrite(&conceptsChip, fpa, chip, NULL, source, config, chip->concepts);422 if (propagateUp && !fpa->hdu) {423 success &= conceptsWrite(&conceptsFPA, fpa, chip, NULL, source, config, fpa->concepts);424 }425 if (propagateDown) {426 psArray *cells = chip->cells; // Array of cells427 for (long i = 0; i < cells->n; i++) {428 pmCell *cell = cells->data[i]; // Cell of interest429 if (cell && !cell->hdu) {430 success &= pmConceptsWriteCell(cell, source, false, config);431 }432 }433 }434 return success;435 }436 437 222 bool pmConceptsBlankCell(pmCell *cell) 438 223 { … … 440 225 psTrace("psModules.concepts", 5, "Blanking cell concepts: %p %p\n", conceptsCell, cell->concepts); 441 226 return conceptsBlank(&conceptsCell, cell->concepts); 442 }443 444 bool pmConceptsReadCell(pmCell *cell, pmConceptSource source, bool propagateUp, pmConfig *config)445 {446 PS_ASSERT_PTR_NON_NULL(cell, false);447 psTrace("psModules.concepts", 5, "Reading cell concepts: %p %p\n", conceptsCell, cell->concepts);448 pmChip *chip = cell->parent; // Chip to which the cell belongs449 pmFPA *fpa = chip->parent; // FPA to which the chip belongs450 451 bool success = conceptsRead(&conceptsCell, fpa, chip, cell, &cell->conceptsRead, source, config,452 cell->concepts);453 if (propagateUp) {454 success &= conceptsRead(&conceptsChip, fpa, chip, cell, &chip->conceptsRead, source, config,455 chip->concepts);456 success &= conceptsRead(&conceptsFPA, fpa, chip, cell, &fpa->conceptsRead, source, config,457 fpa->concepts);458 }459 460 return success;461 }462 463 bool pmConceptsWriteCell(const pmCell *cell, pmConceptSource source, bool propagateUp, pmConfig *config)464 {465 PS_ASSERT_PTR_NON_NULL(cell, false);466 psTrace("psModules.concepts", 5, "Writing cell concepts: %p %p\n", conceptsCell, cell->concepts);467 pmChip *chip = cell->parent; // Chip to which the cell belongs468 pmFPA *fpa = chip->parent; // FPA to which the chip belongs469 470 bool success = conceptsWrite(&conceptsCell, fpa, chip, cell, source, config, cell->concepts);471 if (propagateUp) {472 if (!chip->hdu) {473 success &= conceptsWrite(&conceptsChip, fpa, chip, cell, source, config, chip->concepts);474 if (!fpa->hdu) {475 success &= conceptsWrite(&conceptsFPA, fpa, chip, cell, source, config, fpa->concepts);476 }477 }478 }479 480 return success;481 227 } 482 228 … … 485 231 static void conceptRegister##SUFFIX(const char *name, /* Name of concept */ \ 486 232 const char *comment, /* Comment for concept */ \ 487 pmConceptParseFunc parse, /* Parsing function */ \ 488 pmConceptFormatFunc format, /* Formatting function */ \ 233 pmConceptParseFunc parse, /* Parsing function, or NULL */ \ 234 pmConceptFormatFunc format, /* Formatting function, or NULL */ \ 235 pmConceptCopyFunc copy, /* Copying function, or NULL */ \ 489 236 bool required, /* Required concept? */ \ 490 237 pmFPALevel level /* Level at which concept applies */ \ … … 492 239 { \ 493 240 psMetadataItem *item = psMetadataItemAlloc##TYPENAME(name, comment, DEFAULT); /* Item to add */ \ 494 pmConceptRegister(item, parse, format, required, level); \241 pmConceptRegister(item, parse, format, copy, required, level); \ 495 242 psFree(item); \ 496 243 return; \ … … 515 262 psMetadataItem *item = psMetadataItemAlloc(name, PS_DATA_TIME, comment, time); 516 263 psFree(time); 517 pmConceptRegister(item, p_pmConceptParse_TIME, p_pmConceptFormat_TIME, required, level);264 pmConceptRegister(item, p_pmConceptParse_TIME, p_pmConceptFormat_TIME, NULL, required, level); 518 265 psFree(item); 519 266 } … … 521 268 bool pmConceptsInit(void) 522 269 { 270 if (conceptsInitialised) { 271 return true; 272 } 273 523 274 conceptsInitialised = true; 524 275 … … 527 278 bool init = false; // Did we initialise anything? 528 279 529 if (! conceptsFPA) {280 if (!conceptsFPA) { 530 281 conceptsFPA = psMetadataAlloc(); 531 282 init = true; 532 283 533 284 // Install the standard concepts 534 conceptRegisterStr("FPA.TELESCOPE", "Telescope of origin", NULL, NULL, false, PM_FPA_LEVEL_FPA);535 conceptRegisterStr("FPA.INSTRUMENT", "Instrument name (according to the instrument)", NULL, NULL, false, PM_FPA_LEVEL_FPA);536 conceptRegisterStr("FPA.DETECTOR", "Detector name", NULL, NULL, false, PM_FPA_LEVEL_FPA);537 conceptRegisterStr("FPA.COMMENT", "Observation comment", NULL, NULL, false, PM_FPA_LEVEL_FPA);538 conceptRegisterStr("FPA.OBS.MODE", "Observation mode (eg, survey id)", NULL, NULL, false, PM_FPA_LEVEL_FPA);539 conceptRegisterStr("FPA.OBS.GROUP", "Observation group (eg, associated images)", NULL, NULL, false, PM_FPA_LEVEL_FPA);540 conceptRegisterF32("FPA.FOCUS", "Telescope focus", NULL, NULL, false, PM_FPA_LEVEL_FPA);541 conceptRegisterF32("FPA.AIRMASS", "Airmass at boresight", NULL, NULL, false, PM_FPA_LEVEL_FPA);542 conceptRegisterStr("FPA.FILTERID", "Filter used (parsed, abstract name)", p_pmConceptParse_FPA_FILTER, p_pmConceptFormat_FPA_FILTER, false, PM_FPA_LEVEL_FPA);543 conceptRegisterStr("FPA.FILTER", "Filter used (instrument name)", false, NULL, NULL, PM_FPA_LEVEL_FPA);544 conceptRegisterF32("FPA.POSANGLE", "Position angle of instrument", NULL, NULL, false, PM_FPA_LEVEL_FPA);545 conceptRegisterF32("FPA.ROTANGLE", "Rotator angle of instrument", NULL, NULL, false, PM_FPA_LEVEL_FPA);546 conceptRegisterStr("FPA.RADECSYS", "Celestial coordinate system", NULL, NULL, false, PM_FPA_LEVEL_FPA);547 conceptRegisterF64("FPA.RA", "Right Ascension of boresight", p_pmConceptParse_FPA_Coords, p_pmConceptFormat_FPA_Coords, false, PM_FPA_LEVEL_FPA);548 conceptRegisterF64("FPA.DEC", "Declination of boresight", p_pmConceptParse_FPA_Coords, p_pmConceptFormat_FPA_Coords, false, PM_FPA_LEVEL_FPA);549 conceptRegisterF64("FPA.LONGITUDE", "West longitude of observatory", p_pmConceptParse_FPA_Coords, p_pmConceptFormat_FPA_Coords, false, PM_FPA_LEVEL_FPA);550 conceptRegisterF64("FPA.LATITUDE", "Latitude of observatory", p_pmConceptParse_FPA_Coords, p_pmConceptFormat_FPA_Coords, false, PM_FPA_LEVEL_FPA);551 conceptRegisterF32("FPA.ELEVATION", "Elevation of observatory (metres)", NULL, NULL, false, PM_FPA_LEVEL_FPA);552 conceptRegisterStr("FPA.OBSTYPE", "Type of observation", NULL, NULL, false, PM_FPA_LEVEL_FPA);553 conceptRegisterStr("FPA.OBJECT", "Object of observation", NULL, NULL, false, PM_FPA_LEVEL_FPA);554 conceptRegisterF64("FPA.ALT", "Altitude of boresight", NULL, NULL, false, PM_FPA_LEVEL_FPA);555 conceptRegisterF64("FPA.AZ", "Azimuth of boresight", NULL, NULL, false, PM_FPA_LEVEL_FPA);556 conceptRegisterEnum("FPA.TIMESYS", "Time system", p_pmConceptParse_TIMESYS, p_pmConceptFormat_TIMESYS, false, PM_FPA_LEVEL_FPA);285 conceptRegisterStr("FPA.TELESCOPE", "Telescope of origin", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 286 conceptRegisterStr("FPA.INSTRUMENT", "Instrument name (according to the instrument)", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 287 conceptRegisterStr("FPA.DETECTOR", "Detector name", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 288 conceptRegisterStr("FPA.COMMENT", "Observation comment", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 289 conceptRegisterStr("FPA.OBS.MODE", "Observation mode (eg, survey id)", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 290 conceptRegisterStr("FPA.OBS.GROUP", "Observation group (eg, associated images)", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 291 conceptRegisterF32("FPA.FOCUS", "Telescope focus", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 292 conceptRegisterF32("FPA.AIRMASS", "Airmass at boresight", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 293 conceptRegisterStr("FPA.FILTERID", "Filter used (parsed, abstract name)", p_pmConceptParse_FPA_FILTER, p_pmConceptFormat_FPA_FILTER, NULL, false, PM_FPA_LEVEL_FPA); 294 conceptRegisterStr("FPA.FILTER", "Filter used (instrument name)", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 295 conceptRegisterF32("FPA.POSANGLE", "Position angle of instrument", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 296 conceptRegisterF32("FPA.ROTANGLE", "Rotator angle of instrument", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 297 conceptRegisterStr("FPA.RADECSYS", "Celestial coordinate system", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 298 conceptRegisterF64("FPA.RA", "Right Ascension of boresight", p_pmConceptParse_FPA_Coords, p_pmConceptFormat_FPA_Coords, NULL, false, PM_FPA_LEVEL_FPA); 299 conceptRegisterF64("FPA.DEC", "Declination of boresight", p_pmConceptParse_FPA_Coords, p_pmConceptFormat_FPA_Coords, NULL, false, PM_FPA_LEVEL_FPA); 300 conceptRegisterF64("FPA.LONGITUDE", "West longitude of observatory", p_pmConceptParse_FPA_Coords, p_pmConceptFormat_FPA_Coords, NULL, false, PM_FPA_LEVEL_FPA); 301 conceptRegisterF64("FPA.LATITUDE", "Latitude of observatory", p_pmConceptParse_FPA_Coords, p_pmConceptFormat_FPA_Coords, NULL, false, PM_FPA_LEVEL_FPA); 302 conceptRegisterF32("FPA.ELEVATION", "Elevation of observatory (metres)", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 303 conceptRegisterStr("FPA.OBSTYPE", "Type of observation", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 304 conceptRegisterStr("FPA.OBJECT", "Object of observation", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 305 conceptRegisterF64("FPA.ALT", "Altitude of boresight", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 306 conceptRegisterF64("FPA.AZ", "Azimuth of boresight", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 307 conceptRegisterEnum("FPA.TIMESYS", "Time system", p_pmConceptParse_TIMESYS, p_pmConceptFormat_TIMESYS, p_pmConceptCopy_TIMESYS, false, PM_FPA_LEVEL_FPA); 557 308 conceptRegisterTime("FPA.TIME", "Time of exposure", false, PM_FPA_LEVEL_FPA); 558 conceptRegisterF32("FPA.TEMP", "Temperature of focal plane", NULL, NULL, false, PM_FPA_LEVEL_FPA);559 conceptRegisterF32("FPA.M1X", "Primary Mirror X Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);560 conceptRegisterF32("FPA.M1Y", "Primary Mirror Y Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);561 conceptRegisterF32("FPA.M1Z", "Primary Mirror Z Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);562 conceptRegisterF32("FPA.M1TIP", "Primary Mirror TIP", NULL, NULL, false, PM_FPA_LEVEL_FPA);563 conceptRegisterF32("FPA.M1TILT", "Primary Mirror TILT", NULL, NULL, false, PM_FPA_LEVEL_FPA);564 conceptRegisterF32("FPA.M2X", "Primary Mirror X Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);565 conceptRegisterF32("FPA.M2Y", "Primary Mirror Y Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);566 conceptRegisterF32("FPA.M2Z", "Primary Mirror Z Position", NULL, NULL, false, PM_FPA_LEVEL_FPA);567 conceptRegisterF32("FPA.M2TIP", "Primary Mirror TIP", NULL, NULL, false, PM_FPA_LEVEL_FPA);568 conceptRegisterF32("FPA.M2TILT", "Primary Mirror TILT", NULL, NULL, false, PM_FPA_LEVEL_FPA);569 conceptRegisterF32("FPA.ENV.TEMP", "Environment: Temperature", NULL, NULL, false, PM_FPA_LEVEL_FPA);570 conceptRegisterF32("FPA.ENV.HUMID", "Environment: Humidity", NULL, NULL, false, PM_FPA_LEVEL_FPA);571 conceptRegisterF32("FPA.ENV.WIND", "Environment: Wind speed", NULL, NULL, false, PM_FPA_LEVEL_FPA);572 conceptRegisterF32("FPA.ENV.DIR", "Environment: Wind direction", NULL, NULL, false, PM_FPA_LEVEL_FPA);573 conceptRegisterF32("FPA.TELTEMP.M1", "Telescope Temperatures: M1", p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);574 conceptRegisterF32("FPA.TELTEMP.M1CELL", "Telescope Temperatures: M1 cell", p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);575 conceptRegisterF32("FPA.TELTEMP.M2", "Telescope Temperatures: M2", p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);576 conceptRegisterF32("FPA.TELTEMP.SPIDER", "Telescope Temperatures: spider", p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);577 conceptRegisterF32("FPA.TELTEMP.TRUSS", "Telescope Temperatures: truss", p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);578 conceptRegisterF32("FPA.TELTEMP.EXTRA", "Telescope Temperatures: extra", p_pmConceptParse_TELTEMPS, NULL, false, PM_FPA_LEVEL_FPA);579 conceptRegisterF32("FPA.PON.TIME", "Power On Time", NULL, NULL, false, PM_FPA_LEVEL_FPA);580 conceptRegisterF32("FPA.EXPOSURE", "Exposure time (sec)", NULL, NULL, false, PM_FPA_LEVEL_FPA);581 } 582 if (! conceptsChip) {309 conceptRegisterF32("FPA.TEMP", "Temperature of focal plane", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 310 conceptRegisterF32("FPA.M1X", "Primary Mirror X Position", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 311 conceptRegisterF32("FPA.M1Y", "Primary Mirror Y Position", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 312 conceptRegisterF32("FPA.M1Z", "Primary Mirror Z Position", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 313 conceptRegisterF32("FPA.M1TIP", "Primary Mirror TIP", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 314 conceptRegisterF32("FPA.M1TILT", "Primary Mirror TILT", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 315 conceptRegisterF32("FPA.M2X", "Primary Mirror X Position", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 316 conceptRegisterF32("FPA.M2Y", "Primary Mirror Y Position", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 317 conceptRegisterF32("FPA.M2Z", "Primary Mirror Z Position", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 318 conceptRegisterF32("FPA.M2TIP", "Primary Mirror TIP", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 319 conceptRegisterF32("FPA.M2TILT", "Primary Mirror TILT", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 320 conceptRegisterF32("FPA.ENV.TEMP", "Environment: Temperature", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 321 conceptRegisterF32("FPA.ENV.HUMID", "Environment: Humidity", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 322 conceptRegisterF32("FPA.ENV.WIND", "Environment: Wind speed", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 323 conceptRegisterF32("FPA.ENV.DIR", "Environment: Wind direction", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 324 conceptRegisterF32("FPA.TELTEMP.M1", "Telescope Temperatures: M1", p_pmConceptParse_TELTEMPS, NULL, NULL, false, PM_FPA_LEVEL_FPA); 325 conceptRegisterF32("FPA.TELTEMP.M1CELL", "Telescope Temperatures: M1 cell", p_pmConceptParse_TELTEMPS, NULL, NULL, false, PM_FPA_LEVEL_FPA); 326 conceptRegisterF32("FPA.TELTEMP.M2", "Telescope Temperatures: M2", p_pmConceptParse_TELTEMPS, NULL, NULL, false, PM_FPA_LEVEL_FPA); 327 conceptRegisterF32("FPA.TELTEMP.SPIDER", "Telescope Temperatures: spider", p_pmConceptParse_TELTEMPS, NULL, NULL, false, PM_FPA_LEVEL_FPA); 328 conceptRegisterF32("FPA.TELTEMP.TRUSS", "Telescope Temperatures: truss", p_pmConceptParse_TELTEMPS, NULL, NULL, false, PM_FPA_LEVEL_FPA); 329 conceptRegisterF32("FPA.TELTEMP.EXTRA", "Telescope Temperatures: extra", p_pmConceptParse_TELTEMPS, NULL, NULL, false, PM_FPA_LEVEL_FPA); 330 conceptRegisterF32("FPA.PON.TIME", "Power On Time", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 331 conceptRegisterF32("FPA.EXPOSURE", "Exposure time (sec)", NULL, NULL, NULL, false, PM_FPA_LEVEL_FPA); 332 } 333 if (!conceptsChip) { 583 334 conceptsChip = psMetadataAlloc(); 584 335 init = true; 585 336 586 337 // Install the standard concepts 587 conceptRegisterS32("CHIP.XPARITY", "Orientation in x compared to the rest of the FPA", NULL, NULL, true, PM_FPA_LEVEL_CHIP);588 conceptRegisterS32("CHIP.YPARITY", "Orientation in y compared to the rest of the FPA", NULL, NULL, true, PM_FPA_LEVEL_CHIP);589 conceptRegisterS32("CHIP.X0", "Position of (0,0) on the FPA",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CHIP);590 conceptRegisterS32("CHIP.Y0", "Position of (0,0) on the FPA",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CHIP);591 conceptRegisterS32("CHIP.XSIZE", "Size of chip (pixels)", NULL, NULL, true, PM_FPA_LEVEL_CHIP);592 conceptRegisterS32("CHIP.YSIZE", "Size of chip (pixels)", NULL, NULL, true, PM_FPA_LEVEL_CHIP);593 conceptRegisterF32("CHIP.TEMP", "Temperature of chip", NULL, NULL, false, PM_FPA_LEVEL_CHIP);594 conceptRegisterStr("CHIP.ID", "Chip identifier", NULL, NULL, false, PM_FPA_LEVEL_CHIP);595 } 596 597 if (! conceptsCell) {338 conceptRegisterS32("CHIP.XPARITY", "Orientation in x compared to the rest of the FPA", NULL, NULL, NULL, true, PM_FPA_LEVEL_CHIP); 339 conceptRegisterS32("CHIP.YPARITY", "Orientation in y compared to the rest of the FPA", NULL, NULL, NULL, true, PM_FPA_LEVEL_CHIP); 340 conceptRegisterS32("CHIP.X0", "Position of (0,0) on the FPA",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, NULL, true, PM_FPA_LEVEL_CHIP); 341 conceptRegisterS32("CHIP.Y0", "Position of (0,0) on the FPA",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, NULL, true, PM_FPA_LEVEL_CHIP); 342 conceptRegisterS32("CHIP.XSIZE", "Size of chip (pixels)", NULL, NULL, NULL, true, PM_FPA_LEVEL_CHIP); 343 conceptRegisterS32("CHIP.YSIZE", "Size of chip (pixels)", NULL, NULL, NULL, true, PM_FPA_LEVEL_CHIP); 344 conceptRegisterF32("CHIP.TEMP", "Temperature of chip", NULL, NULL, NULL, false, PM_FPA_LEVEL_CHIP); 345 conceptRegisterStr("CHIP.ID", "Chip identifier", NULL, NULL, NULL, false, PM_FPA_LEVEL_CHIP); 346 } 347 348 if (!conceptsCell) { 598 349 conceptsCell = psMetadataAlloc(); 599 350 init = true; 600 351 601 352 // Install the standard concepts 602 conceptRegisterF32("CELL.GAIN", "CCD gain (e/count)", NULL, NULL, true, PM_FPA_LEVEL_CELL);603 conceptRegisterF32("CELL.READNOISE", "CCD read noise (e)", p_pmConceptParse_CELL_READNOISE, p_pmConceptFormat_CELL_READNOISE, true, PM_FPA_LEVEL_CELL);604 conceptRegisterF32("CELL.SATURATION", "Saturation level (counts)", NULL, NULL, true, PM_FPA_LEVEL_CELL);605 conceptRegisterF32("CELL.BAD", "Bad level (counts)", NULL, NULL, true, PM_FPA_LEVEL_CELL);606 conceptRegisterS32("CELL.XPARITY", "Orientation in x compared to the rest of the chip", NULL, NULL, true, PM_FPA_LEVEL_CELL);607 conceptRegisterS32("CELL.YPARITY", "Orientation in y compared to the rest of the chip", NULL, NULL, true, PM_FPA_LEVEL_CELL);608 conceptRegisterS32("CELL.READDIR", "Read direction, rows=1, cols=2", NULL, NULL, true, PM_FPA_LEVEL_CELL);353 conceptRegisterF32("CELL.GAIN", "CCD gain (e/count)", NULL, NULL, NULL, true, PM_FPA_LEVEL_CELL); 354 conceptRegisterF32("CELL.READNOISE", "CCD read noise (e)", p_pmConceptParse_CELL_READNOISE, p_pmConceptFormat_CELL_READNOISE, NULL, true, PM_FPA_LEVEL_CELL); 355 conceptRegisterF32("CELL.SATURATION", "Saturation level (counts)", NULL, NULL, NULL, true, PM_FPA_LEVEL_CELL); 356 conceptRegisterF32("CELL.BAD", "Bad level (counts)", NULL, NULL, NULL, true, PM_FPA_LEVEL_CELL); 357 conceptRegisterS32("CELL.XPARITY", "Orientation in x compared to the rest of the chip", NULL, NULL, NULL, true, PM_FPA_LEVEL_CELL); 358 conceptRegisterS32("CELL.YPARITY", "Orientation in y compared to the rest of the chip", NULL, NULL, NULL, true, PM_FPA_LEVEL_CELL); 359 conceptRegisterS32("CELL.READDIR", "Read direction, rows=1, cols=2", NULL, NULL, NULL, true, PM_FPA_LEVEL_CELL); 609 360 610 361 // These (CELL.EXPOSURE and CELL.DARKTIME) used to be READOUT.EXPOSURE and READOUT.DARKTIME, but that … … 613 364 // readout is a plane in a 3D image. We'll have to dream up some additional suffix to specify these, 614 365 // but for now.... 615 conceptRegisterF32("CELL.EXPOSURE", "Exposure time (sec)", NULL, NULL, false, PM_FPA_LEVEL_CELL);616 conceptRegisterF32("CELL.DARKTIME", "Time since flush (sec)", NULL, NULL, false, PM_FPA_LEVEL_CELL);617 618 conceptRegisterS32("CELL.XBIN", "Binning in x", p_pmConceptParse_CELL_Binning,p_pmConceptFormat_CELL_XBIN, true, PM_FPA_LEVEL_CELL);619 conceptRegisterS32("CELL.YBIN", "Binning in y",p_pmConceptParse_CELL_Binning,p_pmConceptFormat_CELL_YBIN, true, PM_FPA_LEVEL_CELL);620 conceptRegisterEnum("CELL.TIMESYS", "Time system", p_pmConceptParse_TIMESYS,p_pmConceptFormat_TIMESYS, false, PM_FPA_LEVEL_CELL);366 conceptRegisterF32("CELL.EXPOSURE", "Exposure time (sec)", NULL, NULL, NULL, false, PM_FPA_LEVEL_CELL); 367 conceptRegisterF32("CELL.DARKTIME", "Time since flush (sec)", NULL, NULL, NULL, false, PM_FPA_LEVEL_CELL); 368 369 conceptRegisterS32("CELL.XBIN", "Binning in x", p_pmConceptParse_CELL_Binning,p_pmConceptFormat_CELL_XBIN, NULL, true, PM_FPA_LEVEL_CELL); 370 conceptRegisterS32("CELL.YBIN", "Binning in y",p_pmConceptParse_CELL_Binning,p_pmConceptFormat_CELL_YBIN, NULL, true, PM_FPA_LEVEL_CELL); 371 conceptRegisterEnum("CELL.TIMESYS", "Time system", p_pmConceptParse_TIMESYS,p_pmConceptFormat_TIMESYS, p_pmConceptCopy_TIMESYS, false, PM_FPA_LEVEL_CELL); 621 372 conceptRegisterTime("CELL.TIME", "Time of exposure", false, PM_FPA_LEVEL_CELL); 622 conceptRegisterS32("CELL.X0", "Position of (0,0) on the chip",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);623 conceptRegisterS32("CELL.Y0", "Position of (0,0) on the chip",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);624 conceptRegisterS32("CELL.XSIZE", "Size of cell (pixels)", NULL, NULL, true, PM_FPA_LEVEL_CELL);625 conceptRegisterS32("CELL.YSIZE", "Size of cell (pixels)", NULL, NULL, true, PM_FPA_LEVEL_CELL);626 conceptRegisterS32("CELL.XWINDOW", "Start of cell window (pixels)",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);627 conceptRegisterS32("CELL.YWINDOW", "Start of cell window (pixels)",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, true, PM_FPA_LEVEL_CELL);628 conceptRegisterF32("CELL.VARFACTOR", "Variance factor for conversion from large to small scales", NULL, NULL, true, PM_FPA_LEVEL_CELL);373 conceptRegisterS32("CELL.X0", "Position of (0,0) on the chip",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, NULL, true, PM_FPA_LEVEL_CELL); 374 conceptRegisterS32("CELL.Y0", "Position of (0,0) on the chip",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, NULL, true, PM_FPA_LEVEL_CELL); 375 conceptRegisterS32("CELL.XSIZE", "Size of cell (pixels)", NULL, NULL, NULL, true, PM_FPA_LEVEL_CELL); 376 conceptRegisterS32("CELL.YSIZE", "Size of cell (pixels)", NULL, NULL, NULL, true, PM_FPA_LEVEL_CELL); 377 conceptRegisterS32("CELL.XWINDOW", "Start of cell window (pixels)",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, NULL, true, PM_FPA_LEVEL_CELL); 378 conceptRegisterS32("CELL.YWINDOW", "Start of cell window (pixels)",p_pmConceptParse_Positions,p_pmConceptFormat_Positions, NULL, true, PM_FPA_LEVEL_CELL); 379 conceptRegisterF32("CELL.VARFACTOR", "Variance factor for conversion from large to small scales", NULL, NULL, NULL, true, PM_FPA_LEVEL_CELL); 629 380 630 381 // CELL.TRIMSEC … … 635 386 "Trim section", trimsec); 636 387 psFree(trimsec); 637 pmConceptRegister(cellTrimsec, p_pmConceptParse_CELL_TRIMSEC,p_pmConceptFormat_CELL_TRIMSEC, true, PM_FPA_LEVEL_CELL);388 pmConceptRegister(cellTrimsec, p_pmConceptParse_CELL_TRIMSEC,p_pmConceptFormat_CELL_TRIMSEC, NULL, true, PM_FPA_LEVEL_CELL); 638 389 psFree(cellTrimsec); 639 390 } … … 645 396 "Bias sections", biassecs); 646 397 psFree(biassecs); 647 pmConceptRegister(cellBiassec, p_pmConceptParse_CELL_BIASSEC, p_pmConceptFormat_CELL_BIASSEC, true, PM_FPA_LEVEL_CELL);398 pmConceptRegister(cellBiassec, p_pmConceptParse_CELL_BIASSEC, p_pmConceptFormat_CELL_BIASSEC, NULL, true, PM_FPA_LEVEL_CELL); 648 399 psFree(cellBiassec); 649 400 } … … 666 417 667 418 conceptsInitialised = false; 668 }669 670 671 // List of concepts not to copy, for each level.672 // Must be NULL-terminated673 static const char *dontCopyConceptsFPA[] = { "FPA.OBS", "FPA.NAME", "FPA.CAMERA", 0 };674 static const char *dontCopyConceptsChip[] = { "CHIP.NAME", 0 };675 static const char *dontCopyConceptsCell[] = { "CELL.NAME", "CELL.TRIMSEC", "CELL.BIASSEC", 0 };676 677 // Copy concepts from a source container to a target container, avoiding certain entries678 static void copyConcepts(psMetadata *target, // Target metadata container679 psMetadata *source, // Source metadata container680 const char *dontCopyConcepts[] // Don't copy these concepts681 )682 {683 assert(target);684 assert(source);685 assert(dontCopyConcepts);686 687 psMetadataIterator *iter = psMetadataIteratorAlloc(source, PS_LIST_HEAD, NULL);688 psMetadataItem *item; // Item from iteration689 while ((item = psMetadataGetAndIncrement(iter))) {690 const char *name = item->name; // Name of concept691 bool copyOK = true; // OK to copy692 for (int i = 0; dontCopyConcepts[i] && copyOK; i++) {693 if (!strcmp(name, dontCopyConcepts[i])) {694 copyOK = false;695 }696 }697 if (!copyOK) {698 continue;699 }700 psMetadataItem *new = psMetadataItemCopy(item); // New item, a copy of the old701 psMetadataAddItem(target, new, PS_LIST_TAIL, PS_META_REPLACE);702 psFree(new); // Drop reference703 }704 psFree(iter);705 706 return;707 }708 709 710 bool pmFPACopyConcepts(pmFPA *target, const pmFPA *source)711 {712 PS_ASSERT_PTR_NON_NULL(target, false);713 PS_ASSERT_PTR_NON_NULL(source, false);714 715 // Copy FPA concepts716 copyConcepts(target->concepts, source->concepts, dontCopyConceptsFPA);717 718 // Copy chip concepts719 psArray *targetChips = target->chips; // Chips in target720 psArray *sourceChips = source->chips; // Chips in source721 if (targetChips->n != sourceChips->n) {722 psError(PS_ERR_IO, true, "Number of chips in target (%ld) and source (%ld) differ --- unable to copy "723 "concepts.\n", targetChips->n, sourceChips->n);724 return false;725 }726 for (int i = 0; i < targetChips->n; i++) {727 pmChip *targetChip = targetChips->data[i]; // Target chip of interest728 pmChip *sourceChip = sourceChips->data[i]; // Source chip of interest729 if (! targetChip || ! sourceChip) {730 continue;731 }732 733 copyConcepts(targetChip->concepts, sourceChip->concepts, dontCopyConceptsChip);734 735 // Copy cell concepts736 psArray *targetCells = targetChip->cells; // Cells in target737 psArray *sourceCells = sourceChip->cells; // Cells in source738 if (targetCells->n != sourceCells->n) {739 psError(PS_ERR_IO, true, "Number of cells in target (%ld) and source (%ld) differ for chip %d ---"740 " unable to copy concepts.\n", targetCells->n, sourceCells->n, i);741 return false;742 }743 for (int j = 0; j < targetCells->n; j++) {744 pmCell *targetCell = targetCells->data[j]; // Target chip of interest745 pmCell *sourceCell = sourceCells->data[j]; // Source chip of interest746 if (! targetCell || ! sourceCell) {747 continue;748 }749 750 copyConcepts(targetCell->concepts, sourceCell->concepts, dontCopyConceptsCell);751 }752 }753 754 return true;755 }756 757 758 bool pmConceptsCopyFPA(pmFPA *target, const pmFPA *source, bool chips, bool cells)759 {760 PS_ASSERT_PTR_NON_NULL(target, false);761 PS_ASSERT_PTR_NON_NULL(source, false);762 763 // Copy FPA concepts764 copyConcepts(target->concepts, source->concepts, dontCopyConceptsFPA);765 766 // Copy chip concepts767 bool status = true; // Status of chips768 if (chips) {769 psArray *targetChips = target->chips; // Chips in target770 psArray *sourceChips = source->chips; // Chips in source771 if (targetChips->n != sourceChips->n) {772 psError(PS_ERR_IO, true,773 "Number of chips in target (%ld) and source (%ld) differ --- unable to copy concepts.",774 targetChips->n, sourceChips->n);775 return false;776 }777 for (int i = 0; i < targetChips->n; i++) {778 pmChip *targetChip = targetChips->data[i]; // Target chip of interest779 pmChip *sourceChip = sourceChips->data[i]; // Source chip of interest780 if (! targetChip || ! sourceChip) {781 continue;782 }783 784 status &= pmConceptsCopyChip(targetChip, sourceChip, cells);785 }786 }787 788 return status;789 }790 791 bool pmConceptsCopyChip(pmChip *target, const pmChip *source, bool cells)792 {793 PS_ASSERT_PTR_NON_NULL(target, false);794 PS_ASSERT_PTR_NON_NULL(source, false);795 796 // Copy chip concepts797 copyConcepts(target->concepts, source->concepts, dontCopyConceptsChip);798 799 // Copy cell concepts800 bool status = true; // Status of cells801 if (cells) {802 psArray *targetCells = target->cells; // Cells in target803 psArray *sourceCells = source->cells; // Cells in source804 if (targetCells->n != sourceCells->n) {805 psError(PS_ERR_IO, true,806 "Number of cells in target (%ld) and source (%ld) differ --- unable to copy concepts.",807 targetCells->n, sourceCells->n);808 return false;809 }810 for (int j = 0; j < targetCells->n; j++) {811 pmCell *targetCell = targetCells->data[j]; // Target chip of interest812 pmCell *sourceCell = sourceCells->data[j]; // Source chip of interest813 if (! targetCell || ! sourceCell) {814 continue;815 }816 817 status &= pmConceptsCopyCell(targetCell, sourceCell);818 }819 }820 821 return status;822 }823 824 825 bool pmConceptsCopyCell(pmCell *target, const pmCell *source)826 {827 PS_ASSERT_PTR_NON_NULL(target, false);828 PS_ASSERT_PTR_NON_NULL(source, false);829 830 copyConcepts(target->concepts, source->concepts, dontCopyConceptsCell);831 832 return true;833 419 } 834 420
Note:
See TracChangeset
for help on using the changeset viewer.
