IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 14738


Ignore:
Timestamp:
Sep 4, 2007, 1:56:07 PM (19 years ago)
Author:
Paul Price
Message:

Consolidating some code. Making it so that the convolutions of the reference don't have to be performed twice if the optimum kernel is computed (before, the convolutions were calculated twice --- once in getting the optimum kernel set, and once in calculating the least-squares matrix).

Location:
trunk/psModules/src/imcombine
Files:
4 edited

Legend:

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

    r14716 r14738  
    44 *  @author GLG, MHPCC
    55 *
    6  *  @version $Revision: 1.54 $ $Name: not supported by cvs2svn $
    7  *  @date $Date: 2007-08-30 23:09:52 $
     6 *  @version $Revision: 1.55 $ $Name: not supported by cvs2svn $
     7 *  @date $Date: 2007-09-04 23:56:07 $
    88 *
    99 *  Copyright 2004-2007 Institute for Astronomy, University of Hawaii
     
    548548}
    549549
     550bool pmSubtractionConvolveStamp(pmSubtractionStamp *stamp, const pmSubtractionKernels *kernels, int footprint)
     551{
     552    PS_ASSERT_PTR_NON_NULL(stamp, false);
     553    PS_ASSERT_KERNEL_NON_NULL(stamp->reference, false);
     554    PS_ASSERT_PTR_NON_NULL(kernels, false);
     555    PS_ASSERT_VECTORS_SIZE_EQUAL(kernels->u, kernels->v, false);
     556    PS_ASSERT_INT_NONNEGATIVE(footprint, false);
     557
     558    if (stamp->status != PM_SUBTRACTION_STAMP_CALCULATE) {
     559        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Stamp not marked for calculation.");
     560        return false;
     561    }
     562
     563    if (stamp->convolutions) {
     564        // Already done
     565        return true;
     566    }
     567
     568    stamp->convolutions = psArrayAlloc(kernels->num);
     569    psKernel *reference = stamp->reference; // Reference postage stamp
     570
     571    for (int i = 0; i < kernels->num; i++) {
     572        stamp->convolutions->data[i] = convolveRef(kernels, i, reference, footprint);
     573    }
     574
     575    return true;
     576}
     577
    550578
    551579bool pmSubtractionCalculateEquation(psArray *stamps, const pmSubtractionKernels *kernels, int footprint)
     
    591619        psVectorInit(stampVector, 0.0);
    592620
    593         psKernel *reference = stamp->reference; // Reference postage stamp
    594621        psKernel *input = stamp->input; // Input postage stamp
    595622        psKernel *weight = stamp->weight; // Weight map postage stamp
    596623
    597624        // Generate convolutions of the reference
     625        if (!pmSubtractionConvolveStamp(stamp, kernels, footprint)) {
     626            psError(PS_ERR_UNKNOWN, false, "Unable to convolve stamp %d.", i);
     627            return NULL;
     628        }
     629
    598630        psArray *convolutions = stamp->convolutions; // Convolutions of the reference for each kernel
    599         if (!convolutions) {
    600             stamp->convolutions = convolutions = psArrayAlloc(numKernels);
    601         }
    602         for (int j = 0; j < numKernels; j++) {
    603             if (convolutions->data[j]) {
    604                 psFree(convolutions->data[j]);
    605             }
    606             convolutions->data[j] = convolveRef(kernels, j, reference, footprint);
    607 #ifdef TESTING
    608             {
    609                 psKernel *conv = convolutions->data[j]; // Convolution of interest
    610                 psString filename = NULL;
    611                 psStringAppend(&filename, "conv_%03d_%03d.fits", i, j);
    612                 psFits *fits = psFitsOpen(filename, "w");
    613                 psFree(filename);
    614                 psFitsWriteImage(fits, NULL, conv->image, 0, NULL);
    615                 psFitsClose(fits);
    616             }
    617 #endif
    618        }
    619 
    620631        psImage *polyValues = spatialPolyValues(spatialOrder, stamp->xNorm, stamp->yNorm); // Polynomial terms
    621632
     
    900911            stamp->y = 0;
    901912            stamp->status = PM_SUBTRACTION_STAMP_REJECTED;
     913            // Recalculate convolutions
     914            psFree(stamp->convolutions);
     915            stamp->convolutions = NULL;
    902916        }
    903917    }
  • trunk/psModules/src/imcombine/pmSubtraction.h

    r14709 r14738  
    66 * @author GLG, MHPCC
    77 *
    8  * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
    9  * @date $Date: 2007-08-30 21:45:26 $
     8 * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
     9 * @date $Date: 2007-09-04 23:56:07 $
    1010 *
    1111 * Copyright 2004-207 Institute for Astronomy, University of Hawaii
     
    1717#include <pslib.h>
    1818#include "pmSubtractionKernels.h"
     19#include "pmSubtractionStamps.h"
    1920
    2021/// @addtogroup imcombine Image Combinations
     
    3738                           int size, ///< Half-size of the kernel (pmSubtractionKernels.size)
    3839                           int footprint ///< Half-size of the kernel footprint
     40    );
     41
     42/// Convolve the reference stamp with the kernel components
     43bool pmSubtractionConvolveStamp(pmSubtractionStamp *stamp, ///< Stamp to convolve
     44                                const pmSubtractionKernels *kernels, ///< Kernel parameters
     45                                int footprint ///< Half-size of region over which to calculate equation
    3946    );
    4047
  • trunk/psModules/src/imcombine/pmSubtractionMatch.c

    r14713 r14738  
    214214    // Putting important variable declarations here, since they are freed after a "goto" if there is an error.
    215215    psImage *subMask = NULL;            // Mask for subtraction
    216     psArray *stamps = NULL;             // Stamps for matching PSF
    217216    psRegion *region = NULL;            // Iso-kernel region
    218217    psString regionString = NULL;       // String for region
     218    psArray *stamps = NULL;             // Stamps for matching PSF
    219219    psVector *solution = NULL;          // Solution to match PSF
    220220    pmSubtractionKernels *kernels = NULL; // Kernel basis functions
     
    224224    if (stampsName && strlen(stampsName) > 0) {
    225225        psTrace("psModules.imcombine", 3, "Reading stamps from %s...\n", stampsName);
    226         psVector *xStamp = NULL, *yStamp = NULL; // Stamp positions and fluxes
    227226        if (input) {
    228227            // We have x, y because the target is provided by the input image
     
    234233        if (!stampsData) {
    235234            psError(PS_ERR_IO, false, "Unable to read stamps file %s", stampsName);
    236             goto ERROR;
     235            return false;
    237236        }
    238237
    239238        // Correct for IRAF/FITS (unit-offset) positions to C (zero-offset) positions
    240         xStamp = stampsData->data[0];
    241         yStamp = stampsData->data[1];
     239        psVector *xStamp = stampsData->data[0]; // x positions
     240        psVector *yStamp = stampsData->data[1]; // y positions
    242241        psBinaryOp(xStamp, xStamp, "-", psScalarAlloc(1.0, PS_TYPE_F32));
    243242        psBinaryOp(yStamp, yStamp, "-", psScalarAlloc(1.0, PS_TYPE_F32));
     
    251250
    252251    memCheck("mask");
    253 
    254     if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) {
    255         if (!getStamps(&stamps, stampsData, reference, input, subMask, weight, NULL,
    256                        threshold, stampSpacing, targetWidth, size, footprint)) {
    257             goto ERROR;
    258         }
    259         kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, optFWHMs, optOrder,
    260                                                   stamps, footprint, optThreshold);
    261         // XXX This is not quite the best thing to do here--- we'll find the same set of stamps again later,
    262         // but since we may not be interested in the entire image on the first pass through, we have to blow
    263         // the whole lot away.  The alternative is to mark stamps that are outside the region of interest, and
    264         // ignore them when generating sums and rejecting.
    265         psFree(stamps);
    266         stamps = NULL;
    267 
    268         if (!kernels) {
    269             psErrorClear();
    270             psWarning("Unable to derive optimum ISIS kernel --- switching to default.");
    271         }
    272     }
    273 
    274     if (kernels == NULL) {
    275         // Not an ISIS/GUNK kernel, or the optimum kernel search failed
    276         kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders,
    277                                                inner, binning, ringsOrder);
    278     }
    279 
    280     psMetadataAddPtr(convolved->analysis, PS_LIST_TAIL, "SUBTRACTION.KERNEL", PS_DATA_UNKNOWN,
    281                      "Subtraction kernels", kernels);
    282 
    283     memCheck("kernels");
    284252
    285253    // Get region of interest
     
    307275                        regionString, numCols, numRows);
    308276            }
     277
     278            // Define kernel basis functions
     279            if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) {
     280                if (!getStamps(&stamps, stampsData, reference, input, subMask, weight, NULL,
     281                               threshold, stampSpacing, targetWidth, size, footprint)) {
     282                    goto ERROR;
     283                }
     284                kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, optFWHMs, optOrder,
     285                                                          stamps, footprint, optThreshold);
     286                if (!kernels) {
     287                    psErrorClear();
     288                    psWarning("Unable to derive optimum ISIS kernel --- switching to default.");
     289                }
     290            }
     291            if (kernels == NULL) {
     292                // Not an ISIS/GUNK kernel, or the optimum kernel search failed
     293                kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders,
     294                                                       inner, binning, ringsOrder);
     295            }
     296            psMetadataAddPtr(convolved->analysis, PS_LIST_TAIL, "SUBTRACTION.KERNEL",
     297                             PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "Subtraction kernels", kernels);
     298
     299            memCheck("kernels");
    309300
    310301            int numRejected = -1;               // Number of rejected stamps in each iteration
     
    422413                goto ERROR;
    423414            }
     415            psFree(kernels);
     416            kernels = NULL;
    424417
    425418            // Put the solution on the metadata
     
    466459        goto ERROR;
    467460    }
    468     psFree(kernels);
    469461
    470462    memCheck("convolution");
  • trunk/psModules/src/imcombine/pmSubtractionParams.c

    r14735 r14738  
    221221    }
    222222
    223     // Generate the convolutions
    224     for (int i = 0; i < numStamps; i++) {
    225         pmSubtractionStamp *stamp = stamps->data[i]; // Stamp of interest
    226         if (stamp->status == PM_SUBTRACTION_STAMP_REJECTED || stamp->status == PM_SUBTRACTION_STAMP_NONE) {
    227             continue;
    228         }
    229         if (!stamp->convolutions) {
    230             stamp->convolutions = psArrayAlloc(numKernels);
    231         }
    232 
    233         for (int j = 0; j < numKernels; j++) {
    234             psKernel *kernel = kernels->preCalc->data[j]; // Precalculated kernel
    235             stamp->convolutions->data[j] = p_pmSubtractionConvolveStampPrecalc(stamp->reference, kernel);
    236         }
    237     }
    238 
    239     // Calculate sums invariant with the input image
     223    // Generate the convolutions, accumulate sums, and measure initial chi^2
    240224    double sum1 = 0.0;                  // sum of 1/sigma(x,y)^2
    241     for (int i = 0; i < numStamps; i++) {
    242         pmSubtractionStamp *stamp = stamps->data[i]; // Stamp of interest
    243         if (stamp->status == PM_SUBTRACTION_STAMP_REJECTED || stamp->status == PM_SUBTRACTION_STAMP_NONE) {
    244             continue;
    245         }
    246         psKernel *weight = stamp->weight; // Weight map for stamp
    247 
    248         for (int v = -footprint; v <= footprint; v++) {
    249             psF32 *wt = &weight->kernel[v][-footprint]; // Dereference weight map
    250             for (int u = -footprint; u <= footprint; u++, wt++) {
    251                 sum1 += 1.0 / *wt;
    252             }
    253         }
    254         if (!isfinite(sum1)) {
    255             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    256                     "Sum of 1/sigma^2 is non-finite for stamp %d (%d,%d)\n",
    257                     i, (int)stamp->x, (int)stamp->y);
    258             psFree(kernels);
    259             return NULL;
    260         }
    261     }
    262225    psVector *sumC = psVectorAlloc(numKernels, PS_TYPE_F64); // sum of R(x)*k(u)/sigma(x)^2
    263226    psVector *sumCC = psVectorAlloc(numKernels, PS_TYPE_F64); // sum of [R(x)*k(u)]^2/sigma(x)^2
    264227    psVectorInit(sumC, 0.0);
    265228    psVectorInit(sumCC, 0.0);
    266     for (int i = 0; i < numKernels; i++) {
    267         for (int j = 0; j < numStamps; j++) {
    268             pmSubtractionStamp *stamp = stamps->data[j]; // Stamp of interest
    269             if (stamp->status == PM_SUBTRACTION_STAMP_REJECTED ||
    270                 stamp->status == PM_SUBTRACTION_STAMP_NONE) {
    271                 continue;
    272             }
    273             accumulateConvolutions(&sumC->data.F64[i], &sumCC->data.F64[i], stamp, i, footprint);
    274         }
    275     }
    276 
    277     // Initial chi^2
    278229    double lastChi2 = 0.0;              // Chi^2 from last iteration
    279230    int numPixels = 0;                  // Number of pixels contributing to chi^2
     
    283234            continue;
    284235        }
     236        if (!pmSubtractionConvolveStamp(stamp, kernels, footprint)) {
     237            psError(PS_ERR_UNKNOWN, false, "Unable to convolve stamp %d.", i);
     238            psFree(inputs);
     239            psFree(kernels);
     240            return NULL;
     241        }
     242
     243        // This sum is invariant to the kernel
     244        psKernel *weight = stamp->weight; // Weight map for stamp
     245        for (int v = -footprint; v <= footprint; v++) {
     246            psF32 *wt = &weight->kernel[v][-footprint]; // Dereference weight map
     247            for (int u = -footprint; u <= footprint; u++, wt++) {
     248                sum1 += 1.0 / *wt;
     249            }
     250        }
     251        if (!isfinite(sum1)) {
     252            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     253                    "Sum of 1/sigma^2 is non-finite for stamp %d (%d,%d)\n",
     254                    i, (int)stamp->x, (int)stamp->y);
     255            psFree(inputs);
     256            psFree(kernels);
     257            return NULL;
     258        }
     259
     260        for (int j = 0; j < numKernels; j++) {
     261            accumulateConvolutions(&sumC->data.F64[j], &sumCC->data.F64[j], stamp, j, footprint);
     262        }
     263
    285264        lastChi2 += initialChi2(inputs->data[i], stamp, footprint);
    286265        numPixels += PS_SQR(2 * footprint + 1);
     
    395374    psVector *widthsNew = psVectorAlloc(newSize, PS_TYPE_F32);
    396375    psArray *preCalcNew = psArrayAlloc(newSize);
     376    psArray *convNew = psArrayAlloc(numStamps);
     377    for (int i = 0; i < numStamps; i++) {
     378        convNew->data[i] = psArrayAlloc(newSize);
     379    }
    397380
    398381    for (int i = 0; i < numKernels; i++) {
     
    403386            widthsNew->data.F32[rank] = kernels->widths->data.F32[i];
    404387            preCalcNew->data[rank] = psMemIncrRefCounter(kernels->preCalc->data[i]);
     388
     389            for (int j = 0; j < numStamps; j++) {
     390                psArray *convolutions = convNew->data[j]; // Convolutions for this stamp
     391                pmSubtractionStamp *stamp = stamps->data[j]; // Stamp of interest
     392                convolutions->data[rank] = psMemIncrRefCounter(stamp->convolutions->data[i]);
     393            }
    405394        }
    406395    }
     
    415404    kernels->num = newSize;
    416405
     406    for (int i = 0; i < numStamps; i++) {
     407        pmSubtractionStamp *stamp = stamps->data[i]; // Stamp of interest
     408        psFree(stamp->convolutions);
     409        stamp->convolutions = convNew->data[i];
     410    }
     411
    417412    psFree(ranking);
    418413
Note: See TracChangeset for help on using the changeset viewer.