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

Location:
branches/eam_branches/20090715/psModules/src/imcombine
Files:
12 edited

Legend:

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

    r24622 r25407  
    124124        pmResiduals *resid = psf->residuals;// PSF residuals
    125125        psf->residuals = NULL;
    126         if (!pmReadoutFakeFromSources(fakeRO, fakeSize, fakeSize, fakes, xOffset, yOffset, psf,
     126        if (!pmReadoutFakeFromSources(fakeRO, fakeSize, fakeSize, fakes, 0, xOffset, yOffset, psf,
    127127                                      NAN, radius, true, true)) {
    128128            psError(PS_ERR_UNKNOWN, false, "Unable to generate fake readout.");
     
    298298        }
    299299
    300         // measure the source moments: tophat windowing, no pixel S/N cutoff
     300        // measure the source moments: tophat windowing, no pixel S/N cutoff
    301301        if (!pmSourceMoments(source, maxRadius, 0.0, 1.0)) {
    302302            // Can't do anything about it; limp along as best we can
  • branches/eam_branches/20090715/psModules/src/imcombine/pmStack.c

    r23775 r25407  
    3030#define PIXEL_LIST_BUFFER 100           // Number of entries to add to pixel list at a time
    3131#define PIXEL_MAP_BUFFER 2              // Number of entries to add to pixel map at a time
    32 #define ADD_VARIANCE                    // Allow additional variance (besides variance factor)?
     32//#define ADD_VARIANCE                    // Allow additional variance (besides variance factor)?
    3333#define NUM_DIRECT_STDEV 5              // For less than this number of values, measure stdev directly
    3434
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtraction.c

    r24298 r25407  
    733733
    734734int pmSubtractionRejectStamps(pmSubtractionKernels *kernels, pmSubtractionStampList *stamps,
    735                               const psVector *deviations, psImage *subMask, float sigmaRej, int footprint)
     735                              const psVector *deviations, psImage *subMask, float sigmaRej)
    736736{
    737737    PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, false);
     
    821821    ds9num++;
    822822
     823    int footprint = stamps->footprint;  // Half-size of stamp region of interest
    823824    int numRejected = 0;                // Number of stamps rejected
    824825    int numGood = 0;                    // Number of good stamps
     
    956957    PS_ASSERT_FLOAT_WITHIN_RANGE(y, -1.0, 1.0, NULL);
    957958
    958     psArray *images = psArrayAlloc(solution->n - 1); // Images of each kernel to return
    959     psVector *fakeSolution = psVectorAlloc(solution->n, PS_TYPE_F64); // Fake solution vector
     959    psArray *images = psArrayAlloc(kernels->solution1->n - 1); // Images of each kernel to return
     960    psVector *fakeSolution = psVectorAlloc(kernels->solution1->n, PS_TYPE_F64); // Fake solution vector
    960961    psVectorInit(fakeSolution, 0.0);
    961962
    962     for (int i = 0; i < solution->n - 1; i++) {
    963         fakeSolution->data.F64[i] = solution->data.F64[i];
     963    for (int i = 0; i < kernels->solution1->n - 1; i++) {
     964        fakeSolution->data.F64[i] = kernels->solution1->data.F64[i];
    964965        images->data[i] = pmSubtractionKernelImage(kernels, x, y, wantDual);
    965966        fakeSolution->data.F64[i] = 0.0;
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtraction.h

    r21363 r25407  
    6868                              const psVector *deviations, ///< Deviations for each stamp
    6969                              psImage *subMask, ///< Subtraction mask
    70                               float sigmaRej, ///< Number of RMS deviations above zero at which to reject
    71                               int footprint ///< Half-size of stamp
     70                              float sigmaRej ///< Number of RMS deviations above zero at which to reject
    7271    );
    7372
     
    9493
    9594/// Generate images of the convolution kernel elements
    96 psArray *pmSubtractionKernelSolutions(const psVector *solution, ///< Solution vector
    97                                       const pmSubtractionKernels *kernels, ///< Kernel parameters
    98                                       float x, float y ///< Normalised position [-1,1] for images
     95psArray *pmSubtractionKernelSolutions(const pmSubtractionKernels *kernels, ///< Kernel parameters
     96                                      float x, float y, ///< Normalised position [-1,1] for images
     97                                      bool wantDual ///< Calculate for the dual kernel?
    9998    );
     99
    100100
    101101/// Execute a thread job to convolve a patch of the image
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtractionAnalysis.c

    r23780 r25407  
    1717
    1818
    19 bool pmSubtractionAnalysis(psMetadata *analysis, pmSubtractionKernels *kernels, psRegion *region,
     19bool pmSubtractionAnalysis(psMetadata *analysis, psMetadata *header,
     20                           pmSubtractionKernels *kernels, psRegion *region,
    2021                           int numCols, int numRows)
    2122{
    22     if (analysis) {
    23         PS_ASSERT_METADATA_NON_NULL(analysis, false);
    24     }
     23    PS_ASSERT_METADATA_NON_NULL(analysis, false);
     24    PS_ASSERT_METADATA_NON_NULL(header, false);
    2525    PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, false);
    2626    PM_ASSERT_SUBTRACTION_KERNELS_SOLUTION(kernels, false);
     
    3838                         PS_DATA_REGION | PS_META_DUPLICATE_OK,
    3939                         "Region over which subtraction was performed", subRegion);
     40
     41        psString string = psRegionToString(*subRegion);
    4042        psFree(subRegion);
     43
     44        psMetadataAddStr(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION, PS_META_DUPLICATE_OK,
     45                         "Region over which subtraction was performed", string);
     46        psFree(string);
    4147    }
    4248
     
    4551                     PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "Subtraction kernels", kernels);
    4652    psMetadataAddS32(analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MODE,
    47                      PS_META_DUPLICATE_OK, "Subtraction kernels", kernels->mode);
     53                     PS_META_DUPLICATE_OK, "Subtraction mode", kernels->mode);
     54    psMetadataAddS32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MODE,
     55                     PS_META_DUPLICATE_OK, "Subtraction mode", kernels->mode);
    4856
    4957    // Realisations of kernel
     
    113121    {
    114122        psMetadata *header = psMetadataAlloc(); // Header
    115         for (int i = 0; i < solution->n; i++) {
     123        for (int i = 0; i < kernels->solution1->n; i++) {
    116124            psString name = NULL;       // Header keyword
    117125            psStringAppend(&name, "SOLN%04d", i);
    118             psMetadataAddF64(header, PS_LIST_TAIL, name, 0, NULL, solution->data.F64[i]);
     126            psMetadataAddF64(header, PS_LIST_TAIL, name, 0, NULL, kernels->solution1->data.F64[i]);
    119127            psFree(name);
    120128        }
    121         psArray *kernelImages = pmSubtractionKernelSolutions(solution, kernels, 0.0, 0.0);
     129        psArray *kernelImages = pmSubtractionKernelSolutions(kernels, 0.0, 0.0, false);
    122130        psFits *kernelFile = psFitsOpen("kernels.fits", "w");
    123131        (void)psFitsWriteImageCube(kernelFile, header, kernelImages, NULL);
     
    128136#endif
    129137
    130 
    131     // Set the variance factors
    132     float vf1 = 1.0, vf2 = 1.0;         // Variance factors for each image
    133     switch (kernels->mode) {
    134       case PM_SUBTRACTION_MODE_1:
    135         vf1 = pmSubtractionVarianceFactor(kernels, 0.5, 0.5, false);
    136         break;
    137       case PM_SUBTRACTION_MODE_2:
    138         vf2 = pmSubtractionVarianceFactor(kernels, 0.5, 0.5, false);
    139         break;
    140       case PM_SUBTRACTION_MODE_DUAL:
    141         vf1 = pmSubtractionVarianceFactor(kernels, 0.5, 0.5, false);
    142         vf2 = pmSubtractionVarianceFactor(kernels, 0.5, 0.5, true);
    143         break;
    144       default:
    145         psAbort("Invalid subtraction mode: %x", kernels->mode);
    146     }
    147 
    148     // Weight by the area
    149     if (region) {
    150         float norm = (region->x1 - region->x0 + 1) * (region->y1 - region->y0 + 1) / (numCols * numRows);
    151         vf1 *= norm;
    152         vf2 *= norm;
    153     }
    154 
    155     // Update the variance factor
    156 #define UPDATE_VARFACTOR(VF, ANALYSIS) { \
    157     psMetadataItem *vfItem = psMetadataLookup(analysis, ANALYSIS); \
    158     if (vfItem) { \
    159         psAssert(vfItem->type == PS_TYPE_F32, "Should be the type we said."); \
    160         vfItem->data.F32 += VF; \
    161     } else { \
    162         psMetadataAddF32(analysis, PS_LIST_TAIL, ANALYSIS, 0, "Variance factor weighted by the area", VF); \
    163     } \
    164 }
    165 
    166     UPDATE_VARFACTOR(vf1, PM_SUBTRACTION_ANALYSIS_VARFACTOR_1);
    167     UPDATE_VARFACTOR(vf2, PM_SUBTRACTION_ANALYSIS_VARFACTOR_2);
    168138
    169139    // Kernel shape
     
    201171        psFree(image);
    202172
    203         psMetadataItem *item = psMetadataLookup(analysis, PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Previous
    204         if (item) {
    205             item->data.F32 = PS_MAX(item->data.F32, max);
    206         } else {
    207             psMetadataAddF32(analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_DECONV_MAX, 0,
    208                              "Maximum deconvolution fraction", max);
     173        {
     174            psMetadataItem *item = psMetadataLookup(analysis, PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Previous
     175            if (item) {
     176                max = item->data.F32 = PS_MAX(item->data.F32, max);
     177            } else {
     178                psMetadataAddF32(analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_DECONV_MAX, 0,
     179                                 "Maximum deconvolution fraction", max);
     180            }
     181        }
     182
     183        {
     184            psMetadataItem *item = psMetadataLookup(header, PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Previous
     185            if (item) {
     186                item->data.F32 = max;
     187            } else {
     188                psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_DECONV_MAX, 0,
     189                                 "Maximum deconvolution fraction", max);
     190            }
    209191        }
    210192    }
     
    254236        psMetadataAddF32(analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MYY,
    255237                         PS_META_DUPLICATE_OK, "Moment in yy", m02);
     238
     239        psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_NORM,
     240                         PS_META_DUPLICATE_OK, "Normalisation", m00);
     241        psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MX,
     242                         PS_META_DUPLICATE_OK, "Moment in x", m10);
     243        psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MY,
     244                         PS_META_DUPLICATE_OK, "Moment in y", m01);
     245        psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MXX,
     246                         PS_META_DUPLICATE_OK, "Moment in xx", m20);
     247        psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MXY,
     248                         PS_META_DUPLICATE_OK, "Moment in xy", m11);
     249        psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MYY,
     250                         PS_META_DUPLICATE_OK, "Moment in yy", m02);
    256251    }
    257252
     
    263258
    264259        psMetadataAddF32(analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_BGDIFF,
     260                         PS_META_DUPLICATE_OK, "Background difference", bg);
     261        psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_BGDIFF,
    265262                         PS_META_DUPLICATE_OK, "Background difference", bg);
    266263        psFree(polyValues);
     
    275272        psMetadataAddF32(analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_DEV_RMS, 0, "RMS stamp deviation",
    276273                         kernels->rms);
     274
     275        psMetadataAddS32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_STAMPS, 0, "Number of stamps",
     276                         kernels->numStamps);
     277        psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_DEV_MEAN, 0, "Mean stamp deviation",
     278                         kernels->mean);
     279        psMetadataAddF32(header, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_DEV_RMS, 0, "RMS stamp deviation",
     280                         kernels->rms);
    277281    }
    278282
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtractionAnalysis.h

    r21149 r25407  
    2727bool pmSubtractionAnalysis(
    2828    psMetadata *analysis,               ///< Metadata container for QA information
     29    psMetadata *header,                 ///< Metadata container for QA information to put in header
    2930    pmSubtractionKernels *kernels,      ///< Kernels
    3031    psRegion *region,                   ///< Region for subtraction
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtractionKernels.c

    r24296 r25407  
    765765    return PM_SUBTRACTION_KERNEL_NONE;
    766766}
     767
     768pmSubtractionKernels *pmSubtractionKernelsCopy(const pmSubtractionKernels *in)
     769{
     770    PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(in, NULL);
     771
     772    pmSubtractionKernels *out = psAlloc(sizeof(pmSubtractionKernels)); // Kernels, to return
     773    psMemSetDeallocator(out, (psFreeFunc)subtractionKernelsFree);
     774
     775    out->type = in->type;
     776    out->description = psMemIncrRefCounter(in->description);
     777    out->num = in->num;
     778    out->u = psMemIncrRefCounter(in->u);
     779    out->v = psMemIncrRefCounter(in->v);
     780    out->widths = psMemIncrRefCounter(in->widths);
     781    out->preCalc = psMemIncrRefCounter(in->preCalc);
     782    out->penalty = in->penalty;
     783    out->penalties = psMemIncrRefCounter(in->penalties);
     784    out->uStop = psMemIncrRefCounter(in->uStop);
     785    out->vStop = psMemIncrRefCounter(in->vStop);
     786    out->size = in->size;
     787    out->inner = in->inner;
     788    out->spatialOrder = in->spatialOrder;
     789    out->bgOrder = in->bgOrder;
     790    out->mode = in->mode;
     791    out->numCols = in->numCols;
     792    out->numRows = in->numRows;
     793    out->solution1 = in->solution1 ? psVectorCopy(NULL, in->solution1, PS_TYPE_F64) : NULL;
     794    out->solution2 = in->solution2 ? psVectorCopy(NULL, in->solution2, PS_TYPE_F64) : NULL;
     795
     796    return out;
     797}
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtractionKernels.h

    r20049 r25407  
    203203    );
    204204
     205/// Copy kernels
     206///
     207/// A deep copy is performed on the solution only; the other components are merely pointers.
     208pmSubtractionKernels *pmSubtractionKernelsCopy(
     209    const pmSubtractionKernels *in      // Kernels to copy
     210    );
     211
    205212
    206213#endif
  • 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
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtractionMatch.h

    r23308 r25407  
    8383    );
    8484
     85/// Determine best subtraction mode to use
     86///
     87/// Subtractions are attempted each way, and the mode with the lower residual is taken to be the best
     88pmSubtractionMode pmSubtractionBestMode(
     89    pmSubtractionStampList **stamps,    ///< Stamps to use for solution
     90    pmSubtractionKernels **kernels,     ///< Kernels to use for solution
     91    const psImage *subMask,             ///< Subtraction mask
     92    float rej                           ///< Rejection threshold for stamps
     93    );
    8594
    8695#endif
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtractionStamps.c

    r24066 r25407  
    225225}
    226226
     227pmSubtractionStampList *pmSubtractionStampListCopy(const pmSubtractionStampList *in)
     228{
     229    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(in, NULL);
     230
     231    pmSubtractionStampList *out = psAlloc(sizeof(pmSubtractionStampList)); // Copied stamp list to return
     232    psMemSetDeallocator(out, (psFreeFunc)subtractionStampListFree);
     233
     234    int num = out->num = in->num;       // Number of stamps
     235    out->stamps = psArrayAlloc(num);
     236    out->regions = psArrayAlloc(num);
     237    out->x = NULL;
     238    out->y = NULL;
     239    out->flux = NULL;
     240    out->footprint = in->footprint;
     241
     242    for (int i = 0; i < num; i++) {
     243        psRegion *inRegion = in->regions->data[i]; // Input region
     244        out->regions->data[i] = psRegionAlloc(inRegion->x0, inRegion->x1, inRegion->y0, inRegion->y1);
     245
     246        pmSubtractionStamp *inStamp = in->stamps->data[i]; // Input stamp
     247        pmSubtractionStamp *outStamp = psAlloc(sizeof(pmSubtractionStamp));
     248        psMemSetDeallocator(outStamp, (psFreeFunc)subtractionStampFree);
     249        outStamp->x = inStamp->x;
     250        outStamp->y = inStamp->y;
     251        outStamp->flux = inStamp->flux;
     252        outStamp->xNorm = inStamp->xNorm;
     253        outStamp->yNorm = inStamp->yNorm;
     254        outStamp->status = inStamp->status;
     255
     256        outStamp->image1 = inStamp->image1 ? psKernelCopy(inStamp->image1) : NULL;
     257        outStamp->image2 = inStamp->image2 ? psKernelCopy(inStamp->image2) : NULL;
     258        outStamp->variance = inStamp->variance ? psKernelCopy(inStamp->variance) : NULL;
     259
     260        if (inStamp->convolutions1) {
     261            int size = inStamp->convolutions1->n; // Size of array
     262            outStamp->convolutions1 = psArrayAlloc(size);
     263            for (int j = 0; j < size; j++) {
     264                psKernel *conv = inStamp->convolutions1->data[j]; // Convolution
     265                outStamp->convolutions1->data[j] = conv ? psKernelCopy(conv) : NULL;
     266            }
     267        } else {
     268            outStamp->convolutions1 = NULL;
     269        }
     270        if (inStamp->convolutions2) {
     271            int size = inStamp->convolutions2->n; // Size of array
     272            outStamp->convolutions2 = psArrayAlloc(size);
     273            for (int j = 0; j < size; j++) {
     274                psKernel *conv = inStamp->convolutions2->data[j]; // Convolution
     275                outStamp->convolutions2->data[j] = conv ? psKernelCopy(conv) : NULL;
     276            }
     277        } else {
     278            outStamp->convolutions2 = NULL;
     279        }
     280
     281        outStamp->matrix1 = inStamp->matrix1 ? psImageCopy(NULL, inStamp->matrix1, PS_TYPE_F64) : NULL;
     282        outStamp->matrix2 = inStamp->matrix2 ? psImageCopy(NULL, inStamp->matrix2, PS_TYPE_F64) : NULL;
     283        outStamp->matrixX = inStamp->matrixX ? psImageCopy(NULL, inStamp->matrixX, PS_TYPE_F64) : NULL;
     284        outStamp->vector1 = inStamp->vector1 ? psVectorCopy(NULL, inStamp->vector1, PS_TYPE_F64) : NULL;
     285        outStamp->vector2 = inStamp->vector2 ? psVectorCopy(NULL, inStamp->vector2, PS_TYPE_F64) : NULL;
     286
     287        out->stamps->data[i] = outStamp;
     288    }
     289
     290    return out;
     291}
     292
    227293pmSubtractionStamp *pmSubtractionStampAlloc(void)
    228294{
  • branches/eam_branches/20090715/psModules/src/imcombine/pmSubtractionStamps.h

    r23937 r25407  
    5252    } \
    5353}
     54
     55/// Copy a list of stamps
     56///
     57/// A deep copy is performed of the stamp list and the component stamps
     58pmSubtractionStampList *pmSubtractionStampListCopy(
     59    const pmSubtractionStampList *in    // Stamp list to copy
     60    );
     61
    5462
    5563/// A stamp for image subtraction
Note: See TracChangeset for help on using the changeset viewer.