IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 27732


Ignore:
Timestamp:
Apr 22, 2010, 6:20:17 PM (16 years ago)
Author:
Paul Price
Message:

Need to rescale the covariance matrix when we rescale the images. The previous covariance matrices were appropriate for the *chip* stage, not the warp stage (the pixel scales are currently different). Simulations show that this produces the expected detection limits (+/- 0.1 mag, which is about the expected error; more precision probably requires inserting and recovering fake sources).

Location:
branches/pap
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/pap/psLib/src/imageops/psImageCovariance.c

    r27702 r27732  
    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{
  • branches/pap/psLib/src/imageops/psImageCovariance.h

    r27697 r27732  
    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///
  • branches/pap/pswarp/src/pswarpLoop.c

    r27387 r27732  
    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    {
     
    292274        psArray *covars = psListToArray(covariances); // Array of covariance matrices
    293275        output->covariance = psImageCovarianceAverage(covars);
     276        fprintf(stderr, "Covariance: %f\n", psImageCovarianceFactor(output->covariance));
    294277        psFree(covars);
    295278        psMetadataRemoveKey(output->analysis, PSWARP_ANALYSIS_COVARIANCES);
    296279        psImageCovarianceTransfer(output->variance, output->covariance);
     280    }
     281
     282    // Correct image for change in the plate scale
     283    {
     284        psAssert(input && input->fpa && input->fpa->toSky, "Require astrometry for input");
     285        psAssert(outFPA && outFPA && outFPA->toSky, "Require astrometry for output");
     286
     287        double inScale = input->fpa->toSky->Xs + input->fpa->toSky->Ys; // Plate scale for input
     288        double outScale = outFPA->toSky->Xs + outFPA->toSky->Ys; // Plate scale for output
     289        float correction = PS_SQR(outScale / inScale); // Correction factor to apply to image
     290        psLogMsg("pswarp", PS_LOG_INFO, "Correcting flux by %f to account for pixel scales", correction);
     291        psBinaryOp(output->image, output->image, "*", psScalarAlloc(correction, PS_TYPE_F32));
     292        if (output->variance) {
     293            psBinaryOp(output->variance, output->variance, "*",
     294                       psScalarAlloc(PS_SQR(correction), PS_TYPE_F32));
     295        }
     296        psKernel *covar = psImageCovarianceScale(output->covariance, outScale / inScale); // Scaled covariance
     297        psFree(output->covariance);
     298        output->covariance = covar;
    297299    }
    298300
Note: See TracChangeset for help on using the changeset viewer.