IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 25148


Ignore:
Timestamp:
Aug 20, 2009, 11:47:38 AM (17 years ago)
Author:
watersc1
Message:
 
Location:
branches/czw_branch/cleanup/psModules/src/imcombine
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtraction.c

    r24298 r25148  
    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
  • branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtraction.h

    r21363 r25148  
    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
  • branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionAnalysis.c

    r25051 r25148  
    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
     
    163171        psFree(image);
    164172
    165         psMetadataItem *item = psMetadataLookup(analysis, PM_SUBTRACTION_ANALYSIS_DECONV_MAX); // Previous
    166         if (item) {
    167             item->data.F32 = PS_MAX(item->data.F32, max);
    168         } else {
    169             psMetadataAddF32(analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_DECONV_MAX, 0,
    170                              "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            }
    171191        }
    172192    }
     
    216236        psMetadataAddF32(analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MYY,
    217237                         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);
    218251    }
    219252
     
    225258
    226259        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,
    227262                         PS_META_DUPLICATE_OK, "Background difference", bg);
    228263        psFree(polyValues);
     
    237272        psMetadataAddF32(analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_DEV_RMS, 0, "RMS stamp deviation",
    238273                         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);
    239281    }
    240282
  • branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionKernels.c

    r24296 r25148  
    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/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionKernels.h

    r20049 r25148  
    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/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionMatch.c

    r24292 r25148  
    447447            }
    448448
     449
     450            // Define kernel basis functions
     451            if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) {
     452                kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, optFWHMs, optOrder,
     453                                                          stamps, footprint, optThreshold, penalty, subMode);
     454                if (!kernels) {
     455                    psErrorClear();
     456                    psWarning("Unable to derive optimum ISIS kernel --- switching to default.");
     457                }
     458            }
     459            if (kernels == NULL) {
     460                // Not an ISIS/GUNK kernel, or the optimum kernel search failed
     461                kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders,
     462                                                       inner, binning, ringsOrder, penalty, subMode);
     463            }
     464
     465            memCheck("kernels");
     466
    449467            if (subMode == PM_SUBTRACTION_MODE_UNSURE) {
     468#if 0
    450469                // Get backgrounds
    451470                psStats *bgStats = psStatsAlloc(BG_STAT); // Statistics for background
     
    469488
    470489                pmSubtractionMode newMode = pmSubtractionOrder(stamps, bg1, bg2); // Subtraction mode to use
     490#endif
     491                pmSubtractionMode newMode = pmSubtractionBestMode(&stamps, &kernels, subMask, rej);
    471492                switch (newMode) {
    472493                  case PM_SUBTRACTION_MODE_1:
     
    483504            }
    484505
    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 
    502506            int numRejected = -1;       // Number of rejected stamps in each iteration
    503507            for (int k = 0; k < iter && numRejected != 0; k++) {
     
    535539
    536540                psTrace("psModules.imcombine", 3, "Rejecting stamps...\n");
    537                 numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej, footprint);
     541                numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej);
    538542                if (numRejected < 0) {
    539543                    psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps.");
     
    557561                    goto MATCH_ERROR;
    558562                }
    559                 pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN, footprint);
     563                pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN);
    560564                psFree(deviations);
    561565            }
     
    842846    return mode;
    843847}
     848
     849
     850// Test a subtraction mode by performing a single iteration
     851static bool subtractionModeTest(pmSubtractionStampList *stamps, // Stamps to use to find best mode
     852                                pmSubtractionKernels *kernels, // Kernel description
     853                                const char *description, // Description for trace
     854                                psImage *subMask,  // Subtraction mask
     855                                float rej               // Rejection threshold
     856                                )
     857{
     858    assert(stamps);
     859    assert(kernels);
     860
     861    psTrace("psModules.imcombine", 3, "Calculating %s equation...\n", description);
     862    if (!pmSubtractionCalculateEquation(stamps, kernels)) {
     863        psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
     864        return false;
     865    }
     866
     867    psTrace("psModules.imcombine", 3, "Solving %s equation...\n", description);
     868    if (!pmSubtractionSolveEquation(kernels, stamps)) {
     869        psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
     870        return false;
     871    }
     872
     873    psTrace("psModules.imcombine", 3, "Calculate %s deviations...\n", description);
     874    psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations
     875    if (!deviations) {
     876        psError(PS_ERR_UNKNOWN, false, "Unable to calculate deviations.");
     877        return false;
     878    }
     879
     880    psTrace("psModules.imcombine", 3, "Rejecting %s stamps...\n", description);
     881    long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej);
     882    if (numRejected < 0) {
     883        psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps.");
     884        psFree(deviations);
     885        return false;
     886    }
     887    psFree(deviations);
     888
     889    if (numRejected > 0) {
     890        // Allow re-fit with reduced stamps set
     891        psTrace("psModules.imcombine", 3, "Resolving %s equation...\n", description);
     892        if (!pmSubtractionSolveEquation(kernels, stamps)) {
     893            psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
     894            return false;
     895        }
     896        psTrace("psModules.imcombine", 3, "Recalculate %s deviations...\n", description);
     897        psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations
     898        if (!deviations) {
     899            psError(PS_ERR_UNKNOWN, false, "Unable to calculate deviations.");
     900            return false;
     901        }
     902        psTrace("psModules.imcombine", 3, "Measuring %s quality...\n", description);
     903        long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN);
     904        if (numRejected < 0) {
     905            psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps.");
     906            psFree(deviations);
     907            return false;
     908        }
     909        psFree(deviations);
     910    }
     911
     912    return true;
     913}
     914
     915
     916pmSubtractionMode pmSubtractionBestMode(pmSubtractionStampList **stamps, pmSubtractionKernels **kernels,
     917                                        const psImage *subMask, float rej)
     918{
     919    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(*stamps, PM_SUBTRACTION_MODE_ERR);
     920    PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(*kernels, PM_SUBTRACTION_MODE_ERR);
     921
     922    // Copies of the inputs
     923    pmSubtractionStampList *stamps1 = pmSubtractionStampListCopy(*stamps);
     924    pmSubtractionKernels *kernels1 = pmSubtractionKernelsCopy(*kernels);
     925    psImage *subMask1 = psImageCopy(NULL, subMask, subMask->type.type);
     926    kernels1->mode = PM_SUBTRACTION_MODE_1;
     927
     928    if (!subtractionModeTest(stamps1, kernels1, "forward", subMask1, rej)) {
     929        psError(PS_ERR_UNKNOWN, false, "Unable to test forward subtraction");
     930        psFree(stamps1);
     931        psFree(kernels1);
     932        psFree(subMask1);
     933        return PM_SUBTRACTION_MODE_ERR;
     934    }
     935    psFree(subMask1);
     936
     937    // Copies of the inputs
     938    pmSubtractionStampList *stamps2 = pmSubtractionStampListCopy(*stamps);
     939    pmSubtractionKernels *kernels2 = pmSubtractionKernelsCopy(*kernels);
     940    psImage *subMask2 = psImageCopy(NULL, subMask, subMask->type.type);
     941    kernels2->mode = PM_SUBTRACTION_MODE_2;
     942
     943    if (!subtractionModeTest(stamps2, kernels2, "backward", subMask2, rej)) {
     944        psError(PS_ERR_UNKNOWN, false, "Unable to test backward subtraction");
     945        psFree(stamps2);
     946        psFree(kernels2);
     947        psFree(subMask2);
     948        psFree(stamps1);
     949        psFree(kernels1);
     950        return PM_SUBTRACTION_MODE_ERR;
     951    }
     952    psFree(subMask2);
     953
     954
     955    pmSubtractionStampList *bestStamps = NULL; // Best choice for stamps
     956    pmSubtractionKernels *bestKernels = NULL; // Best choice for kernels
     957    psLogMsg("psModules.imcombine", PS_LOG_INFO,
     958             "Forward: %f +/- %f from %d stamps\nBackward: %f +/- %f from %d stamps\n",
     959             kernels1->mean, kernels1->rms, kernels1->numStamps,
     960             kernels2->mean, kernels2->rms, kernels2->numStamps);
     961
     962    if (kernels1->mean < kernels2->mean) {
     963        bestStamps = stamps1;
     964        bestKernels = kernels1;
     965    } else {
     966        bestStamps = stamps2;
     967        bestKernels = kernels2;
     968    }
     969
     970    psFree(*stamps);
     971    psFree(*kernels);
     972    *stamps = psMemIncrRefCounter(bestStamps);
     973    *kernels = psMemIncrRefCounter(bestKernels);
     974
     975    psFree(stamps1);
     976    psFree(stamps2);
     977    psFree(kernels1);
     978    psFree(kernels2);
     979
     980    return bestKernels->mode;
     981}
     982
  • branches/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionMatch.h

    r23308 r25148  
    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/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionStamps.c

    r24066 r25148  
    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/czw_branch/cleanup/psModules/src/imcombine/pmSubtractionStamps.h

    r23937 r25148  
    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.