IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 10, 2010, 7:34:39 PM (16 years ago)
Author:
eugene
Message:

updates from eam_branches/20091201 (substantially changes to the kernel matching code; updates to pmDetection container, added pmPattern, etc)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/imcombine/pmSubtractionStamps.c

    r26046 r26893  
    4646    psFree(list->y);
    4747    psFree(list->flux);
     48    psFree(list->window);
    4849}
    4950
     
    5758    psFree(stamp->convolutions1);
    5859    psFree(stamp->convolutions2);
    59 
    60     psFree(stamp->matrix1);
    61     psFree(stamp->matrix2);
    62     psFree(stamp->matrixX);
    63     psFree(stamp->vector1);
    64     psFree(stamp->vector2);
    65 
     60    psFree(stamp->matrix);
     61    psFree(stamp->vector);
    6662}
    6763
     
    8076
    8177// Search a region for a suitable stamp
    82 bool stampSearch(int *xStamp, int *yStamp, // Coordinates of stamp, to return
     78bool stampSearch(float *xStamp, float *yStamp, // Coordinates of stamp, to return
    8379                 float *fluxStamp, // Flux of stamp, to return
    8480                 const psImage *image1, const psImage *image2, // Images to search
     
    9389    *fluxStamp = -INFINITY;             // Flux of best stamp
    9490
     91    // fprintf (stderr, "xMin, xMax: %d, %d -> ", xMin, xMax);
     92
    9593    // Ensure we're not going to go outside the bounds of the image
    9694    xMin = PS_MAX(border, xMin);
     
    9997    yMax = PS_MIN(numRows - border - 1, yMax);
    10098
     99    if (xMax < xMin) return false;
     100    if (yMax < yMin) return false;
     101
     102    psAssert (xMin <= xMax, "x mismatch?");
     103    psAssert (yMin <= yMax, "y mismatch?");
     104
    101105    for (int y = yMin; y <= yMax; y++) {
    102106        for (int x = xMin; x <= xMax; x++) {
     
    115119                ((image1) ? image1->data.F32[y][x] : image2->data.F32[y][x]); // Flux at pixel
    116120            if (flux > *fluxStamp) {
    117                 *xStamp = x;
    118                 *yStamp = y;
     121                *xStamp = x + 0.5;
     122                *yStamp = y + 0.5;
    119123                *fluxStamp = flux;
    120124                found = true;
     
    180184
    181185pmSubtractionStampList *pmSubtractionStampListAlloc(int numCols, int numRows, const psRegion *region,
    182                                                     int footprint, float spacing, float sysErr)
     186                                                    int footprint, float spacing, float normFrac,
     187                                                    float sysErr, float skyErr)
    183188{
    184189    pmSubtractionStampList *list = psAlloc(sizeof(pmSubtractionStampList)); // Stamp list to return
     
    220225    list->y = NULL;
    221226    list->flux = NULL;
     227    list->window = NULL;
     228    list->normFrac = normFrac;
     229    list->normWindow = 0;
    222230    list->footprint = footprint;
    223231    list->sysErr = sysErr;
     232    list->skyErr = skyErr;
    224233
    225234    return list;
     
    239248    out->y = NULL;
    240249    out->flux = NULL;
     250    out->window = psMemIncrRefCounter(in->window);
    241251    out->footprint = in->footprint;
     252    out->normWindow = in->normWindow;
    242253
    243254    for (int i = 0; i < num; i++) {
     
    280291        }
    281292
    282         outStamp->matrix1 = inStamp->matrix1 ? psImageCopy(NULL, inStamp->matrix1, PS_TYPE_F64) : NULL;
    283         outStamp->matrix2 = inStamp->matrix2 ? psImageCopy(NULL, inStamp->matrix2, PS_TYPE_F64) : NULL;
    284         outStamp->matrixX = inStamp->matrixX ? psImageCopy(NULL, inStamp->matrixX, PS_TYPE_F64) : NULL;
    285         outStamp->vector1 = inStamp->vector1 ? psVectorCopy(NULL, inStamp->vector1, PS_TYPE_F64) : NULL;
    286         outStamp->vector2 = inStamp->vector2 ? psVectorCopy(NULL, inStamp->vector2, PS_TYPE_F64) : NULL;
     293        outStamp->matrix = inStamp->matrix ? psImageCopy(NULL, inStamp->matrix, PS_TYPE_F64) : NULL;
     294        outStamp->vector = inStamp->vector ? psVectorCopy(NULL, inStamp->vector, PS_TYPE_F64) : NULL;
    287295
    288296        out->stamps->data[i] = outStamp;
     
    310318    stamp->convolutions2 = NULL;
    311319
    312     stamp->matrix1 = NULL;
    313     stamp->matrix2 = NULL;
    314     stamp->matrixX = NULL;
    315     stamp->vector1 = NULL;
    316     stamp->vector2 = NULL;
     320    stamp->matrix = NULL;
     321    stamp->vector = NULL;
     322    stamp->norm = NAN;
    317323
    318324    return stamp;
     
    323329                                                const psImage *image2, const psImage *subMask,
    324330                                                const psRegion *region, float thresh1, float thresh2,
    325                                                 int size, int footprint, float spacing, float sysErr,
    326                                                 pmSubtractionMode mode)
     331                                                int size, int footprint, float spacing, float normFrac,
     332                                                float sysErr, float skyErr, pmSubtractionMode mode)
    327333{
    328334    if (!image1 && !image2) {
     
    380386
    381387    if (!stamps) {
    382         stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing, sysErr);
     388        stamps = pmSubtractionStampListAlloc(numCols, numRows, region, footprint, spacing,
     389                                             normFrac, sysErr, skyErr);
    383390    }
    384391
     
    402409            numSearch++;
    403410
    404             int xStamp = 0, yStamp = 0; // Coordinates of stamp
     411            float xStamp = 0.0, yStamp = 0.0; // Coordinates of stamp
    405412            float fluxStamp = -INFINITY; // Flux of stamp
    406413            bool goodStamp = false;     // Found a good stamp?
     
    414421                // Take stamps off the top of the (sorted) list
    415422                for (int j = xList->n - 1; j >= 0 && !goodStamp; j--) {
    416                     int xCentre = xList->data.F32[j] + 0.5, yCentre = yList->data.F32[j] + 0.5;// Stamp centre
    417 
    418423                    // Chop off the top of the list
    419424                    xList->n = j;
     
    421426                    fluxList->n = j;
    422427
     428#if 0
    423429                    // Fish around a bit to see if we can find a pixel that isn't masked
     430                    // This is not a good idea if we're using the window feature
    424431                    psTrace("psModules.imcombine", 7, "Searching for stamp %d around %d,%d\n",
    425432                            i, xCentre, yCentre);
    426433
    427434                    // Search bounds
     435                    int xCentre = xList->data.F32[j] - 0.5, yCentre = yList->data.F32[j] - 0.5;// Stamp centre
    428436                    int search = footprint - size; // Search radius
    429437                    int xMin = PS_MAX(border, xCentre - search);
     
    434442                    goodStamp = stampSearch(&xStamp, &yStamp, &fluxStamp, image1, image2, thresh1, thresh2,
    435443                                            subMask, xMin, xMax, yMin, yMax, numCols, numRows, border);
     444                    // fprintf (stderr, "find: %d %d ==> %5.1f %5.1f (\n", xCentre, yCentre, xStamp, yStamp);
     445#else
     446                    // Only search the exact centre pixel
     447                    goodStamp = stampSearch(&xStamp, &yStamp, &fluxStamp, image1, image2, thresh1, thresh2,
     448                                            subMask, xList->data.F32[j], xList->data.F32[j],
     449                                            yList->data.F32[j], yList->data.F32[j], numCols, numRows, border);
     450#endif
     451                    if (0 && goodStamp) {
     452                        fprintf (stderr, "find: %6.1f < %6.1f < %6.1f, %6.1f < %6.1f %6.1f\n",
     453                                 region->x0 + size, xStamp, region->x1 - size,
     454                                 region->y0 + size, yStamp, region->y1 - size);
     455                    }
    436456                }
    437457            } else {
     
    488508                                               const psImage *image, const psImage *subMask,
    489509                                               const psRegion *region, int size, int footprint,
    490                                                float spacing, float sysErr, pmSubtractionMode mode)
     510                                               float spacing, float normFrac, float sysErr, float skyErr,
     511                                               pmSubtractionMode mode)
    491512
    492513{
     
    509530    pmSubtractionStampList *stamps = pmSubtractionStampListAlloc(subMask->numCols, subMask->numRows,
    510531                                                                 region, footprint, spacing,
    511                                                                  sysErr); // Stamp list
     532                                                                 normFrac, sysErr, skyErr); // Stamp list
    512533    int numStamps = stamps->num;        // Number of stamps
    513534
     
    531552    for (int i = 0; i < numStars; i++) {
    532553        float xStamp = x->data.F32[i], yStamp = y->data.F32[i]; // Coordinates of stamp
    533         int xPix = xStamp + 0.5, yPix = yStamp + 0.5; // Pixel coordinate of stamp
     554        int xPix = xStamp - 0.5, yPix = yStamp - 0.5; // Pixel coordinate of stamp
    534555        if (!checkStampRegion(xPix, yPix, region)) {
    535556            // It's not in the big region
     
    539560            continue;
    540561        }
     562
     563        // fprintf (stderr, "stamp: %5.1f %5.1f == %d %d\n", xStamp, yStamp, xPix, yPix);
    541564
    542565        bool found = false;
     
    607630
    608631
     632bool pmSubtractionStampsGetWindow(pmSubtractionStampList *stamps, int kernelSize)
     633{
     634    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false);
     635    PS_ASSERT_INT_NONNEGATIVE(kernelSize, false);
     636
     637    int size = stamps->footprint; // Size of postage stamps
     638
     639    psFree (stamps->window);
     640    stamps->window = psKernelAlloc(-size, size, -size, size);
     641    psImageInit(stamps->window->image, 0.0);
     642
     643    // generate normalizations for each stamp
     644    psVector *norm1 = psVectorAlloc(stamps->num, PS_TYPE_F32);
     645    psVector *norm2 = psVectorAlloc(stamps->num, PS_TYPE_F32);
     646    for (int i = 0; i < stamps->num; i++) {
     647        pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest
     648        if (!stamp) continue;
     649        if (!stamp->image1) continue;
     650        if (!stamp->image2) continue;
     651
     652        float sum1 = 0.0;
     653        float sum2 = 0.0;
     654        for (int y = -size; y <= size; y++) {
     655            for (int x = -size; x <= size; x++) {
     656                sum1 += stamp->image1->kernel[y][x];
     657                sum2 += stamp->image2->kernel[y][x];
     658            }
     659        }
     660        norm1->data.F32[i] = sum1;
     661        norm2->data.F32[i] = sum2;
     662    }
     663
     664    // storage vector for flux data
     665    psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     666    psVector *flux1 = psVectorAllocEmpty(2*stamps->num, PS_TYPE_F32);
     667    psVector *flux2 = psVectorAllocEmpty(2*stamps->num, PS_TYPE_F32);
     668
     669    // generate the window pixels
     670    double sum = 0.0;                   // Sum inside the window
     671    float maxValue = 0.0;               // Maximum value, for normalisation
     672    for (int y = -size; y <= size; y++) {
     673        for (int x = -size; x <= size; x++) {
     674
     675            flux1->n = 0;
     676            flux2->n = 0;
     677            for (int i = 0; i < stamps->num; i++) {
     678                pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest
     679                if (!stamp) continue;
     680                if (!stamp->image1) continue;
     681                if (!stamp->image2) continue;
     682
     683                psVectorAppend(flux1, stamp->image1->kernel[y][x] / norm1->data.F32[i]);
     684                psVectorAppend(flux2, stamp->image2->kernel[y][x] / norm2->data.F32[i]);
     685            }
     686
     687            psStatsInit (stats);
     688            if (!psVectorStats (stats, flux1, NULL, NULL, 0)) {
     689                psAbort ("failed to generate stats");
     690            }
     691            float f1 = stats->robustMedian;
     692            psStatsInit (stats);
     693            if (!psVectorStats (stats, flux2, NULL, NULL, 0)) {
     694                psAbort ("failed to generate stats");
     695            }
     696            float f2 = stats->robustMedian;
     697
     698            stamps->window->kernel[y][x] = f1 + f2;
     699            if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(size)) {
     700                sum += stamps->window->kernel[y][x];
     701            }
     702            maxValue = PS_MAX(maxValue, stamps->window->kernel[y][x]);
     703        }
     704    }
     705
     706    psTrace("psModules.imcombine", 3, "Window total: %f, threshold: %f\n",
     707            sum, (1.0 - stamps->normFrac) * sum);
     708    bool done = false;
     709    for (int radius = 1; radius <= size && !done; radius++) {
     710        double within = 0.0;
     711        for (int y = -radius; y <= radius; y++) {
     712            for (int x = -radius; x <= radius; x++) {
     713                if (PS_SQR(x) + PS_SQR(y) <= PS_SQR(radius)) {
     714                    within += stamps->window->kernel[y][x];
     715                }
     716            }
     717        }
     718        psTrace("psModules.imcombine", 5, "Radius %d: %f\n", radius, within);
     719        if (within > (1.0 - stamps->normFrac) * sum) {
     720            stamps->normWindow = radius;
     721            done = true;
     722        }
     723    }
     724
     725    psTrace("psModules.imcombine", 3, "Normalisation window radius set to %d\n", stamps->normWindow);
     726    if (stamps->normWindow == 0 || stamps->normWindow >= size) {
     727        psError(PS_ERR_UNKNOWN, true, "Unable to determine normalisation window size.");
     728        return false;
     729    }
     730
     731    // re-normalize so chisquare values are sensible
     732    for (int y = -size; y <= size; y++) {
     733        for (int x = -size; x <= size; x++) {
     734            stamps->window->kernel[y][x] /= maxValue;
     735        }
     736    }
     737
     738#if 0
     739    {
     740        psFits *fits = psFitsOpen ("window.fits", "w");
     741        psFitsWriteImage (fits, NULL, stamps->window->image, 0, NULL);
     742        psFitsClose (fits);
     743    }
     744#endif
     745
     746    psFree (stats);
     747    psFree (flux1);
     748    psFree(flux2);
     749    psFree (norm1);
     750    psFree (norm2);
     751    return true;
     752}
     753
    609754bool pmSubtractionStampsExtract(pmSubtractionStampList *stamps, psImage *image1, psImage *image2,
    610                                 psImage *variance, int kernelSize)
     755                                psImage *variance, int kernelSize, psRegion bounds)
    611756{
    612757    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false);
     
    625770    }
    626771
    627     int numCols = image1->numCols, numRows = image1->numRows; // Size of images
    628772    int size = kernelSize + stamps->footprint; // Size of postage stamps
    629773
     
    634778        }
    635779
    636         if (isnan(stamp->xNorm)) {
    637             stamp->xNorm = 2.0 * (stamp->x - (float)numCols/2.0) / (float)numCols;
    638         }
    639         if (isnan(stamp->yNorm)) {
    640             stamp->yNorm = 2.0 * (stamp->y - (float)numRows/2.0) / (float)numRows;
    641         }
    642 
    643         int x = stamp->x + 0.5, y = stamp->y + 0.5; // Stamp coordinates
    644         if (x < size || x > numCols - size || y < size || y > numRows - size) {
    645             psError(PS_ERR_UNKNOWN, false, "Stamp %d (%d,%d) is within the image border.\n", i, x, y);
     780        p_pmSubtractionPolynomialNormCoords(&stamp->xNorm, &stamp->yNorm, stamp->x, stamp->y,
     781                                            bounds.x0, bounds.x1, bounds.y0, bounds.y1);
     782
     783        int x = stamp->x - 0.5, y = stamp->y - 0.5; // Stamp coordinates
     784        // fprintf (stderr, "stamp: %5.1f %5.1f == %d %d (size: %d)\n", stamp->x, stamp->y, x, y, size);
     785
     786        if (x < bounds.x0 + size || x > bounds.x1 - size || y < bounds.y0 + size || y > bounds.y1 - size) {
     787            psError(PS_ERR_UNKNOWN, false, "Stamp %d (%d,%d) is within the region border.\n", i, x, y);
    646788            return false;
    647789        }
     
    668810            psImage *varSub = psImageSubset(variance, region); // Subimage with stamp
    669811            psKernel *var = psKernelAllocFromImage(varSub, size, size); // Variance postage stamp
    670             if (isfinite(stamps->sysErr) && stamps->sysErr > 0) {
     812
     813            if ((isfinite(stamps->skyErr) && (stamps->skyErr > 0)) ||
     814                (isfinite(stamps->sysErr) && (stamps->sysErr > 0))) {
    671815                float sysErr = 0.25 * PS_SQR(stamps->sysErr); // Systematic error
     816                float skyErr = stamps->skyErr;
    672817                psKernel *image1 = stamp->image1, *image2 = stamp->image2; // Input images
    673818                for (int y = -size; y <= size; y++) {
    674819                    for (int x = -size; x <= size; x++) {
    675820                        float additional = image1->kernel[y][x] + image2->kernel[y][x];
    676                         weight->kernel[y][x] = 1.0 / (var->kernel[y][x] + sysErr * PS_SQR(additional));
     821                        weight->kernel[y][x] = 1.0 / (skyErr + var->kernel[y][x] + sysErr * PS_SQR(additional));
    677822                    }
    678823                }
     
    698843pmSubtractionStampList *pmSubtractionStampsSetFromSources(const psArray *sources, const psImage *image,
    699844                                                          const psImage *subMask, const psRegion *region,
    700                                                           int size, int footprint, float spacing, float sysErr,
     845                                                          int size, int footprint, float spacing,
     846                                                          float normFrac, float sysErr, float skyErr,
    701847                                                          pmSubtractionMode mode)
    702848{
     
    722868            y->data.F32[numOut] = source->peak->yf;
    723869        }
     870        // fprintf (stderr, "stamp: %5.1f %5.1f\n", x->data.F32[numOut], y->data.F32[numOut]);
    724871        numOut++;
    725872    }
     
    728875
    729876    pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, image, subMask, region, size,
    730                                                             footprint, spacing, sysErr, mode); // Stamps
     877                                                            footprint, spacing, normFrac,
     878                                                            sysErr, skyErr, mode); // Stamps
    731879    psFree(x);
    732880    psFree(y);
     
    742890pmSubtractionStampList *pmSubtractionStampsSetFromFile(const char *filename, const psImage *image,
    743891                                                       const psImage *subMask, const psRegion *region,
    744                                                        int size, int footprint, float spacing, float sysErr,
    745                                                        pmSubtractionMode mode)
     892                                                       int size, int footprint, float spacing, float normFrac,
     893                                                       float sysErr, float skyErr, pmSubtractionMode mode)
    746894{
    747895    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
     
    760908
    761909    pmSubtractionStampList *stamps = pmSubtractionStampsSet(x, y, image, subMask, region, size, footprint,
    762                                                             spacing, sysErr, mode);
     910                                                            spacing, normFrac, sysErr, skyErr, mode);
    763911    psFree(data);
    764912
     
    766914
    767915}
     916
     917
     918bool pmSubtractionStampsResetStatus (pmSubtractionStampList *stamps) {
     919
     920    for (int i = 0; i < stamps->num; i++) {
     921        pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest
     922        if (!stamp) continue;
     923        if (stamp->status != PM_SUBTRACTION_STAMP_USED) continue;
     924        stamp->status = PM_SUBTRACTION_STAMP_CALCULATE;
     925    }
     926    return true;
     927}
     928
Note: See TracChangeset for help on using the changeset viewer.