IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 26035


Ignore:
Timestamp:
Nov 4, 2009, 4:52:05 PM (17 years ago)
Author:
Paul Price
Message:

Soften errors, both in the least-squares matrix/vector construction and in the rejection stage. Softening in the rejection stage seems to be very important so that bright stamps aren't rejected (after which the solution can go crazy). Now carrying around a weight image = 1/variance instead of the variance image. This can be softened, saving many divisions in the matrix/vector construction.

Location:
trunk/psModules/src/imcombine
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/imcombine/pmSubtraction.c

    r25999 r26035  
    2929#define PIXEL_LIST_BUFFER 100           // Number of entries to add to pixel list at a time
    3030#define MIN_SAMPLE_STATS    7           // Minimum number to use sample statistics; otherwise use quartiles
    31 #define USE_SYS_ERR                   // Use systematic error image?
     31#define USE_KERNEL_ERR                  // Use kernel error image?
    3232
    3333//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    266266static void convolveVarianceFFT(psImage *target,// Place the result in here
    267267                              psImage *variance, // Variance map to convolve
    268                               psImage *sys, // Systematic error image
     268                              psImage *kernelErr, // Kernel error image
    269269                              psImage *mask, // Mask image
    270270                              psImageMaskType maskVal, // Value to mask
     
    278278
    279279    psImage *subVariance = variance ? psImageSubset(variance, border) : NULL; // Variance map
    280     psImage *subSys = sys ? psImageSubset(sys, border) : NULL; // Systematic error image
     280    psImage *subKE = kernelErr ? psImageSubset(kernelErr, border) : NULL; // Kernel error image
    281281    psImage *subMask = mask ? psImageSubset(mask, border) : NULL; // Mask
    282282
    283283    // XXX Can trim this a little by combining the convolution: only have to take the FFT of the kernel once
    284284    psImage *convVariance = psImageConvolveFFT(NULL, subVariance, subMask, maskVal, kernel); // Convolved variance
    285     psImage *convSys = subSys ? psImageConvolveFFT(NULL, subSys, subMask, maskVal, kernel) : NULL; // Conv sys
     285    psImage *convKE = subKE ? psImageConvolveFFT(NULL, subKE, subMask, maskVal, kernel) : NULL; // Conv KE
    286286
    287287    psFree(subVariance);
    288     psFree(subSys);
     288    psFree(subKE);
    289289    psFree(subMask);
    290290
    291291    // Now, we have to stick it in where it belongs
    292292    int xMin = region.x0, xMax = region.x1, yMin = region.y0, yMax = region.y1; // Bounds of region
    293     if (convSys) {
     293    if (convKE) {
    294294        for (int yTarget = yMin, ySource = size; yTarget < yMax; yTarget++, ySource++) {
    295295            for (int xTarget = xMin, xSource = size; xTarget < xMax; xTarget++, xSource++) {
    296296                target->data.F32[yTarget][xTarget] = convVariance->data.F32[ySource][xSource] +
    297                     convSys->data.F32[ySource][xSource];
     297                    convKE->data.F32[ySource][xSource];
    298298            }
    299299        }
     
    306306
    307307    psFree(convVariance);
    308     psFree(convSys);
     308    psFree(convKE);
    309309
    310310    return;
     
    342342                                  psImage *image, // Image to convolve
    343343                                  psImage *variance, // Variance map to convolve, or NULL
    344                                   psImage *sys, // Systematic error image, or NULL
     344                                  psImage *kernelErr, // Kernel error image, or NULL
    345345                                  psImage *subMask, // Subtraction mask
    346346                                  const pmSubtractionKernels *kernels, // Kernels
     
    379379        convolveFFT(convImage, image, subMask, subBad, *kernelImage, region, background, kernels->size);
    380380        if (variance) {
    381             convolveVarianceFFT(convVariance, variance, sys, subMask, subBad, *kernelVariance, region, kernels->size);
     381            convolveVarianceFFT(convVariance, variance, kernelErr, subMask, subBad, *kernelVariance,
     382                                region, kernels->size);
    382383        }
    383384    } else {
     
    429430}
    430431
    431 #ifdef USE_SYS_ERR
    432 // Generate an image that can be used to track systematic errors
    433 static psImage *subtractionSysErrImage(const psImage *image, // Image from which to make sys err image
    434                                        float sysError // Relative systematic error
    435                                        )
    436 {
    437     if (!isfinite(sysError) || sysError == 0.0) {
     432#ifdef USE_KERNEL_ERR
     433// Generate an image that can be used to track systematic errors in the kernel
     434static psImage *subtractionKernelErrImage(const psImage *image, // Image from which to make kernel error image
     435                                          float kernelError // Relative systematic error in kernel
     436    )
     437{
     438    if (!isfinite(kernelError) || kernelError == 0.0) {
    438439        return NULL;
    439440    }
    440441
    441442    int numCols = image->numCols, numRows = image->numRows; // Size of image
    442     psImage *sys = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Systematic error image
    443 
    444     float sysError2 = PS_SQR(sysError); // Square of the systematic error
     443    psImage *kernelErr = psImageAlloc(numCols, numRows, PS_TYPE_F32); // Kernel error image
     444
     445    float kernelError2 = PS_SQR(kernelError); // Square of the kernel error
    445446    for (int y = 0; y < numRows; y++) {
    446447        for (int x = 0; x < numCols; x++) {
    447             sys->data.F32[y][x] = PS_SQR(image->data.F32[y][x]) * sysError2;
    448         }
    449     }
    450 
    451     return sys;
     448            kernelErr->data.F32[y][x] = PS_SQR(image->data.F32[y][x]) * kernelError2;
     449        }
     450    }
     451
     452    return kernelErr;
    452453}
    453454#endif
     
    892893                psFree(stamp->image1);
    893894                psFree(stamp->image2);
    894                 psFree(stamp->variance);
    895                 stamp->image1 = stamp->image2 = stamp->variance = NULL;
     895                psFree(stamp->weight);
     896                stamp->image1 = stamp->image2 = stamp->weight = NULL;
    896897                psFree(stamp->matrix1);
    897898                psFree(stamp->matrix2);
     
    10401041                                     psImage *convMask, // Output convolved mask
    10411042                                     const pmReadout *ro1, const pmReadout *ro2, // Input readouts
    1042                                      psImage *sys1, psImage *sys2, // Systematic error images
     1043                                     psImage *kernelErr1, psImage *kernelErr2, // Kernel error images
    10431044                                     psImage *subMask, // Input subtraction mask
    10441045                                     psImageMaskType maskBad, // Mask value to give bad pixels
     
    10661067    if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    10671068        convolveRegion(out1->image, out1->variance, convMask, &kernelImage, &kernelVariance,
    1068                        ro1->image, ro1->variance, sys1, subMask, kernels, polyValues, background, *region,
    1069                        maskBad, maskPoor, poorFrac, useFFT, false);
     1069                       ro1->image, ro1->variance, kernelErr1, subMask, kernels, polyValues, background,
     1070                       *region, maskBad, maskPoor, poorFrac, useFFT, false);
    10701071    }
    10711072    if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    10721073        convolveRegion(out2->image, out2->variance, convMask, &kernelImage, &kernelVariance,
    1073                        ro2->image, ro2->variance, sys2, subMask, kernels, polyValues, background, *region,
    1074                        maskBad, maskPoor, poorFrac, useFFT, kernels->mode == PM_SUBTRACTION_MODE_DUAL);
     1074                       ro2->image, ro2->variance, kernelErr2, subMask, kernels, polyValues, background,
     1075                       *region, maskBad, maskPoor, poorFrac, useFFT,
     1076                       kernels->mode == PM_SUBTRACTION_MODE_DUAL);
    10751077    }
    10761078
     
    11171119    const pmReadout *ro1 = args->data[7]; // Input readout 1
    11181120    const pmReadout *ro2 = args->data[8]; // Input readout 2
    1119     psImage *sys1 = args->data[9]; // Systematic error image 1
    1120     psImage *sys2 = args->data[10]; // Systematic error image 2
     1121    psImage *kernelErr1 = args->data[9]; // Kernel error image 1
     1122    psImage *kernelErr2 = args->data[10]; // Kernel error image 2
    11211123    psImage *subMask = args->data[11]; // Subtraction mask
    11221124    psImageMaskType maskBad = PS_SCALAR_VALUE(args->data[12], PS_TYPE_IMAGE_MASK_DATA); // Output mask value for bad pixels
     
    11281130    bool useFFT = PS_SCALAR_VALUE(args->data[18], U8); // Use FFT for convolution?
    11291131
    1130     return subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, sys1, sys2,
    1131                                     subMask, maskBad, maskPoor, poorFrac, region, kernels, doBG, useFFT);
     1132    return subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, kernelErr1,
     1133                                    kernelErr2, subMask, maskBad, maskPoor, poorFrac, region, kernels,
     1134                                    doBG, useFFT);
    11321135}
    11331136
    11341137bool pmSubtractionConvolve(pmReadout *out1, pmReadout *out2, const pmReadout *ro1, const pmReadout *ro2,
    11351138                           psImage *subMask, int stride, psImageMaskType maskBad, psImageMaskType maskPoor,
    1136                            float poorFrac, float sysError, const psRegion *region,
     1139                           float poorFrac, float kernelError, const psRegion *region,
    11371140                           const pmSubtractionKernels *kernels, bool doBG, bool useFFT)
    11381141{
     
    11721175    PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(poorFrac, 0.0, false);
    11731176    PS_ASSERT_FLOAT_LESS_THAN_OR_EQUAL(poorFrac, 1.0, false);
    1174     PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(sysError, 0.0, false);
    1175     PS_ASSERT_FLOAT_LESS_THAN_OR_EQUAL(sysError, 1.0, false);
     1177    PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(kernelError, 0.0, false);
     1178    PS_ASSERT_FLOAT_LESS_THAN_OR_EQUAL(kernelError, 1.0, false);
    11761179    if (region && psRegionIsNaN(*region)) {
    11771180        psString string = psRegionToString(*region);
     
    12321235    }
    12331236
    1234     psImage *sys1 = NULL, *sys2 = NULL; // Systematic error images
    1235 #ifdef USE_SYS_ERR
     1237    psImage *kernelErr1 = NULL, *kernelErr2 = NULL; // Kernel error images
     1238#ifdef USE_KERNEL_ERR
    12361239    if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    1237         sys1 = subtractionSysErrImage(ro1->image, sysError);
     1240        kernelErr1 = subtractionKernelErrImage(ro1->image, kernelError);
    12381241    }
    12391242    if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    1240         sys2 = subtractionSysErrImage(ro2->image, sysError);
     1243        kernelErr2 = subtractionKernelErrImage(ro2->image, kernelError);
    12411244    }
    12421245#endif
     
    12891292                psArrayAdd(args, 1, (pmReadout*)ro1); // Casting away const
    12901293                psArrayAdd(args, 1, (pmReadout*)ro2); // Casting away const
    1291                 psArrayAdd(args, 1, sys1);
    1292                 psArrayAdd(args, 1, sys2);
     1294                psArrayAdd(args, 1, kernelErr1);
     1295                psArrayAdd(args, 1, kernelErr2);
    12931296                psArrayAdd(args, 1, subMask);
    12941297                PS_ARRAY_ADD_SCALAR(args, maskBad, PS_TYPE_IMAGE_MASK);
     
    13061309                psFree(job);
    13071310            } else {
    1308                 subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, sys1, sys2,
    1309                                          subMask, maskBad, maskPoor, poorFrac, subRegion, kernels, doBG,
    1310                                          useFFT);
     1311                subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2,
     1312                                         kernelErr1, kernelErr2, subMask, maskBad, maskPoor, poorFrac,
     1313                                         subRegion, kernels, doBG, useFFT);
    13111314            }
    13121315            psFree(subRegion);
     
    13331336    psImageConvolveSetThreads(oldThreads);
    13341337
    1335     psFree(sys1);
    1336     psFree(sys2);
     1338    psFree(kernelErr1);
     1339    psFree(kernelErr2);
    13371340
    13381341    // Calculate covariances
  • trunk/psModules/src/imcombine/pmSubtractionEquation.c

    r26031 r26035  
    1717//#define TESTING                         // TESTING output for debugging; may not work with threads!
    1818
    19 #define USE_VARIANCE                    // Include variance in equation?
     19#define USE_WEIGHT                      // Include weight (1/variance) in equation?
    2020
    2121
     
    2929                                  const psKernel *input, // Input image (target)
    3030                                  const psKernel *reference, // Reference image (convolution source)
    31                                   const psKernel *variance,  // Variance image
     31                                  const psKernel *weight,  // Weight image
    3232                                  const psArray *convolutions,         // Convolutions for each kernel
    3333                                  const pmSubtractionKernels *kernels, // Kernels
     
    7474                for (int x = - footprint; x <= footprint; x++) {
    7575                    double cc = iConv->kernel[y][x] * jConv->kernel[y][x];
    76 #ifdef USE_VARIANCE
    77                     cc /= variance->kernel[y][x];
     76#ifdef USE_WEIGHT
     77                    cc *= weight->kernel[y][x];
    7878#endif
    7979                    sumCC += cc;
     
    102102                double rc = ref * conv;
    103103                double c = conv;
    104 #ifdef USE_VARIANCE
    105                 float varVal = 1.0 / variance->kernel[y][x];
    106                 ic *= varVal;
    107                 rc *= varVal;
    108                 c *= varVal;
     104#ifdef USE_WEIGHT
     105                float wtVal = weight->kernel[y][x];
     106                ic *= wtVal;
     107                rc *= wtVal;
     108                c *= wtVal;
    109109#endif
    110110                sumIC += ic;
     
    137137            double rr = PS_SQR(ref);
    138138            double one = 1.0;
    139 #ifdef USE_VARIANCE
    140             float varVal = 1.0 / variance->kernel[y][x];
    141             rr *= varVal;
    142             ir *= varVal;
    143             in *= varVal;
    144             ref *= varVal;
    145             one *= varVal;
     139#ifdef USE_WEIGHT
     140            float wtVal = weight->kernel[y][x];
     141            rr *= wtVal;
     142            ir *= wtVal;
     143            in *= wtVal;
     144            ref *= wtVal;
     145            one *= wtVal;
    146146#endif
    147147            sumRR += rr;
     
    169169                                      const psKernel *image1, // Image 1
    170170                                      const psKernel *image2, // Image 2
    171                                       const psKernel *variance,  // Variance image
     171                                      const psKernel *weight,  // Weight image
    172172                                      const psArray *convolutions1, // Convolutions of image 1 for each kernel
    173173                                      const psArray *convolutions2, // Convolutions of image 2 for each kernel
     
    227227                    double bb = iConv2->kernel[y][x] * jConv2->kernel[y][x];
    228228                    double ab = iConv1->kernel[y][x] * jConv2->kernel[y][x];
    229 #ifdef USE_VARIANCE
    230                     aa /= variance->kernel[y][x];
    231                     bb /= variance->kernel[y][x];
    232                     ab /= variance->kernel[y][x];
     229#ifdef USE_WEIGHT
     230                    float wtVal = weight->kernel[y][x];
     231                    aa *= wtVal;
     232                    bb *= wtVal;
     233                    ab *= wtVal;
    233234#endif
    234235                    sumAA += aa;
     
    258259                for (int x = - footprint; x <= footprint; x++) {
    259260                    double ab = iConv1->kernel[y][x] * jConv2->kernel[y][x];
    260 #ifdef USE_VARIANCE
    261                     ab /= variance->kernel[y][x];
     261#ifdef USE_WEIGHT
     262                    ab *= weight->kernel[y][x];
    262263#endif
    263264                    sumAB += ab;
     
    295296                double i1i2 = i1 * i2;
    296297
    297 #ifdef USE_VARIANCE
    298                 float varVal = 1.0 / variance->kernel[y][x];
    299                 ai2 *= varVal;
    300                 bi2 *= varVal;
    301                 ai1 *= varVal;
    302                 bi1 *= varVal;
    303                 i1i2 *= varVal;
    304                 a *= varVal;
    305                 b *= varVal;
    306                 i2 *= varVal;
     298#ifdef USE_WEIGHT
     299                float wtVal = weight->kernel[y][x];
     300                ai2 *= wtVal;
     301                bi2 *= wtVal;
     302                ai1 *= wtVal;
     303                bi1 *= wtVal;
     304                i1i2 *= wtVal;
     305                a *= wtVal;
     306                b *= wtVal;
     307                i2 *= wtVal;
    307308#endif
    308309
     
    351352            double i1i2 = i1 * i2;
    352353
    353 #ifdef USE_VARIANCE
    354             float varVal = 1.0 / variance->kernel[y][x];
    355             i1 *= varVal;
    356             i1i1 *= varVal;
    357             one *= varVal;
    358             i2 *= varVal;
    359             i1i2 *= varVal;
     354#ifdef USE_WEIGHT
     355            float wtVal = weight->kernel[y][x];
     356            i1 *= wtVal;
     357            i1i1 *= wtVal;
     358            one *= wtVal;
     359            i2 *= wtVal;
     360            i1i2 *= wtVal;
    360361#endif
    361362
     
    619620      case PM_SUBTRACTION_MODE_1:
    620621        status = calculateMatrixVector(stamp->matrix1, stamp->vector1, stamp->image2, stamp->image1,
    621                                        stamp->variance, stamp->convolutions1, kernels, polyValues,
     622                                       stamp->weight, stamp->convolutions1, kernels, polyValues,
    622623                                       footprint);
    623624        break;
    624625      case PM_SUBTRACTION_MODE_2:
    625626        status = calculateMatrixVector(stamp->matrix1, stamp->vector1, stamp->image1, stamp->image2,
    626                                        stamp->variance, stamp->convolutions2, kernels, polyValues,
     627                                       stamp->weight, stamp->convolutions2, kernels, polyValues,
    627628                                       footprint);
    628629        break;
     
    639640#endif
    640641        status = calculateDualMatrixVector(stamp->matrix1, stamp->vector1, stamp->matrix2, stamp->vector2,
    641                                            stamp->matrixX, stamp->image1, stamp->image2, stamp->variance,
     642                                           stamp->matrixX, stamp->image1, stamp->image2, stamp->weight,
    642643                                           stamp->convolutions1, stamp->convolutions2, kernels, polyValues,
    643644                                           footprint);
     
    11631164
    11641165        // Calculate residuals
    1165         psKernel *variance = stamp->variance; // Variance postage stamp
     1166        psKernel *weight = stamp->weight; // Weight postage stamp
    11661167        psImageInit(residual->image, 0.0);
    11671168        if (kernels->mode != PM_SUBTRACTION_MODE_DUAL) {
     
    12471248        for (int y = - footprint; y <= footprint; y++) {
    12481249            for (int x = - footprint; x <= footprint; x++) {
    1249                 double dev = PS_SQR(residual->kernel[y][x]) / variance->kernel[y][x];
     1250                double dev = PS_SQR(residual->kernel[y][x]) * weight->kernel[y][x];
    12501251                deviation += dev;
    12511252#ifdef TESTING
     
    12901291            psFitsClose(fits);
    12911292        }
    1292         if (stamp->variance) {
     1293        if (stamp->weight) {
    12931294            psString filename = NULL;
    1294             psStringAppend(&filename, "stamp_variance_%03d.fits", i);
     1295            psStringAppend(&filename, "stamp_weight_%03d.fits", i);
    12951296            psFits *fits = psFitsOpen(filename, "w");
    12961297            psFree(filename);
    1297             psFitsWriteImage(fits, NULL, stamp->variance->image, 0, NULL);
     1298            psFitsWriteImage(fits, NULL, stamp->weight->image, 0, NULL);
    12981299            psFitsClose(fits);
    12991300        }
  • trunk/psModules/src/imcombine/pmSubtractionMatch.c

    r25464 r26035  
    6868                                 float thresh2,  // Threshold for stamp finding on readout 2
    6969                                 float stampSpacing, // Spacing between stamps
     70                                 float sysError,     // Relative systematic error in images
    7071                                 int size,         // Kernel half-size
    7172                                 int footprint,     // Convolution footprint for stamps
     
    7879
    7980    *stamps = pmSubtractionStampsFind(*stamps, image1, image2, subMask, region, thresh1, thresh2,
    80                                       size, footprint, stampSpacing, mode);
     81                                      size, footprint, stampSpacing, sysError, mode);
    8182    if (!*stamps) {
    8283        psError(psErrorCodeLast(), false, "Unable to find stamps.");
     
    101102                                  const pmReadout *ro1, const pmReadout *ro2, // Input images
    102103                                  int stride, // Size for convolution patches
    103                                   float sysError, // Relative systematic error
     104                                  float sysError,           // Systematic error in images
     105                                  float kernelError, // Systematic error in kernel
    104106                                  psImageMaskType maskVal, // Value to mask for input
    105107                                  psImageMaskType maskBad, // Mask for output bad pixels
     
    151153        PS_ASSERT_FLOAT_LESS_THAN(sysError, 1.0, false);
    152154    }
     155    if (isfinite(kernelError)) {
     156        PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(kernelError, 0.0, false);
     157        PS_ASSERT_FLOAT_LESS_THAN(kernelError, 1.0, false);
     158    }
    153159    // Don't care about maskVal
    154160    // Don't care about maskBad
     
    194200
    195201bool pmSubtractionMatchPrecalc(pmReadout *conv1, pmReadout *conv2, const pmReadout *ro1, const pmReadout *ro2,
    196                                psMetadata *analysis, int stride, float sysError,
     202                               psMetadata *analysis, int stride, float kernelError,
    197203                               psImageMaskType maskVal, psImageMaskType maskBad, psImageMaskType maskPoor,
    198204                               float poorFrac, float badFrac)
     
    264270    }
    265271
    266     if (!subtractionMatchCheck(conv1, conv2, ro1, ro2, stride, sysError, maskVal, maskBad, maskPoor,
    267                                poorFrac, badFrac, mode)) {
     272    if (!subtractionMatchCheck(conv1, conv2, ro1, ro2, stride, NAN, kernelError,
     273                               maskVal, maskBad, maskPoor, poorFrac, badFrac, mode)) {
    268274        psFree(kernels);
    269275        psFree(regions);
     
    300306
    301307        if (!pmSubtractionConvolve(conv1, conv2, ro1, ro2, subMask, stride, maskBad, maskPoor, poorFrac,
    302                                    sysError, region, kernel, true, useFFT)) {
     308                                   kernelError, region, kernel, true, useFFT)) {
    303309            psError(PS_ERR_UNKNOWN, false, "Unable to convolve image.");
    304310            psFree(outAnalysis);
     
    330336                        int inner, int ringsOrder, int binning, float penalty,
    331337                        bool optimum, const psVector *optFWHMs, int optOrder, float optThreshold,
    332                         int iter, float rej, float sysError, psImageMaskType maskVal, psImageMaskType maskBad,
    333                         psImageMaskType maskPoor, float poorFrac, float badFrac, pmSubtractionMode subMode)
    334 {
    335     if (!subtractionMatchCheck(conv1, conv2, ro1, ro2, stride, sysError, maskVal, maskBad, maskPoor,
    336                                poorFrac, badFrac, subMode)) {
     338                        int iter, float rej, float sysError, float kernelError, psImageMaskType maskVal,
     339                        psImageMaskType maskBad, psImageMaskType maskPoor, float poorFrac,
     340                        float badFrac, pmSubtractionMode subMode)
     341{
     342    if (!subtractionMatchCheck(conv1, conv2, ro1, ro2, stride, sysError, kernelError,
     343                               maskVal, maskBad, maskPoor, poorFrac, badFrac, subMode)) {
    337344        return false;
    338345    }
     
    463470            if (stampsName && strlen(stampsName) > 0) {
    464471                stamps = pmSubtractionStampsSetFromFile(stampsName, ro1->image, subMask, region, size,
    465                                                         footprint, stampSpacing, subMode);
     472                                                        footprint, stampSpacing, sysError, subMode);
    466473            } else if (sources) {
    467474                stamps = pmSubtractionStampsSetFromSources(sources, ro1->image, subMask, region, size,
    468                                                            footprint, stampSpacing, subMode);
     475                                                           footprint, stampSpacing, sysError, subMode);
    469476            }
    470477
     
    472479            // doesn't matter.
    473480            if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, NULL, stampThresh1, stampThresh2,
    474                            stampSpacing, size, footprint, subMode)) {
     481                                      stampSpacing, sysError, size, footprint, subMode)) {
    475482                goto MATCH_ERROR;
    476483            }
     
    538545
    539546                if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, region,
    540                                           stampThresh1, stampThresh2, stampSpacing,
     547                                          stampThresh1, stampThresh2, stampSpacing, sysError,
    541548                                          size, footprint, subMode)) {
    542549                    goto MATCH_ERROR;
     
    608615            psTrace("psModules.imcombine", 2, "Convolving...\n");
    609616            if (!pmSubtractionConvolve(conv1, conv2, ro1, ro2, subMask, stride, maskBad, maskPoor, poorFrac,
    610                                        sysError, region, kernels, true, useFFT)) {
     617                                       kernelError, region, kernels, true, useFFT)) {
    611618                psError(PS_ERR_UNKNOWN, false, "Unable to convolve image.");
    612619                goto MATCH_ERROR;
  • trunk/psModules/src/imcombine/pmSubtractionMatch.h

    r25120 r26035  
    3939                        int iter,       ///< Rejection iterations
    4040                        float rej,      ///< Rejection threshold
    41                         float sysError, ///< Relative systematic error
     41                        float sysError, ///< Relative systematic error in images
     42                        float kernelError, ///< Relative systematic error in kernel
    4243                        psImageMaskType maskVal, ///< Value to mask for input
    4344                        psImageMaskType maskBad, ///< Mask for output bad pixels
     
    5556                               psMetadata *analysis, ///< Analysis metadata with pre-calculated kernel, region
    5657                               int stride, ///< Size for convolution patches
    57                                float sysError, ///< Relative systematic error
     58                               float kernelError, ///< Relative systematic error in kernel
    5859                               psImageMaskType maskVal, ///< Value to mask for input
    5960                               psImageMaskType maskBad, ///< Mask for output bad pixels
  • trunk/psModules/src/imcombine/pmSubtractionParams.c

    r21363 r26035  
    7171                            double *sumII, // Sum of I(x)^2/sigma(x)^2
    7272                            double *sumIC, // Sum of I(x)conv(x)/sigma(x)^2
    73                             const pmSubtractionStamp *stamp, // Stamp with variance
     73                            const pmSubtractionStamp *stamp, // Stamp
    7474                            const psKernel *target, // Target stamp
    7575                            int kernelIndex, // Index for kernel component
     
    7878    )
    7979{
    80     psKernel *variance = stamp->variance;   // Variance, sigma(x)^2
     80    psKernel *weight = stamp->weight;   // Weight image
    8181    psKernel *convolution = selectConvolution(stamp, kernelIndex, mode); // Convolution of interest
    8282
    8383    for (int y = -footprint; y <= footprint; y++) {
    8484        psF32 *in = &target->kernel[y][-footprint]; // Dereference input
    85         psF32 *wt = &variance->kernel[y][-footprint]; // Dereference variance
     85        psF32 *wt = &weight->kernel[y][-footprint]; // Dereference weight
    8686        psF32 *conv = &convolution->kernel[y][-footprint]; // Dereference convolution
    8787        for (int x = -footprint; x <= footprint; x++, in++, wt++, conv++) {
    88             double temp = *in / *wt; // Temporary product
     88            double temp = *in * *wt; // Temporary product
    8989            *sumI += temp;
    9090            *sumII += *in * temp;
     
    9898static void accumulateConvolutions(double *sumC, // Sum of conv(x)/sigma(x)^2
    9999                                   double *sumCC, // Sum of conv(x)^2/sigma(x)^2
    100                                    const pmSubtractionStamp *stamp, // Stamp with input and variance
     100                                   const pmSubtractionStamp *stamp, // Stamp with input and weight
    101101                                   int kernelIndex, // Index for kernel component
    102102                                   int footprint, // Size of region of interest
     
    104104    )
    105105{
    106     psKernel *variance = stamp->variance;   // Variance, sigma(x)^2
     106    psKernel *weight = stamp->weight;   // Weight image
    107107    psKernel *convolution = selectConvolution(stamp, kernelIndex, mode); // Convolution of interest
    108108
    109109    for (int y = -footprint; y <= footprint; y++) {
    110         psF32 *wt = &variance->kernel[y][-footprint]; // Dereference variance
     110        psF32 *wt = &weight->kernel[y][-footprint]; // Dereference weight
    111111        psF32 *conv = &convolution->kernel[y][-footprint]; // Dereference convolution
    112112        for (int x = -footprint; x <= footprint; x++, wt++, conv++) {
    113             double convNoise = *conv / *wt; // Temporary product
     113            double convNoise = *conv * *wt; // Temporary product
    114114            *sumC += convNoise;
    115115            *sumCC += *conv * convNoise;
     
    120120
    121121static double accumulateChi2(const psKernel *target, // Target stamp
    122                              pmSubtractionStamp *stamp, // Stamp with variance
     122                             pmSubtractionStamp *stamp, // Stamp with weight
    123123                             int kernelIndex, // Index for kernel component
    124124                             double coeff, // Coefficient of convolution
     
    129129{
    130130    double chi2 = 0.0;
    131     psKernel *variance = stamp->variance;   // Variance, sigma(x)^2
     131    psKernel *weight = stamp->weight;   // Weight image
    132132    psKernel *convolution = selectConvolution(stamp, kernelIndex, mode); // Convolution of interest
    133133
    134134    for (int y = -footprint; y <= footprint; y++) {
    135135        psF32 *in = &target->kernel[y][-footprint]; // Dereference input
    136         psF32 *wt = &variance->kernel[y][-footprint]; // Dereference variance
     136        psF32 *wt = &weight->kernel[y][-footprint]; // Dereference weight
    137137        psF32 *conv = &convolution->kernel[y][-footprint]; // Dereference convolution
    138138        for (int x = -footprint; x <= footprint; x++, in++, wt++, conv++) {
    139             chi2 += PS_SQR(*in - bg - coeff * *conv) / *wt;
     139            chi2 += PS_SQR(*in - bg - coeff * *conv) * *wt;
    140140        }
    141141    }
     
    146146// Return the initial value of chi^2
    147147static double initialChi2(const psKernel *target, // Target stamp
    148                           const pmSubtractionStamp *stamp, // Stamp with variance
     148                          const pmSubtractionStamp *stamp, // Stamp
    149149                          int footprint, // Size of convolution
    150150                          pmSubtractionMode mode // Mode of subtraction
    151151    )
    152152{
    153     psKernel *variance = stamp->variance;   // Variance map
     153    psKernel *weight = stamp->weight;   // Weight image
    154154    psKernel *source;                   // Source stamp
    155155    switch (mode) {
     
    167167    for (int y = -footprint; y <= footprint; y++) {
    168168        psF32 *in = &target->kernel[y][-footprint]; // Dereference input
    169         psF32 *wt = &variance->kernel[y][-footprint]; // Dereference variance
     169        psF32 *wt = &weight->kernel[y][-footprint]; // Dereference weight
    170170        psF32 *ref = &source->kernel[y][-footprint]; // Derference reference
    171171        for (int x = -footprint; x <= footprint; x++, in++, wt++, ref++) {
    172172            float diff = *in - *ref;    // Temporary value
    173             chi2 += PS_SQR(diff) / *wt;
     173            chi2 += PS_SQR(diff) * *wt;
    174174        }
    175175    }
     
    180180// Subtract a convolution from the input
    181181static void subtractConvolution(psKernel *target, // Target stamp
    182                                 const pmSubtractionStamp *stamp, // Stamp with variance
     182                                const pmSubtractionStamp *stamp, // Stamp
    183183                                int kernelIndex, // Index for kernel component
    184184                                float coeff, // Coefficient of subtraction
     
    288288
    289289        // This sum is invariant to the kernel
    290         psKernel *variance = stamp->variance; // Variance map for stamp
     290        psKernel *weight = stamp->weight; // Weight image
    291291        for (int v = -footprint; v <= footprint; v++) {
    292             psF32 *wt = &variance->kernel[v][-footprint]; // Dereference variance map
     292            psF32 *wt = &weight->kernel[v][-footprint]; // Dereference weight
    293293            for (int u = -footprint; u <= footprint; u++, wt++) {
    294                 sum1 += 1.0 / *wt;
     294                sum1 += 1.0 * *wt;
    295295            }
    296296        }
  • trunk/psModules/src/imcombine/pmSubtractionStamps.c

    r25120 r26035  
    5454    psFree(stamp->image1);
    5555    psFree(stamp->image2);
    56     psFree(stamp->variance);
     56    psFree(stamp->weight);
    5757    psFree(stamp->convolutions1);
    5858    psFree(stamp->convolutions2);
     
    180180
    181181pmSubtractionStampList *pmSubtractionStampListAlloc(int numCols, int numRows, const psRegion *region,
    182                                                     int footprint, float spacing)
     182                                                    int footprint, float spacing, float sysErr)
    183183{
    184184    pmSubtractionStampList *list = psAlloc(sizeof(pmSubtractionStampList)); // Stamp list to return
     
    221221    list->flux = NULL;
    222222    list->footprint = footprint;
     223    list->sysErr = sysErr;
    223224
    224225    return list;
     
    256257        outStamp->image1 = inStamp->image1 ? psKernelCopy(inStamp->image1) : NULL;
    257258        outStamp->image2 = inStamp->image2 ? psKernelCopy(inStamp->image2) : NULL;
    258         outStamp->variance = inStamp->variance ? psKernelCopy(inStamp->variance) : NULL;
     259        outStamp->weight = inStamp->weight ? psKernelCopy(inStamp->weight) : NULL;
    259260
    260261        if (inStamp->convolutions1) {
     
    305306    stamp->image1 = NULL;
    306307    stamp->image2 = NULL;
    307     stamp->variance = NULL;
     308    stamp->weight = NULL;
    308309    stamp->convolutions1 = NULL;
    309310    stamp->convolutions2 = NULL;
     
    322323                                                const psImage *image2, const psImage *subMask,
    323324                                                const psRegion *region, float thresh1, float thresh2,
    324                                                 int size, int footprint, float spacing,
     325                                                int size, int footprint, float spacing, float sysErr,
    325326                                                pmSubtractionMode mode)
    326327{
     
    379380
    380381    if (!stamps) {
    381         stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing);
     382        stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing, sysErr);
    382383    }
    383384
     
    452453                psFree(stamp->image1);
    453454                psFree(stamp->image2);
    454                 psFree(stamp->variance);
     455                psFree(stamp->weight);
    455456                psFree(stamp->convolutions1);
    456457                psFree(stamp->convolutions2);
    457                 stamp->image1 = stamp->image2 = stamp->variance = NULL;
     458                stamp->image1 = stamp->image2 = stamp->weight = NULL;
    458459                stamp->convolutions1 = stamp->convolutions2 = NULL;
    459460
     
    487488                                               const psImage *image, const psImage *subMask,
    488489                                               const psRegion *region, int size, int footprint,
    489                                                float spacing, pmSubtractionMode mode)
     490                                               float spacing, float sysErr, pmSubtractionMode mode)
    490491
    491492{
     
    507508    int numStars = x->n;                // Number of stars
    508509    pmSubtractionStampList *stamps = pmSubtractionStampListAlloc(subMask->numCols, subMask->numRows,
    509                                                                  region, footprint, spacing); // Stamp list
     510                                                                 region, footprint, sysErr,
     511                                                                 spacing); // Stamp list
    510512    int numStamps = stamps->num;        // Number of stamps
    511513
     
    616618        PS_ASSERT_IMAGE_TYPE(image2, PS_TYPE_F32, false);
    617619    }
    618     PS_ASSERT_IMAGE_NON_NULL(variance, false);
    619     PS_ASSERT_IMAGES_SIZE_EQUAL(variance, image1, false);
    620     PS_ASSERT_IMAGE_TYPE(variance, PS_TYPE_F32, false);
    621     PS_ASSERT_INT_NONNEGATIVE(kernelSize, false);
     620    if (variance) {
     621        PS_ASSERT_IMAGE_NON_NULL(variance, false);
     622        PS_ASSERT_IMAGES_SIZE_EQUAL(variance, image1, false);
     623        PS_ASSERT_IMAGE_TYPE(variance, PS_TYPE_F32, false);
     624        PS_ASSERT_INT_NONNEGATIVE(kernelSize, false);
     625    }
    622626
    623627    int numCols = image1->numCols, numRows = image1->numRows; // Size of images
     
    646650        assert(stamp->image1 == NULL);
    647651        assert(stamp->image2 == NULL);
    648         assert(stamp->variance == NULL);
     652        assert(stamp->weight == NULL);
    649653
    650654        psRegion region = psRegionSet(x - size, x + size + 1, y - size, y + size + 1); // Region of interest
     
    660664        }
    661665
    662         psImage *wtSub = psImageSubset(variance, region); // Subimage with stamp
    663         stamp->variance = psKernelAllocFromImage(wtSub, size, size);
    664         psFree(wtSub);                  // Drop reference
     666        psKernel *weight = stamp->weight = psKernelAlloc(-size, size, -size, size); // Weight = 1/variance
     667        if (variance) {
     668            psImage *varSub = psImageSubset(variance, region); // Subimage with stamp
     669            psKernel *var = psKernelAllocFromImage(varSub, size, size); // Variance postage stamp
     670            if (isfinite(stamps->sysErr) && stamps->sysErr > 0) {
     671                float sysErr = 0.5 * stamps->sysErr; // Systematic error
     672                psKernel *image1 = stamp->image1, *image2 = stamp->image2; // Input images
     673                for (int y = -size; y <= size; y++) {
     674                    for (int x = -size; x <= size; x++) {
     675                        weight->kernel[y][x] = 1.0 / (var->kernel[y][x] +
     676                                                      sysErr * (image1->kernel[y][x] + image2->kernel[y][x]));
     677                    }
     678                }
     679            } else {
     680                for (int y = -size; y <= size; y++) {
     681                    for (int x = -size; x <= size; x++) {
     682                        weight->kernel[y][x] = 1.0 / var->kernel[y][x];
     683                    }
     684                }
     685            }
     686            psFree(var);
     687            psFree(varSub);
     688        } else {
     689            psImageInit(weight->image, 1.0);
     690        }
    665691
    666692        stamp->status = PM_SUBTRACTION_STAMP_CALCULATE;
     
    672698pmSubtractionStampList *pmSubtractionStampsSetFromSources(const psArray *sources, const psImage *image,
    673699                                                          const psImage *subMask, const psRegion *region,
    674                                                           int size, int footprint, float spacing,
     700                                                          int size, int footprint, float spacing, float sysErr,
    675701                                                          pmSubtractionMode mode)
    676702{
     
    702728
    703729    pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, image, subMask, region, size,
    704                                                             footprint, spacing, mode); // Stamps to return
     730                                                            footprint, spacing, sysErr, mode); // Stamps
    705731    psFree(x);
    706732    psFree(y);
     
    716742pmSubtractionStampList *pmSubtractionStampsSetFromFile(const char *filename, const psImage *image,
    717743                                                       const psImage *subMask, const psRegion *region,
    718                                                        int size, int footprint, float spacing,
     744                                                       int size, int footprint, float spacing, float sysErr,
    719745                                                       pmSubtractionMode mode)
    720746{
     
    734760
    735761    pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, image, subMask, region, size, footprint,
    736                                                             spacing, mode);
     762                                                            spacing, sysErr, mode);
    737763    psFree(data);
    738764
  • trunk/psModules/src/imcombine/pmSubtractionStamps.h

    r25101 r26035  
    2424    psArray *flux;                      ///< Fluxes for possible stamps (or NULL)
    2525    int footprint;                      ///< Half-size of stamps
     26    float sysErr;                       ///< Systematic error
    2627} pmSubtractionStampList;
    2728
     
    3132                                                    const psRegion *region, // Region for stamps, or NULL
    3233                                                    int footprint, // Half-size of stamps
    33                                                     float spacing // Rough average spacing between stamps
     34                                                    float spacing, // Rough average spacing between stamps
     35                                                    float sysErr  // Relative systematic error or NAN
    3436    );
    3537
     
    6870    psKernel *image1;                   ///< Reference image postage stamp
    6971    psKernel *image2;                   ///< Input image postage stamp
    70     psKernel *variance;                 ///< Variance image postage stamp, or NULL
     72    psKernel *weight;                   ///< Weight image (1/variance) postage stamp, or NULL
    7173    psArray *convolutions1;             ///< Convolutions of image 1 for each kernel component, or NULL
    7274    psArray *convolutions2;             ///< Convolutions of image 2 for each kernel component, or NULL
     
    9193                                                int footprint, ///< Half-size for stamps
    9294                                                float spacing, ///< Rough spacing for stamps
     95                                                float sysErr,  ///< Relative systematic error in images
    9396                                                pmSubtractionMode mode ///< Mode for subtraction
    9497    );
     
    103106                                               int footprint, ///< Half-size for stamps
    104107                                               float spacing, ///< Rough spacing for stamps
     108                                               float sysErr,  ///< Systematic error in images
    105109                                               pmSubtractionMode mode ///< Mode for subtraction
    106110    );
     
    115119    int footprint,                      ///< Half-size for stamps
    116120    float spacing,                      ///< Rough spacing for stamps
     121    float sysErr,                       ///< Systematic error in images
    117122    pmSubtractionMode mode              ///< Mode for subtraction
    118123    );
     
    127132    int footprint,                      ///< Half-size for stamps
    128133    float spacing,                      ///< Rough spacing for stamps
     134    float sysErr,                       ///< Systematic error in images
    129135    pmSubtractionMode mode              ///< Mode for subtraction
    130136    );
Note: See TracChangeset for help on using the changeset viewer.