IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 6, 2007, 3:57:15 PM (18 years ago)
Author:
Paul Price
Message:

Implementing dual-convolution. This required reworking those
functions involved with calculating and solving the equations; moved
these into a separate file and made various other cleanups (e.g.,
assertions for pmSubtractionKernels). Removed the normalisation
(central pixel) term from all kernels, because this shouldn't be in
the second kernel (there's only one normalisation term between the two
kernels); the normalisation is treated explicitly in the equations,
along with the background (still only a constant background is
supported for now, but there's a lot of support for a polynomial
background for when I get around to putting it in the equations).
Tested the single convolution, and it's working; same results as
before, apparently. Haven't tested dual convolution yet.

File:
1 edited

Legend:

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

    r15432 r15756  
    44
    55#include <stdio.h>
     6#include <string.h>
    67#include <strings.h>
    78#include <pslib.h>
    89
     10#include "pmSubtraction.h"
    911#include "pmSubtractionKernels.h"
    1012
     
    2224    psFree(kernels->vStop);
    2325    psFree(kernels->preCalc);
    24 }
    25 
    26 // Raise a number to an integer power
     26    psFree(kernels->solution1);
     27    psFree(kernels->solution2);
     28}
     29
     30// Raise an integer to an integer power
    2731static inline long power(int value,     // Value
    2832                         int exp        // Exponent
     
    4549bool p_pmSubtractionKernelsAddGrid(pmSubtractionKernels *kernels, int start, int size)
    4650{
    47     PS_ASSERT_PTR_NON_NULL(kernels, false);
    48     PS_ASSERT_VECTOR_NON_NULL(kernels->u, false);
    49     PS_ASSERT_VECTOR_NON_NULL(kernels->v, false);
    50     PS_ASSERT_VECTOR_NON_NULL(kernels->widths, false);
    51     PS_ASSERT_VECTOR_TYPE(kernels->u, PS_TYPE_S32, false);
    52     PS_ASSERT_VECTOR_TYPE(kernels->v, PS_TYPE_S32, false);
    53     PS_ASSERT_VECTOR_TYPE(kernels->widths, PS_TYPE_F32, false);
    54     PS_ASSERT_ARRAY_NON_NULL(kernels->preCalc, false);
     51    PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, false);
    5552    PS_ASSERT_INT_NONNEGATIVE(start, false);
    5653    PS_ASSERT_INT_NONNEGATIVE(size, false);
    5754
    58     int numNew = PS_SQR(2 * size + 1);  // Number of new kernel parameters to add
     55    int numNew = PS_SQR(2 * size + 1) - 1;  // Number of new kernel parameters to add
    5956
    6057    // Ensure the sizes match
     
    6865    for (int v = - size, index = start; v <= size; v++) {
    6966        for (int u = - size; u <= size; u++, index++) {
     67            if (v == 0 && u == 0) {
     68                // Skip normalisation component: added explicitly
     69                index--;
     70                continue;
     71            }
    7072            kernels->widths->data.F32[index] = NAN;
    7173            kernels->u->data.S32[index] = u;
     
    8183
    8284pmSubtractionKernels *p_pmSubtractionKernelsRawISIS(int size, int spatialOrder,
    83                                                   const psVector *fwhms, const psVector *orders)
     85                                                    const psVector *fwhms, const psVector *orders,
     86                                                    pmSubtractionMode mode)
    8487{
    8588    PS_ASSERT_VECTOR_NON_NULL(fwhms, NULL);
     
    97100    for (int i = 0; i < numGaussians; i++) {
    98101        int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian
    99         psStringAppend(&params, "(%.2f,%d)", fwhms->data.F32[i], orders->data.S32[i]);
     102        psStringAppend(&params, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]);
    100103        num += (gaussOrder + 1) * (gaussOrder + 2) / 2;
    101104    }
    102105
    103106    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_ISIS,
    104                                                               size, spatialOrder); // The kernels
     107                                                              size, spatialOrder, mode); // The kernels
    105108    psStringAppend(&kernels->description, "ISIS(%d,%s,%d)", size, params, spatialOrder);
    106109
     
    149152    }
    150153
    151     kernels->subIndex = -1;
    152 
    153154    return kernels;
    154155}
     
    159160
    160161pmSubtractionKernels *pmSubtractionKernelsAlloc(int numBasisFunctions, pmSubtractionKernelsType type,
    161                                                 int size, int spatialOrder)
     162                                                int size, int spatialOrder, pmSubtractionMode mode)
    162163{
    163164    pmSubtractionKernels *kernels = psAlloc(sizeof(pmSubtractionKernels)); // Kernels, to return
     
    173174    kernels->uStop = NULL;
    174175    kernels->vStop = NULL;
    175     kernels->subIndex = 0;
    176176    kernels->size = size;
    177177    kernels->inner = 0;
    178178    kernels->spatialOrder = spatialOrder;
    179179    kernels->bgOrder = 0;
    180 
    181     return kernels;
    182 }
    183 
    184 pmSubtractionKernels *pmSubtractionKernelsPOIS(int size, int spatialOrder)
     180    kernels->mode = mode;
     181    kernels->solution1 = NULL;
     182    kernels->solution2 = NULL;
     183
     184    return kernels;
     185}
     186
     187pmSubtractionKernels *pmSubtractionKernelsPOIS(int size, int spatialOrder, pmSubtractionMode mode)
    185188{
    186189    PS_ASSERT_INT_POSITIVE(size, NULL);
    187190    PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL);
    188191
    189     int num = PS_SQR(2 * size + 1); // Number of basis functions
     192    int num = PS_SQR(2 * size + 1) - 1; // Number of basis functions
    190193
    191194    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_POIS,
    192                                                               size, spatialOrder); // The kernels
     195                                                              size, spatialOrder, mode); // The kernels
    193196    psStringAppend(&kernels->description, "POIS(%d,%d)", size, spatialOrder);
    194197    psLogMsg("psModules.imcombine", PS_LOG_INFO, "POIS kernel: %d,%d --> %d elements",
     
    199202    }
    200203
    201     kernels->subIndex = num / 2;
    202     assert(kernels->u->data.S32[kernels->subIndex] == 0 &&
    203            kernels->v->data.S32[kernels->subIndex] == 0);
    204 
    205204    return kernels;
    206205}
     
    208207
    209208pmSubtractionKernels *pmSubtractionKernelsISIS(int size, int spatialOrder,
    210                                                const psVector *fwhms, const psVector *orders)
     209                                               const psVector *fwhms, const psVector *orders,
     210                                               pmSubtractionMode mode)
    211211{
    212212    pmSubtractionKernels *kernels = p_pmSubtractionKernelsRawISIS(size, spatialOrder,
    213                                                                   fwhms, orders); // Kernels
     213                                                                  fwhms, orders, mode); // Kernels
    214214    if (!kernels) {
    215215        return NULL;
    216216    }
    217217
    218     // Subtract a reference kernel from all the others to maintain flux scaling
     218    // Subtract normalisation from all the others to maintain flux scaling
    219219    if (spatialOrder > 0) {
    220         int subIndex = 0;                   // Index of kernel to subtract from others
    221         psKernel *subtract = kernels->preCalc->data[subIndex]; // Kernel to subtract from others
    222220        int numGaussians = fwhms->n;       // Number of Gaussians
    223221        for (int i = 0, index = 0; i < numGaussians; i++) {
    224222            for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) {
    225223                for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) {
    226                     if (uOrder % 2 == 0 && vOrder % 2 == 0 && index != subIndex) {
     224                    if (uOrder % 2 == 0 && vOrder % 2 == 0) {
    227225                        psKernel *kernel = kernels->preCalc->data[index]; // Kernel to subtract
    228                         psBinaryOp(kernel->image, kernel->image, "-", subtract->image);
     226                        kernel->kernel[0][0] -= 1.0;
    229227                    }
    230228                }
     
    242240            psFitsWriteImage(kernelFile, NULL, kernel->image, 0, NULL);
    243241            psFitsClose(kernelFile);
    244         }
    245     }
    246 
    247     return kernels;
    248 }
    249 
    250 /// Generate SPAM kernels
    251 pmSubtractionKernels *pmSubtractionKernelsSPAM(int size, ///< Half-size of the kernel
    252                                                int spatialOrder, ///< Order of spatial variations
    253                                                int inner, ///< Inner radius to preserve unbinned
    254                                                int binning ///< Kernel binning factor
    255     )
     242            double sum = 0.0;
     243            for (int y = 0; y < kernel->image->numRows; y++) {
     244                for (int x = 0; x < kernel->image->numCols; x++) {
     245                    sum += kernel->image->data.F32[y][x];
     246                }
     247            }
     248            psTrace("psModules.imcombine.kernel", 10, "Kernel %d sum: %lf\n", i, sum);
     249        }
     250    }
     251
     252    return kernels;
     253}
     254
     255pmSubtractionKernels *pmSubtractionKernelsSPAM(int size, int spatialOrder, int inner, int binning,
     256                                               pmSubtractionMode mode)
    256257{
    257258    PS_ASSERT_INT_POSITIVE(size, NULL);
     
    269270    psTrace("psModules.imcombine", 3, "Inner: %d Outer: %d\n", numInner, numOuter);
    270271
    271     int num = PS_SQR(2 * numTotal + 1); // Number of basis functions
     272    int num = PS_SQR(2 * numTotal + 1) - 1; // Number of basis functions
    272273
    273274    psTrace("psModules.imcombine", 3, "Number of basis functions: %d\n", num);
    274275
    275276    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_SPAM,
    276                                                               size, spatialOrder); // The kernels
     277                                                              size, spatialOrder, mode); // The kernels
    277278    psStringAppend(&kernels->description, "SPAM(%d,%d,%d,%d)", size, inner, binning, spatialOrder);
    278279
     
    280281             size, inner, binning, spatialOrder, num);
    281282
    282     kernels->uStop = psVectorAlloc(num, PS_TYPE_F32);
    283     kernels->vStop = psVectorAlloc(num, PS_TYPE_F32);
     283    kernels->uStop = psVectorAlloc(num, PS_TYPE_S32);
     284    kernels->vStop = psVectorAlloc(num, PS_TYPE_S32);
    284285
    285286    psVector *locations = psVectorAlloc(2 * numTotal + 1, PS_TYPE_S32); // Locations for each kernel element
     
    314315
    315316        for (int j = - numTotal; j <= numTotal; j++, index++) {
     317            if (i == 0 && j == 0) {
     318                // Skip normalisation component: added explicitly
     319                index--;
     320                continue;
     321            }
    316322            int v = locations->data.S32[numTotal + j]; // Location of pixel
    317323            int vStop = v + widths->data.S32[numTotal + j]; // Width of pixel
     
    327333    }
    328334
    329     kernels->subIndex = num / 2;
    330     assert(kernels->u->data.S32[kernels->subIndex] == 0 &&
    331            kernels->v->data.S32[kernels->subIndex] == 0 &&
    332            kernels->uStop->data.S32[kernels->subIndex] == 0 &&
    333            kernels->vStop->data.S32[kernels->subIndex] == 0);
    334 
    335335    psFree(locations);
    336336    psFree(widths);
     
    340340
    341341
    342 /// Generate FRIES kernels
    343 pmSubtractionKernels *pmSubtractionKernelsFRIES(int size, ///< Half-size of the kernel
    344                                                 int spatialOrder, ///< Order of spatial variations
    345                                                 int inner ///< Inner radius to preserve unbinned
    346     )
     342pmSubtractionKernels *pmSubtractionKernelsFRIES(int size, int spatialOrder, int inner, pmSubtractionMode mode)
    347343{
    348344    PS_ASSERT_INT_POSITIVE(size, NULL);
     
    366362    psTrace("psModules.imcombine", 3, "Inner: %d Outer: %d\n", numInner, numOuter);
    367363
    368     int num = PS_SQR(2 * numTotal + 1); // Number of basis functions
     364    int num = PS_SQR(2 * numTotal + 1) - 1; // Number of basis functions
    369365
    370366    psTrace("psModules.imcombine", 3, "Number of basis functions: %d\n", num);
    371367
    372368    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_FRIES,
    373                                                               size, spatialOrder); // The kernels
     369                                                              size, spatialOrder, mode); // The kernels
    374370    psStringAppend(&kernels->description, "FRIES(%d,%d,%d)", size, inner, spatialOrder);
    375371
     
    377373             size, inner, spatialOrder, num);
    378374
    379     kernels->uStop = psVectorAlloc(num, PS_TYPE_F32);
    380     kernels->vStop = psVectorAlloc(num, PS_TYPE_F32);
     375    kernels->uStop = psVectorAlloc(num, PS_TYPE_S32);
     376    kernels->vStop = psVectorAlloc(num, PS_TYPE_S32);
    381377
    382378    psVector *start = psVectorAlloc(2 * numTotal + 1, PS_TYPE_S32);
     
    409405        int uStop = stop->data.S32[numTotal + i]; // Width of pixel
    410406        for (int j = - numTotal; j <= numTotal; j++, index++) {
     407            if (i == 0 && j == 0) {
     408                // Skip normalisation component: added explicitly
     409                index--;
     410                continue;
     411            }
    411412            int v = start->data.S32[numTotal + j]; // Location of pixel
    412413            int vStop = stop->data.S32[numTotal + j]; // Width of pixel
     
    422423    }
    423424
    424     kernels->subIndex = num / 2;
    425     assert(kernels->u->data.S32[kernels->subIndex] == 0 &&
    426            kernels->v->data.S32[kernels->subIndex] == 0 &&
    427            kernels->uStop->data.S32[kernels->subIndex] == 0 &&
    428            kernels->vStop->data.S32[kernels->subIndex] == 0);
    429 
    430425    psFree(start);
    431426    psFree(stop);
     
    436431// Grid United with Normal Kernel
    437432pmSubtractionKernels *pmSubtractionKernelsGUNK(int size, int spatialOrder, const psVector *fwhms,
    438                                                const psVector *orders, int inner)
     433                                               const psVector *orders, int inner, pmSubtractionMode mode)
    439434{
    440435    PS_ASSERT_INT_POSITIVE(size, NULL);
     
    449444
    450445    pmSubtractionKernels *kernels = p_pmSubtractionKernelsRawISIS(size, spatialOrder,
    451                                                                   fwhms, orders); // Kernels
     446                                                                  fwhms, orders, mode); // Kernels
    452447    psStringPrepend(&kernels->description, "GUNK=");
    453448    psStringAppend(&kernels->description, "+POIS(%d,%d)", inner, spatialOrder);
     
    469464
    470465    int numISIS = kernels->num;         // Number of ISIS kernels
    471     int numInner = PS_SQR(2 * inner + 1); // Number of inner kernel elements
    472466
    473467    if (!p_pmSubtractionKernelsAddGrid(kernels, numISIS, inner)) {
     
    475469    }
    476470
    477     kernels->subIndex = numInner/2 + numISIS;
    478     assert(kernels->u->data.S32[kernels->subIndex] == 0 &&
    479            kernels->v->data.S32[kernels->subIndex] == 0);
    480 
    481471    return kernels;
    482472}
    483473
    484474// RINGS --- just what it says
    485 pmSubtractionKernels *pmSubtractionKernelsRINGS(int size, int spatialOrder, int inner, int ringsOrder)
     475pmSubtractionKernels *pmSubtractionKernelsRINGS(int size, int spatialOrder, int inner, int ringsOrder,
     476                                                pmSubtractionMode mode)
    486477{
    487478    PS_ASSERT_INT_POSITIVE(size, NULL);
     
    505496    }
    506497
    507     int numInner = inner;               // Number of pixels in the inner region
     498    int numInner = inner - 1;           // Number of pixels in the inner region
    508499    int numOuter = fibNum;              // Number of summed pixels in the outer region
    509500
    510501    int numRings = numOuter + numInner; // Number of rings (not including the central pixel)
    511     int numPoly = (ringsOrder + 1) * (ringsOrder + 2) / 2; // Number of polynomial variants of each ring
    512 
    513     int num = numRings * numPoly + 1; // Total number of basis functions
     502    int numPoly = PM_SUBTRACTION_POLYTERMS(ringsOrder); // Number of polynomial variants of each ring
     503
     504    int num = numRings * numPoly; // Total number of basis functions
    514505
    515506    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_RINGS,
    516                                                               size, spatialOrder); // The kernels
     507                                                              size, spatialOrder, mode); // The kernels
    517508    psStringAppend(&kernels->description, "RINGS(%d,%d,%d,%d)", size, inner, ringsOrder, spatialOrder);
    518509
     
    522513    // Set the Gaussian kernel parameters
    523514    int fibIndex = 1, fibIndexMinus1 = 0; // Fibonnacci parameters
    524     int radiusLast = 0;                 // Last radius
    525     for (int i = 0, index = 0; i < numRings + 1; i++) {
    526 
     515    int radiusLast = 1;                 // Last radius
     516    for (int i = 1, index = 0; i < numRings + 1; i++) {
    527517        float lower2;                   // Lower limit of radius^2
    528518        float upper2;                   // Upper limit of radius^2
    529         if (i == 0) {
    530             lower2 = 0;
    531             upper2 = PS_SQR(0.5);
    532         } else if (i <= numInner) {
     519        if (i <= inner) {
    533520            // A ring every pixel width
    534521            float radius = i;
     
    572559                    for (int v = -size; v <= size; v++) {
    573560                        int v2 = PS_SQR(v);   // Square of v
    574 //                        float vPoly = power(v, vOrder); // Value of v^vOrder
    575561                        float vPoly = powf(v/(float)size, vOrder); // Value of v^vOrder
    576562
     
    579565                            int distance2 = u2 + v2; // Distance from the centre
    580566                            if (distance2 > lower2 && distance2 < upper2) {
    581 //                                float uPoly = power(u, uOrder); // Value of u^uOrder
    582567                                float uPoly = powf(u/(float)size, uOrder); // Value of u^uOrder
    583568
     
    627612    }
    628613
    629     kernels->subIndex = 0;
    630 
    631614    return kernels;
    632615}
     
    634617pmSubtractionKernels *pmSubtractionKernelsGenerate(pmSubtractionKernelsType type, int size, int spatialOrder,
    635618                                                   const psVector *fwhms, const psVector *orders, int inner,
    636                                                    int binning, int ringsOrder)
     619                                                   int binning, int ringsOrder, pmSubtractionMode mode)
    637620{
    638621    switch (type) {
    639622      case PM_SUBTRACTION_KERNEL_POIS:
    640         return pmSubtractionKernelsPOIS(size, spatialOrder);
     623        return pmSubtractionKernelsPOIS(size, spatialOrder, mode);
    641624      case PM_SUBTRACTION_KERNEL_ISIS:
    642         return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders);
     625        return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders, mode);
    643626      case PM_SUBTRACTION_KERNEL_SPAM:
    644         return pmSubtractionKernelsSPAM(size, spatialOrder, inner, binning);
     627        return pmSubtractionKernelsSPAM(size, spatialOrder, inner, binning, mode);
    645628      case PM_SUBTRACTION_KERNEL_FRIES:
    646         return pmSubtractionKernelsFRIES(size, spatialOrder, inner);
     629        return pmSubtractionKernelsFRIES(size, spatialOrder, inner, mode);
    647630      case PM_SUBTRACTION_KERNEL_GUNK:
    648         return pmSubtractionKernelsGUNK(size, spatialOrder, fwhms, orders, inner);
     631        return pmSubtractionKernelsGUNK(size, spatialOrder, fwhms, orders, inner, mode);
    649632      case PM_SUBTRACTION_KERNEL_RINGS:
    650         return pmSubtractionKernelsRINGS(size, spatialOrder, inner, ringsOrder);
     633        return pmSubtractionKernelsRINGS(size, spatialOrder, inner, ringsOrder, mode);
    651634      default:
    652635        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unknown kernel type: %x", type);
Note: See TracChangeset for help on using the changeset viewer.