IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 15, 2009, 4:03:13 PM (17 years ago)
Author:
eugene
Message:

updates from trunk

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtractionMatch.c

    r24292 r25407  
    1010#include "pmHDU.h"
    1111#include "pmFPA.h"
     12#include "pmHDUUtils.h"
    1213#include "pmSubtractionParams.h"
    1314#include "pmSubtractionKernels.h"
     
    5859
    5960
    60 static bool getStamps(pmSubtractionStampList **stamps, // Stamps to read
    61                       const pmReadout *ro1, // Readout 1
    62                       const pmReadout *ro2, // Readout 2
    63                       const psImage *subMask, // Mask for subtraction, or NULL
    64                       psImage *variance,  // Variance map
    65                       const psRegion *region, // Region of interest, or NULL
    66                       float thresh1,  // Threshold for stamp finding on readout 1
    67                       float thresh2,  // Threshold for stamp finding on readout 2
    68                       float stampSpacing, // Spacing between stamps
    69                       int size,         // Kernel half-size
    70                       int footprint,     // Convolution footprint for stamps
    71                       pmSubtractionMode mode // Mode for subtraction
     61static bool subtractionGetStamps(pmSubtractionStampList **stamps, // Stamps to read
     62                                 const pmReadout *ro1, // Readout 1
     63                                 const pmReadout *ro2, // Readout 2
     64                                 const psImage *subMask, // Mask for subtraction, or NULL
     65                                 psImage *variance,  // Variance map
     66                                 const psRegion *region, // Region of interest, or NULL
     67                                 float thresh1,  // Threshold for stamp finding on readout 1
     68                                 float thresh2,  // Threshold for stamp finding on readout 2
     69                                 float stampSpacing, // Spacing between stamps
     70                                 int size,         // Kernel half-size
     71                                 int footprint,     // Convolution footprint for stamps
     72                                 pmSubtractionMode mode // Mode for subtraction
    7273    )
    7374{
     
    163164}
    164165
     166static void subtractionAnalysisUpdate(pmReadout *conv1, pmReadout *conv2, // Convolved images
     167                                      const psMetadata *analysis, // Analysis metadata
     168                                      const psMetadata *header // Header metadata
     169    )
     170{
     171    if (conv1) {
     172        conv1->analysis = psMetadataCopy(conv1->analysis, analysis);
     173    }
     174    if (conv2) {
     175        conv2->analysis = psMetadataCopy(conv2->analysis, analysis);
     176    }
     177
     178    if (conv1 && conv1->parent) {
     179        pmHDU *hdu = pmHDUFromCell(conv1->parent);
     180        if (hdu) {
     181            hdu->header = psMetadataCopy(hdu->header, header);
     182        }
     183    }
     184    if (conv2 && conv2->parent) {
     185        pmHDU *hdu = pmHDUFromCell(conv2->parent);
     186        if (hdu) {
     187            hdu->header = psMetadataCopy(hdu->header, header);
     188        }
     189    }
     190
     191    return;
     192}
    165193
    166194
     
    253281
    254282    psMetadata *outAnalysis = psMetadataAlloc(); // Output analysis values
     283    psMetadata *outHeader = psMetadataAlloc(); // Output header values
    255284
    256285    psTrace("psModules.imcombine", 2, "Convolving...\n");
     
    259288        psRegion *region = regions->data[i]; // Region of interest
    260289
    261         if (!pmSubtractionAnalysis(outAnalysis, kernel, region, ro1->image->numCols, ro1->image->numRows)) {
     290        if (!pmSubtractionAnalysis(outAnalysis, outHeader, kernel, region,
     291                                   ro1->image->numCols, ro1->image->numRows)) {
    262292            psError(PS_ERR_UNKNOWN, false, "Unable to generate QA data");
    263293            psFree(outAnalysis);
     294            psFree(outHeader);
    264295            psFree(subMask);
    265296            psFree(kernels);
     
    272303            psError(PS_ERR_UNKNOWN, false, "Unable to convolve image.");
    273304            psFree(outAnalysis);
     305            psFree(outHeader);
    274306            psFree(subMask);
    275307            psFree(kernels);
     
    283315    psFree(regions);
    284316
    285     if (conv1) {
    286         psMetadataCopy(conv1->analysis, outAnalysis);
    287     }
    288     if (conv2) {
    289         psMetadataCopy(conv2->analysis, outAnalysis);
    290     }
     317    subtractionAnalysisUpdate(conv1, conv2, outAnalysis, outHeader);
    291318    psFree(outAnalysis);
     319    psFree(outHeader);
    292320
    293321    return true;
     
    369397    pmSubtractionKernels *kernels = NULL; // Kernel basis functions
    370398    psMetadata *analysis = psMetadataAlloc(); // QA data
     399    psMetadata *header = psMetadataAlloc(); // QA data for header
    371400
    372401    int numCols = ro1->image->numCols, numRows = ro1->image->numRows; // Image dimensions
     
    442471            // We get the stamps here; we will also attempt to get stamps at the first iteration, but it
    443472            // doesn't matter.
    444             if (!getStamps(&stamps, ro1, ro2, subMask, variance, NULL, stampThresh1, stampThresh2,
     473            if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, NULL, stampThresh1, stampThresh2,
    445474                           stampSpacing, size, footprint, subMode)) {
    446475                goto MATCH_ERROR;
    447476            }
    448477
     478
     479            // Define kernel basis functions
     480            if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) {
     481                kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, optFWHMs, optOrder,
     482                                                          stamps, footprint, optThreshold, penalty, subMode);
     483                if (!kernels) {
     484                    psErrorClear();
     485                    psWarning("Unable to derive optimum ISIS kernel --- switching to default.");
     486                }
     487            }
     488            if (kernels == NULL) {
     489                // Not an ISIS/GUNK kernel, or the optimum kernel search failed
     490                kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders,
     491                                                       inner, binning, ringsOrder, penalty, subMode);
     492            }
     493
     494            memCheck("kernels");
     495
    449496            if (subMode == PM_SUBTRACTION_MODE_UNSURE) {
     497#if 0
    450498                // Get backgrounds
    451499                psStats *bgStats = psStatsAlloc(BG_STAT); // Statistics for background
     
    469517
    470518                pmSubtractionMode newMode = pmSubtractionOrder(stamps, bg1, bg2); // Subtraction mode to use
     519#endif
     520                pmSubtractionMode newMode = pmSubtractionBestMode(&stamps, &kernels, subMask, rej);
    471521                switch (newMode) {
    472522                  case PM_SUBTRACTION_MODE_1:
     
    483533            }
    484534
    485             // Define kernel basis functions
    486             if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) {
    487                 kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, optFWHMs, optOrder,
    488                                                           stamps, footprint, optThreshold, penalty, subMode);
    489                 if (!kernels) {
    490                     psErrorClear();
    491                     psWarning("Unable to derive optimum ISIS kernel --- switching to default.");
    492                 }
    493             }
    494             if (kernels == NULL) {
    495                 // Not an ISIS/GUNK kernel, or the optimum kernel search failed
    496                 kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders,
    497                                                        inner, binning, ringsOrder, penalty, subMode);
    498             }
    499 
    500             memCheck("kernels");
    501 
    502535            int numRejected = -1;       // Number of rejected stamps in each iteration
    503536            for (int k = 0; k < iter && numRejected != 0; k++) {
    504537                psLogMsg("psModules.imcombine", PS_LOG_INFO, "Iteration %d.", k);
    505538
    506                 if (!getStamps(&stamps, ro1, ro2, subMask, variance, region, stampThresh1, stampThresh2,
    507                                stampSpacing, size, footprint, subMode)) {
     539                if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, region,
     540                                          stampThresh1, stampThresh2, stampSpacing,
     541                                          size, footprint, subMode)) {
    508542                    goto MATCH_ERROR;
    509543                }
     
    535569
    536570                psTrace("psModules.imcombine", 3, "Rejecting stamps...\n");
    537                 numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej, footprint);
     571                numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej);
    538572                if (numRejected < 0) {
    539573                    psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps.");
     
    557591                    goto MATCH_ERROR;
    558592                }
    559                 pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN, footprint);
     593                pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN);
    560594                psFree(deviations);
    561595            }
     
    565599            memCheck("solution");
    566600
    567             if (!pmSubtractionAnalysis(analysis, kernels, region, numCols, numRows)) {
     601            if (!pmSubtractionAnalysis(analysis, header, kernels, region, numCols, numRows)) {
    568602                psError(PS_ERR_UNKNOWN, false, "Unable to generate QA data");
    569603                goto MATCH_ERROR;
     
    601635    memCheck("convolution");
    602636
    603     if (conv1) {
    604         psMetadataCopy(conv1->analysis, analysis);
    605     }
    606     if (conv2) {
    607         psMetadataCopy(conv2->analysis, analysis);
    608     }
     637    subtractionAnalysisUpdate(conv1, conv2, analysis, header);
    609638    psFree(analysis);
     639    psFree(header);
    610640
    611641#ifdef TESTING
     
    629659MATCH_ERROR:
    630660    psFree(analysis);
     661    psFree(header);
    631662    psFree(region);
    632663    psFree(regionString);
     
    842873    return mode;
    843874}
     875
     876
     877// Test a subtraction mode by performing a single iteration
     878static bool subtractionModeTest(pmSubtractionStampList *stamps, // Stamps to use to find best mode
     879                                pmSubtractionKernels *kernels, // Kernel description
     880                                const char *description, // Description for trace
     881                                psImage *subMask,  // Subtraction mask
     882                                float rej               // Rejection threshold
     883                                )
     884{
     885    assert(stamps);
     886    assert(kernels);
     887
     888    psTrace("psModules.imcombine", 3, "Calculating %s equation...\n", description);
     889    if (!pmSubtractionCalculateEquation(stamps, kernels)) {
     890        psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
     891        return false;
     892    }
     893
     894    psTrace("psModules.imcombine", 3, "Solving %s equation...\n", description);
     895    if (!pmSubtractionSolveEquation(kernels, stamps)) {
     896        psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
     897        return false;
     898    }
     899
     900    psTrace("psModules.imcombine", 3, "Calculate %s deviations...\n", description);
     901    psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations
     902    if (!deviations) {
     903        psError(PS_ERR_UNKNOWN, false, "Unable to calculate deviations.");
     904        return false;
     905    }
     906
     907    psTrace("psModules.imcombine", 3, "Rejecting %s stamps...\n", description);
     908    long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej);
     909    if (numRejected < 0) {
     910        psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps.");
     911        psFree(deviations);
     912        return false;
     913    }
     914    psFree(deviations);
     915
     916    if (numRejected > 0) {
     917        // Allow re-fit with reduced stamps set
     918        psTrace("psModules.imcombine", 3, "Resolving %s equation...\n", description);
     919        if (!pmSubtractionSolveEquation(kernels, stamps)) {
     920            psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
     921            return false;
     922        }
     923        psTrace("psModules.imcombine", 3, "Recalculate %s deviations...\n", description);
     924        psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations
     925        if (!deviations) {
     926            psError(PS_ERR_UNKNOWN, false, "Unable to calculate deviations.");
     927            return false;
     928        }
     929        psTrace("psModules.imcombine", 3, "Measuring %s quality...\n", description);
     930        long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN);
     931        if (numRejected < 0) {
     932            psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps.");
     933            psFree(deviations);
     934            return false;
     935        }
     936        psFree(deviations);
     937    }
     938
     939    return true;
     940}
     941
     942
     943pmSubtractionMode pmSubtractionBestMode(pmSubtractionStampList **stamps, pmSubtractionKernels **kernels,
     944                                        const psImage *subMask, float rej)
     945{
     946    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(*stamps, PM_SUBTRACTION_MODE_ERR);
     947    PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(*kernels, PM_SUBTRACTION_MODE_ERR);
     948
     949    // Copies of the inputs
     950    pmSubtractionStampList *stamps1 = pmSubtractionStampListCopy(*stamps);
     951    pmSubtractionKernels *kernels1 = pmSubtractionKernelsCopy(*kernels);
     952    psImage *subMask1 = psImageCopy(NULL, subMask, subMask->type.type);
     953    kernels1->mode = PM_SUBTRACTION_MODE_1;
     954
     955    if (!subtractionModeTest(stamps1, kernels1, "convolve 1", subMask1, rej)) {
     956        psError(PS_ERR_UNKNOWN, false, "Unable to test subtraction with convolution of image 1");
     957        psFree(stamps1);
     958        psFree(kernels1);
     959        psFree(subMask1);
     960        return PM_SUBTRACTION_MODE_ERR;
     961    }
     962    psFree(subMask1);
     963
     964    // Copies of the inputs
     965    pmSubtractionStampList *stamps2 = pmSubtractionStampListCopy(*stamps);
     966    pmSubtractionKernels *kernels2 = pmSubtractionKernelsCopy(*kernels);
     967    psImage *subMask2 = psImageCopy(NULL, subMask, subMask->type.type);
     968    kernels2->mode = PM_SUBTRACTION_MODE_2;
     969
     970    if (!subtractionModeTest(stamps2, kernels2, "convolve 2", subMask2, rej)) {
     971        psError(PS_ERR_UNKNOWN, false, "Unable to test subtraction with convolution of image 2");
     972        psFree(stamps2);
     973        psFree(kernels2);
     974        psFree(subMask2);
     975        psFree(stamps1);
     976        psFree(kernels1);
     977        return PM_SUBTRACTION_MODE_ERR;
     978    }
     979    psFree(subMask2);
     980
     981
     982    pmSubtractionStampList *bestStamps = NULL; // Best choice for stamps
     983    pmSubtractionKernels *bestKernels = NULL; // Best choice for kernels
     984    psLogMsg("psModules.imcombine", PS_LOG_INFO,
     985             "Image 1: %f +/- %f from %d stamps\nImage 2: %f +/- %f from %d stamps\n",
     986             kernels1->mean, kernels1->rms, kernels1->numStamps,
     987             kernels2->mean, kernels2->rms, kernels2->numStamps);
     988
     989    if (kernels1->mean < kernels2->mean) {
     990        bestStamps = stamps1;
     991        bestKernels = kernels1;
     992    } else {
     993        bestStamps = stamps2;
     994        bestKernels = kernels2;
     995    }
     996
     997    psFree(*stamps);
     998    psFree(*kernels);
     999    *stamps = psMemIncrRefCounter(bestStamps);
     1000    *kernels = psMemIncrRefCounter(bestKernels);
     1001
     1002    psFree(stamps1);
     1003    psFree(stamps2);
     1004    psFree(kernels1);
     1005    psFree(kernels2);
     1006
     1007    return bestKernels->mode;
     1008}
     1009
Note: See TracChangeset for help on using the changeset viewer.