IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 26473


Ignore:
Timestamp:
Dec 22, 2009, 9:55:18 AM (16 years ago)
Author:
eugene
Message:

adding hermitian kernels

Location:
branches/eam_branches/20091201/psModules/src/imcombine
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20091201/psModules/src/imcombine/pmSubtractionKernels.c

    r26318 r26473  
    1010#include "pmSubtraction.h"
    1111#include "pmSubtractionKernels.h"
     12#include "pmSubtractionHermitian.h"
    1213
    1314#define RINGS_BUFFER 10                 // Buffer size for RINGS data
    14 
    1515
    1616// Free function for pmSubtractionKernels
     
    5757    for (int i = 0, x = -size; x <= size; i++, x++) {
    5858        kernel->data.F32[i] = norm * power(x, order) * expf(expNorm * PS_SQR(x));
     59    }
     60
     61    return kernel;
     62}
     63
     64// Generate 1D convolution kernel for HERM (normalized for 2D)
     65static psVector *subtractionKernelHERM(float sigma, // Gaussian width
     66                                       int order, // Polynomial order
     67                                       int size // Kernel half-size
     68    )
     69{
     70    int fullSize = 2 * size + 1;        // Full size of kernel
     71    psVector *kernel = psVectorAlloc(fullSize, PS_TYPE_F32); // Kernel to return
     72
     73    // for now, we are only allowing equal orders and sigmas in X and Y
     74    float nf = exp(lgamma(order + 1));
     75    float norm = 1.0 / sqrt(nf*sigma*sqrt(M_2_PI));
     76
     77    for (int i = 0, x = -size; x <= size; i++, x++) {
     78        float xf = x / sigma;
     79        float z = -0.25*xf*xf;
     80        kernel->data.F32[i] = norm * p_pmSubtractionHermitianPolynomial(xf, order) * exp(z);
    5981    }
    6082
     
    189211
    190212#if 0
     213                double sum = 0.0;   // Sum of kernel component
     214                for (int v = -size; v <= size; v++) {
     215                    for (int u = -size; u <= size; u++) {
     216                        sum += kernel->kernel[v][u];
     217                    }
     218                }
     219                fprintf(stderr, "%d sum: %lf\n", index, sum);
     220#endif
     221
     222                kernels->widths->data.F32[index] = fwhms->data.F32[i];
     223                kernels->u->data.S32[index] = uOrder;
     224                kernels->v->data.S32[index] = vOrder;
     225                if (kernels->preCalc->data[index]) {
     226                    psFree(kernels->preCalc->data[index]);
     227                }
     228                kernels->preCalc->data[index] = preCalc;
     229                kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment);
     230
     231                psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index,
     232                        fwhms->data.F32[i], uOrder, vOrder, fabsf(moment));
     233            }
     234        }
     235    }
     236
     237    return kernels;
     238}
     239
     240pmSubtractionKernels *pmSubtractionKernelsHERM(int size, int spatialOrder,
     241                                               const psVector *fwhmsIN, const psVector *ordersIN,
     242                                               float penalty, pmSubtractionMode mode)
     243{
     244    PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL);
     245    PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL);
     246    PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL);
     247    PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL);
     248    PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL);
     249    PS_ASSERT_INT_POSITIVE(size, NULL);
     250    PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL);
     251
     252    // check the requested fwhm values: any values <= 0.0 should be dropped
     253    psVector *fwhms  = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32);
     254    psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32);
     255    for (int i = 0; i < fwhmsIN->n; i++) {
     256        if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
     257        psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
     258        psVectorAppend(orders, ordersIN->data.S32[i]);
     259    }
     260
     261    int numGaussians = fwhms->n;       // Number of Gaussians
     262
     263    int num = 0;                        // Number of basis functions
     264    psString params = NULL;             // List of parameters
     265    for (int i = 0; i < numGaussians; i++) {
     266        int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian
     267        psStringAppend(&params, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]);
     268        num += (gaussOrder + 1) * (gaussOrder + 2) / 2;
     269    }
     270
     271    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_HERM, size, spatialOrder, penalty, mode); // The kernels
     272    psStringAppend(&kernels->description, "HERM(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty);
     273
     274    psLogMsg("psModules.imcombine", PS_LOG_INFO, "HERM kernel: %s,%d --> %d elements", params, spatialOrder, num);
     275    psFree(params);
     276
     277    // Set the kernel parameters
     278    int fullSize = 2 * size + 1;        // Full size of kernels
     279    for (int i = 0, index = 0; i < numGaussians; i++) {
     280        float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma
     281        // Iterate over (u,v) order
     282        for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) {
     283            for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) {
     284                psArray *preCalc = psArrayAlloc(3); // Array to hold precalculated values
     285                psVector *xKernel = preCalc->data[0] = subtractionKernelHERM(sigma, uOrder, size); // x Kernel
     286                psVector *yKernel = preCalc->data[1] = subtractionKernelHERM(sigma, vOrder, size); // y Kernel
     287                psKernel *kernel = preCalc->data[2] = psKernelAlloc(-size, size, -size, size);      // Kernel
     288
     289                // Calculate moments
     290                double moment = 0.0;    // Moment, for penalty
     291                for (int v = -size, y = 0; v <= size; v++, y++) {
     292                    for (int u = -size, x = 0; u <= size; u++, x++) {
     293                        double value = xKernel->data.F32[x] * yKernel->data.F32[y]; // Value of kernel
     294                        kernel->kernel[v][u] = value;
     295                        moment += value * PS_SQR((PS_SQR(u) + PS_SQR(v)));
     296                    }
     297                }
     298
     299                // Normalise sum of kernel component to unity for even functions
     300                if (uOrder % 2 == 0 && vOrder % 2 == 0) {
     301                    double sum = 0.0;   // Sum of kernel component
     302                    for (int v = 0; v < fullSize; v++) {
     303                        for (int u = 0; u < fullSize; u++) {
     304                            sum += xKernel->data.F32[u] * yKernel->data.F32[v];
     305                        }
     306                    }
     307                    sum = 1.0 / sqrt(sum);
     308                    psBinaryOp(xKernel, xKernel, "*", psScalarAlloc(sum, PS_TYPE_F32));
     309                    psBinaryOp(yKernel, yKernel, "*", psScalarAlloc(sum, PS_TYPE_F32));
     310                    psBinaryOp(kernel->image, kernel->image, "*", psScalarAlloc(PS_SQR(sum), PS_TYPE_F32));
     311
     312#if 1
     313                    fprintf(stderr, "%d norm: %lf, null: %f\n", index, sum,kernel->kernel[0][0]);
     314#endif
     315                   
     316                    kernel->kernel[0][0] -= 1.0;
     317                    moment *= PS_SQR(sum);
     318                }
     319
     320
     321#if 1
    191322                double sum = 0.0;   // Sum of kernel component
    192323                for (int v = -size; v <= size; v++) {
     
    662793      case PM_SUBTRACTION_KERNEL_ISIS:
    663794        return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders, penalty, mode);
     795      case PM_SUBTRACTION_KERNEL_HERM:
     796        return pmSubtractionKernelsHERM(size, spatialOrder, fwhms, orders, penalty, mode);
    664797      case PM_SUBTRACTION_KERNEL_SPAM:
    665798        return pmSubtractionKernelsSPAM(size, spatialOrder, inner, binning, penalty, mode);
     
    724857    float penalty = 0.0;                // Penalty for wideness
    725858
    726     if (strncmp(description, "ISIS", 4) == 0) {
    727         // XXX Support for GUNK
     859    // ISIS and HERM have the same description layout
     860    if (!strncmp(description, "ISIS", 4) || !strcmp (description, "HERM")) {
     861        // XXX Support for GUNK (not yet supported)
    728862        if (strstr(description, "+POIS")) {
    729863            type = PM_SUBTRACTION_KERNEL_GUNK;
    730864            psAbort("Deciphering GUNK kernels (%s) is not currently supported.", description);
    731         } else {
    732             type = PM_SUBTRACTION_KERNEL_ISIS;
    733             char *ptr = (char*)description + 5;    // Eat "ISIS("
    734             PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt);
    735 
    736             // Count the number of Gaussians
    737             int numGauss = 0;
    738             for (char *string = ptr; string; string = strchr(string + 1, '(')) {
    739                 numGauss++;
    740             }
    741 
    742             fwhms = psVectorAlloc(numGauss, PS_TYPE_F32);
    743             orders = psVectorAlloc(numGauss, PS_TYPE_S32);
    744 
    745             for (int i = 0; i < numGauss; i++) {
    746                 ptr++;                  // Eat the '('
    747                 PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234,"
    748                 PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)"
    749             }
    750 
    751             ptr++;                      // Eat ','
    752             PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt);
    753             penalty = parseStringFloat(ptr);
    754         }
    755     } else if (strncmp(description, "RINGS", 5) == 0) {
     865        }
     866
     867        type = pmSubtractionKernelsTypeFromString (description);
     868        psAssert (type != PM_SUBTRACTION_KERNEL_NONE, "must  be ISIS or HERM");
     869
     870        char *ptr = (char*)description + 5;    // Eat "ISIS(" or "HERM("
     871        PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt);
     872
     873        // Count the number of Gaussians
     874        int numGauss = 0;
     875        for (char *string = ptr; string; string = strchr(string + 1, '(')) {
     876            numGauss++;
     877        }
     878
     879        fwhms = psVectorAlloc(numGauss, PS_TYPE_F32);
     880        orders = psVectorAlloc(numGauss, PS_TYPE_S32);
     881
     882        for (int i = 0; i < numGauss; i++) {
     883            ptr++;                  // Eat the '('
     884            PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234,"
     885            PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)"
     886        }
     887
     888        ptr++;                      // Eat ','
     889        PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt);
     890        penalty = parseStringFloat(ptr);
     891
     892        return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
     893    }
     894
     895    if (strncmp(description, "RINGS", 5) == 0) {
    756896        type = PM_SUBTRACTION_KERNEL_RINGS;
    757897        char *ptr = (char*)description + 6;
     
    761901        PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt);
    762902        PARSE_STRING_NUMBER(penalty, ptr, ')', parseStringInt);
    763     } else {
    764         psAbort("Deciphering kernels other than ISIS and RINGS is not currently supported.");
    765     }
    766 
     903        return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
     904    }
     905
     906    psAbort("Deciphering kernels other than ISIS, HERM and RINGS is not currently supported.");
    767907
    768908    return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders,
     
    778918    if (strcasecmp(type, "ISIS") == 0) {
    779919        return PM_SUBTRACTION_KERNEL_ISIS;
     920    }
     921    if (strcasecmp(type, "HERM") == 0) {
     922        return PM_SUBTRACTION_KERNEL_HERM;
    780923    }
    781924    if (strcasecmp(type, "SPAM") == 0) {
  • branches/eam_branches/20091201/psModules/src/imcombine/pmSubtractionKernels.h

    r26157 r26473  
    1010    PM_SUBTRACTION_KERNEL_POIS,         ///< Pan-STARRS Optimal Image Subtraction --- delta functions
    1111    PM_SUBTRACTION_KERNEL_ISIS,         ///< Traditional kernel --- gaussians modified by polynomials
     12    PM_SUBTRACTION_KERNEL_HERM,         ///< Hermitian polynomial kernels
    1213    PM_SUBTRACTION_KERNEL_SPAM,         ///< Summed Pixels for Advanced Matching --- summed delta functions
    1314    PM_SUBTRACTION_KERNEL_FRIES,        ///< Fibonacci Radius Increases Excellence of Subtraction
     
    3031    psString description;               ///< Description of the kernel parameters
    3132    long num;                           ///< Number of kernel components (not including the spatial ones)
    32     psVector *u, *v;                    ///< Offset (for POIS) or polynomial order (for ISIS)
    33     psVector *widths;                   ///< Gaussian FWHMs (ISIS)
     33    psVector *u, *v;                    ///< Offset (for POIS) or polynomial order (for ISIS or HERM)
     34    psVector *widths;                   ///< Gaussian FWHMs (ISIS or HERM)
    3435    psVector *uStop, *vStop;            ///< Width of kernel element (SPAM,FRIES only)
    35     psArray *preCalc;                   ///< Array of images containing pre-calculated kernel (for ISIS)
     36    psArray *preCalc;                   ///< Array of images containing pre-calculated kernel (for ISIS or HERM)
    3637    float penalty;                      ///< Penalty for wideness
    3738    psVector *penalties;                ///< Penalty for each kernel component
     
    6465        PS_ASSERT_VECTOR_SIZE((KERNELS)->widths, (KERNELS)->num, RETURNVALUE); \
    6566    } \
     67    if ((KERNELS)->type == PM_SUBTRACTION_KERNEL_HERM) { \
     68        PS_ASSERT_VECTOR_NON_NULL((KERNELS)->widths, RETURNVALUE); \
     69        PS_ASSERT_VECTOR_TYPE((KERNELS)->widths, PS_TYPE_F32, RETURNVALUE); \
     70        PS_ASSERT_VECTOR_SIZE((KERNELS)->widths, (KERNELS)->num, RETURNVALUE); \
     71    } \
    6672    if ((KERNELS)->uStop || (KERNELS)->vStop) { \
    6773        PS_ASSERT_VECTOR_NON_NULL((KERNELS)->uStop, RETURNVALUE); \
     
    142148                                               );
    143149
     150/// Generate HERM kernels
     151pmSubtractionKernels *pmSubtractionKernelsHERM(int size, ///< Half-size of the kernel
     152                                               int spatialOrder, ///< Order of spatial variations
     153                                               const psVector *fwhms, ///< Gaussian FWHMs
     154                                               const psVector *orders, ///< order of hermitian polynomials
     155                                               float penalty, ///< Penalty for wideness
     156                                               pmSubtractionMode mode ///< Mode for subtraction
     157                                               );
     158
    144159/// Generate SPAM kernels
    145160pmSubtractionKernels *pmSubtractionKernelsSPAM(int size, ///< Half-size of the kernel
Note: See TracChangeset for help on using the changeset viewer.