IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 14, 2011, 1:05:28 PM (15 years ago)
Author:
watersc1
Message:

Merge of trunk back into branch.

Location:
branches/czw_branch/20101203
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/czw_branch/20101203

  • branches/czw_branch/20101203/psModules/src/imcombine/pmSubtractionStamps.c

    r29543 r30631  
    2727#include "pmSource.h"
    2828
     29#include "pmSubtractionTypes.h"
    2930#include "pmSubtraction.h"
    3031#include "pmSubtractionStamps.h"
     32#include "pmSubtractionVisual.h"
    3133
    3234#define STAMP_LIST_BUFFER 20            // Number of stamps to add to list at a time
     
    122124            if ((image1 && image1->data.F32[y][x] < thresh1) ||
    123125                (image2 && image2->data.F32[y][x] < thresh2)) {
     126                // fprintf (stderr, "%f,%f : thresh\n", xRaw, yRaw);
    124127                continue;
    125128            }
     
    366369}
    367370
    368 
    369 pmSubtractionStampList *pmSubtractionStampsFind(pmSubtractionStampList *stamps, const psImage *image1,
    370                                                 const psImage *image2, const psImage *subMask,
    371                                                 const psRegion *region, float thresh1, float thresh2,
    372                                                 int size, int footprint, float spacing, float normFrac,
    373                                                 float sysErr, float skyErr, pmSubtractionMode mode)
     371bool pmSubtractionStampsSelect(pmSubtractionStampList **stamps, // Stamps to read
     372                               const pmReadout *ro1, // Readout 1
     373                               const pmReadout *ro2, // Readout 2
     374                               const psImage *subMask, // Mask for subtraction, or NULL
     375                               psImage *variance,  // Variance map
     376                               const psRegion *region, // Region of interest
     377                               float thresh1,  // Threshold for stamp finding on readout 1
     378                               float thresh2,  // Threshold for stamp finding on readout 2
     379                               float stampSpacing, // Spacing between stamps
     380                               float normFrac,     // Fraction of flux in window for normalisation window
     381                               float sysError,     // Relative systematic error in images
     382                               float skyError,     // Relative systematic error in images
     383                               int size,         // Kernel half-size
     384                               int footprint,     // Convolution footprint for stamps
     385                               pmSubtractionMode mode // Mode for subtraction
     386    )
     387{
     388    PS_ASSERT_PTR_NON_NULL(stamps, false);
     389    PM_ASSERT_READOUT_NON_NULL(ro1, false);
     390    PM_ASSERT_READOUT_NON_NULL(ro2, false);
     391    PS_ASSERT_IMAGE_NON_NULL(subMask, false);
     392    PS_ASSERT_IMAGE_NON_NULL(variance, false);
     393    PS_ASSERT_PTR_NON_NULL(region, false);
     394
     395    psTrace("psModules.imcombine", 3, "Finding stamps...\n");
     396
     397    psImage *image1 = ro1 ? ro1->image : NULL, *image2 = ro2 ? ro2->image : NULL; // Images of interest
     398
     399    *stamps = pmSubtractionStampsFind(*stamps, image1, image2, subMask, region, thresh1, thresh2,
     400                                      size, footprint, stampSpacing, normFrac, sysError, skyError, mode);
     401    if (!*stamps) {
     402        psError(psErrorCodeLast(), false, "Unable to find stamps.");
     403        return false;
     404    }
     405
     406    psTrace("psModules.imcombine", 3, "Extracting stamps...\n");
     407    if (!pmSubtractionStampsExtract(*stamps, ro1->image, ro2->image, variance, size, *region)) {
     408        psError(psErrorCodeLast(), false, "Unable to extract stamps.");
     409        return false;
     410    }
     411
     412    pmSubtractionVisualPlotStamps(*stamps, (pmReadout *) ro1);
     413    return true;
     414}
     415
     416pmSubtractionStampList *pmSubtractionStampsFind(pmSubtractionStampList *stamps,
     417                                                const psImage *image1,
     418                                                const psImage *image2,
     419                                                const psImage *subMask,
     420                                                const psRegion *region,
     421                                                float thresh1,
     422                                                float thresh2,
     423                                                int size,
     424                                                int footprint,
     425                                                float spacing,
     426                                                float normFrac,
     427                                                float sysErr,
     428                                                float skyErr,
     429                                                pmSubtractionMode mode)
    374430{
    375431    if (!image1 && !image2) {
     
    429485        stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing,
    430486                                             normFrac, sysErr, skyErr);
     487    }
     488
     489    // XXX TEST : dump all stars in the stamps here
     490    if (0) {
     491        FILE *f = fopen ("stamp.dat", "w");
     492        for (int i = 0; i < stamps->num; i++) {
     493            psVector *xList = stamps->x->data[i];
     494            psVector *yList = stamps->y->data[i]; // Coordinate lists
     495            psVector *fluxList = stamps->flux->data[i]; // List of stamp fluxes
     496
     497            for (int j = 0; j < xList->n; j++) {
     498                fprintf (f, "%d %d  %f %f  %f\n", i, j, xList->data.F32[j], yList->data.F32[j], fluxList->data.F32[j]);
     499            }
     500        }
     501        fclose (f);
    431502    }
    432503
     
    636707    }
    637708
     709    int nTotal = 0;
     710
    638711    // Sort the list by flux, with the brightest last
    639712    for (int i = 0; i < numStamps; i++) {
     
    662735        stamps->y->data[i] = ySorted;
    663736        stamps->flux->data[i] = fluxSorted;
    664     }
    665 
     737        nTotal += num;
     738    }
     739    // fprintf (stderr, "nTotal %d\n", nTotal);
     740   
    666741    return stamps;
    667742}
    668743
    669 
    670 bool pmSubtractionStampsGetWindow(pmSubtractionStampList *stamps, int kernelSize)
     744// we are essentially using aperture photometry to determine the photometric match between the
     745// images.  we need to choose an appropriate-sized aperture for this analysis.  If it is too
     746// large, the measurement will be noisy (and possibly biased) due to the sky noise.  If it is
     747// too small, or inconsistent, the measurement will be biased.  We use Kron-mag like aperture
     748// scaled by the first radial moment.
     749bool pmSubtractionStampsGetWindow(bool *tryAgain, pmSubtractionStampList *stamps, int kernelSize)
    671750{
    672751    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false);
    673752    PS_ASSERT_INT_NONNEGATIVE(kernelSize, false);
    674753
     754    // if we succeed, or fail with an unrecoverable error, do not try again
     755    if (tryAgain) {
     756        *tryAgain = false;
     757    }
     758
    675759    int size = stamps->footprint; // Size of postage stamps
    676760
     761    // window for moments calculations downstream
     762    psFree (stamps->window);
     763    stamps->window = psKernelAlloc(-size, size, -size, size);
     764    psImageInit(stamps->window->image, 0.0);
     765
     766    // window1 and window2 are mean stamp images used here to measure the
     767    // first radial moment, and thus the normalization window
    677768    psFree (stamps->window1);
    678769    stamps->window1 = psKernelAlloc(-size, size, -size, size);
     
    683774    psImageInit(stamps->window2->image, 0.0);
    684775
    685     // Generate a weighting window based on the fwhms (20% larger than the largest)
    686     {
    687         float fwhm1, fwhm2;
    688 
    689         // XXX this is annoyingly hack-ish
    690         pmSubtractionGetFWHMs(&fwhm1, &fwhm2);
    691 
    692         float sigma = 1.5 * PS_MAX(fwhm1, fwhm2) / 2.35;
    693 
    694         psFree (stamps->window);
    695         stamps->window = psKernelAlloc(-size, size, -size, size);
    696         psImageInit(stamps->window->image, 0.0);
    697 
    698         for (int y = -size; y <= size; y++) {
    699             for (int x = -size; x <= size; x++) {
    700                 stamps->window->kernel[y][x] = exp(-0.5*(x*x + y*y)/(sigma*sigma));
    701             }
    702         }
     776    // Generate an initial weighting window based on the fwhms (50% larger than the largest)
     777    float fwhm1, fwhm2;
     778
     779    // XXX this is annoyingly hack-ish
     780    pmSubtractionGetFWHMs(&fwhm1, &fwhm2);
     781   
     782    float sigma = 1.5 * PS_MAX(fwhm1, fwhm2) / 2.35;
     783   
     784    for (int y = -size; y <= size; y++) {
     785        for (int x = -size; x <= size; x++) {
     786            stamps->window->kernel[y][x] = exp(-0.5*(x*x + y*y)/(sigma*sigma));
     787        }
    703788    }
    704789
     
    790875    psTrace("psModules.imcombine", 3, "Window total (2): %f, threshold: %f\n", sum2, (1.0 - stamps->normFrac) * sum2);
    791876
    792 # if (1)
    793     // this block attempts to calculate the radius based on the first radial moment
     877    // attempt to calculate the normalization window based on the first radial moment
    794878    double Sr1 = 0.0;
    795879    double Sr2 = 0.0;
     
    809893    float R2 = Sr2 / Sf2;
    810894
    811     stamps->normWindow1 = 2.0*R1;
    812     stamps->normWindow2 = 2.0*R2;
    813     psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Kron Radii: %f for 1, %f for 2\n", stamps->normWindow1, stamps->normWindow2);
    814 
    815 # else
    816     // XXX : this block attempts to calculate the radius by looking at the curve of growth (or something vaguely equivalent).
    817     // It did not do very well (though a true curve-of-growth analysis might be better...)
    818     bool done1 = false;
    819     bool done2 = false;
    820     double prior1 = 0.0;
    821     double prior2 = 0.0;
    822     double delta1o = 1.0;
    823     double delta2o = 1.0;
    824     for (int radius = 1; radius <= size && !(done1 && done2); radius++) {
    825         double within1 = 0.0;
    826         double within2 = 0.0;
    827         for (int y = -radius; y <= radius; y++) {
    828             for (int x = -radius; x <= radius; x++) {
    829                 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) {
    830                     within1 += stamps->window1->kernel[y][x];
    831                 }
    832                 if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) {
    833                     within2 += stamps->window2->kernel[y][x];
    834                 }
    835             }
    836         }
    837         double delta1 = (within1 - prior1) / within1;
    838         if (!done1 && (fabs(delta1) < stamps->normFrac)) {
    839             // interpolate to the radius at which delta2 is normFrac:
    840             stamps->normWindow1 = radius - (stamps->normFrac - delta1) / (delta1o - delta1);
    841             psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "choosing %f (%d) for 1 (%f : %f)\n", stamps->normWindow1, radius, within1, delta1);
    842             done1 = true;
    843         }
    844         double delta2 = (within2 - prior2) / within2;
    845         if (!done2 && (fabs(delta2) < stamps->normFrac)) {
    846             // interpolate to the radius at which delta2 is normFrac:
    847             stamps->normWindow2 = radius - (stamps->normFrac - delta2) / (delta2o - delta2);
    848             psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "choosing %f (%d) for 2 (%f : %f)\n", stamps->normWindow2, radius, within2, delta2);
    849             done2 = true;
    850         }
    851         psTrace("psModules.imcombine", 5, "Radius %d: %f (%f) and %f (%f)\n", radius, within1, delta1, within2, delta2);
    852 
    853         prior1 = within1;
    854         prior2 = within2;
    855         delta1o = delta1;
    856         delta2o = delta2;
    857 
    858         // if (!done1 && (within1 > (1.0 - stamps->normFrac) * sum1)) {
    859         //     stamps->normWindow1 = radius;
    860         //     done1 = true;
    861         // }
    862         // if (!done2 && (within2 > (1.0 - stamps->normFrac) * sum2)) {
    863         //     stamps->normWindow2 = radius;
    864         //     done2 = true;
    865         // }
    866 
    867     }
    868 # endif
    869 
    870     psTrace("psModules.imcombine", 3, "Normalisation window radii set to %f and %f\n", stamps->normWindow1, stamps->normWindow2);
    871     if (stamps->normWindow1 == 0 || stamps->normWindow1 >= size) {
     895    // Compare the Kron Radii (R1 & R2) to above to the FWHMs : if they are too discrepant, we will need to rescale
     896    psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Kron Radii vs FWHMs 1: fwhm: %f, kron %f\n", fwhm1, R1);
     897    psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Kron Radii vs FWHMs 2: fwhm: %f, kron %f\n", fwhm2, R2);
     898
     899    // XXX CAREFUL : in pmSubtractionMatch.c:703, we rely on this factor of 2.75..
     900    stamps->normWindow1 = 2.75*R1;
     901    stamps->normWindow2 = 2.75*R2;
     902    psLogMsg ("psModules.imcombine", PS_LOG_DETAIL, "Windows from Kron Radii: %f for 1, %f for 2\n", stamps->normWindow1, stamps->normWindow2);
     903
     904    // if the calculated normWindows are too large, we will fall off the stamps.  In this case, we need to try again.
     905    if ((stamps->normWindow1 > size) || (stamps->normWindow2 > size)) {
     906        if (tryAgain) {
     907            *tryAgain = true;
     908        }
     909        psFree (stats);
     910        psFree (flux1);
     911        psFree (flux2);
     912        psFree (norm1);
     913        psFree (norm2);
     914        return false;
     915    }
     916
     917    // this is an unrecoverable error : something really bogus in the data
     918    if (stamps->normWindow1 == 0) {
    872919        psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (1).");
     920        psFree (stats);
     921        psFree (flux1);
     922        psFree (flux2);
     923        psFree (norm1);
     924        psFree (norm2);
    873925        return false;
    874926    }
    875     if (stamps->normWindow2 == 0 || stamps->normWindow2 >= size) {
     927    if (stamps->normWindow2 == 0) {
    876928        psError(PM_ERR_STAMPS, true, "Unable to determine normalisation window size (2).");
     929        psFree (stats);
     930        psFree (flux1);
     931        psFree (flux2);
     932        psFree (norm1);
     933        psFree (norm2);
    877934        return false;
     935    }
     936
     937    // Generate a weighting window based on the kron radii
     938    float radius = 2.0 * PS_MAX(R1, R2);
     939    psImageInit(stamps->window->image, 0.0);
     940
     941    // we use a top-hat window for the moments analysis
     942    for (int y = -size; y <= size; y++) {
     943        for (int x = -size; x <= size; x++) {
     944            if (hypot(x,y) > radius) continue;
     945            stamps->window->kernel[y][x] = 1.0;
     946        }
    878947    }
    879948
     
    890959        }
    891960    }
    892 
    893 #if 0
    894     {
    895         psFits *fits = NULL;
    896         fits = psFitsOpen ("window1.norm.fits", "w");
    897         psFitsWriteImage (fits, NULL, stamps->window1->image, 0, NULL);
    898         psFitsClose (fits);
    899         fits = psFitsOpen ("window2.norm.fits", "w");
    900         psFitsWriteImage (fits, NULL, stamps->window2->image, 0, NULL);
    901         psFitsClose (fits);
    902     }
    903 #endif
    904961
    905962    psFree (stats);
     
    11281185            continue;
    11291186        }
     1187       
     1188        // XXX this is somewhat arbitrary...
     1189        if (source->errMag > 0.05) continue;
     1190        if (fabs(source->psfMag - source->apMag) > 0.5) continue;
     1191
    11301192        if (source->modelPSF) {
    11311193            x->data.F32[numOut] = source->modelPSF->params->data.F32[PM_PAR_XPOS];
     
    11351197            y->data.F32[numOut] = source->peak->yf;
    11361198        }
    1137         // fprintf (stderr, "stamp: %5.1f %5.1f\n", x->data.F32[numOut], y->data.F32[numOut]);
    11381199        numOut++;
    11391200    }
Note: See TracChangeset for help on using the changeset viewer.