IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 2, 2009, 5:10:19 PM (17 years ago)
Author:
eugene
Message:

merge changes from trunk

Location:
branches/eam_branches/20090820
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090820

  • branches/eam_branches/20090820/psModules/src/camera/pmFPA.h

    r21363 r25766  
    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/20090820/psModules/src/camera/pmFPAMaskWeight.c

    r24767 r25766  
    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/20090820/psModules/src/camera/pmFPAMaskWeight.h

    r25116 r25766  
    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
  • branches/eam_branches/20090820/psModules/src/camera/pmFPAMosaic.c

    r21363 r25766  
    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/20090820/psModules/src/camera/pmFPARead.c

    r24792 r25766  
    387387                psFree(regionString);
    388388                psFree(readout);
     389                psFree(iter);
    389390                return false;
    390391            }
  • branches/eam_branches/20090820/psModules/src/camera/pmHDUGenerate.c

    r25167 r25766  
    611611            if (cells->n == 0) {
    612612                // Nothing to do
     613                psFree (cells);
    613614                return true;
    614615            }
     
    660661            if (cells->n == 0) {
    661662                // Nothing to do
     663                psFree (cells);
    662664                return true;
    663665            }
     
    710712                return true;
    711713            }
    712 
    713714            bool status = generateHDU(hdu, cells);
    714715            psFree(cells);
  • branches/eam_branches/20090820/psModules/src/camera/pmReadoutFake.c

    r23960 r25766  
    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);
    11197                continue;
    11298            }
     99            // check that all params are valid:
     100            bool validParams = true;
     101            for (int n = 0; validParams && (n < normModel->params->n); n++) {
     102                if (n == PM_PAR_SKY) continue;
     103                if (n == PM_PAR_I0) continue;
     104                if (n == PM_PAR_XPOS) continue;
     105                if (n == PM_PAR_YPOS) continue;
     106                if (!isfinite(normModel->params->data.F32[n])) validParams = false;
     107            }
     108            if (!validParams) {
     109                psFree(normModel);
     110                continue;
     111            }           
    113112            if (circularise && !circulariseModel(normModel)) {
    114113                psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model.");
     
    121120        }
    122121
    123         pmModel *fakeModel = pmModelFromPSFforXY(psf, x, y, flux);
     122        pmModel *fakeModel = pmModelFromPSFforXY(psf, xSrc, ySrc, flux);
    124123        if (!fakeModel || (fakeModel->flags & MODEL_MASK)) {
    125124            psFree(fakeModel);
    126125            continue;
    127126        }
     127        // check that all params are valid:
     128        bool validParams = true;
     129        for (int n = 0; validParams && (n < fakeModel->params->n); n++) {
     130            if (n == PM_PAR_SKY) continue;
     131            if (n == PM_PAR_I0) continue;
     132            if (n == PM_PAR_XPOS) continue;
     133            if (n == PM_PAR_YPOS) continue;
     134            if (!isfinite(fakeModel->params->data.F32[n])) validParams = false;
     135        }
     136        if (!validParams) {
     137            psFree(fakeModel);
     138            continue;
     139        }               
    128140        if (circularise && !circulariseModel(fakeModel)) {
    129141            psError(PS_ERR_UNKNOWN, false, "Unable to circularise PSF model.");
     
    137149
    138150        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
     151        fakeSource->peak = pmPeakAlloc(xSrc, ySrc, fakeModel->params->data.F32[PM_PAR_I0], PM_PEAK_LONE);
     152        float fakeRadius = 1.0;         // Radius of fake source
     153        if (isfinite(minFlux)) {
     154            fakeRadius = PS_MAX(fakeRadius, fakeModel->modelRadius(fakeModel->params, minFlux));
     155        }
     156        if (radius > 0) {
     157            fakeRadius = PS_MAX(fakeRadius, radius);
     158        }
    142159
    143160        if (xOffset) {
    144             if (!pmSourceDefinePixels(fakeSource, readout, x + xOffset->data.S32[i],
    145                                       y + yOffset->data.S32[i], fakeRadius)) {
     161            if (!pmSourceDefinePixels(fakeSource, readout, xSrc + xOffset->data.S32[i],
     162                                      ySrc + yOffset->data.S32[i], fakeRadius)) {
    146163                psErrorClear();
    147164                continue;
     
    153170            }
    154171        } else {
    155             if (!pmSourceDefinePixels(fakeSource, readout, x, y, fakeRadius)) {
     172            if (!pmSourceDefinePixels(fakeSource, readout, xSrc, ySrc, fakeRadius)) {
    156173                psErrorClear();
    157174                continue;
     
    168185    return true;
    169186}
     187
     188
     189bool pmReadoutFakeFromSources(pmReadout *readout, int numCols, int numRows, const psArray *sources,
     190                              pmSourceMode sourceMask, const psVector *xOffset, const psVector *yOffset,
     191                              const pmPSF *psf, float minFlux, int radius,
     192                              bool circularise, bool normalisePeak)
     193{
     194    PS_ASSERT_ARRAY_NON_NULL(sources, false);
     195
     196    int numSources = sources->n;          // Number of stars
     197    psVector *x = psVectorAllocEmpty(numSources, PS_TYPE_F32);
     198    psVector *y = psVectorAllocEmpty(numSources, PS_TYPE_F32);
     199    psVector *mag = psVectorAllocEmpty(numSources, PS_TYPE_F32);
     200
     201    int numGood = 0;                    // Number of good sources
     202    for (int i = 0; i < numSources; i++) {
     203        pmSource *source = sources->data[i]; // Source of interest
     204        if (!source) {
     205            continue;
     206        }
     207        if (source->mode & sourceMask) {
     208            continue;
     209        }
     210        if (!isfinite(source->psfMag)) {
     211            continue;
     212        }
     213        float xSrc, ySrc;                     // Coordinates of source
     214        if (source->modelPSF) {
     215            xSrc = source->modelPSF->params->data.F32[PM_PAR_XPOS];
     216            ySrc = source->modelPSF->params->data.F32[PM_PAR_YPOS];
     217        } else {
     218            xSrc = source->peak->xf;
     219            ySrc = source->peak->yf;
     220        }
     221
     222        x->data.F32[numGood] = xSrc;
     223        y->data.F32[numGood] = ySrc;
     224        mag->data.F32[numGood] = source->psfMag;
     225        numGood++;
     226    }
     227    x->n = numGood;
     228    y->n = numGood;
     229    mag->n = numGood;
     230
     231    bool status = pmReadoutFakeFromVectors(readout, numCols, numRows, x, y, mag, xOffset, yOffset, psf,
     232                                           minFlux, radius, circularise, normalisePeak);
     233    psFree(x);
     234    psFree(y);
     235    psFree(mag);
     236
     237    return status;
     238}
  • branches/eam_branches/20090820/psModules/src/camera/pmReadoutFake.h

    r20999 r25766  
    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.