IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 26, 2008, 4:03:24 PM (18 years ago)
Author:
Paul Price
Message:

Two major changes. 1. Optimising ISIS kernels: instead of doing an FFT convolution, they're separable. 2. Trying to make the convolved weight map account for systematic errors in the convolution kernel by assuming a relative error in each kernel pixel (currently hardwired with a #define, but we can turn it into a recipe value later, or get an estimate from the data) and propagating that into the variance map. The effect is to increase the variance near the bright stars, which is hopefully sufficient to decrease the number of false sources detected in bad subtractions.

File:
1 edited

Legend:

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

    r19209 r19765  
    4242    }
    4343    return result;
     44}
     45
     46// Generate 1D convolution kernel for ISIS
     47static psVector *subtractionKernelISIS(float sigma, // Gaussian width
     48                                       int order, // Polynomial order
     49                                       int size // Kernel half-size
     50    )
     51{
     52    int fullSize = 2 * size + 1;        // Full size of kernel
     53    psVector *kernel = psVectorAlloc(fullSize, PS_TYPE_F32); // Kernel to return
     54
     55    float expNorm = -0.5 / PS_SQR(sigma); // Normalisation for exponential
     56    float norm = 1.0 / (M_2_PI * sqrtf(sigma)); // Normalisation for Gaussian
     57    for (int i = 0, x = -size; x <= size; i++, x++) {
     58        kernel->data.F32[i] = norm * power(x, order) * expf(expNorm * PS_SQR(x));
     59    }
     60
     61    return kernel;
    4462}
    4563
     
    116134
    117135    // Set the kernel parameters
     136    int fullSize = 2 * size + 1;        // Full size of kernels
    118137    for (int i = 0, index = 0; i < numGaussians; i++) {
    119138        float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma
    120         float norm = 1.0 / (M_2_PI * sqrtf(sigma)); // Normalisation for Gaussian
    121139        // Iterate over (u,v) order
    122140        for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) {
    123141            for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) {
    124                 // Set the pre-calculated kernel
    125                 psKernel *preCalc = psKernelAlloc(-size, size, -size, size);
    126                 double sum = 0.0;       // Normalisation
     142                psArray *preCalc = psArrayAlloc(2); // Array to hold precalculated values
     143                psVector *xKernel = preCalc->data[0] = subtractionKernelISIS(sigma, uOrder, size); // x Kernel
     144                psVector *yKernel = preCalc->data[1] = subtractionKernelISIS(sigma, vOrder, size); // y Kernel
     145
     146                // Calculate moments
     147                double sum = 0.0;       // Sum of kernel component, for normalisation
    127148                double moment = 0.0;    // Moment, for penalty
    128                 for (int v = -size; v <= size; v++) {
    129                     for (int u = -size; u <= size; u++) {
    130                         sum += preCalc->kernel[v][u] = norm * power(u, uOrder) * power(v, vOrder) *
    131                             expf(-0.5 * (PS_SQR(u) + PS_SQR(v)) / PS_SQR(sigma));
    132                         moment += preCalc->kernel[v][u] * (PS_SQR(u) + PS_SQR(v));
     149                for (int v = -size, y = 0; v <= size; v++, y++) {
     150                    for (int u = -size, x = 0; u <= size; u++, x++) {
     151                        double value = xKernel->data.F32[x] * yKernel->data.F32[y]; // Value of kernel
     152                        sum += value;
     153                        moment += value * (PS_SQR(u) + PS_SQR(v));
    133154                    }
    134155                }
     156                moment = 0.0;
    135157
    136158                // Normalise sum of kernel component to unity for even functions
    137159                if (uOrder % 2 == 0 && vOrder % 2 == 0) {
    138                     for (int v = -size; v <= size; v++) {
    139                         for (int u = -size; u <= size; u++) {
    140                             preCalc->kernel[v][u] = preCalc->kernel[v][u] / sum;
     160                    double sum = 0.0;   // Sum of kernel component
     161                    for (int v = 0; v < fullSize; v++) {
     162                        for (int u = 0; u < fullSize; u++) {
     163                            sum += xKernel->data.F32[u] * yKernel->data.F32[v];
    141164                        }
    142165                    }
    143                     preCalc->kernel[0][0] -= 1.0;
     166                    sum = 1.0 / sum;
     167                    psBinaryOp(xKernel, xKernel, "*", psScalarAlloc(sum, PS_TYPE_F32));
     168                    psBinaryOp(yKernel, yKernel, "*", psScalarAlloc(sum, PS_TYPE_F32));
     169                    moment *= sum;
    144170                }
    145171
     
    702728            // Count the number of Gaussians
    703729            int numGauss = 0;
    704             for (char *string = ptr; string; string = strchr(string, '(')) {
     730            for (char *string = ptr; string; string = strchr(string + 1, '(')) {
    705731                numGauss++;
    706732            }
Note: See TracChangeset for help on using the changeset viewer.