Changeset 7589 for trunk/psModules/src/camera/pmFPAConstruct.c
- Timestamp:
- Jun 16, 2006, 3:50:43 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/camera/pmFPAConstruct.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/camera/pmFPAConstruct.c
r7526 r7589 200 200 201 201 202 // Looks up the particular content based on the header 203 static const char *getContent(psMetadata *fileInfo, // The FILE from the camera format configuration 204 psMetadata *contents, // The CONTENTS from the camera format configuration 205 psMetadata *header // The (primary) header 202 // Looks up the particular content, based on the chip and cell 203 static const char *getContent(const psMetadata *fileInfo, // The FILE from the camera format configuration 204 const psMetadata *contents, // The CONTENTS from the camera format configuration 205 const pmChip *chip, // The chip of interest 206 const pmCell *cell // The cell of interest 206 207 ) 207 208 { 208 209 assert(fileInfo); 209 210 assert(contents); 210 assert( header);211 assert(chip); 211 212 212 213 bool mdok = true; // Status of MD lookup 213 c onst char *contentHeaders = psMetadataLookupStr(&mdok, fileInfo, "CONTENT"); // Headers for content214 if (!mdok || !content Headers || strlen(contentHeaders) == 0) {214 char *contentKey = psMetadataLookupStr(&mdok, fileInfo, "CONTENT"); // Key for CONTENTS 215 if (!mdok || !contentKey || strlen(contentKey) == 0) { 215 216 psError(PS_ERR_IO, true, "Unable to find CONTENT in FILE within camera format configuration.\n"); 216 217 return NULL; 217 218 } 218 219 219 psList *keywords = psStringSplit(contentHeaders, " ,;", true); // List of keywords 220 psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false); // Iterator 221 psString keyword = NULL; // Keyword, from iteration 222 psString contentsKey = NULL; // Key to the CONTENTS menu 223 bool first = true; // Is it the first value? 224 while ((keyword = psListGetAndIncrement(keywordsIter))) { 225 const char *value = psMetadataLookupStr(&mdok, header, keyword); 226 if (first) { 227 psStringAppend(&contentsKey, "%s", value); 228 first = false; 229 } else { 230 psStringAppend(&contentsKey, "_%s", value); 231 } 232 } 233 psFree(keywordsIter); 234 psFree(keywords); 235 psTrace(__func__, 5, "Looking up %s in the CONTENTS.\n", contentsKey); 236 const char *content = psMetadataLookupStr(&mdok, contents, contentsKey); 220 contentKey = psStringCopy(contentKey); // So that we're not altering something someone else might use... 221 222 // Replace some concept names 223 if (strstr(contentKey, "{CHIP.NAME}")) { 224 if (!chip) { 225 psError(PS_ERR_IO, true, "CONTENT in FILE refers to CHIP.NAME, but no chip was provided.\n"); 226 psFree(contentKey); 227 return NULL; 228 } 229 const char *name = psMetadataLookupStr(&mdok, chip->concepts, "CHIP.NAME"); 230 if (mdok && name && strlen(name) > 0) { 231 contentKey = psStringSubstitute(contentKey, name, "{CHIP.NAME}"); 232 } 233 } 234 235 if (strstr(contentKey, "{CELL.NAME}")) { 236 if (!chip) { 237 psError(PS_ERR_IO, true, "CONTENT in FILE refers to CELL.NAME, but no chip was provided.\n"); 238 psFree(contentKey); 239 return NULL; 240 } 241 const char *name = psMetadataLookupStr(&mdok, cell->concepts, "CELL.NAME"); 242 if (mdok && name && strlen(name) > 0) { 243 contentKey = psStringSubstitute(contentKey, name, "{CELL.NAME}"); 244 } 245 } 246 247 psTrace(__func__, 5, "Looking up %s in the CONTENTS.\n", contentKey); 248 const char *content = psMetadataLookupStr(&mdok, contents, contentKey); 237 249 if (!mdok || !content || strlen(content) == 0) { 238 psError(PS_ERR_IO, true, "Unable to find %s in the CONTENTS.\n", contentsKey); 239 return NULL; 240 } 241 psFree(contentsKey); 250 psFree(contentKey); 251 psError(PS_ERR_IO, true, "Unable to find %s in the CONTENTS.\n", contentKey); 252 return NULL; 253 } 254 255 psFree(contentKey); 242 256 243 257 return content; … … 253 267 pmFPALevel level, // The level at which to add the HDU 254 268 const char *contents, // The contents line, consisting of a list of chip:cell 255 psMetadata *format // Camera format configuration269 const psMetadata *format // Camera format configuration 256 270 ) 257 271 { … … 364 378 } 365 379 366 static pmFPALevel hduLevel( psMetadata *format // The camera format configuration380 static pmFPALevel hduLevel(const psMetadata *format // The camera format configuration 367 381 ) 368 382 { … … 442 456 } 443 457 444 bool pmFPAAddSourceFromView(pmFPA *fpa, // The FPA 445 const pmFPAview *phuView, // The view, corresponding to the PHU 446 psMetadata *format // Format of file 458 459 // This is the engine for the pmFPAAddSourceFrom{Header,View} functions 460 // It returns a view corresponding to the PHU 461 static pmFPAview *addSource(pmFPA *fpa, // The FPA 462 const pmFPAview *phuView, // The view corresponding to the PHU, or NULL 463 const psMetadata *header, // The PHU header, or NULL 464 const psMetadata *format // Format of file 447 465 ) 448 466 { 449 PS_ASSERT_PTR_NON_NULL(fpa, false); 450 PS_ASSERT_PTR_NON_NULL(phuView, false); 451 PS_ASSERT_PTR_NON_NULL(format, false); 452 453 // Where does the PHU go? 454 bool mdok = true; // Status of MD lookup 455 psMetadata *fileInfo = psMetadataLookupMD(&mdok, format, "FILE"); // File information from the format 456 if (!mdok || !fileInfo) { 457 psError(PS_ERR_IO, false, "Unable to find FILE information in the camera format configuration.\n"); 458 return false; 459 } 460 const char *phuType = psMetadataLookupStr(&mdok, fileInfo, "PHU"); // What is the PHU? 461 if (!mdok || strlen(phuType) == 0) { 462 psError(PS_ERR_IO, false, "Unable to find PHU in the FILE information of the camera format.\n"); 463 return false; 464 } 465 466 // Generate the PHU 467 pmHDU *phdu = pmHDUAlloc("PHU"); // The primary header data unit 468 phdu->format = psMemIncrRefCounter(format); 469 470 // Put in the PHU 471 pmChip *chip = NULL; // The chip that corresponds to the PHU 472 pmCell *cell = NULL; // The cell that corresponds to the PHU 473 if (strcasecmp(phuType, "FPA") == 0) { 474 addHDUtoFPA(fpa, phdu); 475 psFree(phdu); 476 } else { 477 psArray *chips = fpa->chips; // Array of chips 478 if (phuView->chip < 0 || phuView->chip > chips->n) { 479 psError(PS_ERR_IO, true, "PHU specified by the camera format requires specification of a " 480 "particular chip, which cannot be determined from the view (%d).\n", phuView->chip); 481 psFree(phdu); 482 return false; 483 } 484 chip = chips->data[phuView->chip]; 485 if (strcasecmp(phuType, "CHIP") == 0) { 486 addHDUtoChip(chip, phdu); 487 psFree(phdu); 488 } else if (strcasecmp(phuType, "CELL") == 0) { 489 psArray *cells = chip->cells; // Array of cells 490 if (phuView->cell < 0 || phuView->cell > cells->n) { 491 psError(PS_ERR_IO, true, "PHU specified by the camera format requires specification of a " 492 "particular cell, which cannot be determined from the view (%d).\n", phuView->cell); 493 psFree(phdu); 494 return false; 495 } 496 addHDUtoCell(cell, phdu); 497 psFree(phdu); 498 } else { 499 psError(PS_ERR_IO, true, "PHU in the camera configuration format is not FPA, CHIP or CELL.\n"); 500 psFree(phdu); 501 return false; 502 } 503 } 504 505 // Put in the extensions 506 pmFPALevel level = hduLevel(format);// The level for the HDUs to go 507 if (level == PM_FPA_LEVEL_NONE) { 508 // No extensions. We're done unless PHU == FPA, in which case we need to process the contents 509 if (strcasecmp(phuType, "FPA") == 0) { 510 const char *content = psMetadataLookupStr(&mdok, format, "CONTENTS"); // Contents of the FITS file 511 if (!mdok || !content || strlen(content) == 0) { 512 psError(PS_ERR_IO, true, "Unable to find CONTENTS of type STR in the camera " 513 "format configuration.\n"); 514 return false; 515 } 516 if (processContents(fpa, chip, cell, phdu, level, content, format) < 0) { 517 psError(PS_ERR_IO, false, "Error setting contents.\n"); 518 return false; 519 } 520 } 521 return true; 522 } 523 psMetadata *contents = psMetadataLookupMD(&mdok, format, "CONTENTS"); // The contents of the FITS file 524 if (!mdok || !contents) { 525 psError(PS_ERR_IO, false, "Unable to find CONTENTS in the camera format configuration.\n"); 526 return false; 527 } 528 529 psMetadataIterator *contentsIter = psMetadataIteratorAlloc(contents, PS_LIST_HEAD, NULL); // Iterator 530 psMetadataItem *contentsItem = NULL;// Item from the contents iteration 531 while ((contentsItem = psMetadataGetAndIncrement(contentsIter))) { 532 if (contentsItem->type != PS_DATA_STRING) { 533 psLogMsg(__func__, PS_LOG_WARN, "Content item %s is not of type STR --- ignored.\n", 534 contentsItem->name); 535 continue; 536 } 537 pmHDU *hdu = pmHDUAlloc(contentsItem->name); // HDU to add 538 hdu->format = psMemIncrRefCounter(format); 539 const char *content = contentsItem->data.V; // The content data 540 if (processContents(fpa, chip, cell, hdu, level, content, format) < 0) { 541 psError(PS_ERR_IO, false, "Error setting contents for %s", contentsItem->name); 542 psFree(hdu); 543 psFree(contentsIter); 544 545 return false; 546 } 547 psFree(hdu); 548 } 549 psFree(contentsIter); 550 551 return true; 552 } 553 554 555 556 // Add an input file to the FPA 557 pmFPAview *pmFPAAddSourceFromHeader(pmFPA *fpa, // The FPA 558 psMetadata *phu, // Primary header of file 559 psMetadata *format // Format of file 560 ) 561 { 562 PS_ASSERT_PTR_NON_NULL(fpa, NULL); 563 PS_ASSERT_PTR_NON_NULL(phu, NULL); 564 PS_ASSERT_PTR_NON_NULL(format, NULL); 467 assert(fpa); 468 assert(phuView || header); 469 assert(format); 565 470 566 471 bool mdok = true; // Status from metadata lookups … … 571 476 } 572 477 573 // Check the name of the FPA 574 psString newFPAname = phuNameFromHeader("FPA.NAME", fileInfo, phu); // New name for the FPA 575 if (!newFPAname) { 576 psError(PS_ERR_IO, true, "Unable to determine FPA.NAME"); 577 return NULL; 578 } 579 580 // is FPAname already defined, new name must match it 581 // XXX if not, is it an error? 582 const char *currentFPAname = psMetadataLookupStr(&mdok, fpa->concepts, "FPA.NAME"); // Current name 583 if (mdok && currentFPAname && strlen(currentFPAname) > 0 && strcmp(currentFPAname, newFPAname) != 0) { 584 psLogMsg(__func__, PS_LOG_WARN, "FPA.NAME for new source (%s) doesn't match FPA.NAME for current " 585 "fpa (%s).\n", newFPAname, currentFPAname); 586 } 587 psMetadataAddStr(fpa->concepts, PS_LIST_HEAD, "FPA.NAME", PS_META_REPLACE, "Name of FPA", newFPAname); 588 psFree(newFPAname); // Drop reference 589 590 // Where does the PHU go? 478 // At what level does the PHU go? 591 479 const char *phuType = psMetadataLookupStr(&mdok, fileInfo, "PHU"); // What is the PHU? 592 480 if (!mdok || strlen(phuType) == 0) { … … 594 482 return NULL; 595 483 } 484 485 // Prepare the PHU to be placed in the camera hierarchy 596 486 pmHDU *phdu = pmHDUAlloc("PHU"); // The primary header data unit 597 phdu->header = psMemIncrRefCounter(phu); 598 phdu->format = psMemIncrRefCounter(format); 599 // Generate the view 600 pmFPAview *view = pmFPAviewAlloc(0); // The FPA view corresponding to the PHU, to be returned 601 view->chip = -1; 602 view->cell = -1; 603 view->readout = -1; 604 605 // And what are the individual extensions? 487 // Casting to psPtr to avoide "warning: passing arg 1 of `p_psMemIncrRefCounter' discards qualifiers from 488 // pointer target type" 489 phdu->header = psMemIncrRefCounter((const psPtr)header); 490 phdu->format = psMemIncrRefCounter((const psPtr)format); 491 pmFPAview *view = pmFPAviewAlloc(0); // View, to be returned 492 if (phuView) { 493 // Copy the view, for the case where we're given a header. 494 *view = *phuView; 495 } 496 497 // And at what level do the individual extensions go? 606 498 const char *extType = psMetadataLookupStr(&mdok, fileInfo, "EXTENSIONS"); // What's in the extns? 607 499 if (!mdok || strlen(extType) == 0) { … … 611 503 } 612 504 613 614 // This is a special case: PHU=FPA and EXTENSIONS=NONE. The only reason to do this is in the case of 615 // single CCD imagers, where the entire FPA is in the PHU image. In this case, the CONTENTS is of type 616 // STR (rather than METADATA), and has the usual chip:cell. 505 // Now, there are a few cases: 506 507 // 1. PHU=FPA and EXTENSIONS=NONE. This is a single CCD imager, where the entire FPA is in the PHU image. 508 // In this case, the CONTENTS is of type STR (rather than METADATA), and has the usual chip:cell:cellType. 509 // 510 // 2. PHU=CHIP or PHU=CELL, and EXTENSIONS=NONE. This is a single chip or cell from a mosaic camera in 511 // its own file (e.g., Megacam split). In this case, the CONTENTS is of type METADATA, and consists of a 512 // menu of choices for the contents of the file. This is because we need to work out which chip and/or 513 // cell it comes from. 514 // 515 // 3. EXTENSIONS=CHIP or EXTENSIONS=CELL. This is a mosaic camera, with multiple extensions. In this 516 // case, the CONTENTS is of type METADATA, and consists of a list of contents of the file. 517 // 518 // In all of the above cases, the contents are specified by chip:cell:cellType triples. It's just how the 519 // contents as a *whole* are collected that changes, and what that collection means. 520 // 521 // We deal with each of these cases in turn. 522 523 // Case 1: PHU=FPA and EXTENSIONS=NONE. We need to parse the single list of chip:cell:cellType entries. 617 524 if (strcasecmp(phuType, "FPA") == 0 && strcasecmp(extType, "NONE") == 0) { 618 525 const char *contents = psMetadataLookupStr(&mdok, format, "CONTENTS"); // The contents of the file … … 628 535 psFree(phdu); 629 536 psFree(view); 630 631 537 return NULL; 632 538 } 633 634 539 psFree(phdu); 540 635 541 return view; 636 542 } 637 543 638 // In all other cases, the CONTENTS is of type METADATA, and is either a menu if EXTENSIONS=NONE, or639 // alist of extensions otherwise.544 // In cases 2 and 3, the CONTENTS is of type METADATA, and is either a menu (if EXTENSIONS=NONE), or a 545 // list of extensions otherwise. 640 546 psMetadata *contents = psMetadataLookupMD(&mdok, format, "CONTENTS"); // The contents of the FITS file 641 547 if (!mdok || !contents) { … … 649 555 } 650 556 } 651 557 psFree(phdu); 652 558 psFree(view); 653 559 return NULL; 654 560 } 655 561 656 // No extensions --- only have the PHU. In this case, the CONTENTS is a menu, with CONTENT indicating 657 // header keywords that provides a key to the CONTENTS menu. 562 // Case 2: EXTENSIONS=NONE. We only have the PHU. The value of CONTENT tells us a header keyword, which 563 // gives us the key to the CONTENTS menu. Or, if we've got the view specifying the PHU, we can get the 564 // chip/cell directly from that. 658 565 if (strcasecmp(extType, "NONE") == 0) { 659 // We have already dealt with the case PHU=FPA, in a special case, above. 660 const char *content = getContent(fileInfo, contents, phu); // The content: string of chip:cell pairs 661 662 // Need to look up what chip we have. 663 psString chipName = phuNameFromHeader("CHIP.NAME", fileInfo, phu); 664 psTrace(__func__, 5, "This is chip %s\n", chipName); 566 pmChip *chip = NULL; // The chip of interest 567 pmCell *cell = NULL; // The cell of interest 568 pmFPALevel level = PM_FPA_LEVEL_NONE; // Level for HDU to be added 569 570 if (phuView) { 571 // We can get the chip/cell from the view 572 if (phuView->chip != -1 && phuView->chip < fpa->chips->n) { 573 chip = fpa->chips->data[phuView->chip]; 574 level = PM_FPA_LEVEL_CHIP; 575 if (phuView->cell != -1) { 576 if (phuView->cell < chip->cells->n) { 577 cell = chip->cells->data[phuView->cell]; 578 level = PM_FPA_LEVEL_CELL; 579 } else { 580 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "PHU view for cell (%d) does not " 581 "correspond to camera format.\n", phuView->cell); 582 psFree(phdu); 583 return NULL; 584 } 585 } 586 } else { 587 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "PHU view for chip (%d) does not correspond to " 588 "camera format.\n", phuView->chip); 589 psFree(phdu); 590 return NULL; 591 } 592 } else { 593 // Need to look up what chip we have. 594 psString chipName = phuNameFromHeader("CHIP.NAME", fileInfo, header); 595 psTrace(__func__, 5, "This is chip %s\n", chipName); 596 int chipNum = pmFPAFindChip(fpa, chipName); // Chip number 597 if (chipNum == -1) { 598 psError(PS_ERR_IO, true, "Unable to find chip %s in FPA.\n", chipName); 599 psFree(phdu); 600 psFree(view); 601 return NULL; 602 } 603 pmChip *chip = fpa->chips->data[chipNum]; // Chip of interest 604 view->chip = chipNum; 605 606 if (strcasecmp(phuType, "CHIP") == 0) { 607 level = PM_FPA_LEVEL_CHIP; 608 } else if (strcasecmp(phuType, "CELL") == 0) { 609 level = PM_FPA_LEVEL_CELL; 610 // Need to look up what cell we have. 611 psString cellName = phuNameFromHeader("CELL.NAME", fileInfo, header); 612 int cellNum = pmChipFindCell(chip, cellName); // Cell number 613 if (cellNum == -1) { 614 psError(PS_ERR_IO, true, "Unable to find cell %s in chip %s.\n", cellName, chipName); 615 psFree(view); 616 psFree(phdu); 617 return NULL; 618 } 619 cell = chip->cells->data[cellNum]; 620 view->cell = cellNum; 621 psFree(cellName); 622 } else { 623 // We have already dealt with the case PHU=FPA, in a special case above, so if we get here 624 // it's an error. 625 psError(PS_ERR_IO, true, "PHU is not FPA, CHIP or CELL.\n"); 626 psFree(phdu); 627 psFree(view); 628 return NULL; 629 } 630 psFree(chipName); 631 } 632 633 const char *content = getContent(fileInfo, contents, chip, cell); // The chip:cell:cellType triples 634 if (!content || strlen(content) == 0) { 635 psError(PS_ERR_IO, false, "Unable to get CONTENTS.\n"); 636 psFree(phdu); 637 psFree(view); 638 return NULL; 639 } 640 if (processContents(fpa, chip, cell, phdu, level, content, format) < 0) { 641 psError(PS_ERR_IO, false, "Error setting CONTENTS"); 642 psFree(phdu); 643 psFree(view); 644 return NULL; 645 } 646 psFree(phdu); 647 648 return view; 649 } 650 651 // Case 3: EXTENSIONS=CHIP or EXTENSIONS=CELL. We have extensions that we iterate through. The CONTENTS 652 // is a list of extensions. 653 pmChip *chip = NULL; // The chip of interest 654 pmCell *cell = NULL; // The cell of interest 655 656 // First, put in the PHU 657 if (strcasecmp(phuType, "FPA") == 0) { 658 addHDUtoFPA(fpa, phdu); 659 } else { 660 // Get the chip 661 psString chipName = phuNameFromHeader("CHIP.NAME", fileInfo, header); // Name of the chip 665 662 int chipNum = pmFPAFindChip(fpa, chipName); // Chip number 666 663 if (chipNum == -1) { … … 669 666 return NULL; 670 667 } 671 pmChip *chip = fpa->chips->data[chipNum]; // Chip of interest672 view->chip = chipNum;673 674 pmCell *cell = NULL; // Cell of interest675 676 pmFPALevel level = PM_FPA_LEVEL_NONE; // Level for HDU to be added677 if (strcasecmp(phuType, "CHIP") == 0) {678 level = PM_FPA_LEVEL_CHIP;679 } else if (strcasecmp(phuType, "CELL") == 0) {680 level = PM_FPA_LEVEL_CELL;681 // Need to look up what cell we have.682 psString cellName = phuNameFromHeader("CELL.NAME", fileInfo, phu);683 int cellNum = pmChipFindCell(chip, cellName); // Cell number684 if (cellNum == -1) {685 psError(PS_ERR_IO, true, "Unable to find cell %s in chip %s.\n", cellName, chipName);686 psFree(view);687 return NULL;688 }689 cell = chip->cells->data[cellNum];690 view->cell = cellNum;691 psFree(cellName);692 } else {693 psError(PS_ERR_IO, true, "PHU is not FPA, CHIP or CELL.\n");694 psFree(view);695 return NULL;696 }697 psFree(chipName);698 699 if (processContents(fpa, chip, cell, phdu, level, content, format) < 0) {700 psError(PS_ERR_IO, false, "Error setting CONTENTS");701 psFree(phdu);702 psFree(view);703 return NULL;704 }705 psFree(phdu);706 return view;707 }708 709 710 // From here on, we have extensions that we iterate through. The CONTENTS is a list of extensions.711 pmChip *chip = NULL; // The chip of interest712 pmCell *cell = NULL; // The cell of interest713 714 // First, put in the PHU715 if (strcasecmp(phuType, "FPA") == 0) {716 addHDUtoFPA(fpa, phdu);717 } else {718 // Get the chip719 psString chipName = phuNameFromHeader("CHIP.NAME", fileInfo, phu); // Name of the chip720 int chipNum = pmFPAFindChip(fpa, chipName); // Chip number721 if (chipNum == -1) {722 psError(PS_ERR_IO, true, "Unable to find chip %s in FPA.\n", chipName);723 psFree(view);724 return NULL;725 }726 668 chip = fpa->chips->data[chipNum]; // The specified chip 727 669 view->chip = chipNum; … … 730 672 addHDUtoChip(chip, phdu); 731 673 } else if (strcasecmp(phuType, "CELL") == 0) { 732 psString cellName = phuNameFromHeader("CELL.NAME", fileInfo, phu); // Name of the cell674 psString cellName = phuNameFromHeader("CELL.NAME", fileInfo, header); // Name of the cell 733 675 int cellNum = pmChipFindCell(chip, cellName); // Cell number 734 676 if (cellNum == -1) { … … 764 706 765 707 pmHDU *hdu = pmHDUAlloc(extName); // The extension 766 hdu->format = psMemIncrRefCounter(format); 708 // Casting to avoid "warning: passing arg 1 of `p_psMemIncrRefCounter' discards qualifiers from 709 // pointer target type" 710 hdu->format = psMemIncrRefCounter((const psPtr)format); 767 711 768 712 if (processContents(fpa, chip, cell, hdu, level, contentsItem->data.V, format) < 0) { … … 778 722 779 723 if (!pmConceptsReadFPA(fpa, PM_CONCEPT_SOURCE_DEFAULTS, true, NULL)) { 780 ps Error(PS_ERR_UNKNOWN, false, "Unable to read concepts from defaults for FPA %s. Attempting to "781 "proceed anyway.\n", currentFPAname);724 psLogMsg(__func__, PS_LOG_WARN, "Unable to read concepts from defaults for FPA. Attempting to " 725 "proceed anyway.\n"); 782 726 } 783 727 784 728 return view; 729 730 } 731 732 733 bool pmFPAAddSourceFromView(pmFPA *fpa, // The FPA 734 const pmFPAview *phuView, // The view, corresponding to the PHU 735 const psMetadata *format // Format of file 736 ) 737 { 738 PS_ASSERT_PTR_NON_NULL(fpa, false); 739 PS_ASSERT_PTR_NON_NULL(phuView, false); 740 PS_ASSERT_PTR_NON_NULL(format, false); 741 742 return addSource(fpa, phuView, NULL, format) ? true : false; 743 } 744 745 746 747 // Add an input file to the FPA 748 pmFPAview *pmFPAAddSourceFromHeader(pmFPA *fpa, // The FPA 749 psMetadata *phu, // Primary header of file 750 const psMetadata *format // Format of file 751 ) 752 { 753 PS_ASSERT_PTR_NON_NULL(fpa, NULL); 754 PS_ASSERT_PTR_NON_NULL(phu, NULL); 755 PS_ASSERT_PTR_NON_NULL(format, NULL); 756 757 bool mdok = true; // Status from metadata lookups 758 psMetadata *fileInfo = psMetadataLookupMD(&mdok, format, "FILE"); // The file information 759 if (!mdok || !fileInfo) { 760 psError(PS_ERR_IO, false, "Unable to find FILE in the camera format configuration.\n"); 761 return NULL; 762 } 763 764 // Check the name of the FPA 765 psString newFPAname = phuNameFromHeader("FPA.NAME", fileInfo, phu); // New name for the FPA 766 if (!newFPAname) { 767 psError(PS_ERR_IO, true, "Unable to determine FPA.NAME"); 768 return NULL; 769 } 770 771 // is FPAname already defined, new name must match it; otherwise, warn the user that something potentially 772 // bad is happening. 773 const char *currentFPAname = psMetadataLookupStr(&mdok, fpa->concepts, "FPA.NAME"); // Current name 774 if (mdok && currentFPAname && strlen(currentFPAname) > 0 && strcmp(currentFPAname, newFPAname) != 0) { 775 psLogMsg(__func__, PS_LOG_WARN, "FPA.NAME for new source (%s) doesn't match FPA.NAME for current " 776 "fpa (%s).\n", newFPAname, currentFPAname); 777 } 778 psMetadataAddStr(fpa->concepts, PS_LIST_HEAD, "FPA.NAME", PS_META_REPLACE, "Name of FPA", newFPAname); 779 psFree(newFPAname); // Drop reference 780 781 return addSource(fpa, NULL, phu, format); 785 782 } 786 783
Note:
See TracChangeset
for help on using the changeset viewer.
