IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 25372


Ignore:
Timestamp:
Sep 14, 2009, 4:15:24 PM (17 years ago)
Author:
Paul Price
Message:

Reworking the variance renormalisation, following Gene's code from ppSubVarianceRescale.c

Location:
trunk/psModules/src/camera
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/camera/pmFPAMaskWeight.c

    r24767 r25372  
    111111        // psError(PS_ERR_IO, true, "CELL.SATURATION is not set --- unable to set mask.\n");
    112112        // return false;
    113         psWarning("CELL.SATURATION is not set --- completely masking cell.\n");
    114         saturation = NAN;
     113        psWarning("CELL.SATURATION is not set --- completely masking cell.\n");
     114        saturation = NAN;
    115115    }
    116116    float bad = psMetadataLookupF32(&mdok, cell->concepts, "CELL.BAD"); // Bad level
     
    118118        // psError(PS_ERR_IO, true, "CELL.BAD is not set --- unable to set mask.\n");
    119119        // return false;
    120         psWarning("CELL.BAD is not set --- completely masking cell.\n");
    121         bad = NAN;
     120        psWarning("CELL.BAD is not set --- completely masking cell.\n");
     121        bad = NAN;
    122122    }
    123123    psTrace("psModules.camera", 5, "Saturation: %f, bad: %f\n", saturation, bad);
    124124
    125     // if CELL.GAIN or CELL.READNOISE are not set, then the variance will be set to NAN; 
     125    // if CELL.GAIN or CELL.READNOISE are not set, then the variance will be set to NAN;
    126126    // in this case, we have to set the mask as well
    127127    float gain = psMetadataLookupF32(&mdok, cell->concepts, "CELL.GAIN"); // Cell gain
     
    140140    // completely mask if SATURATION or BAD are invalid
    141141    if (isnan(saturation) || isnan(bad) || isnan(gain) || isnan(readnoise)) {
    142         psImageInit(mask, badMask);
    143         return true;
     142        psImageInit(mask, badMask);
     143        return true;
    144144    }
    145145
     
    230230        // return false;
    231231        psWarning("CELL.GAIN is not set --- setting variance to NAN\n");
    232         gain = NAN;
     232        gain = NAN;
    233233    }
    234234    float readnoise = psMetadataLookupF32(&mdok, cell->concepts, "CELL.READNOISE"); // Cell read noise
     
    237237        // return false;
    238238        psWarning("CELL.READNOISE is not set --- setting variance to NAN\n");
    239         readnoise = NAN;
     239        readnoise = NAN;
    240240    }
    241241    // if we have a non-NAN readnoise, then we need to ensure it has been updated (not necessary if NAN)
     
    248248    if (isnan(gain) || isnan(readnoise)) {
    249249        if (!readout->variance) {
    250             // generate the image if needed
     250            // generate the image if needed
    251251            readout->variance = psImageAlloc(readout->image->numCols, readout->image->numRows, PS_TYPE_F32);
    252252        }
    253         // XXX need to set the mask, if defined
     253        // XXX need to set the mask, if defined
    254254        psImageInit(readout->variance, NAN);
    255         return true;
     255        return true;
    256256    }
    257257
     
    262262
    263263        // a negative variance is non-sensical. if the image value drops below 1, the variance must be 1.
    264         // XXX this calculation is wrong: limit is 1 e-, but this is in DN
     264        // XXX this calculation is wrong: limit is 1 e-, but this is in DN
    265265        readout->variance = (psImage*)psUnaryOp(readout->variance, readout->variance, "abs");
    266266        readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "max",
     
    276276    // apply a supplied readnoise map (NOTE: in DN, not electrons):
    277277    if (noiseMap) {
    278         psImage *rdVar = (psImage*)psBinaryOp(NULL, (const psPtr) noiseMap, "*", (const psPtr) noiseMap);
    279         readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", rdVar);
    280         psFree (rdVar);
     278        psImage *rdVar = (psImage*)psBinaryOp(NULL, (const psPtr) noiseMap, "*", (const psPtr) noiseMap);
     279        readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", rdVar);
     280        psFree (rdVar);
    281281    } else {
    282         readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", psScalarAlloc(readnoise*readnoise/gain/gain, PS_TYPE_F32));
     282        readout->variance = (psImage*)psBinaryOp(readout->variance, readout->variance, "+", psScalarAlloc(readnoise*readnoise/gain/gain, PS_TYPE_F32));
    283283    }
    284284
     
    362362
    363363
    364 bool pmReadoutVarianceRenormPixels(const pmReadout *readout, psImageMaskType maskVal,
    365                                  psStatsOptions meanStat, psStatsOptions stdevStat, psRandom *rng)
     364bool pmReadoutVarianceRenormalise(const pmReadout *readout, psImageMaskType maskVal,
     365                                  int sample, float minValid, float maxValid)
    366366{
    367367    PM_ASSERT_READOUT_NON_NULL(readout, false);
     
    371371    psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout parts
    372372
    373     if (!psMemIncrRefCounter(rng)) {
    374         rng = psRandomAlloc(PS_RANDOM_TAUS);
    375     }
    376 
    377     psStats *varianceStats = psStatsAlloc(meanStat);// Statistics for mean
    378     if (!psImageBackground(varianceStats, NULL, variance, mask, maskVal, rng)) {
    379         psError(PS_ERR_UNKNOWN, false, "Unable to measure mean variance for image");
    380         psFree(varianceStats);
    381         psFree(rng);
    382         return false;
    383     }
    384     float meanVariance = varianceStats->robustMedian; // Mean variance
    385     psFree(varianceStats);
    386 
    387     psStats *imageStats = psStatsAlloc(stdevStat);// Statistics for mean
    388     if (!psImageBackground(imageStats, NULL, image, mask, maskVal, rng)) {
    389         psError(PS_ERR_UNKNOWN, false, "Unable to measure stdev of image");
    390         psFree(imageStats);
    391         psFree(rng);
    392         return false;
    393     }
    394     float stdevImage = imageStats->robustStdev; // Standard deviation of image
    395     psFree(imageStats);
    396     psFree(rng);
    397 
    398     float correction = PS_SQR(stdevImage) / meanVariance; // Correction to take variance to what it should be
    399     psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising variance map by %f", correction);
    400     psBinaryOp(variance, variance, "*", psScalarAlloc(correction, PS_TYPE_F32));
    401 
    402     return true;
    403 }
    404 
    405 
    406 bool pmReadoutVarianceRenormPhot(const pmReadout *readout, psImageMaskType maskVal, int num, float width,
    407                                psStatsOptions meanStat, psStatsOptions stdevStat, psRandom *rng)
    408 {
    409     PM_ASSERT_READOUT_NON_NULL(readout, false);
    410     PM_ASSERT_READOUT_IMAGE(readout, false);
    411     PM_ASSERT_READOUT_VARIANCE(readout, false);
    412 
    413     if (!psMemIncrRefCounter(rng)) {
    414         rng = psRandomAlloc(PS_RANDOM_TAUS);
    415     }
    416 
    417     psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout images
    418 
    419     // Measure background
    420     psStats *bgStats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);// Statistics for background
    421     if (!psImageBackground(bgStats, NULL, image, mask, maskVal, rng)) {
    422         psError(PS_ERR_UNKNOWN, false, "Unable to measure background for image");
    423         psFree(bgStats);
    424         psFree(rng);
    425         return false;
    426     }
    427     float bgMean = bgStats->robustMedian; // Background level
    428     float bgNoise = bgStats->robustStdev; // Background standard deviation
    429     psFree(bgStats);
    430     psTrace("psModules.camera", 5, "Background is %f +/- %f\n", bgMean, bgNoise);
    431 
    432 
    433     // Construct kernels for flux measurement
    434     // We use N(0,width) and N(0,width/sqrt(2)) kernels, following psphotSignificanceImage.
    435     float sigFactor = 4.0 * M_PI * PS_SQR(width); // Factor for conversion from im/wt ratio to significance
    436     int size = RENORM_NUM_SIGMA, fullSize = 2 * size + 1; // Half-size and full size of Gaussian
    437     psVector *gauss = psVectorAlloc(fullSize, PS_TYPE_F32); // Gaussian for weighting
    438     psVector *gauss2 = psVectorAlloc(fullSize, PS_TYPE_F32); // Gaussian squared
    439     for (int i = 0, x = -size; i < fullSize; i++, x++) {
    440         gauss->data.F32[i] = expf(-0.5 * PS_SQR(x) / PS_SQR(width));
    441         gauss2->data.F32[i] = expf(-PS_SQR(x) / PS_SQR(width));
    442     }
    443 
    444     // Size of image
    445     int numCols = image->numCols, numRows = image->numRows; // Size of images
    446     int xSize = numCols - fullSize, ySize = numRows - fullSize; // Size of consideration
    447     int xOffset = size, yOffset = size;       // Offset to region of consideration
    448 
    449     // Measure fluxes
    450     float peakFlux = RENORM_PEAK * bgNoise;     // Peak flux for fake sources
    451     psVector *noise = psVectorAlloc(num, PS_TYPE_F32); // Measurements of the noise
    452     psVector *source = psVectorAlloc(num, PS_TYPE_F32); // Measurements of fake sources
    453     psVector *guess = psVectorAlloc(num, PS_TYPE_F32); // Guess at significance
    454     psVector *photMask = psVectorAlloc(num, PS_TYPE_VECTOR_MASK); // Mask for fluxes
    455     for (int i = 0; i < num; i++) {
    456         // Coordinates of interest
    457         int xPix = psRandomUniform(rng) * xSize + xOffset + 0.5;
    458         int yPix = psRandomUniform(rng) * ySize + yOffset + 0.5;
    459         psAssert(xPix - size >= 0 && xPix + size < numCols &&
    460                  yPix - size >= 0 && yPix + size < numRows,
    461                  "Bad pixel position: %d,%d", xPix, yPix);
    462 
    463         // Weighted aperture photometry
    464         // This has the same effect as smoothing the image by the window function
    465         float sumNoise = 0.0;       // Sum for noise measurement
    466         float sumSource = 0.0;      // Sum for source measurement
    467         float sumVariance = 0.0;      // Sum for variance measurement
    468         float sumGauss = 0.0, sumGauss2 = 0.0; // Sums of Gaussian kernels
    469         for (int v = 0, y = yPix - size; v < fullSize; v++, y++) {
    470             float xSumNoise = 0.0;  // Sum for noise measurement in x
    471             float xSumSource = 0.0; // Sum for source measurement in x
    472             float xSumVariance = 0.0; // Sum for variance measurement in x
    473             float xSumGauss = 0.0, xSumGauss2 = 0.0; // Sums of Gaussian kernels in x
    474             float yGauss = gauss->data.F32[v]; // Value of Gaussian in y
    475             for (int u = 0, x = xPix - size; u < fullSize; u++, x++) {
    476                 if (mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) {
     373    int numCols = image->numCols, numRows = image->numRows; // Size of image
     374    int numPix = numCols * numRows;                         // Number of pixels
     375    int num = PS_MAX(sample, numPix);                       // Number we care about
     376    psVector *signoise = psVectorAllocEmpty(num, PS_TYPE_F32);   // Signal-to-noise values
     377
     378    if (num >= numPix) {
     379        // We have an image smaller than Nsubset, so just loop over the image pixels
     380        int index = 0;                  // Index for vector
     381        for (int y = 0; y < numRows; y++) {
     382            for (int x = 0; x < numCols; x++) {
     383                if ((mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) ||
     384                    !isfinite(image->data.F32[y][x]) || !isfinite(variance->data.F32[y][x])) {
    477385                    continue;
    478386                }
    479                 float value = image->data.F32[y][x] - bgMean; // Value of image
    480                 float xGauss = gauss->data.F32[u]; // Value of Gaussian in x
    481                 float xGauss2 = gauss2->data.F32[u]; // Value of Gaussian^2 in x
    482                 xSumNoise += value * xGauss;
    483                 xSumSource += (value + peakFlux * xGauss * yGauss) * xGauss;
    484                 xSumVariance += variance->data.F32[y][x] * xGauss2;
    485                 xSumGauss += xGauss;
    486                 xSumGauss2 += xGauss2;
    487             }
    488             float yGauss2 = gauss2->data.F32[v]; // Value of Gaussian^2 in y
    489             sumNoise += xSumNoise * yGauss;
    490             sumSource += xSumSource * yGauss;
    491             sumVariance += xSumVariance * yGauss2;
    492             sumGauss += xSumGauss * yGauss;
    493             sumGauss2 += xSumGauss2 * yGauss2;
    494         }
    495 
    496         photMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = ((isfinite(sumNoise) && isfinite(sumSource) &&
    497                                                 isfinite(sumVariance) && sumGauss > 0 && sumGauss2 > 0) ?
    498                                                0 : 0xFF);
    499 
    500         float smoothImageNoise = sumNoise / sumGauss; // Value of smoothed image pixel for noise
    501         float smoothImageSource = sumSource / sumGauss; // Value of smoothed image pixel for source
    502         float smoothVariance = sumVariance / sumGauss2; // Value of smoothed variance pixel
    503 
    504         noise->data.F32[i] = smoothImageNoise;
    505         source->data.F32[i] = smoothImageSource;
    506         guess->data.F32[i] = (sumSource > 0) ? sigFactor * PS_SQR(smoothImageSource) / smoothVariance : 0.0;
    507         psTrace("psModules.camera", 10, "Flux %d (%d,%d): %f, %f, %f\n",
    508                 i, xPix, yPix, smoothImageNoise, smoothImageSource, smoothVariance);
    509     }
    510     psFree(gauss);
    511     psFree(gauss2);
    512     psFree(rng);
    513 
    514     // Standard deviation of fluxes gives us the real significance
    515     psStats *stdevStats = psStatsAlloc(stdevStat); // Statistics
    516     if (!psVectorStats(stdevStats, noise, NULL, photMask, 0xFF)) {
    517         psError(PS_ERR_UNKNOWN, false, "Unable to measure standard deviation of fluxes");
    518         psFree(stdevStats);
    519         psFree(noise);
    520         psFree(source);
    521         psFree(guess);
    522         psFree(photMask);
     387
     388                signoise->data.F32[index] = image->data.F32[y][x] / sqrtf(variance->data.F32[y][x]);
     389                index++;
     390            }
     391        }
     392        signoise->n = index;
     393    } else {
     394        psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator
     395        int index = 0;                  // Index for vector
     396        for (long i = 0; i < num; i++) {
     397            // Pixel coordinates
     398            int pixel = numPix * psRandomUniform(rng);
     399            int x = pixel % numCols;
     400            int y = pixel / numCols;
     401
     402            if ((mask && mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) ||
     403                !isfinite(image->data.F32[y][x]) || !isfinite(variance->data.F32[y][x])) {
     404                continue;
     405            }
     406
     407            signoise->data.F32[index] = image->data.F32[y][x] / sqrtf(variance->data.F32[y][x]);
     408            index++;
     409        }
     410        signoise->n = index;
     411        psFree(rng);
     412    }
     413
     414    psStats *stats = psStatsAlloc(PS_STAT_ROBUST_STDEV); // Statistics
     415
     416    if (!psVectorStats(stats, signoise, NULL, NULL, 0)) {
     417        psError(PS_ERR_UNKNOWN, false, "Unable to measure statistics on S/N image");
     418        psFree(signoise);
    523419        return false;
    524420    }
    525     float stdev = psStatsGetValue(stdevStats, stdevStat); // Standard deviation of fluxes
    526     psFree(stdevStats);
    527     psFree(noise);
    528     psTrace("psModules.camera", 5, "Standard deviation of fluxes is %f\n", stdev);
    529 
    530     // Ratio of measured significance to guessed significance
    531     psVector *ratio = psVectorAlloc(num, PS_TYPE_F32); // Ratio of measured to guess
    532     for (int i = 0; i < num; i++) {
    533         float measuredSig = PS_SQR(source->data.F32[i] / stdev); // Measured significance
    534         ratio->data.F32[i] = measuredSig / guess->data.F32[i];
    535         if (guess->data.F32[i] <= 0.0 || source->data.F32[i] <= 0.0 || !isfinite(ratio->data.F32[i])) {
    536             photMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xFF;
    537         }
    538         psTrace("psModules.camera", 9, "Ratio %d: %f, %f, %f\n",
    539                 i, guess->data.F32[i], measuredSig, ratio->data.F32[i]);
    540     }
    541     psFree(source);
    542     psFree(guess);
    543 
    544     psStats *meanStats = psStatsAlloc(meanStat | stdevStat); // Statistics
    545     if (!psVectorStats(meanStats, ratio, NULL, photMask, 0xFF)) {
    546         psError(PS_ERR_UNKNOWN, false, "Unable to measure mean ratio");
    547         psFree(meanStats);
    548         psFree(ratio);
    549         psFree(photMask);
    550         return false;
    551     }
    552     float meanRatio = psStatsGetValue(meanStats, meanStat); // Mean ratio
    553     psTrace("psModules.camera", 5, "Mean significance ratio is %f +/- %f\n",
    554             meanRatio, psStatsGetValue(meanStats, stdevStat));
    555     psFree(meanStats);
    556     psFree(ratio);
    557     psFree(photMask);
    558 
    559     psLogMsg("psModules.camera", PS_LOG_INFO, "Renormalising variance map by %f", meanRatio);
    560     psBinaryOp(variance, variance, "*", psScalarAlloc(meanRatio, PS_TYPE_F32));
     421    psFree(signoise);
     422
     423    float correction = stats->robustStdev; // Correction factor
     424    psFree(stats);
     425    psLogMsg("psModules.camera", PS_LOG_DETAIL, "Variance renormalisation factor is %f", correction);
     426
     427    // Check valid range of correction factor
     428    if ((isfinite(minValid) && correction < minValid) || (isfinite(maxValid) && correction > maxValid)) {
     429        psWarning("Variance renormalisation is outside valid range: %f vs %f:%f --- no correction made",
     430                  correction, minValid, maxValid);
     431        return true;
     432    }
     433
     434    psBinaryOp(variance, variance, "*", psScalarAlloc(PS_SQR(correction), PS_TYPE_F32));
     435
     436    pmHDU *hdu = pmHDUFromReadout(readout); // HDU for readout
     437    if (hdu)  {
     438        psString history = NULL;
     439        psStringAppend(&history, "Rescaled variance by %6.4f (stdev by %6.4f)",
     440                       PS_SQR(correction), correction);
     441        psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, history);
     442    }
    561443
    562444    return true;
    563445}
    564446
    565 
    566 bool pmReadoutVarianceRenorm(const pmReadout *readout, psImageMaskType maskVal, psStatsOptions meanStat,
    567                            psStatsOptions stdevStat, int width, psRandom *rng)
    568 {
    569     PM_ASSERT_READOUT_NON_NULL(readout, false);
    570     PM_ASSERT_READOUT_IMAGE(readout, false);
    571     PM_ASSERT_READOUT_VARIANCE(readout, false);
    572     PS_ASSERT_INT_POSITIVE(width, false);
    573 
    574     if (!psMemIncrRefCounter(rng)) {
    575         rng = psRandomAlloc(PS_RANDOM_TAUS);
    576     }
    577 
    578     psImage *image = readout->image, *mask = readout->mask, *variance = readout->variance; // Readout images
    579     int numCols = image->numCols, numRows = image->numRows; // Size of images
    580     int xNum = numCols / width + 1, yNum = numRows / width + 1; // Number of renormalisation regions
    581     float xSize = numCols / (float)xNum, ySize = numRows / (float)yNum; // Size of renormalisation regions
    582 
    583     psStats *meanStats = psStatsAlloc(meanStat), *stdevStats = psStatsAlloc(stdevStat); // Statistics
    584     psVector *buffer = NULL;
    585 
    586     for (int j = 0; j < yNum; j++) {
    587         // Bounds in y
    588         int yMin = j * ySize;
    589         int yMax = (j + 1) * ySize;
    590         for (int i = 0; i < xNum; i++) {
    591             // Bounds in x
    592             int xMin = i * xSize;
    593             int xMax = (i + 1) * xSize;
    594 
    595             psRegion region = psRegionSet(xMin, xMax, yMin, yMax); // Region of interest
    596             psImage *subImage = psImageSubset(image, region); // Sub-image of the image pixels
    597             psImage *subVariance = psImageSubset(variance, region); // Sub image of the variance pixels
    598             psImage *subMask = mask ? psImageSubset(mask, region) : NULL; // Sub-image of the mask pixels
    599 
    600             if (!psImageBackground(stdevStats, &buffer, subImage, subMask, maskVal, rng) ||
    601                 !psImageBackground(meanStats, &buffer, subVariance, subMask, maskVal, rng)) {
    602                 // Nothing we can do about it, but don't want to keel over and die, so do our best to flag it.
    603                 psString regionStr = psRegionToString(region); // String with region
    604                 psWarning("Unable to measure statistics over %s", regionStr);
    605                 psFree(regionStr);
    606                 psErrorClear();
    607                 psImageInit(subVariance, NAN);
    608                 if (subMask) {
    609                     psImageInit(subMask, maskVal);
    610                 }
    611             } else {
    612                 double meanVar = psStatsGetValue(meanStats, meanStat); // Mean of variance map
    613                 double stdev = psStatsGetValue(stdevStats, stdevStat); // Standard deviation of image
    614                 psTrace("psModules.camera", 3,
    615                         "Region [%d:%d,%d:%d] has variance %lf, but mean of variance map is %lf\n",
    616                         xMin, xMax, yMin, yMax, PS_SQR(stdev), meanVar);
    617                 psBinaryOp(subVariance, subVariance, "*", psScalarAlloc(PS_SQR(stdev) / meanVar, PS_TYPE_F32));
    618             }
    619 
    620             psFree(subImage);
    621             psFree(subVariance);
    622             psFree(subMask);
    623         }
    624     }
    625     psFree(meanStats);
    626     psFree(stdevStats);
    627     psFree(rng);
    628     psFree(buffer);
    629 
    630     return true;
    631 }
    632447
    633448
  • trunk/psModules/src/camera/pmFPAMaskWeight.h

    r25116 r25372  
    8080///
    8181/// The variance map is adjusted so that the mean matches the actual pixel variance in the image
    82 bool pmReadoutVarianceRenormPixels(
    83     const pmReadout *readout,           ///< Readout to normalise
    84     psImageMaskType maskVal,                 ///< Value to mask
    85     psStatsOptions meanStat,            ///< Statistic to measure the mean (of the variance map)
    86     psStatsOptions stdevStat,           ///< Statistic to measure the stdev (of the image)
    87     psRandom *rng                       ///< Random number generator
    88     );
    89 
    90 /// Renormalise the variance map to match the actual photometry variance
    91 ///
    92 /// The variance map is adjusted so that the actual significance of fake sources matches the
    93 /// guestimated significance
    94 bool pmReadoutVarianceRenormPhot(
     82bool pmReadoutVarianceRenormalise(
    9583    const pmReadout *readout,           ///< Readout to normalise
    9684    psImageMaskType maskVal,            ///< Value to mask
    97     int num,                            ///< Number of instances to measure over the image
    98     float width,                        ///< Photometry width
    99     psStatsOptions meanStat,            ///< Statistic to measure the mean
    100     psStatsOptions stdevStat,           ///< Statistic to measure the stdev
    101     psRandom *rng                       ///< Random number generator
    102     );
    103 
    104 /// Renormalise the variance map to match the actual variance
    105 ///
    106 /// The variance in the image is measured in patches, and the variance map is adjusted so that the mean for
    107 /// that patch corresponds.
    108 bool pmReadoutVarianceRenorm(const pmReadout *readout, // Readout to normalise
    109                              psImageMaskType maskVal, // Value to mask
    110                              psStatsOptions meanStat, // Statistic to measure the mean (of the variance map)
    111                              psStatsOptions stdevStat, // Statistic to measure the stdev (of the image)
    112                              int width,   // Width of patch (pixels)
    113                              psRandom *rng // Random number generator (for sub-sampling images)
     85    int sample,                         ///< Sample size
     86    float minValid,                     ///< Minimum valid renormalisation, or NAN
     87    float maxValid                      ///< Maximum valid renormalisation, or NAN
    11488    );
    11589
Note: See TracChangeset for help on using the changeset viewer.