IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 10, 2010, 7:34:39 PM (16 years ago)
Author:
eugene
Message:

updates from eam_branches/20091201 (substantially changes to the kernel matching code; updates to pmDetection container, added pmPattern, etc)

File:
1 edited

Legend:

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

    r26584 r26893  
    2121#include "pmSubtractionStamps.h"
    2222#include "pmSubtractionEquation.h"
     23#include "pmSubtractionVisual.h"
    2324#include "pmSubtractionThreads.h"
    2425
     
    6364}
    6465
    65 // Contribute to an image of the solved kernel component for ISIS
    66 static void solvedKernelISIS(psKernel *kernel, // Kernel, updated
    67                              const pmSubtractionKernels *kernels, // Kernel basis functions
    68                              float value,                         // Normalisation value for basis function
    69                              int index                  // Index of basis function of interest
     66// Contribute to an image of the solved kernel component using the preCalculated image
     67static void solvedKernelPreCalc(psKernel *kernel, // Kernel, updated
     68                                const pmSubtractionKernels *kernels, // Kernel basis functions
     69                                float value,                         // Normalisation value for basis function
     70                                int index                  // Index of basis function of interest
    7071    )
    7172{
    7273    int size = kernels->size;           // Kernel half-size
    73     psArray *preCalc = kernels->preCalc->data[index]; // Precalculated values
     74    pmSubtractionKernelPreCalc *preCalc = kernels->preCalc->data[index]; // Precalculated values
    7475#if 0
    75     psVector *xKernel = preCalc->data[0]; // Kernel in x
    76     psVector *yKernel = preCalc->data[1]; // Kernel in y
    7776    // Iterating over the kernel
    7877    for (int y = 0, v = -size; v <= size; y++, v++) {
    79         float yValue = value * yKernel->data.F32[y];
     78        float yValue = value * preCalc->yKernel->data.F32[y];
    8079        for (int x = 0, u = -size; u <= size; x++, u++) {
    81             kernel->kernel[v][u] +=  yValue * xKernel->data.F32[x];
     80            kernel->kernel[v][u] +=  yValue * preCalc->xKernel->data.F32[x];
    8281        }
    8382    }
     
    8786    }
    8887#else
    89     psKernel *k = preCalc->data[2]; // Kernel image
    9088    for (int v = -size; v <= size; v++) {
    9189        for (int u = -size; u <= size; u++) {
    92             kernel->kernel[v][u] +=  value * k->kernel[v][u];
     90            kernel->kernel[v][u] +=  value * preCalc->kernel->kernel[v][u];
    9391        }
    9492    }
     
    119117    for (int i = 0; i < numKernels; i++) {
    120118        double value = p_pmSubtractionSolutionCoeff(kernels, polyValues, i, wantDual); // Polynomial value
     119        if (wantDual) {
     120            // The model is built with the dual convolution terms added, so to produce zero residual the
     121            // equation results in negative coefficients which we must undo.
     122            value *= -1.0;
     123        }
    121124
    122125        switch (kernels->type) {
     
    149152          case PM_SUBTRACTION_KERNEL_GUNK: {
    150153              if (i < kernels->inner) {
    151                   solvedKernelISIS(kernel, kernels, value, i);
     154                  solvedKernelPreCalc(kernel, kernels, value, i);
    152155              } else {
    153156                  // Using delta function
     
    159162              break;
    160163          }
    161           case PM_SUBTRACTION_KERNEL_ISIS: {
    162               solvedKernelISIS(kernel, kernels, value, i);
     164          case PM_SUBTRACTION_KERNEL_ISIS:
     165          case PM_SUBTRACTION_KERNEL_ISIS_RADIAL:
     166          case PM_SUBTRACTION_KERNEL_HERM:
     167          case PM_SUBTRACTION_KERNEL_DECONV_HERM: {
     168              solvedKernelPreCalc(kernel, kernels, value, i);
    163169              break;
    164170          }
    165171          case PM_SUBTRACTION_KERNEL_RINGS: {
    166               psArray *preCalc = kernels->preCalc->data[i]; // Precalculated data
    167               psVector *uCoords = preCalc->data[0]; // u coordinates
    168               psVector *vCoords = preCalc->data[1]; // v coordinates
    169               psVector *poly = preCalc->data[2]; // Polynomial values
    170               int num = uCoords->n;     // Number of pixels
     172              pmSubtractionKernelPreCalc *preCalc = kernels->preCalc->data[i]; // Precalculated kernels
     173              int num = preCalc->uCoords->n;     // Number of pixels
    171174
    172175              for (int j = 0; j < num; j++) {
    173                   int u = uCoords->data.S32[j], v = vCoords->data.S32[j]; // Kernel coordinates
    174                   kernel->kernel[v][u] += poly->data.F32[j] * value;
     176                  int u = preCalc->uCoords->data.S32[j];
     177                  int v = preCalc->vCoords->data.S32[j]; // Kernel coordinates
     178                  kernel->kernel[v][u] += preCalc->poly->data.F32[j] * value;
    175179              }
    176180              // Photometric scaling is built into the kernel --- no subtraction!
     
    419423                    *target |= maskBad;
    420424                } else if (*source & subConvPoor) {
     425                    *target &= ~maskBad;
    421426                    *target |= maskPoor;
     427                } else {
     428                    *target &= ~maskBad & ~maskPoor;
    422429                }
    423430            }
     
    454461#endif
    455462
    456 // Convolve a stamp using an ISIS kernel basis function
    457 static psKernel *convolveStampISIS(const psKernel *image, // Image to convolve
    458                                    const pmSubtractionKernels *kernels, // Kernel basis functions
    459                                    int index,                            // Index of basis function of interest
    460                                    int footprint                         // Half-size of stamp
     463// Convolve a stamp using a pre-calculated kernel basis function
     464static psKernel *convolveStampPreCalc(const psKernel *image, // Image to convolve
     465                                      const pmSubtractionKernels *kernels, // Kernel basis functions
     466                                      int index,                            // Index of basis function of interest
     467                                      int footprint                         // Half-size of stamp
    461468    )
    462469{
    463     psArray *preCalc = kernels->preCalc->data[index]; // Precalculated data
     470    pmSubtractionKernelPreCalc *preCalc = kernels->preCalc->data[index]; // Precalculated data
    464471#if 0
    465472    // Convolving using separable convolution
    466     psVector *xKernel = preCalc->data[0]; // Kernel in x
    467     psVector *yKernel = preCalc->data[1]; // Kernel in y
    468473    int size = kernels->size;     // Size of kernel
    469474
     
    477482            float value = 0.0;    // Value of convolved pixel
    478483            int uMin = x - size, uMax = x + size; // Range for u
    479             psF32 *xKernelData = &xKernel->data.F32[xKernel->n - 1]; // Kernel values
     484            psF32 *xKernelData = &preCalc->xKernel->data.F32[xKernel->n - 1]; // Kernel values
    480485            psF32 *imageData = &image->kernel[y][uMin]; // Image values
    481486            for (int u = uMin; u <= uMax; u++, xKernelData--, imageData++) {
     
    492497            float value = 0.0;    // Value of convolved pixel
    493498            int vMin = y - size, vMax = y + size; // Range for v
    494             psF32 *yKernelData = &yKernel->data.F32[yKernel->n - 1]; // Kernel values
     499            psF32 *yKernelData = &preCalc->yKernel->data.F32[yKernel->n - 1]; // Kernel values
    495500            psF32 *imageData = &temp->kernel[x][vMin]; // Image values; NOTE: wrong way!
    496501            for (int v = vMin; v <= vMax; v++, yKernelData--, imageData++) {
     
    509514#else
    510515    // Convolving using precalculated kernel
    511     return p_pmSubtractionConvolveStampPrecalc(image, preCalc->data[2]);
     516    return p_pmSubtractionConvolveStampPrecalc(image, preCalc->kernel);
    512517#endif
    513518}
     
    525530    int x0 = - image->xMin, y0 = - image->yMin; // Position of centre of convolved image
    526531    psKernel *convolved = psKernelAllocFromImage(conv, x0, y0); // Kernel version
     532
     533    // pmSubtractionVisualShowSubtraction(image->image, kernel->image, conv);
     534
    527535    psFree(conv);
    528536    return convolved;
     
    569577}
    570578
     579void p_pmSubtractionPolynomialNormCoords(float *xOut, float *yOut, float xIn, float yIn,
     580                                         int xMin, int xMax, int yMin, int yMax)
     581{
     582    float xNormSize = xMax - xMin, yNormSize = yMax - yMin; // Size to use for normalisation
     583    *xOut = 2.0 * (float)(xIn - xMin - xNormSize/2.0) / xNormSize;
     584    *yOut = 2.0 * (float)(yIn - yMin - yNormSize/2.0) / yNormSize;
     585    return;
     586}
     587
    571588psImage *p_pmSubtractionPolynomialFromCoords(psImage *output, const pmSubtractionKernels *kernels,
    572                                              int numCols, int numRows, int x, int y)
     589                                             int x, int y)
    573590{
    574591    assert(kernels);
    575     assert(numCols > 0 && numRows > 0);
    576 
    577     // Size to use when calculating normalised coordinates (different from actual size when convolving
    578     // subimage)
    579     int xNormSize = (kernels->numCols > 0 ? kernels->numCols : numCols);
    580     int yNormSize = (kernels->numRows > 0 ? kernels->numRows : numRows);
    581 
    582     // Normalised coordinates
    583     float yNorm = 2.0 * (float)(y - yNormSize/2.0) / (float)yNormSize;
    584     float xNorm = 2.0 * (float)(x - xNormSize/2.0) / (float)xNormSize;
    585 
     592
     593    float xNorm, yNorm;                 // Normalised coordinates
     594    p_pmSubtractionPolynomialNormCoords(&xNorm, &yNorm, x, y,
     595                                        kernels->xMin, kernels->xMax, kernels->yMin, kernels->yMax);
    586596    return p_pmSubtractionPolynomial(output, kernels->spatialOrder, xNorm, yNorm);
    587597}
     
    664674          if (index < kernels->inner) {
    665675              // Photometric scaling is already built in to the precalculated kernel
    666               return convolveStampISIS(image, kernels, index, footprint);
     676              return convolveStampPreCalc(image, kernels, index, footprint);
    667677          }
    668678          // Using delta function
     
    673683          return convolved;
    674684      }
    675       case PM_SUBTRACTION_KERNEL_ISIS: {
    676           return convolveStampISIS(image, kernels, index, footprint);
    677       }
     685      case PM_SUBTRACTION_KERNEL_ISIS:
     686      case PM_SUBTRACTION_KERNEL_ISIS_RADIAL:
     687      case PM_SUBTRACTION_KERNEL_HERM:
     688      case PM_SUBTRACTION_KERNEL_DECONV_HERM: {
     689            return convolveStampPreCalc(image, kernels, index, footprint);
     690        }
    678691      case PM_SUBTRACTION_KERNEL_RINGS: {
    679           psKernel *convolved = psKernelAlloc(-footprint, footprint,
    680                                               -footprint, footprint); // Convolved image
    681           psArray *preCalc = kernels->preCalc->data[index]; // Precalculated data
    682           psVector *uCoords = preCalc->data[0]; // u coordinates
    683           psVector *vCoords = preCalc->data[1]; // v coordinates
    684           psVector *poly = preCalc->data[2]; // Polynomial values
    685           int num = uCoords->n;         // Number of pixels
    686           psS32 *uData = uCoords->data.S32, *vData = vCoords->data.S32; // Dereference u,v coordinates
    687           psF32 *polyData = poly->data.F32; // Dereference polynomial values
     692          psKernel *convolved = psKernelAlloc(-footprint, footprint, -footprint, footprint); // Convolved image
     693          pmSubtractionKernelPreCalc *preCalc = kernels->preCalc->data[index]; // Precalculated data
     694
     695          int num = preCalc->uCoords->n;         // Number of pixels
     696          psS32 *uData = preCalc->uCoords->data.S32; // Dereference v coordinate
     697          psS32 *vData = preCalc->vCoords->data.S32; // Dereference u coordinate
     698          psF32 *polyData = preCalc->poly->data.F32; // Dereference polynomial values
    688699          psF32 **imageData = image->kernel;  // Dereference image
    689700          psF32 **convData = convolved->kernel; // Dereference convolved image
     
    765776
    766777
    767 
    768 
    769778int pmSubtractionRejectStamps(pmSubtractionKernels *kernels, pmSubtractionStampList *stamps,
    770779                              const psVector *deviations, psImage *subMask, float sigmaRej)
     
    860869    int numGood = 0;                    // Number of good stamps
    861870    double newMean = 0.0;               // New mean
     871    psString log = NULL;                // Log message
     872    psStringAppend(&log, "Rejecting stamps, mean = %f, threshold = %f\n", mean, limit);
    862873    for (int i = 0; i < stamps->num; i++) {
    863874        pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest
     
    872883                // Mask out the stamp in the image so you it's not found again
    873884                psTrace("psModules.imcombine", 3, "Rejecting stamp %d (%d,%d)\n", i,
    874                         (int)(stamp->x + 0.5), (int)(stamp->y + 0.5));
     885                        (int)(stamp->x - 0.5), (int)(stamp->y - 0.5));
     886                psStringAppend(&log, "Stamp %d (%d,%d): %f\n", i,
     887                               (int)(stamp->x - 0.5), (int)(stamp->y - 0.5),
     888                               fabsf(deviations->data.F32[i] - mean));
    875889                numRejected++;
    876890                for (int y = stamp->y - footprint; y <= stamp->y + footprint; y++) {
     
    895909                psFree(stamp->weight);
    896910                stamp->image1 = stamp->image2 = stamp->weight = NULL;
    897                 psFree(stamp->matrix1);
    898                 psFree(stamp->matrix2);
    899                 psFree(stamp->matrixX);
    900                 stamp->matrix1 = stamp->matrix2 = stamp->matrixX = NULL;
    901                 psFree(stamp->vector1);
    902                 psFree(stamp->vector2);
    903                 stamp->vector1 = stamp->vector2 = NULL;
     911                psFree(stamp->matrix);
     912                stamp->matrix = NULL;
     913                psFree(stamp->vector);
     914                stamp->vector = NULL;
    904915            } else {
    905916                numGood++;
     
    910921    }
    911922    newMean /= numGood;
     923
     924    if (numRejected == 0) {
     925        psStringAppend(&log, "<none>\n");
     926    }
     927    psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "%s", log);
     928    psFree(log);
    912929
    913930    if (ds9) {
     
    9951012    psVector *backup = psVectorCopy(NULL, solution, PS_TYPE_F64);  // Backup version
    9961013
    997     int num = wantDual ? solution->n - 1 : solution->n; // Number of kernel basis functions
     1014    int num = kernels->num;            // Number of kernel basis functions
    9981015
    9991016    psImage *polyValues = p_pmSubtractionPolynomial(NULL, kernels->spatialOrder, x, y); // Solved polynomial
     
    10601077    // Only generate polynomial values every kernel footprint, since we have already assumed
    10611078    // (with the stamps) that it does not vary rapidly on this scale.
    1062     psImage *polyValues = p_pmSubtractionPolynomialFromCoords(NULL, kernels, numCols, numRows,
    1063                                                               xMin + x0 + size + 1,
    1064                                                               yMin + y0 + size + 1);
     1079    psImage *polyValues = p_pmSubtractionPolynomialFromCoords(NULL, kernels, xMin + x0 + size + 1,
     1080                                                              yMin + y0 + size + 1);        // Polynomial
    10651081    float background = doBG ? p_pmSubtractionSolutionBackground(kernels, polyValues) : 0.0; // Background term
    10661082
     
    11371153bool pmSubtractionConvolve(pmReadout *out1, pmReadout *out2, const pmReadout *ro1, const pmReadout *ro2,
    11381154                           psImage *subMask, int stride, psImageMaskType maskBad, psImageMaskType maskPoor,
    1139                            float poorFrac, float kernelError, const psRegion *region,
     1155                           float poorFrac, float kernelError, float covarFrac, const psRegion *region,
    11401156                           const pmSubtractionKernels *kernels, bool doBG, bool useFFT)
    11411157{
     
    11461162        PM_ASSERT_READOUT_NON_NULL(ro1, false);
    11471163        PM_ASSERT_READOUT_IMAGE(ro1, false);
     1164        PM_ASSERT_READOUT_IMAGE(out1, false);
    11481165        numCols = ro1->image->numCols;
    11491166        numRows = ro1->image->numRows;
     
    11551172        PM_ASSERT_READOUT_NON_NULL(ro2, false);
    11561173        PM_ASSERT_READOUT_IMAGE(ro2, false);
     1174        PM_ASSERT_READOUT_IMAGE(out2, false);
    11571175        if (numCols == 0 && numRows == 0) {
    11581176            numCols = ro2->image->numCols;
     
    11771195    PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(kernelError, 0.0, false);
    11781196    PS_ASSERT_FLOAT_LESS_THAN_OR_EQUAL(kernelError, 1.0, false);
     1197    PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(covarFrac, 0.0, false);
     1198    PS_ASSERT_FLOAT_LESS_THAN(covarFrac, 1.0, false);
    11791199    if (region && psRegionIsNaN(*region)) {
    11801200        psString string = psRegionToString(*region);
     
    11881208    bool threaded = pmSubtractionThreaded(); // Running threaded?
    11891209
    1190     // Outputs
    1191     if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    1192         if (!out1->image) {
    1193             out1->image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
    1194         }
    1195         if (ro1->variance) {
    1196             if (!out1->variance) {
    1197                 out1->variance = psImageAlloc(numCols, numRows, PS_TYPE_F32);
    1198             }
    1199             psImageInit(out1->variance, 0.0);
    1200         }
    1201     }
    1202     if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    1203         if (!out2->image) {
    1204             out2->image = psImageAlloc(numCols, numRows, PS_TYPE_F32);
    1205         }
    1206         if (ro2->variance) {
    1207             if (!out2->variance) {
    1208                 out2->variance = psImageAlloc(numCols, numRows, PS_TYPE_F32);
    1209             }
    1210             psImageInit(out2->variance, 0.0);
    1211         }
    1212     }
    12131210    psImage *convMask = NULL;           // Convolved mask image (common to inputs 1 and 2)
    12141211    if (subMask) {
    12151212        if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    1216             if (!out1->mask) {
    1217                 out1->mask = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK);
    1218             }
    1219             psImageInit(out1->mask, 0);
    12201213            convMask = out1->mask;
    12211214        }
    12221215        if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    1223             if (!out2->mask) {
    1224                 out2->mask = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK);
    1225             }
    1226             psImageInit(out2->mask, 0);
    12271216            if (!convMask) {
    12281217                convMask = out2->mask;
     
    12441233
    12451234    // Get region for convolution: [xMin:xMax,yMin:yMax]
    1246     int xMin = size, xMax = numCols - size;
    1247     int yMin = size, yMax = numRows - size;
     1235    int xMin = kernels->xMin + size, xMax = kernels->xMax - size;
     1236    int yMin = kernels->yMin + size, yMax = kernels->yMax - size;
    12481237    if (region) {
    12491238        xMin = PS_MAX(region->x0, xMin);
     
    13361325
    13371326    // Calculate covariances
    1338     // This can take a while, so we only do it for a single instance
    1339     // XXX psImageCovarianceCalculate could be multithreaded
     1327    // This can be fairly involved, so we only do it for a single instance
     1328    // Enable threads for covariance calculation, since we're not threading on top of it.
     1329    oldThreads = psImageCovarianceSetThreads(true);
    13401330    if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    13411331        psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel
     1332        psKernelTruncate(kernel, covarFrac);
    13421333        out1->covariance = psImageCovarianceCalculate(kernel, ro1->covariance);
    13431334        psFree(kernel);
     
    13461337        psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0,
    13471338                                               kernels->mode == PM_SUBTRACTION_MODE_DUAL); // Conv. kernel
     1339        psKernelTruncate(kernel, covarFrac);
    13481340        out2->covariance = psImageCovarianceCalculate(kernel, ro2->covariance);
    13491341        psFree(kernel);
    13501342    }
     1343    psImageCovarianceSetThreads(oldThreads);
    13511344
    13521345    // Copy anything that wasn't convolved
     
    13881381    }
    13891382
    1390 
    13911383    psLogMsg("psModules.imcombine", PS_LOG_INFO, "Convolve image: %f sec",
    13921384             psTimerClear("pmSubtractionConvolve"));
Note: See TracChangeset for help on using the changeset viewer.