IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 8, 2010, 2:24:01 PM (17 years ago)
Author:
Paul Price
Message:

Dual convolution seems to be working again!

File:
1 edited

Legend:

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

    r26505 r26547  
    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);
    9595    }
     
    132132            kernels->preCalc->data[index] = NULL;
    133133            kernels->penalties->data.F32[index] = kernels->penalty * PS_SQR(PS_SQR(u) + PS_SQR(v));
    134             if (!isfinite(kernels->penalties->data.F32[index])) {
    135                 psAbort ("invalid penalty");
    136             }
     134            psAssert(isfinite(kernels->penalties->data.F32[index]), "Invalid penalty");
    137135
    138136            psTrace("psModules.imcombine", 7, "Kernel %d: %d %d\n", index, u, v);
     
    154152    double moment = 0.0;    // Moment, for penalty
    155153    for (int v = -size; v <= size; v++) {
    156         for (int u = -size; u <= size; u++) {
    157             double value = preCalc->kernel->kernel[v][u];
    158             moment += value * PS_SQR((PS_SQR(u) + PS_SQR(v)));
    159         }
     154        for (int u = -size; u <= size; u++) {
     155            double value = preCalc->kernel->kernel[v][u];
     156            moment += value * PS_SQR((PS_SQR(u) + PS_SQR(v)));
     157        }
    160158    }
    161159
     
    171169
    172170    for (int v = -size; v <= size; v++) {
    173         for (int u = -size; u <= size; u++) {
    174             sum += preCalc->kernel->kernel[v][u];
    175             min = PS_MIN(preCalc->kernel->kernel[v][u], min);
    176             max = PS_MAX(preCalc->kernel->kernel[v][u], max);
    177         }
     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        }
    178176    }
    179177#if 0
     
    183181    // only even terms have non-zero sums
    184182    if ((uOrder % 2 == 0) && (vOrder % 2 == 0)) {
    185         moment /= sum;
     183        moment /= sum;
    186184    } else {
    187         moment = 0.0;
     185        moment = 0.0;
    188186    }
    189187
     
    193191
    194192    if (AlardLuptonStyle && (uOrder % 2 == 0 && vOrder % 2 == 0)) {
    195         zeroNull = true;
     193        zeroNull = true;
    196194    }
    197195    if (!AlardLuptonStyle && (uOrder == 0 && vOrder == 0)) {
    198         zeroNull = true;
     196        zeroNull = true;
    199197    }
    200198    if ((uOrder % 2) || (vOrder % 2)) {
    201         // scale2D = 1.0 / (preCalc->kernel->image->numCols * preCalc->kernel->image->numRows * max);
    202         scale2D = 1.0 / max;
    203         scale1D = sqrt(scale2D);
     199        // scale2D = 1.0 / (preCalc->kernel->image->numCols * preCalc->kernel->image->numRows * max);
     200        scale2D = 1.0 / max;
     201        scale1D = sqrt(scale2D);
    204202    }
    205203
     
    208206    psBinaryOp(preCalc->kernel->image, preCalc->kernel->image, "*", psScalarAlloc(scale2D, PS_TYPE_F32));
    209207    if (zeroNull) {
    210         preCalc->kernel->kernel[0][0] -= 1.0;
     208        preCalc->kernel->kernel[0][0] -= 1.0;
    211209    }
    212210
     
    216214    max = FLT_MIN;
    217215    for (int v = -size; v <= size; v++) {
    218         for (int u = -size; u <= size; u++) {
    219             sum += preCalc->kernel->kernel[v][u];
    220             min = PS_MIN(preCalc->kernel->kernel[v][u], min);
    221             max = PS_MAX(preCalc->kernel->kernel[v][u], max);
    222         }
     216        for (int u = -size; u <= size; u++) {
     217            sum += preCalc->kernel->kernel[v][u];
     218            min = PS_MIN(preCalc->kernel->kernel[v][u], min);
     219            max = PS_MAX(preCalc->kernel->kernel[v][u], max);
     220        }
    223221    }
    224222    fprintf(stderr, "%d mod: %lf, null: %f, min: %lf, max: %lf, scale: %f\n", index, sum, preCalc->kernel->kernel[0][0], min, max, scale2D);
     
    229227    kernels->v->data.S32[index] = vOrder;
    230228    if (kernels->preCalc->data[index]) {
    231         psFree(kernels->preCalc->data[index]);
     229        psFree(kernels->preCalc->data[index]);
    232230    }
    233231    kernels->preCalc->data[index] = preCalc;
    234232    kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment);
    235233    if (!isfinite(kernels->penalties->data.F32[index])) {
    236         psAbort ("invalid penalty");
     234        psAbort ("invalid penalty");
    237235    }
    238236
    239237    psTrace("psModules.imcombine", 7, "Kernel %d: %f %d %d %f\n", index,
    240             fwhm, uOrder, vOrder, fabsf(moment));
     238            fwhm, uOrder, vOrder, fabsf(moment));
    241239
    242240    return true;
     
    259257    psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32);
    260258    for (int i = 0; i < fwhmsIN->n; i++) {
    261         if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
    262         psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
    263         psVectorAppend(orders, ordersIN->data.S32[i]);
     259        if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
     260        psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
     261        psVectorAppend(orders, ordersIN->data.S32[i]);
    264262    }
    265263
     
    288286        for (int uOrder = 0; uOrder <= orders->data.S32[i]; uOrder++) {
    289287            for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) {
    290 
    291288                pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_ISIS, uOrder, vOrder, size, sigma); // structure to hold precalculated values
    292                 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);
     289                pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);
    293290            }
    294291        }
     
    299296
    300297pmSubtractionKernels *pmSubtractionKernelsHERM(int size, int spatialOrder,
    301                                                const psVector *fwhmsIN, const psVector *ordersIN,
    302                                                float penalty, pmSubtractionMode mode)
     298                                               const psVector *fwhmsIN, const psVector *ordersIN,
     299                                               float penalty, pmSubtractionMode mode)
    303300{
    304301    PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL);
     
    314311    psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32);
    315312    for (int i = 0; i < fwhmsIN->n; i++) {
    316         if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
    317         psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
    318         psVectorAppend(orders, ordersIN->data.S32[i]);
     313        if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
     314        psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
     315        psVectorAppend(orders, ordersIN->data.S32[i]);
    319316    }
    320317
     
    342339            for (int vOrder = 0; vOrder <= orders->data.S32[i] - uOrder; vOrder++, index++) {
    343340                pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values
    344                 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);
     341                pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);
    345342            }
    346343        }
     
    351348
    352349pmSubtractionKernels *pmSubtractionKernelsDECONV_HERM(int size, int spatialOrder,
    353                                                      const psVector *fwhmsIN, const psVector *ordersIN,
    354                                                      float penalty, pmSubtractionMode mode)
     350                                                     const psVector *fwhmsIN, const psVector *ordersIN,
     351                                                     float penalty, pmSubtractionMode mode)
    355352{
    356353    PS_ASSERT_VECTOR_NON_NULL(fwhmsIN, NULL);
     
    366363    psVector *orders = psVectorAllocEmpty (ordersIN->n, PS_TYPE_S32);
    367364    for (int i = 0; i < fwhmsIN->n; i++) {
    368         if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
    369         psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
    370         psVectorAppend(orders, ordersIN->data.S32[i]);
     365        if (fwhmsIN->data.F32[i] <= FLT_EPSILON) continue;
     366        psVectorAppend(fwhms, fwhmsIN->data.F32[i]);
     367        psVectorAppend(orders, ordersIN->data.S32[i]);
    371368    }
    372369
     
    405402                pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc(PM_SUBTRACTION_KERNEL_HERM, uOrder, vOrder, size, sigma); // structure to hold precalculated values
    406403
    407                 // save the generated 2D kernel as the target, deconvolve it by Gaussian, replacing the generated 2D kernel
    408                 psKernel *kernelTarget = preCalc->kernel;
     404                // save the generated 2D kernel as the target, deconvolve it by Gaussian, replacing the generated 2D kernel
     405                psKernel *kernelTarget = preCalc->kernel;
    409406                preCalc->kernel = pmSubtractionDeconvolveKernel(kernelTarget, kernelGauss); // Kernel
    410407
    411                 // XXX do we use Alard-Lupton normalization (last param true) or not?
    412                 pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);
    413 
    414                 // XXXX test demo that deconvolved kernel is valid
     408                // XXX do we use Alard-Lupton normalization (last param true) or not?
     409                pmSubtractionKernelPreCalcNormalize (kernels, preCalc, index, size, uOrder, vOrder, fwhms->data.F32[i], true);
     410
     411                // XXXX test demo that deconvolved kernel is valid
    415412# if 1
    416                 psImage *kernelConv = psImageConvolveFFT(NULL, preCalc->kernel->image, NULL, 0, kernelGauss);
    417                 psArrayAdd (deconKernels, 100, kernelConv);
    418                 psFree (kernelConv);
    419 
    420                 if (!uOrder && !vOrder){
    421                     pmSubtractionVisualShowSubtraction (kernelTarget->image, preCalc->kernel->image, kernelConv);
    422                 }
     413                psImage *kernelConv = psImageConvolveFFT(NULL, preCalc->kernel->image, NULL, 0, kernelGauss);
     414                psArrayAdd (deconKernels, 100, kernelConv);
     415                psFree (kernelConv);
     416
     417                if (!uOrder && !vOrder){
     418                    pmSubtractionVisualShowSubtraction (kernelTarget->image, preCalc->kernel->image, kernelConv);
     419                }
    423420# endif
    424421            }
     
    429426    psImage *dot = psImageAlloc(deconKernels->n, deconKernels->n, PS_TYPE_F32);
    430427    for (int i = 0; i < deconKernels->n; i++) {
    431         for (int j = 0; j <= i; j++) {
    432             psImage *t1 = deconKernels->data[i];
    433             psImage *t2 = deconKernels->data[j];
    434 
    435             double sum = 0.0;
    436             for (int iy = 0; iy < t1->numRows; iy++) {
    437                 for (int ix = 0; ix < t1->numCols; ix++) {
    438                     sum += t1->data.F32[iy][ix] * t2->data.F32[iy][ix];
    439                 }
    440             }
    441             dot->data.F32[j][i] = sum;
    442             dot->data.F32[i][j] = sum;
    443         }
     428        for (int j = 0; j <= i; j++) {
     429            psImage *t1 = deconKernels->data[i];
     430            psImage *t2 = deconKernels->data[j];
     431
     432            double sum = 0.0;
     433            for (int iy = 0; iy < t1->numRows; iy++) {
     434                for (int ix = 0; ix < t1->numCols; ix++) {
     435                    sum += t1->data.F32[iy][ix] * t2->data.F32[iy][ix];
     436                }
     437            }
     438            dot->data.F32[j][i] = sum;
     439            dot->data.F32[i][j] = sum;
     440        }
    444441    }
    445442    pmSubtractionVisualShowSubtraction (dot, NULL, NULL);
     
    494491    switch (type) {
    495492      case PM_SUBTRACTION_KERNEL_ISIS:
    496         preCalc->xKernel = pmSubtractionKernelISIS(sigma, uOrder, size);
    497         preCalc->yKernel = pmSubtractionKernelISIS(sigma, vOrder, size);
    498         preCalc->uCoords = NULL;
    499         preCalc->vCoords = NULL;
    500         preCalc->poly    = NULL;
    501         break;
     493        preCalc->xKernel = pmSubtractionKernelISIS(sigma, uOrder, size);
     494        preCalc->yKernel = pmSubtractionKernelISIS(sigma, vOrder, size);
     495        preCalc->uCoords = NULL;
     496        preCalc->vCoords = NULL;
     497        preCalc->poly    = NULL;
     498        break;
    502499      case PM_SUBTRACTION_KERNEL_HERM:
    503         preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size);
    504         preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size);
    505         preCalc->uCoords = NULL;
    506         preCalc->vCoords = NULL;
    507         preCalc->poly    = NULL;
    508         break;
     500        preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size);
     501        preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size);
     502        preCalc->uCoords = NULL;
     503        preCalc->vCoords = NULL;
     504        preCalc->poly    = NULL;
     505        break;
    509506      case PM_SUBTRACTION_KERNEL_DECONV_HERM:
    510         preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size);
    511         preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size);
    512         preCalc->uCoords = NULL;
    513         preCalc->vCoords = NULL;
    514         preCalc->poly    = NULL;
    515         break;
     507        preCalc->xKernel = pmSubtractionKernelHERM(sigma, uOrder, size);
     508        preCalc->yKernel = pmSubtractionKernelHERM(sigma, vOrder, size);
     509        preCalc->uCoords = NULL;
     510        preCalc->vCoords = NULL;
     511        preCalc->poly    = NULL;
     512        break;
    516513      case PM_SUBTRACTION_KERNEL_RINGS:
    517         // the RINGS kernel uses the uCoords, vCoords, and poly elements of the structure
    518         // we allocate these vectors here, but leave the kernel generation to the main function
    519         preCalc->xKernel = NULL;
    520         preCalc->yKernel = NULL;
    521         preCalc->kernel  = NULL;
    522         preCalc->uCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // u coords
    523         preCalc->vCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // v coords
    524         preCalc->poly    = psVectorAllocEmpty(size, PS_TYPE_F32); // Polynomial
    525         return preCalc;
     514        // the RINGS kernel uses the uCoords, vCoords, and poly elements of the structure
     515        // we allocate these vectors here, but leave the kernel generation to the main function
     516        preCalc->xKernel = NULL;
     517        preCalc->yKernel = NULL;
     518        preCalc->kernel  = NULL;
     519        preCalc->uCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // u coords
     520        preCalc->vCoords = psVectorAllocEmpty(size, PS_TYPE_S32); // v coords
     521        preCalc->poly    = psVectorAllocEmpty(size, PS_TYPE_F32); // Polynomial
     522        return preCalc;
    526523      default:
    527         psAbort("programming error: invalid type for PreCalc kernel");
     524        psAbort("programming error: invalid type for PreCalc kernel");
    528525    }
    529526
     
    532529    // generate 2D kernel from 1D realizations
    533530    for (int v = -size, y = 0; v <= size; v++, y++) {
    534         for (int u = -size, x = 0; u <= size; u++, x++) {
    535             preCalc->kernel->kernel[v][u] = preCalc->xKernel->data.F32[x] * preCalc->yKernel->data.F32[y]; // Value of kernel
    536         }
    537     }
    538    
     531        for (int u = -size, x = 0; u <= size; u++, x++) {
     532            preCalc->kernel->kernel[v][u] = preCalc->xKernel->data.F32[x] * preCalc->yKernel->data.F32[y]; // Value of kernel
     533        }
     534    }
     535
    539536    return preCalc;
    540537}
     
    864861            for (int vOrder = 0; vOrder <= (i == 0 ? 0 : ringsOrder - uOrder); vOrder++, index++) {
    865862
    866                 pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc (PM_SUBTRACTION_KERNEL_RINGS, 0, 0, RINGS_BUFFER, 0.0);
     863                pmSubtractionKernelPreCalc *preCalc = pmSubtractionKernelPreCalcAlloc (PM_SUBTRACTION_KERNEL_RINGS, 0, 0, RINGS_BUFFER, 0.0);
    867864                double moment = 0.0;    // Moment, for penalty
    868865
     
    870867                    // Central pixel is easy
    871868                    preCalc->uCoords->data.S32[0] = 0;
    872                     preCalc->vCoords->data.S32[0] = 0;
     869                    preCalc->vCoords->data.S32[0] = 0;
    873870                    preCalc->poly->data.F32[0] = 1.0;
    874871                    preCalc->uCoords->n = 1;
    875                     preCalc->vCoords->n = 1;
    876                     preCalc->poly->n = 1;
     872                    preCalc->vCoords->n = 1;
     873                    preCalc->poly->n = 1;
    877874                    radiusLast = 0;
    878875                    moment = 0.0;
     
    931928                kernels->v->data.S32[index] = vOrder;
    932929                kernels->penalties->data.F32[index] = kernels->penalty * fabsf(moment);
    933                 if (!isfinite(kernels->penalties->data.F32[index])) {
    934                     psAbort ("invalid penalty");
    935                 }
     930                if (!isfinite(kernels->penalties->data.F32[index])) {
     931                    psAbort ("invalid penalty");
     932                }
    936933
    937934                psTrace("psModules.imcombine", 7, "Kernel %d: %d %d %d\n", index,
     
    10261023            type = PM_SUBTRACTION_KERNEL_GUNK;
    10271024            psAbort("Deciphering GUNK kernels (%s) is not currently supported.", description);
    1028         } 
    1029 
    1030         type = pmSubtractionKernelsTypeFromString (description);
    1031         psAssert (type != PM_SUBTRACTION_KERNEL_NONE, "must  be ISIS, HERM or DECONV_HERM");
    1032 
    1033         char *ptr = NULL;
    1034         switch (type) {
    1035           case PM_SUBTRACTION_KERNEL_ISIS:
    1036           case PM_SUBTRACTION_KERNEL_HERM:
    1037             ptr = (char*) description + 5;    // Eat "ISIS(" or "HERM("
    1038             break;
    1039           case PM_SUBTRACTION_KERNEL_DECONV_HERM:
    1040             ptr = (char*) description + 12;    // Eat "DECONV_HERM("
    1041             break;
    1042           default:
    1043             psAbort("programming error: invalid kernel type");
    1044         }
    1045         PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt);
    1046 
    1047         // Count the number of Gaussians
    1048         int numGauss = 0;
    1049         for (char *string = ptr; string; string = strchr(string + 1, '(')) {
    1050             numGauss++;
    1051         }
    1052 
    1053         fwhms = psVectorAlloc(numGauss, PS_TYPE_F32);
    1054         orders = psVectorAlloc(numGauss, PS_TYPE_S32);
    1055 
    1056         for (int i = 0; i < numGauss; i++) {
    1057             ptr++;                  // Eat the '('
    1058             PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234,"
    1059             PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)"
    1060         }
    1061 
    1062         ptr++;                      // Eat ','
    1063         PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt);
    1064         penalty = parseStringFloat(ptr);
    1065 
    1066         return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
    1067     } 
     1025        }
     1026
     1027        type = pmSubtractionKernelsTypeFromString (description);
     1028        psAssert (type != PM_SUBTRACTION_KERNEL_NONE, "must  be ISIS, HERM or DECONV_HERM");
     1029
     1030        char *ptr = NULL;
     1031        switch (type) {
     1032          case PM_SUBTRACTION_KERNEL_ISIS:
     1033          case PM_SUBTRACTION_KERNEL_HERM:
     1034            ptr = (char*) description + 5;    // Eat "ISIS(" or "HERM("
     1035            break;
     1036          case PM_SUBTRACTION_KERNEL_DECONV_HERM:
     1037            ptr = (char*) description + 12;    // Eat "DECONV_HERM("
     1038            break;
     1039          default:
     1040            psAbort("programming error: invalid kernel type");
     1041        }
     1042        PARSE_STRING_NUMBER(size, ptr, ',', parseStringInt);
     1043
     1044        // Count the number of Gaussians
     1045        int numGauss = 0;
     1046        for (char *string = ptr; string; string = strchr(string + 1, '(')) {
     1047            numGauss++;
     1048        }
     1049
     1050        fwhms = psVectorAlloc(numGauss, PS_TYPE_F32);
     1051        orders = psVectorAlloc(numGauss, PS_TYPE_S32);
     1052
     1053        for (int i = 0; i < numGauss; i++) {
     1054            ptr++;                  // Eat the '('
     1055            PARSE_STRING_NUMBER(fwhms->data.F32[i], ptr, ',', parseStringFloat); // Eat "1.234,"
     1056            PARSE_STRING_NUMBER(orders->data.S32[i], ptr, ')', parseStringInt); // Eat "3)"
     1057        }
     1058
     1059        ptr++;                      // Eat ','
     1060        PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt);
     1061        penalty = parseStringFloat(ptr);
     1062
     1063        return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
     1064    }
    10681065
    10691066    if (strncmp(description, "RINGS", 5) == 0) {
     
    10751072        PARSE_STRING_NUMBER(spatialOrder, ptr, ',', parseStringInt);
    10761073        PARSE_STRING_NUMBER(penalty, ptr, ')', parseStringInt);
    1077         return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
    1078     } 
     1074        return pmSubtractionKernelsGenerate(type, size, spatialOrder, fwhms, orders, inner, binning, ringsOrder, penalty, mode);
     1075    }
    10791076
    10801077    psAbort("Deciphering kernels other than ISIS, HERM, DECONV_HERM or RINGS is not currently supported.");
Note: See TracChangeset for help on using the changeset viewer.