IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

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

updates from trunk

Location:
branches/eam_branches/20090715/psModules/src/camera
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090715/psModules/src/camera/pmFPA.h

    r21363 r25407  
    4848    psPlaneTransform *toTPA;  ///< Transformation from focal plane to tangent plane, or NULL
    4949    psProjection *toSky;         ///< Projection from tangent plane to sky, or NULL
     50    bool wcsCDkeys;
    5051    // Information
    5152    psMetadata *concepts;               ///< FPA-level concepts
  • branches/eam_branches/20090715/psModules/src/camera/pmFPAMaskWeight.c

    r24767 r25407  
    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 covar = sqrtf(psImageCovarianceFactor(readout->covariance)); // Covariance factor
     424    float correction = stats->robustStdev / covar; // Correction factor
     425    psFree(stats);
     426    psLogMsg("psModules.camera", PS_LOG_DETAIL, "Variance renormalisation factor is %f", correction);
     427
     428    // Check valid range of correction factor
     429    if ((isfinite(minValid) && correction < minValid) || (isfinite(maxValid) && correction > maxValid)) {
     430        psWarning("Variance renormalisation is outside valid range: %f vs %f:%f --- no correction made",
     431                  correction, minValid, maxValid);
     432        return true;
     433    }
     434
     435    psBinaryOp(variance, variance, "*", psScalarAlloc(PS_SQR(correction), PS_TYPE_F32));
     436
     437    pmHDU *hdu = pmHDUFromReadout(readout); // HDU for readout
     438    if (hdu)  {
     439        psString history = NULL;
     440        psStringAppend(&history, "Rescaled variance by %6.4f (stdev by %6.4f)",
     441                       PS_SQR(correction), correction);
     442        psMetadataAddStr(hdu->header, PS_LIST_TAIL, "HISTORY", PS_META_DUPLICATE_OK, NULL, history);
     443        psFree(history);
     444    }
    561445
    562446    return true;
    563447}
    564448
    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 }
    632449
    633450
  • branches/eam_branches/20090715/psModules/src/camera/pmFPAMaskWeight.h

    r24483 r25407  
    1515/// @addtogroup Camera Camera Layout
    1616/// @{
    17 
    18 #if 0
    19 /// Pixel mask values
    20 typedef enum {
    21     PM_MASK_CLEAR    = 0x00,            ///< The pixel is not masked
    22     PM_MASK_BLANK    = 0x01,            ///< The pixel is blank or has no (valid) data
    23     PM_MASK_FLAT     = 0x02,            ///< The pixel is non-positive in the flat-field
    24     PM_MASK_DETECTOR = 0x02,            ///< The detector pixel is bad (e.g., bad column, charge trap)
    25     PM_MASK_SAT      = 0x04,            ///< The pixel is saturated in the image of interest
    26     PM_MASK_BAD      = 0x04,            ///< The pixel is low in the image of interest
    27     PM_MASK_RANGE    = 0x04,            ///< The pixel is out of range in the image of interest
    28     PM_MASK_CR       = 0x08,            ///< The pixel is probably a CR
    29     PM_MASK_SPARE1   = 0x10,            ///< Spare mask value
    30     PM_MASK_SPARE2   = 0x20,            ///< Spare mask value
    31     PM_MASK_SUSPECT  = 0x40,            ///< The pixel is suspected of being bad, but may not be
    32     PM_MASK_MARK     = 0x80,            ///< The pixel is marked as temporarily ignored
    33 } pmMaskValue;
    34 #define PM_MASK_MARK 0x80            ///< The pixel is marked as temporarily ignored
    35 #define PM_MASK_SAT  0x04            ///< The pixel is saturated in the image of interest
    36 #endif
    3717
    3818/// Set a temporary readout mask using CELL.SATURATION and CELL.BAD
     
    5434/// can't be generated.
    5535bool pmReadoutSetVariance(pmReadout *readout, ///< Readout for which to set variance
    56                           const psImage *noiseMap, ///< 2D image of the read noise in DN
     36                          const psImage *noiseMap, ///< 2D image of the read noise in DN
    5737                          bool poisson    ///< Include poisson variance (in addition to read noise)?
    5838    );
     
    7353/// with HDU entry).  This is intended for most operations.
    7454bool pmReadoutGenerateVariance(pmReadout *readout, ///< Readout for which to generate variance
    75                           const psImage *noiseMap, ///< 2D image of the read noise in DN
     55                          const psImage *noiseMap, ///< 2D image of the read noise in DN
    7656                               bool poisson    ///< Include poisson variance (in addition to read noise)?
    7757    );
     
    8363                                   psImageMaskType sat, ///< Mask value to give saturated pixels
    8464                                   psImageMaskType bad, ///< Mask value to give bad (low) pixels
    85                                    const psImage *noiseMap, ///< 2D image of the read noise in DN
     65                                   const psImage *noiseMap, ///< 2D image of the read noise in DN
    8666                                   bool poisson ///< Include poisson variance (in addition to read noise)?
    8767    );
     
    9373                                psImageMaskType sat, ///< Mask value to give saturated pixels
    9474                                psImageMaskType bad, ///< Mask value to give bad (low) pixels
    95                                 const psImage *noiseMap, ///< 2D image of the read noise in DN
     75                                const psImage *noiseMap, ///< 2D image of the read noise in DN
    9676                                bool poisson ///< Include poisson variance (in addition to read noise)?
    9777    );
     
    10080///
    10181/// The variance map is adjusted so that the mean matches the actual pixel variance in the image
    102 bool pmReadoutVarianceRenormPixels(
    103     const pmReadout *readout,           ///< Readout to normalise
    104     psImageMaskType maskVal,                 ///< Value to mask
    105     psStatsOptions meanStat,            ///< Statistic to measure the mean (of the variance map)
    106     psStatsOptions stdevStat,           ///< Statistic to measure the stdev (of the image)
    107     psRandom *rng                       ///< Random number generator
    108     );
    109 
    110 /// Renormalise the variance map to match the actual photometry variance
    111 ///
    112 /// The variance map is adjusted so that the actual significance of fake sources matches the
    113 /// guestimated significance
    114 bool pmReadoutVarianceRenormPhot(
     82bool pmReadoutVarianceRenormalise(
    11583    const pmReadout *readout,           ///< Readout to normalise
    11684    psImageMaskType maskVal,            ///< Value to mask
    117     int num,                            ///< Number of instances to measure over the image
    118     float width,                        ///< Photometry width
    119     psStatsOptions meanStat,            ///< Statistic to measure the mean
    120     psStatsOptions stdevStat,           ///< Statistic to measure the stdev
    121     psRandom *rng                       ///< Random number generator
    122     );
    123 
    124 /// Renormalise the variance map to match the actual variance
    125 ///
    126 /// The variance in the image is measured in patches, and the variance map is adjusted so that the mean for
    127 /// that patch corresponds.
    128 bool pmReadoutVarianceRenorm(const pmReadout *readout, // Readout to normalise
    129                              psImageMaskType maskVal, // Value to mask
    130                              psStatsOptions meanStat, // Statistic to measure the mean (of the variance map)
    131                              psStatsOptions stdevStat, // Statistic to measure the stdev (of the image)
    132                              int width,   // Width of patch (pixels)
    133                              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
    13488    );
    13589
  • branches/eam_branches/20090715/psModules/src/camera/pmFPAMosaic.c

    r21363 r25407  
    740740static bool chipMosaic(psImage **mosaicImage, // The mosaic image, to be returned
    741741                       psImage **mosaicMask, // The mosaic mask, to be returned
    742                        psImage **mosaicVariances, // The mosaic variances, to be returned
     742                       psImage **mosaicVariance, // The mosaic variance, to be returned
    743743                       int *xBinChip, int *yBinChip, // The binning in x and y, to be returned
    744744                       const pmChip *chip, // Chip to mosaic
     
    749749    assert(mosaicImage);
    750750    assert(mosaicMask);
    751     assert(mosaicVariances);
     751    assert(mosaicVariance);
    752752    assert(xBinChip);
    753753    assert(yBinChip);
     
    826826    if (allGood) {
    827827        *mosaicImage = imageMosaic(images, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, BLANK_VALUE);
    828         *mosaicVariances = imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, BLANK_VALUE);
     828        *mosaicVariance = imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, BLANK_VALUE);
    829829        *mosaicMask = imageMosaic(masks, xFlip, yFlip, xBin, yBin, *xBinChip, *yBinChip, x0, y0, blank);
    830830    }
     
    847847static bool fpaMosaic(psImage **mosaicImage, // The mosaic image, to be returned
    848848                      psImage **mosaicMask, // The mosaic mask, to be returned
    849                       psImage **mosaicVariances, // The mosaic variances, to be returned
     849                      psImage **mosaicVariance, // The mosaic variance, to be returned
    850850                      int *xBinFPA, int *yBinFPA, // The binning in x and y, to be returned
    851851                      const pmFPA *fpa,  // FPA to mosaic
     
    857857    assert(mosaicImage);
    858858    assert(mosaicMask);
    859     assert(mosaicVariances);
     859    assert(mosaicVariance);
    860860    assert(xBinFPA);
    861861    assert(yBinFPA);
     
    960960    if (allGood) {
    961961        *mosaicImage = imageMosaic(images, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, BLANK_VALUE);
    962         *mosaicVariances = imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, BLANK_VALUE);
     962        *mosaicVariance = imageMosaic(variances, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, BLANK_VALUE);
    963963        *mosaicMask = imageMosaic(masks, xFlip, yFlip, xBin, yBin, *xBinFPA, *yBinFPA, x0, y0, blank);
    964964    }
     
    10251025    psImage *mosaicImage   = NULL;      // The mosaic image
    10261026    psImage *mosaicMask    = NULL;      // The mosaic mask
    1027     psImage *mosaicVariances = NULL;      // The mosaic variances
     1027    psImage *mosaicVariance = NULL;      // The mosaic variances
    10281028
    10291029    // Find the HDU
     
    10521052        }
    10531053        if (hdu->variances) {
    1054             mosaicVariances = psImageSubset(hdu->variances->data[0], bounds);
    1055             if (!mosaicVariances) {
     1054            mosaicVariance = psImageSubset(hdu->variances->data[0], bounds);
     1055            if (!mosaicVariance) {
    10561056                psError(PS_ERR_UNKNOWN, false, "Unable to select variance pixels.\n");
    10571057                return false;
     
    10611061        // Case 2 --- we need to mosaic by cut and paste
    10621062        psTrace("psModules.camera", 1, "Case 2 mosaicking: cut and paste.\n");
    1063         if (!chipMosaic(&mosaicImage, &mosaicMask, &mosaicVariances, &xBin, &yBin, source, targetCell, blank)) {
     1063        if (!chipMosaic(&mosaicImage, &mosaicMask, &mosaicVariance, &xBin, &yBin, source, targetCell, blank)) {
    10641064            psError(PS_ERR_UNKNOWN, false, "Unable to mosaic cells.\n");
    10651065            return false;
     
    10691069    }
    10701070    psTrace("psModules.camera", 1, "xBin,yBin: %d,%d\n", xBin, yBin);
     1071
    10711072
    10721073    // Set the concepts for the target cell
     
    10901091    target->parent->concepts = psMetadataCopy(target->parent->concepts, source->parent->concepts); // FPA lvl
    10911092
     1093    // Average the covariances
     1094    psList *covariances = psListAlloc(NULL); // Input covariance matrices
     1095    for (int i = 0; i < source->cells->n; i++) {
     1096        pmCell *cell = source->cells->data[i]; // Cell of interest
     1097        if (!cell || !cell->data_exists) {
     1098            continue;
     1099        }
     1100        pmReadout *ro = cell->readouts->data[0]; // Readout of interest
     1101        if (!ro || !ro->covariance) {
     1102            continue;
     1103        }
     1104        psListAdd(covariances, PS_LIST_TAIL, ro->covariance);
     1105    }
     1106    psKernel *mosaicCovariance = NULL;  // Covariance for mosaic
     1107    if (psListLength(covariances) > 0) {
     1108        psArray *covarArray = psListToArray(covariances); // Array with covariances
     1109        mosaicCovariance = psImageCovarianceAverage(covarArray);
     1110        psFree(covarArray);
     1111    }
     1112    psFree(covariances);
     1113
    10921114    // Now make a new readout to go in the target cell
    10931115    pmReadout *newReadout = pmReadoutAlloc(targetCell); // New readout
    10941116    newReadout->image  = mosaicImage;
    10951117    newReadout->mask   = mosaicMask;
    1096     newReadout->variance = mosaicVariances;
     1118    newReadout->variance = mosaicVariance;
     1119    newReadout->covariance = mosaicCovariance;
    10971120    psFree(newReadout);                 // Drop reference
    10981121
     
    13341357    target->concepts = psMetadataCopy(target->concepts, source->concepts);
    13351358
     1359    // Average the covariances
     1360    psList *covariances = psListAlloc(NULL); // Input covariance matrices
     1361    for (int i = 0; i < covariances->n; i++) {
     1362        pmChip *chip = chips->data[i];  // Chip of interest
     1363        if (!chip || !chip->data_exists) {
     1364            continue;
     1365        }
     1366        psArray *cells = chip->cells;   // Cells in chip
     1367        for (long j = 0; j < cells->n; j++) {
     1368            pmCell *cell = cells->data[i]; // Cell of interest
     1369            if (!cell || !cell->data_exists) {
     1370                continue;
     1371            }
     1372            pmReadout *ro = cell->readouts->data[0]; // Readout of interest
     1373            if (!ro || !ro->covariance) {
     1374                continue;
     1375            }
     1376            psListAdd(covariances, PS_LIST_TAIL, ro->covariance);
     1377        }
     1378    }
     1379    psKernel *mosaicCovariances = NULL; // Covariance for mosaic
     1380    if (psListLength(covariances) > 0) {
     1381        psArray *covarArray = psListToArray(covariances); // Array with covariances
     1382        mosaicCovariances = psImageCovarianceAverage(covarArray);
     1383        psFree(covarArray);
     1384    }
     1385    psFree(covariances);
     1386
    13361387    // Now make a new readout to go in the new cell
    13371388    pmReadout *newReadout = pmReadoutAlloc(targetCell); // New readout
     
    13391390    newReadout->mask   = mosaicMask;
    13401391    newReadout->variance = mosaicVariances;
     1392    newReadout->covariance = mosaicCovariances;
    13411393    psFree(newReadout);                 // Drop reference
    13421394
  • branches/eam_branches/20090715/psModules/src/camera/pmReadoutFake.c

    r23960 r25407  
    2828#define MODEL_TYPE "PS_MODEL_RGAUSS"    // Type of model to use
    2929#define MAX_AXIS_RATIO 20.0             // Maximum axis ratio for PSF model
    30 #define SOURCE_MASK (PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_CR_LIMIT) // Mask to apply to input sources
    3130#define MODEL_MASK (PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE | \
    3231                    PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models
     
    5049}
    5150
    52 bool pmReadoutFakeFromSources(pmReadout *readout, int numCols, int numRows, const psArray *sources,
    53                               const psVector *xOffset, const psVector *yOffset, const pmPSF *psf,
    54                               float minFlux, int radius, bool circularise, bool normalisePeak)
     51
     52bool pmReadoutFakeFromVectors(pmReadout *readout, int numCols, int numRows,
     53                              const psVector *x, const psVector *y, const psVector *mag,
     54                              const psVector *xOffset, const psVector *yOffset,
     55                              const pmPSF *psf, float minFlux, int radius,
     56                              bool circularise, bool normalisePeak)
    5557{
    5658    PS_ASSERT_PTR_NON_NULL(readout, false);
    5759    PS_ASSERT_INT_LARGER_THAN(numCols, 0, false);
    5860    PS_ASSERT_INT_LARGER_THAN(numRows, 0, false);
    59     PS_ASSERT_ARRAY_NON_NULL(sources, false);
    60 
     61    PS_ASSERT_VECTOR_NON_NULL(x, false);
     62    PS_ASSERT_VECTOR_TYPE(x, PS_TYPE_F32, false);
     63    PS_ASSERT_VECTOR_NON_NULL(y, false);
     64    PS_ASSERT_VECTOR_TYPE(y, PS_TYPE_F32, false);
     65    PS_ASSERT_VECTORS_SIZE_EQUAL(y, x, false);
     66    PS_ASSERT_VECTOR_NON_NULL(mag, false);
     67    PS_ASSERT_VECTOR_TYPE(mag, PS_TYPE_F32, false);
     68    PS_ASSERT_VECTORS_SIZE_EQUAL(mag, x, false);
     69    long numSources = x->n;              // Number of sources
    6170    if (xOffset || yOffset) {
    6271        PS_ASSERT_VECTOR_NON_NULL(xOffset, false);
     
    6473        PS_ASSERT_VECTORS_SIZE_EQUAL(xOffset, yOffset, false);
    6574        PS_ASSERT_VECTOR_TYPE(xOffset, PS_TYPE_S32, false);
    66         PS_ASSERT_VECTOR_TYPE_EQUAL(xOffset, yOffset, false);
    67         if (xOffset->n != sources->n) {
     75        PS_ASSERT_VECTOR_TYPE(yOffset, PS_TYPE_S32, false);
     76        if (xOffset->n != numSources) {
    6877            psError(PS_ERR_BAD_PARAMETER_SIZE, true,
    6978                    "Number of offset vectors (%ld) and sources (%ld) doesn't match",
    70                     xOffset->n, sources->n);
     79                    xOffset->n, numSources);
    7180            return false;
    7281        }
    7382    }
    7483    PS_ASSERT_PTR_NON_NULL(psf, false);
    75     if (radius > 0 && isfinite(minFlux) && minFlux > 0.0) {
    76         psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Cannot define both minimum flux and fixed radius.");
    77         return false;
    78     }
    7984
    8085    readout->image = psImageRecycle(readout->image, numCols, numRows, PS_TYPE_F32);
    8186    psImageInit(readout->image, 0);
    8287
    83     int numSources = sources->n;          // Number of stars
    84     for (int i = 0; i < numSources; i++) {
    85         pmSource *source = sources->data[i]; // Source of interest
    86         if (!source) {
    87             continue;
    88         }
    89         if (source->mode & SOURCE_MASK) {
    90             continue;
    91         }
    92         if (!isfinite(source->psfMag)) {
    93             continue;
    94         }
    95         float x, y;                     // Coordinates of source
    96         if (source->modelPSF) {
    97             x = source->modelPSF->params->data.F32[PM_PAR_XPOS];
    98             y = source->modelPSF->params->data.F32[PM_PAR_YPOS];
    99         } else {
    100             x = source->peak->xf;
    101             y = source->peak->yf;
    102         }
    103 
    104         float flux = powf(10.0, -0.4 * source->psfMag); // Flux of source
     88    for (long i = 0; i < numSources; i++) {
     89        float flux = powf(10.0, -0.4 * mag->data.F32[i]); // Flux of source
     90        float xSrc = x->data.F32[i], ySrc = y->data.F32[i]; // Coordinates of source
    10591
    10692        if (normalisePeak) {
    10793            // Normalise flux
    108             pmModel *normModel = pmModelFromPSFforXY(psf, x, y, 1.0); // Model for normalisation
     94            pmModel *normModel = pmModelFromPSFforXY(psf, xSrc, ySrc, 1.0); // Model for normalisation
    10995            if (!normModel || (normModel->flags & MODEL_MASK)) {
    11096                psFree(normModel);
     
    121107        }
    122108
    123         pmModel *fakeModel = pmModelFromPSFforXY(psf, x, y, flux);
     109        pmModel *fakeModel = pmModelFromPSFforXY(psf, xSrc, ySrc, flux);
    124110        if (!fakeModel || (fakeModel->flags & MODEL_MASK)) {
    125111            psFree(fakeModel);
     
    137123
    138124        pmSource *fakeSource = pmSourceAlloc(); // Fake source to generate
    139         fakeSource->peak = pmPeakAlloc(x, y, fakeModel->params->data.F32[PM_PAR_I0], PM_PEAK_LONE);
    140         float fakeRadius = radius > 0 ? radius :
    141             PS_MAX(1.0, fakeModel->modelRadius(fakeModel->params, minFlux)); // Radius of fake source
     125        fakeSource->peak = pmPeakAlloc(xSrc, ySrc, fakeModel->params->data.F32[PM_PAR_I0], PM_PEAK_LONE);
     126        float fakeRadius = 1.0;         // Radius of fake source
     127        if (isfinite(minFlux)) {
     128            fakeRadius = PS_MAX(fakeRadius, fakeModel->modelRadius(fakeModel->params, minFlux));
     129        }
     130        if (radius > 0) {
     131            fakeRadius = PS_MAX(fakeRadius, radius);
     132        }
    142133
    143134        if (xOffset) {
    144             if (!pmSourceDefinePixels(fakeSource, readout, x + xOffset->data.S32[i],
    145                                       y + yOffset->data.S32[i], fakeRadius)) {
     135            if (!pmSourceDefinePixels(fakeSource, readout, xSrc + xOffset->data.S32[i],
     136                                      ySrc + yOffset->data.S32[i], fakeRadius)) {
    146137                psErrorClear();
    147138                continue;
     
    153144            }
    154145        } else {
    155             if (!pmSourceDefinePixels(fakeSource, readout, x, y, fakeRadius)) {
     146            if (!pmSourceDefinePixels(fakeSource, readout, xSrc, ySrc, fakeRadius)) {
    156147                psErrorClear();
    157148                continue;
     
    168159    return true;
    169160}
     161
     162
     163bool pmReadoutFakeFromSources(pmReadout *readout, int numCols, int numRows, const psArray *sources,
     164                              pmSourceMode sourceMask, const psVector *xOffset, const psVector *yOffset,
     165                              const pmPSF *psf, float minFlux, int radius,
     166                              bool circularise, bool normalisePeak)
     167{
     168    PS_ASSERT_ARRAY_NON_NULL(sources, false);
     169
     170    int numSources = sources->n;          // Number of stars
     171    psVector *x = psVectorAllocEmpty(numSources, PS_TYPE_F32);
     172    psVector *y = psVectorAllocEmpty(numSources, PS_TYPE_F32);
     173    psVector *mag = psVectorAllocEmpty(numSources, PS_TYPE_F32);
     174
     175    int numGood = 0;                    // Number of good sources
     176    for (int i = 0; i < numSources; i++) {
     177        pmSource *source = sources->data[i]; // Source of interest
     178        if (!source) {
     179            continue;
     180        }
     181        if (source->mode & sourceMask) {
     182            continue;
     183        }
     184        if (!isfinite(source->psfMag)) {
     185            continue;
     186        }
     187        float xSrc, ySrc;                     // Coordinates of source
     188        if (source->modelPSF) {
     189            xSrc = source->modelPSF->params->data.F32[PM_PAR_XPOS];
     190            ySrc = source->modelPSF->params->data.F32[PM_PAR_YPOS];
     191        } else {
     192            xSrc = source->peak->xf;
     193            ySrc = source->peak->yf;
     194        }
     195
     196        x->data.F32[numGood] = xSrc;
     197        y->data.F32[numGood] = ySrc;
     198        mag->data.F32[numGood] = source->psfMag;
     199        numGood++;
     200    }
     201    x->n = numGood;
     202    y->n = numGood;
     203    mag->n = numGood;
     204
     205    bool status = pmReadoutFakeFromVectors(readout, numCols, numRows, x, y, mag, xOffset, yOffset, psf,
     206                                           minFlux, radius, circularise, normalisePeak);
     207    psFree(x);
     208    psFree(y);
     209    psFree(mag);
     210
     211    return status;
     212}
  • branches/eam_branches/20090715/psModules/src/camera/pmReadoutFake.h

    r20999 r25407  
    1111#include <pmTrend2D.h>
    1212#include <pmPSF.h>
     13#include <pmSourceMasks.h>
     14
     15/// Generate a fake readout from vectors
     16bool pmReadoutFakeFromVectors(pmReadout *readout, ///< Output readout
     17                              int numCols, int numRows, ///< Dimension of image
     18                              const psVector *x, const psVector *y, ///< Source coordinates
     19                              const psVector *mag, ///< Source magnitudes
     20                              const psVector *xOffset, ///< x offsets for sources (source -> img), or NULL
     21                              const psVector *yOffset, ///< y offsets for sources (source -> img), or NULL
     22                              const pmPSF *psf, ///< PSF for sources
     23                              float minFlux, ///< Minimum flux to bother about; for setting source radius
     24                              int radius, ///< Fixed radius for sources
     25                              bool circularise, ///< Circularise PSF model?
     26                              bool normalisePeak ///< Normalise the peak value?
     27    );
    1328
    1429/// Generate a fake readout from an array of sources
    15 bool pmReadoutFakeFromSources(pmReadout *readout, ///< Output readout, or NULL
     30bool pmReadoutFakeFromSources(pmReadout *readout, ///< Output readout
    1631                              int numCols, int numRows, ///< Dimension of image
    1732                              const psArray *sources, ///< Array of pmSource
     33                              pmSourceMode sourceMask, ///< Mask for sources
    1834                              const psVector *xOffset, ///< x offsets for sources (source -> img), or NULL
    1935                              const psVector *yOffset, ///< y offsets for sources (source -> img), or NULL
Note: See TracChangeset for help on using the changeset viewer.