IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 19345


Ignore:
Timestamp:
Sep 3, 2008, 12:22:04 PM (18 years ago)
Author:
Paul Price
Message:

Threading pmStackReject

Location:
trunk/psModules/src/imcombine
Files:
2 edited

Legend:

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

    r19282 r19345  
    88
    99#include "pmSubtraction.h"
     10#include "pmSubtractionThreads.h"
    1011#include "pmSubtractionKernels.h"
    1112
     
    1314
    1415//#define TESTING                         // Testing output
     16
     17// Mask values
     18typedef enum {
     19    PM_STACK_MASK_BAD      = 0x01,      // Bad pixel
     20    PM_STACK_MASK_CONVOLVE = 0x02,      // Touching a bad pixel
     21} pmStackMask;
     22
     23static bool threaded = false;           // Running threaded?
     24
     25
     26// Grow the rejection mask
     27static inline bool stackRejectGrow(psImage *target,   // Target mask image (product)
     28                                   psImage *source, // Source mask image (to be grown)
     29                                   const pmSubtractionKernels *kernels, // Subtraction kernels
     30                                   int numCols, int numRows, // Size of image
     31                                   int xMin, int xMax, int yMin, int yMax, // Bounds of convolution
     32                                   float poorFrac       // Fraction for "poor"
     33    )
     34{
     35    int size = kernels->size;           // Half-size of convolution kernel
     36    psImage *polyValues = p_pmSubtractionPolynomialFromCoords(NULL, kernels, numCols, numRows,
     37                                                              xMin + size + 1, yMin + size + 1); // Polynomial
     38    int box = p_pmSubtractionBadRadius(NULL, kernels, polyValues, false, poorFrac); // Radius of bad box
     39    psFree(polyValues);
     40
     41    if (box > 0) {
     42        // Convolve a subimage, then stick it in the target
     43        if (threaded) {
     44            psMutexLock(source);
     45        }
     46        psImage *mask = psImageSubset(source, psRegionSet(xMin - box, xMax + box,
     47                                                          yMin - box, yMax + box)); // Mask to convolve
     48        if (threaded) {
     49            psMutexUnlock(source);
     50        }
     51        psImage *convolved = psImageConvolveMask(NULL, mask, PM_STACK_MASK_BAD, PM_STACK_MASK_CONVOLVE,
     52                                                 -box, box, -box, box); // Convolved mask
     53        if (threaded) {
     54            psMutexLock(source);
     55        }
     56        psFree(mask);
     57        if (threaded) {
     58            psMutexUnlock(source);
     59        }
     60
     61        int numBytes = (xMax - xMin) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK); // Number of bytes to copy
     62        psAssert(convolved->numCols - 2 * box == xMax - xMin, "Bad number of columns");
     63        psAssert(convolved->numRows - 2 * box == yMax - yMin, "Bad number of rows");
     64
     65        for (int yTarget = yMin, ySource = box; yTarget < yMax; yTarget++, ySource++) {
     66            memcpy(&target->data.PS_TYPE_MASK_DATA[yTarget][xMin],
     67                   &convolved->data.PS_TYPE_MASK_DATA[ySource][box], numBytes);
     68        }
     69        psFree(convolved);
     70    }
     71    return true;
     72}
     73
     74// Thread entry for stackRejectGrow
     75static bool stackRejectGrowThread(psThreadJob *job // Job to execute
     76    )
     77{
     78    PS_ASSERT_THREAD_JOB_NON_NULL(job, false);
     79
     80    psArray *args = job->args;          // Job arguments
     81    psImage *target = args->data[0];    // Target mask image
     82    psImage *source = args->data[1];    // Source mask image
     83    const pmSubtractionKernels *kernels = args->data[2]; // Subtraction kernels
     84    int numCols = PS_SCALAR_VALUE(args->data[3], S32); // Number of columns
     85    int numRows = PS_SCALAR_VALUE(args->data[4], S32); // Number of rows
     86    int xMin = PS_SCALAR_VALUE(args->data[5], S32); // Minimum x value
     87    int xMax = PS_SCALAR_VALUE(args->data[6], S32); // Maximum x value
     88    int yMin = PS_SCALAR_VALUE(args->data[7], S32); // Minimum y value
     89    int yMax = PS_SCALAR_VALUE(args->data[8], S32); // Maximum y value
     90    float poorFrac = PS_SCALAR_VALUE(args->data[9], F32); // Fraction for "poor"
     91
     92    return stackRejectGrow(target, source, kernels, numCols, numRows, xMin, xMax, yMin, yMax, poorFrac);
     93}
     94
     95bool pmStackRejectThreadsInit(void)
     96{
     97    if (threaded) {
     98        psAbort("Already running threaded.");
     99    }
     100    threaded = true;
     101
     102    if (!pmSubtractionThreaded()) {
     103        pmSubtractionThreadsInit(NULL, NULL);
     104    }
     105
     106    {
     107        psThreadTask *task = psThreadTaskAlloc("PSMODULES_STACK_REJECT_GROW", 10);
     108        task->function = &stackRejectGrowThread;
     109        psThreadTaskAdd(task);
     110        psFree(task);
     111    }
     112
     113    return true;
     114}
    15115
    16116
     
    52152    pmReadout *inRO = pmReadoutAlloc(NULL); // Readout with input image
    53153    inRO->image = image;
     154    if (threaded) {
     155        psMutexInit(image);
     156    }
    54157    for (int i = 0; i < numRegions; i++) {
    55158        psRegion *region = subRegions->data[i]; // Region of interest
     
    70173        float yNorm = (region->y0 + 0.5 * (region->y1 - region->y0) - kernels->numRows/2.0) /
    71174            (float)kernels->numRows;
    72         psImage *image = pmSubtractionKernelImage(kernels, xNorm, yNorm, false);
    73         if (!image) {
     175        psImage *kernel = pmSubtractionKernelImage(kernels, xNorm, yNorm, false);
     176        if (!kernel) {
    74177            psError(PS_ERR_UNKNOWN, false, "Unable to generate kernel image.");
    75178            psFree(convRO);
     
    78181        }
    79182        float sum = 0.0;
    80         for (int y = 0; y < image->numRows; y++) {
    81             for (int x = 0; x < image->numCols; x++) {
    82                 sum += image->data.F32[y][x];
     183        for (int y = 0; y < kernel->numRows; y++) {
     184            for (int x = 0; x < kernel->numCols; x++) {
     185                sum += kernel->data.F32[y][x];
    83186            }
    84187        }
    85         psFree(image);
     188        psFree(kernel);
    86189
    87190        // Range for normalisation
     
    97200        }
    98201    }
     202    if (threaded) {
     203        psMutexDestroy(image);
     204    }
    99205    psFree(inRO);
    100206    psImage *convolved = psMemIncrRefCounter(convRO->image);
     
    123229        }
    124230    }
    125     psFree(convolved);
    126231
    127232    // Now, grow the mask to include everything that touches a bad pixel in the convolution
    128     // Mask values:
    129     // 0x0f: we think this is bad
    130     // 0xf0: this is within the convolution kernel of a bad pixel
    131     mask = psPixelsToMask(NULL, bad, psRegionSet(0, numCols - 1, 0, numRows - 1), 0x0f);
     233    psImage *source = psPixelsToMask(NULL, bad, psRegionSet(0, numCols - 1, 0, numRows - 1),
     234                                     PM_STACK_MASK_BAD); // Mask image to grow
     235    psImage *target = psImageRecycle(convolved, numCols, numRows, PS_TYPE_U8); // Grown image
     236    if (threaded) {
     237        psMutexInit(source);
     238    }
    132239    for (int i = 0; i < subRegions->n; i++) {
    133240        psRegion *region = subRegions->data[i]; // Subtraction region
     
    141248        int yMin = PS_MAX(region->y0, size), yMax = PS_MIN(region->y1, numRows - size);
    142249
    143         psImage *polyValues = NULL;     // Pre-calculated polynomial values
    144250        for (int j = yMin; j < yMax; j += fullSize) {
    145251            int ySubMax = PS_MIN(j + fullSize, yMax); // Range for subregion of interest
     
    147253                int xSubMax = PS_MIN(i + fullSize, xMax); // Range for subregion of interest
    148254
    149                 polyValues = p_pmSubtractionPolynomialFromCoords(polyValues, kernels, numCols, numRows,
    150                                                                  i + size + 1, j + size + 1);
    151                 int box = p_pmSubtractionBadRadius(NULL, kernels, polyValues,
    152                                                    false, poorFrac); // Radius of bad box
    153                 if (box > 0) {
    154                     // Convolve a subimage, then stick it in the original
    155                     psImage *subMask = psImageSubset(mask, psRegionSet(i - box, xSubMax + box,
    156                                                                        j - box, ySubMax + box)); // Subimage
    157                     psImage *convolved = psImageConvolveMask(NULL, subMask, 0x0f, 0xf0,
    158                                                              -box, box, -box, box); // Convolved mask
    159                     psFree(subMask);
    160 
    161                     int numBytes = (xSubMax - i) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK); // Number of bytes to copy
    162                     psAssert(convolved->numCols - 2 * box == xSubMax - i, "Bad number of columns");
    163                     psAssert(convolved->numRows - 2 * box == ySubMax - j, "Bad number of rows");
    164 
    165                     for (int yTarget = j, ySource = box; yTarget < ySubMax; yTarget++, ySource++) {
    166                         memcpy(&mask->data.PS_TYPE_MASK_DATA[yTarget][i],
    167                                &convolved->data.PS_TYPE_MASK_DATA[ySource][box], numBytes);
     255                if (threaded) {
     256                    psThreadJob *job = psThreadJobAlloc("PSMODULES_STACK_REJECT_GROW"); // Job to execute
     257                    psArray *args = job->args; // Job arguments
     258                    psArrayAdd(args, 1, target);
     259                    psMutexLock(source);
     260                    psArrayAdd(args, 1, source);
     261                    psMutexUnlock(source);
     262                    psArrayAdd(args, 1, kernels);
     263                    PS_ARRAY_ADD_SCALAR(args, numCols, PS_TYPE_S32);
     264                    PS_ARRAY_ADD_SCALAR(args, numRows, PS_TYPE_S32);
     265                    PS_ARRAY_ADD_SCALAR(args, i, PS_TYPE_S32);
     266                    PS_ARRAY_ADD_SCALAR(args, xSubMax, PS_TYPE_S32);
     267                    PS_ARRAY_ADD_SCALAR(args, j, PS_TYPE_S32);
     268                    PS_ARRAY_ADD_SCALAR(args, ySubMax, PS_TYPE_S32);
     269                    PS_ARRAY_ADD_SCALAR(args, poorFrac, PS_TYPE_F32);
     270                    if (!psThreadJobAddPending(job)) {
     271                        psFree(job);
     272                        psFree(source);
     273                        psFree(target);
     274                        return false;
    168275                    }
    169                     psFree(convolved);
     276                    psFree(job);
     277                } else if (!stackRejectGrow(target, source, kernels, numCols, numRows,
     278                                              i, xSubMax, j, ySubMax, poorFrac)) {
     279                    psError(PS_ERR_UNKNOWN, false, "Unable to grow bad pixels.");
     280                    psFree(source);
     281                    psFree(target);
     282                    return NULL;
    170283                }
    171284            }
    172285        }
    173         psFree(polyValues);
    174     }
    175     bad = psPixelsFromMask(bad, mask, 0xff);
     286    }
     287
     288    if (!psThreadPoolWait(false)) {
     289        psError(PS_ERR_UNKNOWN, false, "Unable to grow bad pixels.");
     290        psFree(source);
     291        psFree(target);
     292        return NULL;
     293    }
     294
     295    if (threaded) {
     296        psMutexDestroy(source);
     297    }
     298    psFree(source);
     299    bad = psPixelsFromMask(bad, target, 0xff);
    176300
    177301    return bad;
  • trunk/psModules/src/imcombine/pmStackReject.h

    r19282 r19345  
    1717    );
    1818
     19/// Initialise threads for stack rejection
     20bool pmStackRejectThreadsInit(void);
    1921
    2022#endif
Note: See TracChangeset for help on using the changeset viewer.