IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 28006 for trunk


Ignore:
Timestamp:
May 18, 2010, 2:34:09 PM (16 years ago)
Author:
eugene
Message:

merging changes from PAP branch with modifications to the covariance matrix calculation

Location:
trunk
Files:
15 edited
11 copied

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/Ohana

  • trunk/Ohana/src/relastro

  • trunk/ippconfig

    • Property svn:mergeinfo deleted
  • trunk/ppSim

    • Property svn:mergeinfo deleted
  • trunk/ppSub/src/ppSubReadoutSubtract.c

    r26982 r28006  
    4848    pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT");
    4949    outRO->image = (psImage*)psBinaryOp(outRO->image, minuend->image, "-", subtrahend->image);
    50     if (minuend->variance && subtrahend->variance) {
    51         outRO->variance = (psImage*)psBinaryOp(outRO->variance, minuend->variance, "+", subtrahend->variance);
    52     }
    5350    outRO->mask = (psImage*)psBinaryOp(outRO->mask, minuend->mask, "|", subtrahend->mask);
     51    outRO->variance = (psImage*)psBinaryOp(outRO->variance, minuend->variance, "+", subtrahend->variance);
    5452
     53    // Measure the variance scales
     54    psStats *varStats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); // Statistics for variance images
     55    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS);           // Random number generator
     56    psImageMaskType maskVal = pmConfigMaskGet("MASK.VALUE", config) |
     57        pmConfigMaskGet("BLANK", config); // Bits to mask in inputs
     58    psImageBackground(varStats, NULL, minuend->variance, minuend->mask, maskVal, rng);
     59    float minuendVar = varStats->robustMedian; // Mean variance for minuend
     60    psImageBackground(varStats, NULL, subtrahend->variance, subtrahend->mask, maskVal, rng);
     61    float subtrahendVar = varStats->robustMedian; // Mean variance for subtrahend
     62    psFree(varStats);
     63    psFree(rng);
     64
     65    // Combine the covariances
     66    // These are weighted by the appropriate mean variance.  This is probably not perfectly correct, but it
     67    // does seem to reproduce the correct magnitude limit in psphot.
    5568    psArray *covars = psArrayAlloc(2);  // Covariance pseudo-matrices
     69    psVector *covarWeights = psVectorAlloc(2, PS_TYPE_F32); // Weights for covariances
    5670    covars->data[0] = psMemIncrRefCounter(minuend->covariance);
    5771    covars->data[1] = psMemIncrRefCounter(subtrahend->covariance);
    58     outRO->covariance = psImageCovarianceAverage(covars);
     72    covarWeights->data.F32[0] = minuendVar;
     73    covarWeights->data.F32[1] = subtrahendVar;
     74    outRO->covariance = psImageCovarianceAverageWeighted(covars, covarWeights);
    5975    psFree(covars);
     76    psFree(covarWeights);
     77
     78    psImageCovarianceTransfer(outRO->variance, outRO->covariance);
    6079
    6180    outRO->data_exists = true;
  • trunk/psLib/src/imageops/psImageCovariance.c

    r27702 r28006  
    1111#include "psMemory.h"
    1212#include "psConstants.h"
     13#include "psImageStructManip.h"
     14#include "psImagePixelManip.h"
    1315#include "psImageConvolve.h"
    1416#include "psTrace.h"
     
    1618#include "psScalar.h"
    1719#include "psThread.h"
     20#include "psImageInterpolate.h"
    1821
    1922#include "psImageCovariance.h"
    2023
    2124static bool threaded = false;           // Run threaded?
    22 
    2325
    2426psKernel *psImageCovarianceNone(void)
     
    530532
    531533
     534psKernel *psImageCovarianceScale(const psKernel *in, float scale)
     535{
     536    // Trivial cases
     537    if (!in) {
     538        psKernel *out = psKernelAlloc(0, 0, 0, 0); // Output covariance
     539        out->kernel[0][0] = 1.0;
     540        return out;
     541    }
     542    PS_ASSERT_KERNEL_NON_NULL(in, NULL);
     543    if (scale == 1.0) {
     544        psImage *copy = psImageCopy(NULL, in->image, PS_TYPE_F32); // Copy of input covariance
     545        psKernel *out = psKernelAllocFromImage(copy, -in->xMin, -in->yMin); // Output covariance
     546        psFree(copy);
     547        return out;
     548    }
     549
     550    int xMinIn = in->xMin, xMaxIn = in->xMax, yMinIn = in->yMin, yMaxIn = in->yMax; // Input size
     551    int xMinOut = (float)xMinIn / scale - 0.5, xMaxOut = (float)xMaxIn / scale + 0.5;     // Output size in x
     552    int yMinOut = (float)yMinIn / scale - 0.5, yMaxOut = (float)yMaxIn / scale + 0.5;     // Output size in y
     553
     554    // Over-fill the covariance matrix so we're not troubled by edge effects
     555    psKernel *overfill = psKernelAlloc(xMinIn - 1, xMaxIn + 1, yMinIn - 1, yMaxIn + 1); // Overfilled covar
     556    psImageInit(overfill->image, 0.0);
     557    int numOverlay = (xMaxIn - xMinIn + 1) * (yMaxIn - yMinIn + 1); // Number of pixels to overlay
     558    if (psImageOverlaySection(overfill->image, in->image, 1, 1, "=") != numOverlay) {
     559        psError(psErrorCodeLast(), false, "Unable to overfill covariance matrix.");
     560        psFree(overfill);
     561        return NULL;
     562    }
     563
     564    psImageInterpolation *interp = psImageInterpolationAlloc(PS_INTERPOLATE_BILINEAR, overfill->image,
     565                                                             NULL, NULL, 0, NAN, NAN, 0xFF, 0xFF,
     566                                                             0.0, 0); // Interpolation
     567    psFree(overfill);
     568
     569    // In transforming the positions, we get +0.5 to account for the centre of the pixels being at 0.5
     570    // and +1 to account for the overfill.
     571
     572    psKernel *out = psKernelAlloc(xMinOut, xMaxOut, yMinOut, yMaxOut); // Output covariance
     573    for (int y = yMinOut; y <= yMaxOut; y++) {
     574        float yIn = y * scale + 0.5 - yMinIn + 1; // Position on input image (not the kernel)
     575        for (int x = xMinOut; x <= xMaxOut; x++) {
     576            float xIn = x * scale + 0.5 - xMinIn + 1; // Position on input (not the kernel)
     577            double value;                                     // Value on output
     578            if (!psImageInterpolate(&value, NULL, NULL, xIn, yIn, interp)) {
     579                psError(psErrorCodeLast(), false, "Unable to interpolate kernel.");
     580                return false;
     581            }
     582            out->kernel[y][x] = value;
     583        }
     584    }
     585
     586    psFree(interp);
     587
     588    return out;
     589}
     590
     591
    532592bool psImageCovarianceSetThreads(bool set)
    533593{
  • trunk/psLib/src/imageops/psImageCovariance.h

    r27697 r28006  
    9090    );
    9191
     92
     93/// Rescale a covariance matrix following a change in plate scale
     94///
     95/// The covariance matrix is stretched or shrunk to match the new plate scale.
     96psKernel *psImageCovarianceScale(
     97    const psKernel *in,                 ///< Input covariance pseudo-matrix
     98    float scale                         ///< Scale factor (output plate scale relative to input plate scale)
     99    );
     100
    92101/// Control threading for image covariance functions
    93102///
  • trunk/psModules

    • Property svn:mergeinfo deleted
  • trunk/psphot

    • Property svn:mergeinfo deleted
  • trunk/psphot/src/psphotEfficiency.c

    r27657 r28006  
    7373    psTrace("psphot.fake", 1, "Limiting flux: %f\n", fluxLim);
    7474    psTrace("psphot.fake", 1, "Limiting mag: %f\n", *magLim);
     75    psLogMsg("psphot", PS_LOG_INFO,
     76             "Detection efficiency:\n"
     77             "  Mean variance: %f * %f\n"
     78             "  Threshold: %f\n"
     79             "  Normalisation: %f\n"
     80             "  Limiting magnitude: %f\n",
     81             meanVar, *covarFactor, thresh, *norm, *magLim);
    7582
    7683    *radius = smoothSigma * smoothNsigma;
     
    166173    // loop over the available readouts
    167174    for (int i = 0; i < num; i++) {
    168         if (i == chisqNum) continue; // skip chisq image
    169         if (!psphotEfficiencyReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
     175        if (i == chisqNum) continue; // skip chisq image
     176        if (!psphotEfficiencyReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
    170177            psError (PSPHOT_ERR_CONFIG, false, "failed to measure detection efficiency for PSPHOT.INPUT entry %d", i);
    171             return false;
    172         }
     178            return false;
     179        }
    173180    }
    174181    return true;
  • trunk/pswarp/src/pswarp.h

    r27126 r28006  
    2929#define PSASTRO_RECIPE "PSASTRO" ///< Name of the recipe to use
    3030
    31 #define PSWARP_ANALYSIS_VARFACTOR "PSWARP.VARFACTOR" ///< Name for variance factor in analysis metadata
    3231#define PSWARP_ANALYSIS_GOODPIX   "PSWARP.GOODPIX" ///< Name for number of good pixels in analysis metadata
    3332#define PSWARP_ANALYSIS_COVARIANCES "PSWARP.COVARIANCES" ///< Name for covariance matrices on analysis MD
     33#define PSWARP_ANALYSIS_JACOBIAN "PSWARP.JACOBIAN" ///< Name for Jacobian on analysis MD
    3434
    3535/**
     
    7070    int xMin, xMax, yMin, yMax;         ///< Bounds of tile
    7171    psKernel *covariance;               ///< Covariance matrix
     72    double jacobian;                    ///< (Square root of) local Jacobian
    7273} pswarpTransformTileArgs;
    7374
  • trunk/pswarp/src/pswarpLoop.c

    r27387 r28006  
    267267    }
    268268
    269     // Correct image for change in the plate scale
    270     {
    271         psAssert(input && input->fpa && input->fpa->toSky, "Require astrometry for input");
    272         psAssert(outFPA && outFPA && outFPA->toSky, "Require astrometry for output");
    273 
    274         double inScale = input->fpa->toSky->Xs + input->fpa->toSky->Ys; // Plate scale for input
    275         double outScale = outFPA->toSky->Xs + outFPA->toSky->Ys; // Plate scale for output
    276         float correction = PS_SQR(outScale / inScale); // Correction factor to apply to image
    277         psLogMsg("pswarp", PS_LOG_INFO, "Correcting flux by %f to account for pixel scales", correction);
    278 
    279         psBinaryOp(output->image, output->image, "*", psScalarAlloc(correction, PS_TYPE_F32));
    280         if (output->variance) {
    281             psBinaryOp(output->variance, output->variance, "*",
    282                        psScalarAlloc(PS_SQR(correction), PS_TYPE_F32));
    283         }
    284     }
    285 
    286 
    287269    // Set covariance matrix for output
    288270    {
     
    291273        psAssert(covariances, "Should be there");
    292274        psArray *covars = psListToArray(covariances); // Array of covariance matrices
    293         output->covariance = psImageCovarianceAverage(covars);
     275        psKernel *covar = psImageCovarianceAverage(covars);
    294276        psFree(covars);
    295277        psMetadataRemoveKey(output->analysis, PSWARP_ANALYSIS_COVARIANCES);
     278
     279        // Correct covariance matrix scale for the mean (square root of the) Jacobian
     280        double jacobian = psMetadataLookupF64(NULL, output->analysis, PSWARP_ANALYSIS_JACOBIAN); // Jacobian
     281        int goodPixels = psMetadataLookupS32(NULL, output->analysis, PSWARP_ANALYSIS_GOODPIX);   // Good pixels
     282        jacobian /= goodPixels;
     283        output->covariance = psImageCovarianceScale(covar, jacobian);
     284        psFree(covar);
     285
    296286        psImageCovarianceTransfer(output->variance, output->covariance);
    297287    }
  • trunk/pswarp/src/pswarpTransformReadout.c

    r27096 r28006  
    148148    psThreadJob *job = NULL;
    149149    int xMin = output->image->numCols, xMax = 0, yMin = output->image->numRows, yMax = 0; // Bounds
    150     int goodPixels = 0;                 // total number of good pixels across all tiles
     150    int goodPixels = psMetadataLookupS32(&mdok, output->analysis, PSWARP_ANALYSIS_GOODPIX); // Number of pixels
    151151    psList *covariances = psMetadataLookupPtr(&mdok, output->analysis,
    152152                                              PSWARP_ANALYSIS_COVARIANCES); // Collection of covar. matrices
     
    157157        psFree(covariances);            // Drop reference; still have the copy on the analysis metadata
    158158    }
     159    double jacobian = psMetadataLookupF64(&mdok, output->analysis, PSWARP_ANALYSIS_JACOBIAN); // Jacobian
     160    if (!isfinite(jacobian)) {
     161        jacobian = 0.0;
     162    }
     163
    159164    while ((job = psThreadJobGetDone()) != NULL) {
    160165        if (job->args->n < 1) {
     
    171176                psListAdd(covariances, PS_LIST_TAIL, args->covariance);
    172177            }
     178            if (args->goodPixels > 0 && isfinite(args->jacobian)) {
     179                jacobian += args->jacobian * args->goodPixels;
     180            }
    173181        }
    174182        psFree(job);
    175183    }
    176184    psFree(grid);
     185
     186    psMetadataAddS32(output->analysis, PS_LIST_TAIL, PSWARP_ANALYSIS_GOODPIX, PS_META_REPLACE,
     187                     "Number of good pixels", goodPixels);
     188    psMetadataAddF64(output->analysis, PS_LIST_TAIL, PSWARP_ANALYSIS_JACOBIAN, PS_META_REPLACE,
     189                     "Jacobian of transformation", jacobian);
    177190
    178191    if (xMin < xMax && yMin < yMax) {
  • trunk/pswarp/src/pswarpTransformTile.c

    r27096 r28006  
    4444    args->yMax = PS_MIN_S32;
    4545    args->covariance = NULL;
     46    args->jacobian = NAN;
    4647
    4748    return args;
     
    5051bool pswarpTransformTile(pswarpTransformTileArgs *args)
    5152{
    52     psImage *inImage = args->input->image; ///< Input image
    53     psImage *outImage = args->output->image; ///< Output image
     53    pmReadout *input = args->input;        // Input readout
     54    psImage *inImage = input->image, *inMask = input->mask; // Input images
     55    pmReadout *output = args->output;      // Output readout
     56    psImage *outImage = output->image, *outVariance = output->variance, *outMask = output->mask; // Outputs
    5457
    5558    int inNumCols = inImage->numCols, inNumRows = inImage->numRows; ///< Size of input image
     
    6164
    6265    // Dereference images for convenience
    63     psF32 **outImageData     = args->output->image->data.F32;
    64     psF32 **outVarData       = (args->output->variance) ? args->output->variance->data.F32 : NULL;
    65     psImageMaskType **outMaskData = (args->output->mask)   ? args->output->mask->data.PS_TYPE_IMAGE_MASK_DATA : NULL;
    66     psImageMaskType **inMaskData  = (args->input->mask)    ? args->input->mask->data.PS_TYPE_IMAGE_MASK_DATA : NULL;
     66    psF32 **outImageData     = outImage->data.F32;
     67    psF32 **outVarData       = outVariance ? outVariance->data.F32 : NULL;
     68    psImageMaskType **outMaskData = outMask ? outMask->data.PS_TYPE_IMAGE_MASK_DATA : NULL;
     69    psImageMaskType **inMaskData  = inMask ? inMask->data.PS_TYPE_IMAGE_MASK_DATA : NULL;
    6770
    6871    pswarpMap *map = args->grid->maps[args->gridX][args->gridY]; ///< Map for this tile
     
    7477    int yMin = PS_MAX(minPt.y, 0);
    7578    int yMax = PS_MIN(maxPt.y, outNumRows);
     79
     80    double jacobian = map->Xx * map->Yy - map->Yx * map->Xy; // Jacobian of transformation
     81    double jacobian2 = PS_SQR(jacobian);                     // Square Jacobian
    7682
    7783    // Iterate over the output image pixels (parent frame)
     
    8793            // pswarpMapApply converts the output coordinate (x,y) to the input coordinate.
    8894            // both are in the parent frames of the input and output images.
    89             double xInRaw, yInRaw;      // Input raw pixel coordinates
    90             pswarpMapApply(&xInRaw, &yInRaw, map, x + 0.5, y + 0.5);
    91             double xIn = xInRaw - outCol0, yIn = yInRaw - outRow0; // Position on input image
     95            double xIn, yIn;            // Input pixel coordinates
     96            pswarpMapApply(&xIn, &yIn, map, x + 0.5, y + 0.5);
    9297            if (xIn < 0 || xIn >= inNumCols || yIn < 0 || yIn >= inNumRows) {
    9398                continue;
     
    105110
    106111            if (outImageData) {
    107                 outImageData[yOut][xOut] = imageValue;
     112                outImageData[yOut][xOut] = imageValue * jacobian;
    108113            }
    109114            if (outVarData) {
    110                 outVarData[yOut][xOut] = varValue;
     115                outVarData[yOut][xOut] = varValue * jacobian2;
    111116            }
    112117            if (outMaskData) {
     
    122127        double xIn, yIn;                // Position of interest on input
    123128        pswarpMapApply(&xIn, &yIn, map, xOut + 0.5, yOut + 0.5);
    124         // XXX Why are we subtracting the *output* col0,row0 from the *input* coordinates?
    125         // I expect these are zero, so that it makes no difference, but it's distracting.
    126         xIn -= outCol0;
    127         yIn -= outRow0;
    128129        psKernel *kernel = psImageInterpolationKernel(xIn, yIn, args->interp->mode); // Interpolation kernel
    129130        args->covariance = psImageCovarianceCalculate(kernel, args->input->covariance);
     131        args->jacobian = sqrt(jacobian);
    130132        psFree(kernel);
    131133    }
Note: See TracChangeset for help on using the changeset viewer.