IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 26574


Ignore:
Timestamp:
Jan 12, 2010, 3:55:01 PM (16 years ago)
Author:
eugene
Message:

add ISIS_RADIAL (ISIS + radial Hermitian); modify pmSubtractionKernelPreCalcNormalize to force zero null on odd terms

File:
1 edited

Legend:

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

    r26553 r26574  
    9090
    9191    for (int i = 0, x = -size; x <= size; i++, x++) {
    92         float xf = x / sigma;
    93         float z = -0.25*xf*xf;
     92        float xf = x / sigma;
     93        float z = -0.25*xf*xf;
    9494        kernel->data.F32[i] = norm * p_pmSubtractionHermitianPolynomial(xf, order) * exp(z);
     95    }
     96
     97    return kernel;
     98}
     99
     100// Generate 1D convolution kernel for HERM (normalized for 2D)
     101psKernel *pmSubtractionKernelHERM_RADIAL(float sigma, // Gaussian width
     102                                         int order, // Polynomial order
     103                                         int size // Kernel half-size
     104    )
     105{
     106    psKernel *kernel = psKernelAlloc(-size, size, -size, size); // 2D Kernel
     107
     108    // for now, we are only allowing equal orders and sigmas in X and Y
     109    float nf = exp(lgamma(order + 1));
     110    float norm = 1.0 / sqrt(nf*sigma*sqrt(M_2_PI));
     111
     112    // generate 2D radial hermitian
     113    for (int v = -size; v <= size; v++) {
     114        for (int u = -size; u <= size; u++) {
     115            float r = hypot(u, v) / sigma;
     116            float z = -0.25*r*r;
     117            kernel->kernel[v][u] = norm * p_pmSubtractionHermitianPolynomial(r, order) * exp(z);
     118        }
    95119    }
    96120
     
    132156            kernels->preCalc->data[index] = NULL;
    133157            kernels->penalties->data.F32[index] = kernels->penalty * PS_SQR(PS_SQR(u) + PS_SQR(v));
    134             psAssert(isfinite(kernels->penalties->data.F32[index]), "Invalid penalty");
    135 
     158            psAssert (isfinite(kernels->penalties->data.F32[index]), "invalid penalty");
    136159            psTrace("psModules.imcombine", 7, "Kernel %d: %d %d\n", index, u, v);
    137160        }
     
    147170}
    148171
    149 bool pmSubtractionKernelPreCalcNormalize (pmSubtractionKernels *kernels, pmSubtractionKernelPreCalc *preCalc, int index, int size, int uOrder, int vOrder, float fwhm, bool AlardLuptonStyle) {
     172bool pmSubtractionKernelPreCalcNormalize (pmSubtractionKernels *kernels, pmSubtractionKernelPreCalc *preCalc, int index, int size, int uOrder, int vOrder, float fwhm, bool AlardLuptonStyle, bool forceZeroNull) {
    150173
    151174    // Calculate moments
    152175    double moment = 0.0;    // Moment, for penalty
    153176    for (int v = -size; v <= size; v++) {
    154         for (int u = -size; u <= size; u++) {
    155             double value = preCalc->kernel->kernel[v][u];
    156             moment += PS_SQR(value) * PS_SQR((PS_SQR(u) + PS_SQR(v)));
    157         }
     177        for (int u = -size; u <= size; u++) {
     178            double value = preCalc->kernel->kernel[v][u];
     179            moment += PS_SQR(value) * PS_SQR((PS_SQR(u) + PS_SQR(v)));
     180        }
    158181    }
    159182
     
    169192
    170193    for (int v = -size; v <= size; v++) {
    171         for (int u = -size; u <= size; u++) {
    172             sum += preCalc->kernel->kernel[v][u];
    173             min = PS_MIN(preCalc->kernel->kernel[v][u], min);
    174             max = PS_MAX(preCalc->kernel->kernel[v][u], max);
    175         }
     194        for (int u = -size; u <= size; u++) {
     195            sum += preCalc->kernel->kernel[v][u];
     196            min = PS_MIN(preCalc->kernel->kernel[v][u], min);
     197            max = PS_MAX(preCalc->kernel->kernel[v][u], max);
     198        }
    176199    }
    177200#if 0
     
    181204    // only even terms have non-zero sums
    182205    if ((uOrder % 2 == 0) && (vOrder % 2 == 0)) {
    183         moment /= PS_SQR(sum);
     206        moment /= PS_SQR(sum);
     207    } else {
     208        // XXX keep this?
     209        moment = 0.0;
    184210    }
    185211
     
    189215
    190216    if (AlardLuptonStyle && (uOrder % 2 == 0 && vOrder % 2 == 0)) {
    191         zeroNull = true;
     217        zeroNull = true;
    192218    }
    193219    if (!AlardLuptonStyle && (uOrder == 0 && vOrder == 0)) {
    194         zeroNull = true;
    195     }
    196     if ((uOrder % 2) || (vOrder % 2)) {
    197         // scale2D = 1.0 / (preCalc->kernel->image->numCols * preCalc->kernel->image->numRows * max);
    198         scale2D = 1.0 / max;
    199         scale1D = sqrt(scale2D);
    200     }
    201 
    202     psBinaryOp(preCalc->xKernel, preCalc->xKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32));
    203     psBinaryOp(preCalc->yKernel, preCalc->yKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32));
     220        zeroNull = true;
     221    }
     222    if (forceZeroNull) {
     223        zeroNull = true;
     224    }
     225    if (!forceZeroNull && ((uOrder % 2) || (vOrder % 2))) {
     226        // scale2D = 1.0 / (preCalc->kernel->image->numCols * preCalc->kernel->image->numRows * max);
     227        scale2D = 1.0 / max;
     228        scale1D = sqrt(scale2D);
     229    }
     230
     231    if (preCalc->xKernel) {
     232        psBinaryOp(preCalc->xKernel, preCalc->xKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32));
     233    }
     234    if (preCalc->yKernel) {
     235        psBinaryOp(preCalc->yKernel, preCalc->yKernel, "*", psScalarAlloc(scale1D, PS_TYPE_F32));
     236    }
    204237    psBinaryOp(preCalc->kernel->image, preCalc->kernel->image, "*", psScalarAlloc(scale2D, PS_TYPE_F32));
    205238    if (zeroNull) {
    206         preCalc->kernel->kernel[0][0] -= 1.0;
     239        preCalc->kernel->kernel[0][0] -= 1.0;
    207240    }
    208241
     
    212245    max = FLT_MIN;
    213246    for (int v = -size; v <= size; v++) {
    214         for (int u = -size; u <= size; u++) {
    215             sum += preCalc->kernel->kernel[v][u];
    216             min = PS_MIN(preCalc->kernel->kernel[v][u], min);
    217             max = PS_MAX(preCalc->kernel->kernel[v][u], max);
    218         }
     247        for (int u = -size; u <= size; u++) {
     248            sum += preCalc->kernel->kernel[v][u];
     249            min = PS_MIN(preCalc->kernel->kernel[v][u], min);
     250            max = PS_MAX(preCalc->kernel->kernel[v][u], max);
     251        }
    219252    }
    220253    fprintf(stderr, "%d mod: %lf, null: %f, min: %lf, max: %lf, scale: %f\n", index, sum, preCalc->kernel->kernel[0][0], min, max, scale2D);
     
    225258    kernels->v->data.S32[index] = vOrder;
    226259    if (kernels->preCalc->data[index]) {
    227         psFree(kernels->preCalc->data[index]);
     260        psFree(kernels->preCalc->data[index]);
    228261    }
    229262    kernels->preCalc->data[index] = preCalc;
    230263    kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment);
    231 
    232     psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index,
    233             fwhm, uOrder, vOrder, fabsf(moment));
     264    psAssert (isfinite(kernels->penalties->data.F32[index]), "invalid penalty");
     265    psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index, fwhm, uOrder, vOrder, fabsf(moment));
    234266
    235267    return true;
     
    252284    psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32);
    253285    for (int i = 0; i < fwhmsIN->n; i++) {
    254         if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
    255         psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
    256         psVectorAppend(orders, ordersIN->data.S32[i]);
     286        if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
     287        psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
     288        psVectorAppend(orders, ordersIN->data.S32[i]);
    257289    }
    258290
     
    273305    psLogMsg("psModules.imcombine", PS_LOG_INFO, "ISIS kernel: %s,%d --> %d elements",
    274306             params, spatialOrder, num);
     307    psFree(params);
     308
     309    // Set the kernel parameters
     310    for (int i = 0, index = 0; i < numGaussians; i++) {
     311        float sigma = fwhms->data.F32[i] / (2.0 * sqrtf(2.0 * logf(2.0))); // Gaussian sigma
     312        // Iterate over (u,v) order
     313        for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) {
     314            for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) {
     315
     316                pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS, uOrder, vOrder, size, sigma); // structure to hold precalculated values
     317                pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false);
     318                // pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], false, false);
     319            }
     320        }
     321    }
     322
     323    return kernels;
     324}
     325
     326pmSubtractionKernels *pmSubtractionKernelsISIS_RADIAL(int size, int spatialOrder,
     327                                                      const psVector *fwhmsIN, const psVector *ordersIN,
     328                                                      float penalty, pmSubtractionMode mode)
     329{
     330    PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL);
     331    PS_ASSERT_VECTOR_TYPE(fwhmsIN, PS_TYPE_F32, NULL);
     332    PS_ASSERT_VECTOR_NON_NULL(ordersIN, NULL);
     333    PS_ASSERT_VECTOR_TYPE(ordersIN, PS_TYPE_S32, NULL);
     334    PS_ASSERT_VECTORS_SIZE_EQUAL(fwhmsIN, ordersIN, NULL);
     335    PS_ASSERT_INT_POSITIVE(size, NULL);
     336    PS_ASSERT_INT_NONNEGATIVE(spatialOrder, NULL);
     337
     338    // check the requested fwhm values: any values <= 0.0 should be dropped
     339    psVector *fwhms  = psVectorAllocEmpty (fwhmsIN->n, PS_TYPE_F32);
     340    psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32);
     341    for (int i = 0; i < fwhmsIN->n; i++) {
     342        if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
     343        psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
     344        psVectorAppend(orders, ordersIN->data.S32[i]);
     345    }
     346
     347    int numGaussians = fwhms->n;       // Number of Gaussians
     348
     349    int num = 0;                        // Number of basis functions
     350    psString params = NULL;             // List of parameters
     351    for (int i = 0; i < numGaussians; i++) {
     352        int gaussOrder = orders->data.S32[i]; // Polynomial order to apply to Gaussian
     353        psStringAppend(&params, "(%.1f,%d)", fwhms->data.F32[i], orders->data.S32[i]);
     354        num += (gaussOrder + 1) * (gaussOrder + 2) / 2;
     355        num += (11 - gaussOrder - 1);   // include all higher order radial terms
     356    }
     357
     358    pmSubtractionKernels *kernels = pmSubtractionKernelsAlloc(num, PM_SUBTRACTION_KERNEL_ISIS_RADIAL, size, spatialOrder, penalty, mode); // The kernels
     359    psStringAppend(&kernels->description, "ISIS_RADIAL(%d,%s,%d,%.2e)", size, params, spatialOrder, penalty);
     360
     361    psLogMsg("psModules.imcombine", PS_LOG_INFO, "ISIS_RADIAL kernel: %s,%d --> %d elements", params, spatialOrder, num);
    275362    psFree(params);
    276363
     
    282369            for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) {
    283370                pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS, uOrder, vOrder, size, sigma); // structure to hold precalculated values
    284                 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);
     371                pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false);
    285372            }
    286373        }
    287     }
    288 
     374        for (int order = orders->data.S32[i] + 1; order < 11; order ++, index ++) {
     375            // XXX modify size for hermitians to account for sqrt(2) in Hermitian definition (relative to ISIS Gaussian)
     376            pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS_RADIAL, order, order, size, sigma / sqrt(2.0)); // structure to hold precalculated values
     377            pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, order, order, fwhms->data.F32[i], true, true);
     378        }
     379    }
    289380    return kernels;
    290381}
    291382
    292383pmSubtractionKernels *pmSubtractionKernelsHERM(int size, int spatialOrder,
    293                                                const psVector *fwhmsIN, const psVector *ordersIN,
    294                                                float penalty, pmSubtractionMode mode)
     384                                               const psVector *fwhmsIN, const psVector *ordersIN,
     385                                               float penalty, pmSubtractionMode mode)
    295386{
    296387    PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL);
     
    306397    psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32);
    307398    for (int i = 0; i < fwhmsIN->n; i++) {
    308         if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
    309         psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
    310         psVectorAppend(orders, ordersIN->data.S32[i]);
     399        if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
     400        psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
     401        psVectorAppend(orders, ordersIN->data.S32[i]);
    311402    }
    312403
     
    334425            for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) {
    335426                pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values
    336                 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);
     427                pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false);
    337428            }
    338429        }
     
    343434
    344435pmSubtractionKernels *pmSubtractionKernelsDECONV_HERM(int size, int spatialOrder,
    345                                                      const psVector *fwhmsIN, const psVector *ordersIN,
    346                                                      float penalty, pmSubtractionMode mode)
     436                                                     const psVector *fwhmsIN, const psVector *ordersIN,
     437                                                     float penalty, pmSubtractionMode mode)
    347438{
    348439    PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL);
     
    358449    psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32);
    359450    for (int i = 0; i < fwhmsIN->n; i++) {
    360         if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
    361         psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
    362         psVectorAppend(orders, ordersIN->data.S32[i]);
     451        if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
     452        psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
     453        psVectorAppend(orders, ordersIN->data.S32[i]);
    363454    }
    364455
     
    397488                pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values
    398489
    399                 // save the generated 2D kernel as the target, deconvolve it by Gaussian, replacing the generated 2D kernel
    400                 psKernel *kernelTarget = preCalc->kernel;
     490                // save the generated 2D kernel as the target, deconvolve it by Gaussian, replacing the generated 2D kernel
     491                psKernel *kernelTarget = preCalc->kernel;
    401492                preCalc->kernel = pmSubtractionDeconvolveKernel(kernelTarget, kernelGauss); // Kernel
    402493
    403                 // XXX do we use Alard-Lupton normalization (last param true) or not?
    404                 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);
    405 
    406                 // XXXX test demo that deconvolved kernel is valid
     494                // XXX do we use Alard-Lupton normalization (last param true) or not?
     495                pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true, false);
     496
     497                // XXXX test demo that deconvolved kernel is valid
    407498# if 1
    408                 psImage *kernelConv = psImageConvolveFFT(NULL, preCalc->kernel->image, NULL, 0, kernelGauss);
    409                 psArrayAdd (deconKernels, 100, kernelConv);
    410                 psFree (kernelConv);
    411 
    412                 if (!uOrder && !vOrder){
    413                     pmSubtractionVisualShowSubtraction (kernelTarget->image, preCalc->kernel->image, kernelConv);
    414                 }
     499                psImage *kernelConv = psImageConvolveFFT(NULL, preCalc->kernel->image, NULL, 0, kernelGauss);
     500                psArrayAdd (deconKernels, 100, kernelConv);
     501                psFree (kernelConv);
     502
     503                if (!uOrder && !vOrder){
     504                    pmSubtractionVisualShowSubtraction (kernelTarget->image, preCalc->kernel->image, kernelConv);
     505                }
    415506# endif
    416507            }
     
    421512    psImage *dot = psImageAlloc(deconKernels->n, deconKernels->n, PS_TYPE_F32);
    422513    for (int i = 0; i < deconKernels->n; i++) {
    423         for (int j = 0; j <= i; j++) {
    424             psImage *t1 = deconKernels->data[i];
    425             psImage *t2 = deconKernels->data[j];
    426 
    427             double sum = 0.0;
    428             for (int iy = 0; iy < t1->numRows; iy++) {
    429                 for (int ix = 0; ix < t1->numCols; ix++) {
    430                     sum += t1->data.F32[iy][ix] * t2->data.F32[iy][ix];
    431                 }
    432             }
    433             dot->data.F32[j][i] = sum;
    434             dot->data.F32[i][j] = sum;
    435         }
     514        for (int j = 0; j <= i; j++) {
     515            psImage *t1 = deconKernels->data[i];
     516            psImage *t2 = deconKernels->data[j];
     517
     518            double sum = 0.0;
     519            for (int iy = 0; iy < t1->numRows; iy++) {
     520                for (int ix = 0; ix < t1->numCols; ix++) {
     521                    sum += t1->data.F32[iy][ix] * t2->data.F32[iy][ix];
     522                }
     523            }
     524            dot->data.F32[j][i] = sum;
     525            dot->data.F32[i][j] = sum;
     526        }
    436527    }
    437528    pmSubtractionVisualShowSubtraction (dot, NULL, NULL);
     
    460551    kernels->v = psVectorAlloc(numBasisFunctions, PS_TYPE_S32);
    461552    kernels->widths = psVectorAlloc(numBasisFunctions, PS_TYPE_F32);
     553    kernels->uStop = NULL;
     554    kernels->vStop = NULL;
    462555    kernels->preCalc = psArrayAlloc(numBasisFunctions);
    463556    kernels->penalty = penalty;
    464557    kernels->penalties = psVectorAlloc(numBasisFunctions, PS_TYPE_F32);
    465     kernels->uStop = NULL;
    466     kernels->vStop = NULL;
    467558    kernels->size = size;
    468559    kernels->inner = 0;
     
    474565    kernels->solution1 = NULL;
    475566    kernels->solution2 = NULL;
     567    kernels->mean = NAN;
     568    kernels->rms = NAN;
     569    kernels->numStamps = 0;
     570
     571    kernels->fSigResMean  = NAN;
     572    kernels->fSigResStdev = NAN;
     573    kernels->fMaxResMean  = NAN;
     574    kernels->fMaxResStdev = NAN;
     575    kernels->fMinResMean  = NAN;
     576    kernels->fMinResStdev = NAN;
    476577
    477578    return kernels;
     
    486587    switch (type) {
    487588      case PM_SUBTRACTION_KERNEL_ISIS:
    488         preCalc->xKernel = pmSubtractionKernelISIS(sigma, uOrder, size);
    489         preCalc->yKernel = pmSubtractionKernelISIS(sigma, vOrder, size);
    490         preCalc->uCoords = NULL;
    491         preCalc->vCoords = NULL;
    492         preCalc->poly    = NULL;
    493         break;
     589        preCalc->xKernel = pmSubtractionKernelISIS(sigma, uOrder, size);
     590        preCalc->yKernel = pmSubtractionKernelISIS(sigma, vOrder, size);
     591        preCalc->uCoords = NULL;
     592        preCalc->vCoords = NULL;
     593        preCalc->poly    = NULL;
     594        break;
    494595      case PM_SUBTRACTION_KERNEL_HERM:
    495         preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size);
    496         preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size);
    497         preCalc->uCoords = NULL;
    498         preCalc->vCoords = NULL;
    499         preCalc->poly    = NULL;
    500         break;
    501       case PM_SUBTRACTION_KERNEL_DECONV_HERM:
    502         preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size);
    503         preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size);
    504         preCalc->uCoords = NULL;
    505         preCalc->vCoords = NULL;
    506         preCalc->poly    = NULL;
    507         break;
     596        preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size);
     597        preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size);
     598        preCalc->uCoords = NULL;
     599        preCalc->vCoords = NULL;
     600        preCalc->poly    = NULL;
     601        break;
    508602      case PM_SUBTRACTION_KERNEL_RINGS:
    509         // the RINGS kernel uses the uCoords, vCoords, and poly elements of the structure
    510         // we allocate these vectors here, but leave the kernel generation to the main function
    511         preCalc->xKernel = NULL;
    512         preCalc->yKernel = NULL;
    513         preCalc->kernel  = NULL;
    514         preCalc->uCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // u coords
    515         preCalc->vCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // v coords
    516         preCalc->poly    = psVectorAllocEmpty(size, PS_TYPE_F32); // Polynomial
    517         return preCalc;
     603        // the RINGS kernel uses the uCoords, vCoords, and poly elements of the structure
     604        // we allocate these vectors here, but leave the kernel generation to the main function
     605        preCalc->xKernel = NULL;
     606        preCalc->yKernel = NULL;
     607        preCalc->kernel  = NULL;
     608        preCalc->uCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // u coords
     609        preCalc->vCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // v coords
     610        preCalc->poly    = psVectorAllocEmpty(size, PS_TYPE_F32); // Polynomial
     611        return preCalc;
     612      case PM_SUBTRACTION_KERNEL_ISIS_RADIAL:
     613        preCalc->kernel  = pmSubtractionKernelHERM_RADIAL(sigma, uOrder, size);
     614        preCalc->xKernel = NULL;
     615        preCalc->yKernel = NULL;
     616        preCalc->uCoords = NULL;
     617        preCalc->vCoords = NULL;
     618        preCalc->poly    = NULL;
     619        return preCalc;
    518620      default:
    519         psAbort("programming error: invalid type for PreCalc kernel");
     621        psAbort("programming error: invalid type for PreCalc kernel");
    520622    }
    521623
     
    524626    // generate 2D kernel from 1D realizations
    525627    for (int v = -size, y = 0; v <= size; v++, y++) {
    526         for (int u = -size, x = 0; u <= size; u++, x++) {
    527             preCalc->kernel->kernel[v][u] = preCalc->xKernel->data.F32[x] * preCalc->yKernel->data.F32[y]; // Value of kernel
    528         }
    529     }
    530 
     628        for (int u = -size, x = 0; u <= size; u++, x++) {
     629            preCalc->kernel->kernel[v][u] = preCalc->xKernel->data.F32[x] * preCalc->yKernel->data.F32[y]; // Value of kernel
     630        }
     631    }
     632   
    531633    return preCalc;
    532634}
     
    753855}
    754856
    755 // Grid United with Normal Kernel
     857// Grid United with Normal Kernel [description: GUNK=ISIS(...)+POIS(...)]
    756858pmSubtractionKernels *pmSubtractionKernelsGUNK(int size, int spatialOrder, const psVector *fwhms,
    757859                                               const psVector *orders, int inner, float penalty,
     
    856958            for (int vOrder = 0; vOrder <= (i == 0 ? 0 : ringsOrder - uOrder); vOrder++, index++) {
    857959
    858                 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc (PM_SUBTRACTION_KERNEL_RINGS, 0, 0, RINGS_BUFFER, 0.0);
     960                pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc (PM_SUBTRACTION_KERNEL_RINGS, 0, 0, RINGS_BUFFER, 0.0);
    859961                double moment = 0.0;    // Moment, for penalty
    860962
     
    862964                    // Central pixel is easy
    863965                    preCalc->uCoords->data.S32[0] = 0;
    864                     preCalc->vCoords->data.S32[0] = 0;
     966                    preCalc->vCoords->data.S32[0] = 0;
    865967                    preCalc->poly->data.F32[0] = 1.0;
    866968                    preCalc->uCoords->n = 1;
    867                     preCalc->vCoords->n = 1;
    868                     preCalc->poly->n = 1;
     969                    preCalc->vCoords->n = 1;
     970                    preCalc->poly->n = 1;
    869971                    radiusLast = 0;
    870972                    moment = 0.0;
     
    9231025                kernels->v->data.S32[index] = vOrder;
    9241026                kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment);
    925                 if (!isfinite(kernels->penalties->data.F32[index])) {
    926                     psAbort ("invalid penalty");
    927                 }
     1027                if (!isfinite(kernels->penalties->data.F32[index])) {
     1028                    psAbort ("invalid penalty");
     1029                }
    9281030
    9291031                psTrace("psModules.imcombine", 7, "Kernel %d: %d %d %d\n", index,
     
    9461048      case PM_SUBTRACTION_KERNEL_ISIS:
    9471049        return pmSubtractionKernelsISIS(size, spatialOrder, fwhms, orders, penalty, mode);
     1050      case PM_SUBTRACTION_KERNEL_ISIS_RADIAL:
     1051        return pmSubtractionKernelsISIS_RADIAL(size, spatialOrder, fwhms, orders, penalty, mode);
    9481052      case PM_SUBTRACTION_KERNEL_HERM:
    9491053        return pmSubtractionKernelsHERM(size, spatialOrder, fwhms, orders, penalty, mode);
     
    10121116    float penalty = 0.0;                // Penalty for wideness
    10131117
    1014     // ISIS, HERM, and DECONV_HERM have the same description layout
    1015     if (!strncmp(description, "ISIS", 4) || !strcmp (description, "HERM") || !strcmp (description, "DECONV_HERM")) {
    1016         // XXX Support for GUNK (not yet supported)
    1017         if (strstr(description, "+POIS")) {
    1018             type = PM_SUBTRACTION_KERNEL_GUNK;
    1019             psAbort("Deciphering GUNK kernels (%s) is not currently supported.", description);
    1020         }
    1021 
    1022         type = pmSubtractionKernelsTypeFromString (description);
    1023         psAssert (type != PM_SUBTRACTION_KERNEL_NONE, "must  be ISIS, HERM or DECONV_HERM");
    1024 
    1025         char *ptr = NULL;
    1026         switch (type) {
    1027           case PM_SUBTRACTION_KERNEL_ISIS:
    1028           case PM_SUBTRACTION_KERNEL_HERM:
    1029             ptr = (char*) description + 5;    // Eat "ISIS(" or "HERM("
    1030             break;
    1031           case PM_SUBTRACTION_KERNEL_DECONV_HERM:
    1032             ptr = (char*) description + 12;    // Eat "DECONV_HERM("
    1033             break;
    1034           default:
    1035             psAbort("programming error: invalid kernel type");
    1036         }
    1037         PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt);
    1038 
    1039         // Count the number of Gaussians
    1040         int numGauss = 0;
    1041         for (char *string = ptr; string; string = strchr(string + 1, '(')) {
    1042             numGauss++;
    1043         }
    1044 
    1045         fwhms = psVectorAlloc(numGauss, PS_TYPE_F32);
    1046         orders = psVectorAlloc(numGauss, PS_TYPE_S32);
    1047 
    1048         for (int i = 0; i < numGauss; i++) {
    1049             ptr++;                  // Eat the '('
    1050             PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234,"
    1051             PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)"
    1052         }
    1053 
    1054         ptr++;                      // Eat ','
    1055         PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt);
    1056         penalty = parseStringFloat(ptr);
    1057 
    1058         return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
    1059     }
    1060 
    1061     if (strncmp(description, "RINGS", 5) == 0) {
    1062         type = PM_SUBTRACTION_KERNEL_RINGS;
    1063         char *ptr = (char*)description + 6;
     1118    // currently known descriptions:
     1119    // ISIS(...), ISIS_RADIAL(...), HERM(...), DECONV_HERM(...), POIS(...), SPAM(...),
     1120    // FRIES(...), GUNK=ISIS(...)+POIS(...), RINGS(...),
     1121    // the descriptive name is the set of characters before the (
     1122   
     1123    type = pmSubtractionKernelsTypeFromString (description);
     1124    char *ptr = strchr(description, '(');
     1125    psAssert (ptr, "description is missing kernel parameters");
     1126
     1127    switch (type) {
     1128      case PM_SUBTRACTION_KERNEL_ISIS:
     1129      case PM_SUBTRACTION_KERNEL_ISIS_RADIAL:
     1130      case PM_SUBTRACTION_KERNEL_HERM:
     1131      case PM_SUBTRACTION_KERNEL_DECONV_HERM:
     1132        PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt);
     1133
     1134        // Count the number of Gaussians
     1135        int numGauss = 0;
     1136        for (char *string = ptr; string; string = strchr(string + 1, '(')) {
     1137            numGauss++;
     1138        }
     1139
     1140        fwhms = psVectorAlloc(numGauss, PS_TYPE_F32);
     1141        orders = psVectorAlloc(numGauss, PS_TYPE_S32);
     1142
     1143        for (int i = 0; i < numGauss; i++) {
     1144            ptr++;                                                               // Eat the '('
     1145            PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234,"
     1146            PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt);  // Eat "3)"
     1147        }
     1148
     1149        ptr++;                      // Eat ','
     1150        PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt);
     1151        penalty = parseStringFloat(ptr);
     1152
     1153        return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
     1154
     1155      case PM_SUBTRACTION_KERNEL_RINGS:
    10641156        PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt);
    10651157        PARSE_STRING_NUMBER(inner, ptr, ',', parseStringInt);
     
    10671159        PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt);
    10681160        PARSE_STRING_NUMBER(penalty, ptr, ')', parseStringInt);
    1069         return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
    1070     }
    1071 
    1072     psAbort("Deciphering kernels other than ISIS, HERM, DECONV_HERM or RINGS is not currently supported.");
    1073 
    1074     return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders,
    1075                                         inner, binning, ringsOrder, penalty, mode);
    1076 }
    1077 
    1078 
     1161        return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
     1162      default:
     1163        psAbort("Deciphering kernels other than ISIS, HERM, DECONV_HERM or RINGS is not currently supported.");
     1164    }
     1165    return NULL;
     1166}
     1167
     1168
     1169// the input string can either be just the name or the description string.  Currently known
     1170// descriptions: ISIS(...), ISIS_RADIAL(...), HERM(...), DECONV_HERM(...), POIS(...),
     1171// SPAM(...), FRIES(...), GUNK=ISIS(...)+POIS(...), RINGS(...),
    10791172pmSubtractionKernelsType pmSubtractionKernelsTypeFromString(const char *type)
    10801173{
    1081     if (strcasecmp(type, "POIS") == 0) {
     1174    // for a bare name (ISIS, HERM), use the full string length.
     1175    // otherwise, use the length up to the first '('
     1176    int nameLength = strlen(type);
     1177    char *ptr = strchr(type, '(');
     1178    if (ptr) {
     1179        nameLength = ptr - type;
     1180    }
     1181
     1182    if (strncasecmp(type, "POIS", nameLength) == 0) {
    10821183        return PM_SUBTRACTION_KERNEL_POIS;
    10831184    }
    1084     if (strcasecmp(type, "ISIS") == 0) {
     1185    if (strncasecmp(type, "ISIS", nameLength) == 0) {
    10851186        return PM_SUBTRACTION_KERNEL_ISIS;
    10861187    }
    1087     if (strcasecmp(type, "HERM") == 0) {
     1188    if (strncasecmp(type, "ISIS_RADIAL", nameLength) == 0) {
     1189        return PM_SUBTRACTION_KERNEL_ISIS_RADIAL;
     1190    }
     1191    if (strncasecmp(type, "HERM", nameLength) == 0) {
    10881192        return PM_SUBTRACTION_KERNEL_HERM;
    10891193    }
    1090     if (strcasecmp(type, "DECONV_HERM") == 0) {
     1194    if (strncasecmp(type, "DECONV_HERM", nameLength) == 0) {
    10911195        return PM_SUBTRACTION_KERNEL_DECONV_HERM;
    10921196    }
    1093     if (strcasecmp(type, "SPAM") == 0) {
     1197    if (strncasecmp(type, "SPAM", nameLength) == 0) {
    10941198        return PM_SUBTRACTION_KERNEL_SPAM;
    10951199    }
    1096     if (strcasecmp(type, "FRIES") == 0) {
     1200    if (strncasecmp(type, "FRIES", nameLength) == 0) {
    10971201        return PM_SUBTRACTION_KERNEL_FRIES;
    10981202    }
    1099     if (strcasecmp(type, "GUNK") == 0) {
     1203    if (strncasecmp(type, "GUNK", nameLength) == 0) {
    11001204        return PM_SUBTRACTION_KERNEL_GUNK;
    11011205    }
    1102     if (strcasecmp(type, "RINGS") == 0) {
     1206    // note that GUNK has a somewhat different description
     1207    if (strncasecmp(type, "GUNK=ISIS", nameLength) == 0) {
     1208        return PM_SUBTRACTION_KERNEL_GUNK;
     1209    }
     1210    if (strncasecmp(type, "RINGS", nameLength) == 0) {
    11031211        return PM_SUBTRACTION_KERNEL_RINGS;
    11041212    }
Note: See TracChangeset for help on using the changeset viewer.