Changeset 19337
- Timestamp:
- Sep 3, 2008, 9:50:19 AM (18 years ago)
- Location:
- trunk/ppStack/src
- Files:
-
- 1 added
- 4 edited
-
Makefile.am (modified) (1 diff)
-
ppStack.h (modified) (6 diffs)
-
ppStackLoop.c (modified) (13 diffs)
-
ppStackReadout.c (modified) (4 diffs)
-
ppStackThread.c (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppStack/src/Makefile.am
r18346 r19337 14 14 ppStackVersion.c \ 15 15 ppStackMatch.c \ 16 ppStackSources.c 16 ppStackSources.c \ 17 ppStackThread.c 17 18 18 19 noinst_HEADERS = \ -
trunk/ppStack/src/ppStack.h
r19214 r19337 5 5 #define PPSTACK_INSPECT_PIXELS "PPSTACK.PIXELS" // Name of rejected pixels metadata items 6 6 7 #include <pslib.h> 7 8 #include <psmodules.h> 9 10 // Mask values for inputs 11 typedef enum { 12 PPSTACK_MASK_MATCH = 0x01, // PSF-matching failed 13 PPSTACK_MASK_REJECT = 0x02, // Rejection failed 14 PPSTACK_MASK_BAD = 0x04, // Bad image (too many pixels rejected) 15 PPSTACK_MASK_ALL = 0xff // All errors 16 } ppStackMask; 17 18 // Thread for stacking chunks 19 // 20 // Each input file contributes a readout, into which is read a chunk from that file 21 typedef struct { 22 psArray *readouts; // Input readouts to read and stack 23 bool read; // Has the scan been read? 24 bool busy; // Is the scan being processed? 25 int firstScan; // First row of the chunk to be read for this group 26 int lastScan; // Last row of the chunk to be read for this group 27 } ppStackThread; 28 29 // Allocator 30 ppStackThread *ppStackThreadAlloc(psArray *readouts // Inputs readouts to read and stack 31 ); 32 33 // Data for threads 34 typedef struct { 35 psArray *threads; // Threads doing stacking 36 int lastScan; // Last row that's been read 37 psArray *imageFits; // FITS file pointers for images 38 psArray *maskFits; // FITS file pointers for masks 39 psArray *weightFits; // FITS file pointers for weights 40 } ppStackThreadData; 41 42 // Set up thread data 43 ppStackThreadData *ppStackThreadDataSetup(const psArray *cells, // Array of input cells 44 const psArray *imageNames, // Names of images to read 45 const psArray *maskNames, // Names of masks to read 46 const psArray *weightNames, // Names of weight maps to read 47 const pmConfig *config // Configuration 48 ); 49 50 // Read chunk into the first available file thread 51 ppStackThread *ppStackThreadRead(bool *status, // Status of read 52 ppStackThreadData *stack, // Stacks available for reading 53 pmConfig *config, // Configuration 54 int numChunk, // Chunk number (only for interest) 55 int overlap // Overlap between subsequent scans 56 ); 57 58 // Initialise the threads 59 void ppStackThreadInit(void); 8 60 9 61 // Setup command-line arguments … … 31 83 32 84 // Perform stacking on a readout 33 bool ppStackReadoutInitial(const pmConfig *config, // Configuration 34 pmReadout *outRO, // Output readout 35 const psArray *readouts, // Input readouts 36 const psArray *regions, // Array with array of regions used in each PSF matching 37 const psArray *kernels // Array with array of kernels used in each PSF matching 85 // 86 // Returns an array of pixels to inspect for each input image 87 psArray *ppStackReadoutInitial(const pmConfig *config, // Configuration 88 pmReadout *outRO, // Output readout 89 const psArray *readouts, // Input readouts 90 const psArray *regions, // Array with array of regions used in each PSF match 91 const psArray *kernels // Array with array of kernels used in each PSF match 92 ); 93 94 // Thread entry point for ppStackReadoutInitial 95 bool ppStackReadoutInitialThread(psThreadJob *job // Job to process 38 96 ); 39 97 … … 43 101 const psArray *readouts, // Input readouts 44 102 const psArray *rejected // Array with pixels rejected in each image 103 ); 104 105 // Thread entry point for ppStackReadoutFinal 106 bool ppStackReadoutFinalThread(psThreadJob *job // Job to process 45 107 ); 46 108 … … 62 124 63 125 /// Convolve image to match specified seeing 64 bool ppStackMatch(pmReadout *readout, // /<Readout to be convolved; replaced with output126 bool ppStackMatch(pmReadout *readout, // Readout to be convolved; replaced with output 65 127 psArray **regions, // Array of regions used in each PSF matching, returned 66 128 psArray **kernels, // Array of kernels used in each PSF matching, returned 67 const psArray *sources, // /<Array of sources68 const pmPSF *psf, // /<Target PSF69 psRandom *rng, // /<Random number generator70 const pmConfig *config // /<Configuration129 const psArray *sources, // Array of sources 130 const pmPSF *psf, // Target PSF 131 psRandom *rng, // Random number generator 132 const pmConfig *config // Configuration 71 133 ); 72 134 … … 75 137 /// 76 138 /// Corrects the sources to have consistent magnitudes. Returns the source lists. 77 psArray *ppStackSourceListAdd(psArray *lists, // /<List to which to add, or NULL78 psArray *sources, // /<Sources to add79 const pmConfig *config // /<Configuration139 psArray *ppStackSourceListAdd(psArray *lists, // List to which to add, or NULL 140 psArray *sources, // Sources to add 141 const pmConfig *config // Configuration 80 142 ); 81 143 … … 83 145 /// 84 146 /// Corrects the sources to have consistent magnitudes where possible. Returns the sources 85 psArray *ppStackSourceListCombine(psArray *lists, // /<Source lists86 const pmConfig *config // /<Configuration147 psArray *ppStackSourceListCombine(psArray *lists, // Source lists 148 const pmConfig *config // Configuration 87 149 ); 88 150 89 151 /// Print sources into a ds9 regions file 90 void ppStackSourcesPrint(const psArray *sources // /<Sources to print152 void ppStackSourcesPrint(const psArray *sources // Sources to print 91 153 ); 92 154 -
trunk/ppStack/src/ppStackLoop.c
r19283 r19337 12 12 #include "ppStack.h" 13 13 14 #define TESTING14 //#define TESTING 15 15 16 16 #define WCS_TOLERANCE 0.001 // Tolerance for WCS … … 95 95 } 96 96 97 #if 098 // Set the data level for a list of files99 static void fileSetDataLevel(pmConfig *config, // Configuration100 char **files, // Files for which to set level101 pmFPALevel level // Level to set102 )103 {104 assert(config);105 assert(files);106 107 for (int i = 0; files[i] != NULL; i++) {108 psArray *selected = pmFPAfileSelect(config->files, files[i]); // Selected files of interest109 for (int j = 0; j < selected->n; j++) {110 pmFPAfile *file = selected->data[j];111 assert(file);112 file->dataLevel = level;113 }114 psFree(selected);115 }116 return;117 }118 #endif119 120 97 // Iterate down the hierarchy, loading files; we can get away with this because we're working on skycells 121 98 static pmFPAview *filesIterateDown(pmConfig *config // Configuration … … 244 221 } 245 222 int num = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs 246 int numScans = psMetadataLookupS32(NULL, recipe, "ROWS"); // Number of scans to read at once247 223 248 224 psMetadata *ppsub = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe … … 412 388 int numGood = 0; // Number of good frames 413 389 int numCols = 0, numRows = 0; // Size of image 390 psVector *inputMask = psVectorAlloc(num, PS_TYPE_U8); // Mask for inputs 391 psVectorInit(inputMask, 0); 414 392 for (int i = 0; i < num; i++) { 415 393 psTrace("ppStack", 2, "Convolving input %d of %d to target PSF....\n", i, num); … … 423 401 psFree(targetPSF); 424 402 psFree(rng); 403 psFree(inputMask); 425 404 return false; 426 405 } … … 439 418 psFree(targetPSF); 440 419 psFree(rng); 420 psFree(inputMask); 441 421 return false; 442 422 } … … 447 427 if (!ppStackMatch(readout, ®ions, &kernels, sources, targetPSF, rng, config)) { 448 428 psErrorStackPrint(stderr, "Unable to match image %d --- ignoring.", i); 429 inputMask->data.U8[i] = PPSTACK_MASK_MATCH; 449 430 psErrorClear(); 450 431 continue; … … 474 455 if (numGood == 0) { 475 456 psError(PS_ERR_UNKNOWN, false, "No good images to combine."); 476 return false; 477 } 478 457 psFree(subKernels); 458 psFree(subRegions); 459 psFree(cells); 460 psFree(inputMask); 461 return false; 462 } 479 463 480 464 #ifdef TESTING … … 482 466 #endif 483 467 468 ppStackThreadInit(); 469 ppStackThreadData *stack = ppStackThreadDataSetup(cells, imageNames, maskNames, weightNames, 470 config); // Data for stacking 471 psFree(cells); 472 484 473 memDump("preinitial"); 485 474 486 // Stack the convolv ed files475 // Stack the convolvd files 487 476 psTrace("ppStack", 1, "Initial stack of convolved images....\n"); 477 pmReadout *outRO = NULL; // Output readout 478 pmFPAview *view = NULL; // View to readout 488 479 { 480 int row0, col0; // Offset for readout 481 int numCols, numRows; // Size of readout 482 ppStackThread *thread = stack->threads->data[0]; // Representative thread 483 if (!pmReadoutStackSetOutputSize(&col0, &row0, &numCols, &numRows, thread->readouts)) { 484 psError(PS_ERR_UNKNOWN, false, "problem setting output readout size."); 485 psFree(subKernels); 486 psFree(subRegions); 487 psFree(stack); 488 psFree(inputMask); 489 return false; 490 } 491 489 492 pmFPAfileActivate(config->files, false, NULL); 490 493 fileActivation(config, combineFiles, true); 491 pmFPAview *view = filesIterateDown(config);494 view = filesIterateDown(config); 492 495 if (!view) { 493 psFree(cells);494 496 psFree(subKernels); 495 497 psFree(subRegions); 496 return false; 497 } 498 psFree(stack); 499 psFree(inputMask); 500 return false; 501 } 502 498 503 pmCell *outCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT"); // Output cell 499 pmReadout *outRO = pmReadoutAlloc(outCell); // Output readout 500 501 psArray *readouts = psArrayAlloc(num); // Readouts for convolved images 502 for (int i = 0; i < num; i++) { 503 pmCell *cell = cells->data[i]; // Cell of interest 504 if (!cell) { 505 // Bad image 506 continue; 507 } 508 pmReadout *ro = cell->readouts->data[0]; // Readout of interest 509 if (!ro) { 510 ro = pmReadoutAlloc(cell); 511 } 512 readouts->data[i] = ro; // Readout into which to read 513 } 514 psFree(cells); 515 516 // FITS files 517 psArray *imageFits = psArrayAlloc(num); 518 psArray *maskFits = psArrayAlloc(num); 519 psArray *weightFits = psArrayAlloc(num); 520 for (int i = 0; i < num; i++) { 521 if (!readouts->data[i]) { 522 // Bad image 523 continue; 524 } 525 // Resolved names 526 psString imageResolved = pmConfigConvertFilename(imageNames->data[i], config, false, false); 527 psString maskResolved = pmConfigConvertFilename(maskNames->data[i], config, false, false); 528 psString weightResolved = pmConfigConvertFilename(weightNames->data[i], config, false, false); 529 imageFits->data[i] = psFitsOpen(imageResolved, "r"); 530 maskFits->data[i] = psFitsOpen(maskResolved, "r"); 531 weightFits->data[i] = psFitsOpen(weightResolved, "r"); 532 psFree(imageResolved); 533 psFree(maskResolved); 534 psFree(weightResolved); 535 if (!imageFits->data[i] || !maskFits->data[i] || !weightFits->data[i]) { 536 psError(PS_ERR_UNKNOWN, false, "Unable to open convolved files %s, %s, %s", 537 (char*)imageNames->data[i], (char*)maskNames->data[i], (char*)weightNames->data[i]); 504 outRO = pmReadoutAlloc(outCell); // Output readout 505 506 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits to mask for bad 507 psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels 508 if (!pmReadoutStackDefineOutput(outRO, col0, row0, numCols, numRows, true, true, maskBad)) { 509 psError(PS_ERR_UNKNOWN, false, "Unable to prepare output."); 510 psFree(subKernels); 511 psFree(subRegions); 512 psFree(stack); 513 psFree(inputMask); 514 psFree(view); 515 psFree(outRO); 516 return false; 517 } 518 519 bool status; // Status of read 520 for (int numChunk = 0; true; numChunk++) { 521 ppStackThread *thread = ppStackThreadRead(&status, stack, config, numChunk, overlap); 522 if (!status) { 523 // Something went wrong 524 psError(PS_ERR_UNKNOWN, false, "Unable to read chunk %d", numChunk); 538 525 psFree(subKernels); 539 526 psFree(subRegions); 527 psFree(stack); 528 psFree(inputMask); 529 psFree(view); 530 psFree(outRO); 540 531 return false; 541 532 } 542 } 543 544 // Read convolutions by chunks 545 bool more = true; // More to read? 546 for (int numChunk = 0; more; numChunk++) { 547 psTrace("ppStack", 2, "Initial stack of chunk %d....\n", numChunk); 533 if (!thread) { 534 // Nothing more to read 535 break; 536 } 537 538 // call: ppStackReadoutInitial(config, outRO, readouts, subRegions, subKernels) 539 psThreadJob *job = psThreadJobAlloc("PPSTACK_INITIAL_COMBINE"); // Job to start 540 psArrayAdd(job->args, 1, thread); 541 psArrayAdd(job->args, 1, config); 542 psArrayAdd(job->args, 1, outRO); 543 psArrayAdd(job->args, 1, subRegions); 544 psArrayAdd(job->args, 1, subKernels); 545 if (!psThreadJobAddPending(job)) { 546 psFree(job); 547 psFree(subKernels); 548 psFree(subRegions); 549 psFree(stack); 550 psFree(inputMask); 551 psFree(view); 552 psFree(outRO); 553 return false; 554 } 555 psFree(job); 556 } 557 558 if (!psThreadPoolWait(false)) { 559 psError(PS_ERR_UNKNOWN, false, "Unable to do initial combination."); 560 psFree(subKernels); 561 psFree(subRegions); 562 psFree(stack); 563 psFree(inputMask); 564 psFree(view); 565 psFree(outRO); 566 return false; 567 } 568 569 memDump("initial"); 570 } 571 572 // Pixel rejection 573 psArray *rejected = psArrayAlloc(num); 574 { 575 psArray *inspect = psArrayAlloc(num); // Pixels to inspect 576 int numRejected = 0; // Number of inputs rejected completely 577 578 // Count images rejected out of hand 579 for (int i = 0; i < num; i++) { 580 if (inputMask->data.U8[i]) { 581 numRejected++; 582 } 583 inspect->data[i] = psPixelsAllocEmpty(PIXELS_BUFFER); 584 } 585 586 // Harvest the jobs, combining the inspection lists 587 psThreadJob *job; // Completed job 588 while ((job = psThreadJobGetDone())) { 589 psArray *results = job->results; // Results of job 590 psAssert(results && results->n == num, "Results array."); 548 591 for (int i = 0; i < num; i++) { 549 pmReadout *readout = readouts->data[i]; 550 if (!readout) { 551 // Bad image 592 if (inputMask->data.U8[i]) { 552 593 continue; 553 594 } 554 555 if (!pmReadoutReadChunk(readout, imageFits->data[i], 0, numScans, overlap, 556 config) || 557 !pmReadoutReadChunkMask(readout, maskFits->data[i], 0, numScans, overlap, 558 config) || 559 !pmReadoutReadChunkWeight(readout, weightFits->data[i], 0, numScans, overlap, 560 config)) { 561 psError(PS_ERR_IO, false, "Unable to read chunk %d for file %d", numChunk, i); 562 psFree(readouts); 563 psFree(subKernels); 564 psFree(subRegions); 565 psFree(outRO); 566 psFree(view); 567 return false; 568 } 569 } 570 571 #ifndef PS_NO_TRACE 572 { 573 pmReadout *ro = NULL; // Representative readout 574 for (int i = 0; i < num && !ro; i++) { 575 ro = readouts->data[i]; 576 } 577 psAssert(ro, "There should be a readout here."); 578 psTrace("ppStack", 4, "Stack: [%d:%d,%d:%d]\n", ro->col0, ro->col0 + ro->image->numCols, 579 ro->row0, ro->row0 + ro->image->numRows); 580 } 581 #endif 582 583 if (!ppStackReadoutInitial(config, outRO, readouts, subRegions, subKernels)) { 584 psError(PS_ERR_UNKNOWN, false, "Unable to stack images.\n"); 585 psFree(readouts); 586 psFree(subKernels); 587 psFree(subRegions); 588 psFree(outRO); 589 psFree(view); 590 return false; 591 } 592 593 for (int i = 0; i < num && more; i++) { 594 pmReadout *readout = readouts->data[i]; 595 if (!readout) { 596 // Bad image 597 continue; 598 } 599 more &= pmReadoutMore(readout, imageFits->data[i], 0, numScans, config); 600 more &= pmReadoutMoreMask(readout, maskFits->data[i], 0, numScans, config); 601 more &= pmReadoutMoreWeight(readout, weightFits->data[i], 0, numScans, config); 602 } 603 } 604 605 memDump("initial"); 606 607 // Reset for the second read 608 // Extract the rejection lists 609 psArray *rejected = psArrayAlloc(num); // Pixels to inspect 610 int numRejected = 0; // Number of inputs rejected completely 595 inspect->data[i] = psPixelsConcatenate(inspect->data[i], results->data[i]); 596 } 597 psFree(job); 598 } 599 611 600 for (int i = 0; i < num; i++) { 612 pmReadout *ro = readouts->data[i]; // Readout of interest 613 if (!ro) { 614 // Bad image 615 numRejected++; 601 if (inputMask->data.U8[i]) { 616 602 continue; 617 603 } 618 psPixels *inspect = psPixelsAllocEmpty(PIXELS_BUFFER); // Inspection list for this readout619 psMetadataIterator *iter = psMetadataIteratorAlloc(ro->analysis, PS_LIST_HEAD,620 "^" PPSTACK_INSPECT_PIXELS "$"); // Iterator621 psMetadataItem *item;622 while ((item = psMetadataGetAndIncrement(iter))) {623 psPixels *pixels = item->data.V; // Rejected pixels624 if (!pixels) {625 continue;626 }627 psTrace("ppStack", 5, "Adding %ld pixels to inspect to image %d", pixels->n, i);628 inspect = psPixelsConcatenate(inspect, pixels);629 }630 psFree(iter);631 psMetadataRemoveKey(ro->analysis, PPSTACK_INSPECT_PIXELS);632 pmReadoutFreeData(ro);633 634 psLogMsg("ppStack", PS_LOG_INFO, "%ld total pixels to inspect from image %d", inspect->n, i);635 604 636 605 #ifdef TESTING … … 648 617 #endif 649 618 650 psPixels *reject = pmStackReject(inspect , numCols, numRows, threshold, poorFrac,651 subRegions->data[i], subKernels->data[i]); // Pixels to reject619 psPixels *reject = pmStackReject(inspect->data[i], numCols, numRows, threshold, poorFrac, 620 subRegions->data[i], subKernels->data[i]); // Rejected pixels 652 621 653 622 #ifdef TESTING … … 665 634 #endif 666 635 667 psFree(inspect); 636 psFree(inspect->data[i]); 637 inspect->data[i] = NULL; 638 668 639 if (!reject) { 669 640 psWarning("Rejection on image %d didn't work --- reject entire image.", i); 670 641 numRejected++; 642 inputMask->data.U8[i] = PPSTACK_MASK_REJECT; 671 643 } else { 672 float frac = reject->n / (float)( outRO->image->numCols * outRO->image->numRows); // Pixel frac644 float frac = reject->n / (float)(numCols * numRows); // Pixel fraction 673 645 psLogMsg("ppStack", PS_LOG_INFO, "%ld pixels rejected from image %d (%.1f%%)", 674 reject->n, i, frac * 100.0);646 reject->n, i, frac * 100.0); 675 647 if (frac > imageRej) { 676 648 psWarning("Image %d rejected completely because rejection fraction (%.3f) " … … 679 651 // reject == NULL means reject image completely 680 652 reject = NULL; 653 inputMask->data.U8[i] = PPSTACK_MASK_BAD; 681 654 numRejected++; 682 655 } 683 656 } 684 657 rejected->data[i] = reject; 685 686 memDump("reject"); 687 688 } 658 } 659 660 psFree(inspect); 689 661 psFree(subKernels); 690 662 psFree(subRegions); … … 692 664 if (numRejected == num) { 693 665 psError(PS_ERR_UNKNOWN, true, "All inputs completely rejected; unable to proceed."); 694 psFree( readouts);666 psFree(stack); 695 667 psFree(rejected); 668 psFree(inputMask); 669 psFree(view); 696 670 psFree(outRO); 671 return false; 672 } 673 } 674 675 memDump("reject"); 676 677 // Final combination 678 psTrace("ppStack", 2, "Final stack of convolved images....\n"); 679 { 680 stack->lastScan = 0; // Reset read 681 bool status; // Status of read 682 for (int numChunk = 0; true; numChunk++) { 683 ppStackThread *thread = ppStackThreadRead(&status, stack, config, numChunk, 0); 684 if (!status) { 685 // Something went wrong 686 psError(PS_ERR_UNKNOWN, false, "Unable to read chunk %d", numChunk); 687 psFree(stack); 688 psFree(rejected); 689 psFree(inputMask); 690 psFree(view); 691 psFree(outRO); 692 return false; 693 } 694 if (!thread) { 695 // Nothing more to read 696 break; 697 } 698 699 // call: ppStackReadoutFinal(config, outRO, readouts, rejected) 700 psThreadJob *job = psThreadJobAlloc("PPSTACK_FINAL_COMBINE"); // Job to start 701 psArrayAdd(job->args, 1, thread); 702 psArrayAdd(job->args, 1, config); 703 psArrayAdd(job->args, 1, outRO); 704 psArrayAdd(job->args, 1, rejected); 705 if (!psThreadJobAddPending(job)) { 706 psFree(job); 707 psFree(stack); 708 psFree(rejected); 709 psFree(inputMask); 710 psFree(view); 711 psFree(outRO); 712 return false; 713 } 714 psFree(job); 715 } 716 717 if (!psThreadPoolWait(true)) { 718 psError(PS_ERR_UNKNOWN, false, "Unable to do final combination."); 719 psFree(stack); 720 psFree(inputMask); 721 psFree(rejected); 697 722 psFree(view); 698 return false; 699 } 700 701 memDump("prefinal"); 702 703 // Read convolutions by chunks 704 psTrace("ppStack", 2, "Final stack of convolved images....\n"); 705 more = true; 706 for (int numChunk = 0; more; numChunk++) { 707 psTrace("ppStack", 2, "Final stack of chunk %d....\n", numChunk); 708 for (int i = 0; i < num; i++) { 709 if (!rejected->data[i]) { 710 continue; 711 } 712 pmReadout *readout = readouts->data[i]; 713 assert(readout); 714 715 if (!pmReadoutReadChunk(readout, imageFits->data[i], 0, numScans, 0, config) || 716 !pmReadoutReadChunkMask(readout, maskFits->data[i], 0, numScans, 0, config) || 717 !pmReadoutReadChunkWeight(readout, weightFits->data[i], 0, numScans, 0, 718 config)) { 719 psError(PS_ERR_IO, false, "Unable to read chunk %d for file %d", numChunk, i); 720 psFree(readouts); 721 psFree(rejected); 722 psFree(outRO); 723 psFree(view); 724 return false; 725 } 726 } 727 728 #ifndef PS_NO_TRACE 729 { 730 pmReadout *ro = NULL; 731 for (int i = 0; i < num && !ro; i++) { 732 if (!rejected->data[i]) { 733 continue; 723 psFree(outRO); 724 return false; 725 } 726 } 727 728 memDump("final"); 729 730 psTrace("ppStack", 2, "Cleaning up after combination....\n"); 731 732 // Ensure masked regions really look masked 733 { 734 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits for bad 735 psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels 736 if (!pmReadoutMaskApply(outRO, maskBad)) { 737 psWarning("Unable to apply mask"); 738 } 739 } 740 741 // Close up 742 bool wcsDone = false; // Have we done the WCS? 743 for (int i = 0; i < num; i++) { 744 if (!inputMask->data.U8[i]) { 745 continue; 746 } 747 if (!wcsDone) { 748 // Copy astrometry over 749 wcsDone = true; 750 ppStackThread *thread = stack->threads->data[0]; // Representative stack 751 pmReadout *inRO = thread->readouts->data[i]; // Template readout 752 pmHDU *inHDU = pmHDUFromCell(inRO->parent); // Template HDU 753 pmHDU *outHDU = pmHDUFromCell(outRO->parent); // Output HDU 754 pmChip *outChip = outRO->parent->parent; // Output chip 755 pmFPA *outFPA = outChip->parent; // Output FPA 756 if (!outHDU || !inHDU) { 757 psWarning("Unable to find HDU at FPA level to copy astrometry."); 758 } else { 759 if (!pmAstromReadWCS(outFPA, outChip, inHDU->header, 1.0)) { 760 psErrorClear(); 761 psWarning("Unable to read WCS astrometry from input FPA."); 762 wcsDone = false; 763 } else { 764 if (!outHDU->header) { 765 outHDU->header = psMetadataAlloc(); 734 766 } 735 ro = readouts->data[i]; 736 } 737 if (ro && ro->image) { 738 psTrace("ppStack", 4, "Stack: [%d:%d,%d:%d]\n", ro->col0, ro->col0 + ro->image->numCols, 739 ro->row0, ro->row0 + ro->image->numRows); 740 } 741 } 742 #endif 743 744 if (!ppStackReadoutFinal(config, outRO, readouts, rejected)) { 745 psError(PS_ERR_UNKNOWN, false, "Unable to stack images.\n"); 746 psFree(readouts); 747 psFree(rejected); 748 psFree(outRO); 749 psFree(view); 750 return false; 751 } 752 753 for (int i = 0; i < num && more; i++) { 754 pmReadout *readout = readouts->data[i]; 755 if (!readout) { 756 continue; 757 } 758 more &= pmReadoutMore(readout, imageFits->data[i], 0, numScans, config); 759 more &= pmReadoutMoreMask(readout, maskFits->data[i], 0, numScans, config); 760 more &= pmReadoutMoreWeight(readout, weightFits->data[i], 0, numScans, config); 761 } 762 } 763 764 psFree(rejected); 765 for (int i = 0; i < readouts->n; i++) { 766 pmReadout *ro = readouts->data[i]; // Readout of interest 767 if (!ro) { 768 continue; 769 } 770 pmReadoutFreeData(ro); 771 } 772 psFree(readouts); 773 774 // Ensure masked regions really look masked 775 { 776 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits for bad 777 psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels 778 if (!pmReadoutMaskApply(outRO, maskBad)) { 779 psWarning("Unable to apply mask"); 780 } 781 } 782 783 // Close up 784 bool wcsDone = false; // Have we done the WCS? 785 for (int i = 0; i < num; i++) { 786 if (!readouts->data[i]) { 787 continue; 788 } 789 if (!wcsDone) { 790 // Copy astrometry over 791 wcsDone = true; 792 pmReadout *inRO = readouts->data[i]; // Template readout 793 pmHDU *inHDU = pmHDUFromCell(inRO->parent); // Template HDU 794 pmHDU *outHDU = pmHDUFromCell(outRO->parent); // Output HDU 795 pmChip *outChip = outRO->parent->parent; // Output chip 796 pmFPA *outFPA = outChip->parent; // Output FPA 797 if (!outHDU || !inHDU) { 798 psWarning("Unable to find HDU at FPA level to copy astrometry."); 799 } else { 800 if (!pmAstromReadWCS(outFPA, outChip, inHDU->header, 1.0)) { 767 if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_TOLERANCE)) { 801 768 psErrorClear(); 802 psWarning("Unable to read WCS astrometry from input FPA.");769 psWarning("Unable to write WCS astrometry to output FPA."); 803 770 wcsDone = false; 804 } else {805 if (!outHDU->header) {806 outHDU->header = psMetadataAlloc();807 }808 if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_TOLERANCE)) {809 psErrorClear();810 psWarning("Unable to write WCS astrometry to output FPA.");811 wcsDone = false;812 }813 771 } 814 772 } 815 773 } 816 817 psFitsClose(imageFits->data[i]); 818 psFitsClose(maskFits->data[i]); 819 psFitsClose(weightFits->data[i]); 820 imageFits->data[i] = NULL; 821 maskFits->data[i] = NULL; 822 weightFits->data[i] = NULL; 823 if (tempDelete) { 824 psString imageResolved = pmConfigConvertFilename(imageNames->data[i], config, false, false); 825 psString maskResolved = pmConfigConvertFilename(maskNames->data[i], config, false, false); 826 psString weightResolved = pmConfigConvertFilename(weightNames->data[i], config, false, false); 827 if (unlink(imageResolved) == -1 || unlink(maskResolved) == -1 || 828 unlink(weightResolved) == -1) { 829 psWarning("Unable to delete temporary files for image %d", i); 830 } 831 psFree(imageResolved); 832 psFree(maskResolved); 833 psFree(weightResolved); 834 } 835 } 836 psFree(imageNames); 837 psFree(maskNames); 838 psFree(weightNames); 839 psFree(imageFits); 840 psFree(maskFits); 841 psFree(weightFits); 842 843 memDump("final"); 844 845 if (psMetadataLookupBool(&mdok, recipe, "PHOTOMETRY")) { 846 847 fileActivation(config, combineFiles, false); 848 fileActivation(config, photFiles, true); 849 pmFPAview *photView = filesIterateDown(config); 850 851 psTrace("ppStack", 1, "Photometering stacked image....\n"); 852 if (!ppStackPhotometry(config, outRO, view)) { 853 psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry on output."); 854 psFree(outRO); 855 psFree(photView); 856 psFree(view); 857 return false; 858 } 774 } 775 776 if (tempDelete) { 777 psString imageResolved = pmConfigConvertFilename(imageNames->data[i], config, false, false); 778 psString maskResolved = pmConfigConvertFilename(maskNames->data[i], config, false, false); 779 psString weightResolved = pmConfigConvertFilename(weightNames->data[i], config, false, false); 780 if (unlink(imageResolved) == -1 || unlink(maskResolved) == -1 || 781 unlink(weightResolved) == -1) { 782 psWarning("Unable to delete temporary files for image %d", i); 783 } 784 psFree(imageResolved); 785 psFree(maskResolved); 786 psFree(weightResolved); 787 } 788 } 789 psFree(imageNames); 790 psFree(maskNames); 791 psFree(weightNames); 792 793 psFree(inputMask); 794 psFree(stack); 795 796 memDump("cleanup"); 797 798 if (psMetadataLookupBool(&mdok, recipe, "PHOTOMETRY")) { 799 psTrace("ppStack", 1, "Photometering stacked image....\n"); 800 801 fileActivation(config, combineFiles, false); 802 fileActivation(config, photFiles, true); 803 pmFPAview *photView = filesIterateDown(config); 804 if (!ppStackPhotometry(config, outRO, photView)) { 805 psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry on output."); 806 psFree(outRO); 859 807 psFree(photView); 860 861 fileActivation(config, combineFiles, true); 862 } 863 864 memDump("phot"); 865 866 // Statistics on output 867 if (stats) { 868 psTrace("ppStack", 1, "Gathering statistics on stacked image....\n"); 869 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits for bad 870 psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels 871 872 ppStatsFPA(stats, outCell->parent->parent, view, maskBad, config); 873 } 874 875 memDump("stats"); 876 877 // Put version information into the header 878 pmHDU *hdu = pmHDUFromCell(outRO->parent); 879 if (!hdu) { 880 psError(PS_ERR_UNKNOWN, false, "Unable to find HDU for output."); 881 return false; 882 } 883 if (!hdu->header) { 884 hdu->header = psMetadataAlloc(); 885 } 886 ppStackVersionMetadata(hdu->header); 887 888 // Write out the output files 889 filesIterateUp(config); 890 808 return false; 809 } 810 psFree(photView); 811 812 fileActivation(config, combineFiles, true); 813 } 814 815 memDump("phot"); 816 817 // Statistics on output 818 if (stats) { 819 psTrace("ppStack", 1, "Gathering statistics on stacked image....\n"); 820 psString maskBadStr = psMetadataLookupStr(NULL, recipe, "MASK.BAD"); // Name of bits for bad 821 psMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels 822 823 ppStatsFPA(stats, outRO->parent->parent->parent, view, maskBad, config); 824 } 825 826 memDump("stats"); 827 828 // Put version information into the header 829 pmHDU *hdu = pmHDUFromCell(outRO->parent); 830 if (!hdu) { 831 psError(PS_ERR_UNKNOWN, false, "Unable to find HDU for output."); 891 832 psFree(outRO); 892 833 psFree(view); 893 } 834 return false; 835 } 836 if (!hdu->header) { 837 hdu->header = psMetadataAlloc(); 838 } 839 ppStackVersionMetadata(hdu->header); 840 841 // Write out the output files 842 filesIterateUp(config); 843 844 psFree(outRO); 845 psFree(view); 894 846 895 847 // Write out summary statistics -
trunk/ppStack/src/ppStackReadout.c
r19267 r19337 12 12 //#define TESTING // Write debugging output? 13 13 14 15 bool ppStackReadoutInitial(const pmConfig *config, pmReadout *outRO, const psArray *readouts, 16 const psArray *regions, const psArray *kernels) 14 bool ppStackReadoutInitialThread(psThreadJob *job) 15 { 16 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 17 18 psArray *args = job->args; // Arguments 19 ppStackThread *thread = args->data[0]; // Thread 20 pmConfig *config = args->data[1]; // Configuration 21 pmReadout *outRO = args->data[2]; // Output readout 22 psArray *subRegions = args->data[3]; // Regions for PSF-matching 23 psArray *subKernels = args->data[4]; // Kernels for PSF-matching 24 25 psArray *inspect = ppStackReadoutInitial(config, outRO, thread->readouts, subRegions, subKernels); 26 27 job->results = inspect; 28 thread->busy = false; 29 30 return inspect ? true : false; 31 } 32 33 bool ppStackReadoutFinalThread(psThreadJob *job) 34 { 35 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 36 37 psArray *args = job->args; // Arguments 38 ppStackThread *thread = args->data[0]; // Thread 39 pmConfig *config = args->data[1]; // Configuration 40 pmReadout *outRO = args->data[2]; // Output readout 41 psArray *rejected = args->data[3]; // Rejected pixels 42 43 bool status = ppStackReadoutFinal(config, outRO, thread->readouts, rejected); // Status of operation 44 45 thread->busy = false; 46 47 return status; 48 } 49 50 51 psArray *ppStackReadoutInitial(const pmConfig *config, pmReadout *outRO, const psArray *readouts, 52 const psArray *regions, const psArray *kernels) 17 53 { 18 54 assert(config); … … 88 124 89 125 // Save list of pixels to inspect 126 psArray *inspect = psArrayAlloc(num); // List of pixels to inspect 90 127 for (int i = 0; i < num; i++) { 91 128 pmStackData *data = stack->data[i]; // Data for this image … … 97 134 continue; 98 135 } 99 psMetadataAddPtr(readout->analysis, PS_LIST_TAIL, PPSTACK_INSPECT_PIXELS, 100 PS_DATA_PIXELS | PS_META_DUPLICATE_OK, "Pixels to inspect from initial combination", 101 data->inspect); 136 inspect->data[i] = psMemIncrRefCounter(data->inspect); 102 137 } 103 138 psFree(stack); … … 105 140 sectionNum++; 106 141 107 return true;142 return inspect; 108 143 } 109 144
Note:
See TracChangeset
for help on using the changeset viewer.
