IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 18962


Ignore:
Timestamp:
Aug 8, 2008, 8:10:29 AM (18 years ago)
Author:
Paul Price
Message:

Adding threads to pmSubtractionCalculateEquation and pmSubtractionOrder. More work needs to be done in threading the final convolution.

Location:
trunk/psModules/src
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/imcombine/Makefile.am

    r18146 r18962  
    1616        pmSubtractionParams.c   \
    1717        pmSubtractionStamps.c   \
     18        pmSubtractionThreads.c  \
    1819        pmPSFEnvelope.c
    1920
     
    3132        pmSubtractionParams.h   \
    3233        pmSubtractionStamps.h   \
     34        pmSubtractionThreads.h  \
    3335        pmPSFEnvelope.h
    3436
  • trunk/psModules/src/imcombine/pmSubtraction.c

    r18652 r18962  
    550550        rms = 0.74 * (stats->sampleUQ - stats->sampleLQ);
    551551    }
     552    psFree(stats);
    552553
    553554    psTrace("psModules.imcombine", 1, "Mean: %f\n", mean);
  • trunk/psModules/src/imcombine/pmSubtractionEquation.c

    r18287 r18962  
    1010#include "pmSubtractionKernels.h"
    1111#include "pmSubtractionStamps.h"
     12#include "pmSubtractionThreads.h"
    1213
    1314#include "pmSubtractionEquation.h"
     
    479480//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    480481
    481 bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, const pmSubtractionKernels *kernels)
     482bool pmSubtractionCalculateEquationThread(const psThreadJob *job)
     483{
     484    PS_ASSERT_THREAD_JOB_NON_NULL(job, false);
     485
     486    pmSubtractionStampList *stamps = job->args->data[0]; // List of stamps
     487    const pmSubtractionKernels *kernels = job->args->data[1]; // Kernels
     488    int index = PS_SCALAR_VALUE(job->args->data[2], S32); // Stamp index
     489
     490    return pmSubtractionCalculateEquationStamp(stamps, kernels, index);
     491}
     492
     493bool pmSubtractionCalculateEquationStamp(pmSubtractionStampList *stamps, const pmSubtractionKernels *kernels,
     494                                         int index)
    482495{
    483496    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false);
    484497    PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, false);
     498    PS_ASSERT_INT_NONNEGATIVE(index, false);
     499    PS_ASSERT_INT_LESS_THAN(index, stamps->num, false);
    485500
    486501    int footprint = stamps->footprint;  // Half-size of stamps
     
    494509    int numParams = numKernels * numSpatial + 1 + numBackground;
    495510
    496     psImage *polyValues = NULL;         // Polynomial terms
     511    pmSubtractionStamp *stamp = stamps->stamps->data[index]; // Stamp of interest
     512    psAssert(stamp->status == PM_SUBTRACTION_STAMP_CALCULATE, "We only operate on stamps with this state.");
     513
     514    // Generate convolutions
     515    if (!pmSubtractionConvolveStamp(stamp, kernels, footprint)) {
     516        psError(PS_ERR_UNKNOWN, false, "Unable to convolve stamp %d.", index);
     517        return NULL;
     518    }
     519
     520#ifdef TESTING
     521    for (int j = 0; j < numKernels; j++) {
     522        if (stamp->convolutions1) {
     523            psString convName = NULL;
     524            psStringAppend(&convName, "conv1_%03d_%03d.fits", index, j);
     525            psFits *fits = psFitsOpen(convName, "w");
     526            psFree(convName);
     527            psKernel *conv = stamp->convolutions1->data[j];
     528            psFitsWriteImage(fits, NULL, conv->image, 0, NULL);
     529            psFitsClose(fits);
     530        }
     531
     532        if (stamp->convolutions2) {
     533            psString convName = NULL;
     534            psStringAppend(&convName, "conv2_%03d_%03d.fits", index, j);
     535            psFits *fits = psFitsOpen(convName, "w");
     536            psFree(convName);
     537            psKernel *conv = stamp->convolutions2->data[j];
     538            psFitsWriteImage(fits, NULL, conv->image, 0, NULL);
     539            psFitsClose(fits);
     540        }
     541    }
     542#endif
     543
     544    psImage *polyValues = p_pmSubtractionPolynomial(NULL, spatialOrder,
     545                                                    stamp->xNorm, stamp->yNorm); // Polynomial terms
     546
     547    bool new = stamp->vector1 ? false : true; // Is this a new run?
     548    if (new) {
     549        stamp->matrix1 = psImageAlloc(numParams, numParams, PS_TYPE_F64);
     550        stamp->vector1 = psVectorAlloc(numParams, PS_TYPE_F64);
     551    }
     552#ifdef TESTING
     553    psImageInit(stamp->matrix1, NAN);
     554    psVectorInit(stamp->vector1, NAN);
     555#endif
     556
     557    bool status;                    // Status of least-squares matrix/vector calculation
     558    switch (kernels->mode) {
     559      case PM_SUBTRACTION_MODE_1:
     560        status = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions1, stamp->image1,
     561                                 stamp->weight, polyValues, footprint, true);
     562        status &= calculateVector(stamp->vector1, kernels, stamp->convolutions1, stamp->image1,
     563                                  stamp->image2, stamp->weight, polyValues, footprint, true);
     564        break;
     565      case PM_SUBTRACTION_MODE_2:
     566        status = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions2, stamp->image2,
     567                                 stamp->weight, polyValues, footprint, true);
     568        status &= calculateVector(stamp->vector1, kernels, stamp->convolutions2, stamp->image2,
     569                                  stamp->image1, stamp->weight, polyValues, footprint, true);
     570        break;
     571      case PM_SUBTRACTION_MODE_DUAL:
     572        if (new) {
     573            stamp->matrix2 = psImageAlloc(numKernels * numSpatial, numKernels * numSpatial, PS_TYPE_F64);
     574            stamp->matrixX = psImageAlloc(numParams, numKernels * numSpatial, PS_TYPE_F64);
     575            stamp->vector2 = psVectorAlloc(numKernels * numSpatial, PS_TYPE_F64);
     576        }
     577#ifdef TESTING
     578        psImageInit(stamp->matrix2, NAN);
     579        psImageInit(stamp->matrixX, NAN);
     580        psVectorInit(stamp->vector2, NAN);
     581#endif
     582        status  = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions1, stamp->image1,
     583                                  stamp->weight, polyValues, footprint, true);
     584        status &= calculateMatrix(stamp->matrix2, kernels, stamp->convolutions2, NULL,
     585                                  stamp->weight, polyValues, footprint, false);
     586        status &= calculateMatrixCross(stamp->matrixX, kernels, stamp->convolutions1,
     587                                       stamp->convolutions2, stamp->image1, stamp->weight, polyValues,
     588                                       footprint);
     589        status &= calculateVector(stamp->vector1, kernels, stamp->convolutions1, stamp->image1,
     590                                  stamp->image2, stamp->weight, polyValues, footprint, true);
     591        status &= calculateVector(stamp->vector2, kernels, stamp->convolutions2, NULL,
     592                                  stamp->image2, stamp->weight, polyValues, footprint, false);
     593        break;
     594      default:
     595        psAbort("Unsupported subtraction mode: %x", kernels->mode);
     596    }
     597
     598    if (!status) {
     599        stamp->status = PM_SUBTRACTION_STAMP_REJECTED;
     600        psWarning("Rejecting stamp %d (%d,%d) because of bad equation",
     601                  index, (int)(stamp->x + 0.5), (int)(stamp->y + 0.5));
     602    } else {
     603        stamp->status = PM_SUBTRACTION_STAMP_USED;
     604    }
     605
     606#ifdef TESTING
     607    if (psTraceGetLevel("psModules.imcombine.equation") >= 10) {
     608        psString matrixName = NULL;
     609        psStringAppend(&matrixName, "matrix1_%d.fits", index);
     610        psFits *matrixFile = psFitsOpen(matrixName, "w");
     611        psFree(matrixName);
     612        psFitsWriteImage(matrixFile, NULL, stamp->matrix1, 0, NULL);
     613        psFitsClose(matrixFile);
     614
     615        matrixName = NULL;
     616        psStringAppend(&matrixName, "vector1_%d.fits", index);
     617        psImage *dummy = psImageAlloc(stamp->vector1->n, 1, PS_TYPE_F64);
     618        memcpy(dummy->data.F64[0], stamp->vector1->data.F64,
     619               PSELEMTYPE_SIZEOF(PS_TYPE_F64) * stamp->vector1->n);
     620        matrixFile = psFitsOpen(matrixName, "w");
     621        psFree(matrixName);
     622        psFitsWriteImage(matrixFile, NULL, dummy, 0, NULL);
     623        psFree(dummy);
     624        psFitsClose(matrixFile);
     625
     626        if (stamp->vector2) {
     627            matrixName = NULL;
     628            psStringAppend(&matrixName, "vector2_%d.fits", index);
     629            dummy = psImageAlloc(stamp->vector2->n, 1, PS_TYPE_F64);
     630            memcpy(dummy->data.F64[0], stamp->vector2->data.F64,
     631                   PSELEMTYPE_SIZEOF(PS_TYPE_F64) * stamp->vector2->n);
     632            matrixFile = psFitsOpen(matrixName, "w");
     633            psFree(matrixName);
     634            psFitsWriteImage(matrixFile, NULL, dummy, 0, NULL);
     635            psFree(dummy);
     636            psFitsClose(matrixFile);
     637        }
     638
     639        if (kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
     640            matrixName = NULL;
     641            psStringAppend(&matrixName, "matrix2_%d.fits", index);
     642            matrixFile = psFitsOpen(matrixName, "w");
     643            psFree(matrixName);
     644            psFitsWriteImage(matrixFile, NULL, stamp->matrix2, 0, NULL);
     645            psFitsClose(matrixFile);
     646
     647            matrixName = NULL;
     648            psStringAppend(&matrixName, "matrixX_%d.fits", index);
     649            matrixFile = psFitsOpen(matrixName, "w");
     650            psFree(matrixName);
     651            psFitsWriteImage(matrixFile, NULL, stamp->matrixX, 0, NULL);
     652            psFitsClose(matrixFile);
     653        }
     654    }
     655#endif
     656
     657    psFree(polyValues);
     658
     659    return true;
     660}
     661
     662bool pmSubtractionCalculateEquation(pmSubtractionStampList *stamps, const pmSubtractionKernels *kernels)
     663{
     664    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false);
     665    PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(kernels, false);
    497666
    498667    // We iterate over each stamp, allocate the matrix and vectors if
     
    504673        }
    505674
    506         // Generate convolutions
    507         if (!pmSubtractionConvolveStamp(stamp, kernels, footprint)) {
    508             psError(PS_ERR_UNKNOWN, false, "Unable to convolve stamp %d.", i);
    509             psFree(polyValues);
    510             return NULL;
    511         }
    512 
    513 #ifdef TESTING
    514         for (int j = 0; j < numKernels; j++) {
    515             if (stamp->convolutions1) {
    516                 psString convName = NULL;
    517                 psStringAppend(&convName, "conv1_%03d_%03d.fits", i, j);
    518                 psFits *fits = psFitsOpen(convName, "w");
    519                 psFree(convName);
    520                 psKernel *conv = stamp->convolutions1->data[j];
    521                 psFitsWriteImage(fits, NULL, conv->image, 0, NULL);
    522                 psFitsClose(fits);
    523             }
    524 
    525             if (stamp->convolutions2) {
    526                 psString convName = NULL;
    527                 psStringAppend(&convName, "conv2_%03d_%03d.fits", i, j);
    528                 psFits *fits = psFitsOpen(convName, "w");
    529                 psFree(convName);
    530                 psKernel *conv = stamp->convolutions2->data[j];
    531                 psFitsWriteImage(fits, NULL, conv->image, 0, NULL);
    532                 psFitsClose(fits);
    533             }
    534         }
    535 #endif
    536 
    537         polyValues = p_pmSubtractionPolynomial(polyValues, spatialOrder, stamp->xNorm, stamp->yNorm);
    538 
    539 
    540             stamp->matrix1 = psImageAlloc(numParams, numParams, PS_TYPE_F64);
    541             stamp->vector1 = psVectorAlloc(numParams, PS_TYPE_F64);
    542 #ifdef TESTING
    543             psImageInit(stamp->matrix1, NAN);
    544             psVectorInit(stamp->vector1, NAN);
    545 #endif
    546 
    547         bool status;                    // Status of least-squares matrix/vector calculation
    548         switch (kernels->mode) {
    549           case PM_SUBTRACTION_MODE_1:
    550             status = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions1, stamp->image1,
    551                                      stamp->weight, polyValues, footprint, true);
    552             status &= calculateVector(stamp->vector1, kernels, stamp->convolutions1, stamp->image1,
    553                                       stamp->image2, stamp->weight, polyValues, footprint, true);
    554             break;
    555           case PM_SUBTRACTION_MODE_2:
    556             status = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions2, stamp->image2,
    557                                      stamp->weight, polyValues, footprint, true);
    558             status &= calculateVector(stamp->vector1, kernels, stamp->convolutions2, stamp->image2,
    559                                       stamp->image1, stamp->weight, polyValues, footprint, true);
    560             break;
    561           case PM_SUBTRACTION_MODE_DUAL:
    562             stamp->matrix2 = psImageAlloc(numKernels * numSpatial, numKernels * numSpatial, PS_TYPE_F64);
    563             stamp->matrixX = psImageAlloc(numParams, numKernels * numSpatial, PS_TYPE_F64);
    564             stamp->vector2 = psVectorAlloc(numKernels * numSpatial, PS_TYPE_F64);
    565 #ifdef TESTING
    566             psImageInit(stamp->matrix2, NAN);
    567             psImageInit(stamp->matrixX, NAN);
    568             psVectorInit(stamp->vector2, NAN);
    569 #endif
    570             status  = calculateMatrix(stamp->matrix1, kernels, stamp->convolutions1, stamp->image1,
    571                                       stamp->weight, polyValues, footprint, true);
    572             status &= calculateMatrix(stamp->matrix2, kernels, stamp->convolutions2, NULL,
    573                                       stamp->weight, polyValues, footprint, false);
    574             status &= calculateMatrixCross(stamp->matrixX, kernels, stamp->convolutions1,
    575                                            stamp->convolutions2, stamp->image1, stamp->weight, polyValues,
    576                                            footprint);
    577             status &= calculateVector(stamp->vector1, kernels, stamp->convolutions1, stamp->image1,
    578                                       stamp->image2, stamp->weight, polyValues, footprint, true);
    579             status &= calculateVector(stamp->vector2, kernels, stamp->convolutions2, NULL,
    580                                       stamp->image2, stamp->weight, polyValues, footprint, false);
    581             break;
    582           default:
    583             psAbort("Unsupported subtraction mode: %x", kernels->mode);
    584         }
    585 
    586         if (!status) {
    587             stamp->status = PM_SUBTRACTION_STAMP_REJECTED;
    588             psWarning("Rejecting stamp %d (%d,%d) because of bad equation",
    589                       i, (int)(stamp->x + 0.5), (int)(stamp->y + 0.5));
     675        if (pmSubtractionThreaded()) {
     676            psThreadJob *job = psThreadJobAlloc("PSMODULES_SUBTRACTION_CALCULATE_EQUATION");
     677            psArrayAdd(job->args, 1, stamps);
     678            psArrayAdd(job->args, 1, (pmSubtractionKernels*)kernels); // Casting away const to put on array
     679            PS_ARRAY_ADD_SCALAR(job->args, i, PS_TYPE_S32);
     680            if (!psThreadJobAddPending(job)) {
     681                psFree(job);
     682                return false;
     683            }
     684            psFree(job);
    590685        } else {
    591             stamp->status = PM_SUBTRACTION_STAMP_USED;
    592         }
    593 
    594 #ifdef TESTING
    595         if (psTraceGetLevel("psModules.imcombine.equation") >= 10) {
    596             psString matrixName = NULL;
    597             psStringAppend(&matrixName, "matrix1_%d.fits", i);
    598             psFits *matrixFile = psFitsOpen(matrixName, "w");
    599             psFree(matrixName);
    600             psFitsWriteImage(matrixFile, NULL, stamp->matrix1, 0, NULL);
    601             psFitsClose(matrixFile);
    602 
    603             matrixName = NULL;
    604             psStringAppend(&matrixName, "vector1_%d.fits", i);
    605             psImage *dummy = psImageAlloc(stamp->vector1->n, 1, PS_TYPE_F64);
    606             memcpy(dummy->data.F64[0], stamp->vector1->data.F64,
    607                    PSELEMTYPE_SIZEOF(PS_TYPE_F64) * stamp->vector1->n);
    608             matrixFile = psFitsOpen(matrixName, "w");
    609             psFree(matrixName);
    610             psFitsWriteImage(matrixFile, NULL, dummy, 0, NULL);
    611             psFree(dummy);
    612             psFitsClose(matrixFile);
    613 
    614             if (stamp->vector2) {
    615                 matrixName = NULL;
    616                 psStringAppend(&matrixName, "vector2_%d.fits", i);
    617                 dummy = psImageAlloc(stamp->vector2->n, 1, PS_TYPE_F64);
    618                 memcpy(dummy->data.F64[0], stamp->vector2->data.F64,
    619                        PSELEMTYPE_SIZEOF(PS_TYPE_F64) * stamp->vector2->n);
    620                 matrixFile = psFitsOpen(matrixName, "w");
    621                 psFree(matrixName);
    622                 psFitsWriteImage(matrixFile, NULL, dummy, 0, NULL);
    623                 psFree(dummy);
    624                 psFitsClose(matrixFile);
    625             }
    626 
    627             if (kernels->mode == PM_SUBTRACTION_MODE_DUAL) {
    628                 matrixName = NULL;
    629                 psStringAppend(&matrixName, "matrix2_%d.fits", i);
    630                 matrixFile = psFitsOpen(matrixName, "w");
    631                 psFree(matrixName);
    632                 psFitsWriteImage(matrixFile, NULL, stamp->matrix2, 0, NULL);
    633                 psFitsClose(matrixFile);
    634 
    635                 matrixName = NULL;
    636                 psStringAppend(&matrixName, "matrixX_%d.fits", i);
    637                 matrixFile = psFitsOpen(matrixName, "w");
    638                 psFree(matrixName);
    639                 psFitsWriteImage(matrixFile, NULL, stamp->matrixX, 0, NULL);
    640                 psFitsClose(matrixFile);
    641             }
    642         }
    643 #endif
    644 
    645     }
    646     psFree(polyValues);
     686            pmSubtractionCalculateEquationStamp(stamps, kernels, i);
     687        }
     688    }
     689
     690    if (!psThreadPoolWait(true)) {
     691        psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
     692        return false;
     693    }
    647694
    648695    return true;
  • trunk/psModules/src/imcombine/pmSubtractionEquation.h

    r18287 r18962  
    44#include "pmSubtractionStamps.h"
    55#include "pmSubtractionKernels.h"
     6
     7/// Execute a thread job to calculate the least-squares equation for a stamp
     8bool pmSubtractionCalculateEquationThread(const psThreadJob *job ///< Job to execute
     9    );
     10
     11/// Calculate the least-squares equation to match the image quality for a single stamp
     12bool pmSubtractionCalculateEquationStamp(pmSubtractionStampList *stamps, ///< Stamps
     13                                         const pmSubtractionKernels *kernels, ///< Kernel parameters
     14                                         int index ///< Index of stamp
     15                                    );
    616
    717/// Calculate the least-squares equation to match the image quality
  • trunk/psModules/src/imcombine/pmSubtractionMatch.c

    r18348 r18962  
    1616#include "pmSubtraction.h"
    1717#include "pmSubtractionMask.h"
     18#include "pmSubtractionThreads.h"
    1819#include "pmSubtractionMatch.h"
     20
    1921
    2022#define KERNEL_MOSAIC 2                 // Half-number of kernel instances in the mosaic image
     
    631633                                 float bg, // Background in image
    632634                                 int size, // Maximum size
    633                                  psArray **models, // Buffer of models
    634                                  psVector **modelSums // Buffer of model sums
     635                                 const psArray *models, // Buffer of models
     636                                 const psVector *modelSums // Buffer of model sums
    635637    )
    636638{
     
    639641    assert(modelSums);
    640642
    641     int xMin = kernel->xMin, xMax = kernel->xMax; // Bounds in x
    642     int yMin = kernel->yMin, yMax = kernel->yMax; // Bounds in y
    643 
    644     // Generate models
    645     if (!*models) {
    646         assert(!*modelSums);
    647         *models = psArrayAlloc(size);
    648         *modelSums = psVectorAlloc(size, PS_TYPE_F64);
    649         for (int sigma = 0; sigma < size; sigma++) {
    650             psKernel *model = psKernelAlloc(xMin, xMax, yMin, yMax); // Gaussian model
    651             float invSigma2 = 1.0 / (float)PS_SQR(1 + sigma); // Inverse sigma squared
    652             double sumGG = 0.0;         // Sum of square of Gaussian
    653             for (int y = yMin; y <= yMax; y++) {
    654                 int y2 = PS_SQR(y);     // y squared
    655                 for (int x = xMin; x <= xMax; x++) {
    656                     float rad2 = PS_SQR(x) + y2; // Radius squared
    657                     float value = expf(-rad2 * invSigma2); // Model value
    658                     model->kernel[y][x] = value;
    659                     sumGG += PS_SQR(value);
    660                 }
    661             }
    662             (*models)->data[sigma] = model;
    663             (*modelSums)->data.F64[sigma] = sumGG;
    664         }
    665     }
     643    int xMin = -size, xMax = size; // Bounds in x
     644    int yMin = -size, yMax = size; // Bounds in y
    666645
    667646    // Fit gaussians of varying widths to the image, record the chi^2
     
    669648    for (int sigma = 0; sigma < size; sigma++) {
    670649        double sumFG = 0.0; // Sum for calculating the normalisation of the Gaussian
    671         psKernel *model = (*models)->data[sigma]; // Model of interest
     650        psKernel *model = models->data[sigma]; // Model of interest
    672651        for (int y = yMin; y <= yMax; y++) {
    673652            for (int x = xMin; x <= xMax; x++) {
     
    675654            }
    676655        }
    677         float norm = sumFG / (*modelSums)->data.F64[sigma]; // Normalisation for Gaussian
     656        float norm = sumFG * modelSums->data.F64[sigma]; // Normalisation for Gaussian
    678657        double sumDev2 = 0.0;           // Sum of square deviations
    679658        for (int y = yMin; y <= yMax; y++) {
     
    700679}
    701680
     681
     682bool pmSubtractionOrderStamp(psVector *ratios, psVector *mask, const pmSubtractionStampList *stamps,
     683                             const psArray *models, const psVector *modelSums,
     684                             int index, float bg1, float bg2)
     685{
     686    PS_ASSERT_VECTOR_NON_NULL(ratios, false);
     687    PS_ASSERT_VECTOR_NON_NULL(mask, false);
     688    PS_ASSERT_VECTORS_SIZE_EQUAL(ratios, mask, false);
     689    PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false);
     690    PS_ASSERT_INT_NONNEGATIVE(index, false);
     691    PS_ASSERT_INT_LESS_THAN(index, stamps->num, false);
     692    PS_ASSERT_ARRAY_NON_NULL(models, false);
     693    PS_ASSERT_VECTOR_NON_NULL(modelSums, false);
     694    PS_ASSERT_VECTOR_SIZE(modelSums, models->n, false);
     695
     696    pmSubtractionStamp *stamp = stamps->stamps->data[index]; // Stamp of interest
     697    psAssert(stamp->status == PM_SUBTRACTION_STAMP_CALCULATE || stamp->status == PM_SUBTRACTION_STAMP_USED,
     698             "We checked this earlier.");
     699
     700    // Widths of stars
     701    int width1 = subtractionOrderWidth(stamp->image1, bg1, stamps->footprint, models, modelSums);
     702    int width2 = subtractionOrderWidth(stamp->image2, bg2, stamps->footprint, models, modelSums);
     703
     704    if (width1 == 0 || width2 == 0) {
     705        ratios->data.F32[index] = NAN;
     706        mask->data.PS_TYPE_MASK_DATA[index] = 0xff;
     707    } else {
     708        ratios->data.F32[index] = (float)width1 / (float)width2;
     709        mask->data.PS_TYPE_MASK_DATA[index] = 0;
     710    }
     711
     712    return true;
     713}
     714
     715bool pmSubtractionOrderThread(const psThreadJob *job)
     716{
     717    PS_ASSERT_THREAD_JOB_NON_NULL(job, false);
     718
     719    psVector *ratios = job->args->data[0]; // Ratios of widths
     720    psVector *mask = job->args->data[1]; // Mask for ratios
     721    const pmSubtractionStampList *stamps = job->args->data[2]; // List of stamps
     722    const psArray *models = job->args->data[3]; // Gaussian models
     723    const psVector *modelSums = job->args->data[4]; // Gaussian model sums
     724    int index = PS_SCALAR_VALUE(job->args->data[5], S32); // Stamp index
     725    float bg1 = PS_SCALAR_VALUE(job->args->data[6], F32); // Background of image 1
     726    float bg2 = PS_SCALAR_VALUE(job->args->data[7], F32); // Background of image 2
     727
     728    return pmSubtractionOrderStamp(ratios, mask, stamps, models, modelSums, index, bg1, bg2);
     729}
     730
    702731pmSubtractionMode pmSubtractionOrder(pmSubtractionStampList *stamps, float bg1, float bg2)
    703732{
     
    706735    psVector *mask = psVectorAlloc(stamps->num, PS_TYPE_MASK); // Mask for stamps
    707736    psVector *ratios = psVectorAlloc(stamps->num, PS_TYPE_F32); // Ratios of widths
    708     psArray *models = NULL;             // Gaussian models
    709     psVector *modelSums = NULL;         // Gaussian model sums
     737
     738    // Generate models
     739    int size = stamps->footprint;       // Maximum size
     740    psArray *models = psArrayAlloc(size); // Gaussian models
     741    psVector *modelSums = psVectorAlloc(size, PS_TYPE_F64); // Gaussian model sums
     742    for (int sigma = 0; sigma < size; sigma++) {
     743        psKernel *model = psKernelAlloc(-size, size, -size, size); // Gaussian model
     744        float invSigma2 = 1.0 / (float)PS_SQR(1 + sigma); // Inverse sigma squared
     745        double sumGG = 0.0;         // Sum of square of Gaussian
     746        for (int y = -size; y <= size; y++) {
     747            int y2 = PS_SQR(y);     // y squared
     748            for (int x = -size; x <= size; x++) {
     749                float rad2 = PS_SQR(x) + y2; // Radius squared
     750                float value = expf(-rad2 * invSigma2); // Model value
     751                model->kernel[y][x] = value;
     752                sumGG += PS_SQR(value);
     753            }
     754        }
     755        models->data[sigma] = model;
     756        modelSums->data.F64[sigma] = 1.0 / sumGG;
     757    }
     758
     759    // Fit models to stamps
    710760    for (int i = 0; i < stamps->num; i++) {
    711761        pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest
     
    715765        }
    716766
    717         // Widths of stars
    718         int width1 = subtractionOrderWidth(stamp->image1, bg1, stamps->footprint, &models, &modelSums);
    719         int width2 = subtractionOrderWidth(stamp->image2, bg2, stamps->footprint, &models, &modelSums);
    720 
    721         if (width1 == 0 || width2 == 0) {
    722             ratios->data.F32[i] = NAN;
    723             mask->data.PS_TYPE_MASK_DATA[i] = 0xff;
     767        if (pmSubtractionThreaded()) {
     768            psThreadJob *job = psThreadJobAlloc("PSMODULES_SUBTRACTION_ORDER");
     769            psArrayAdd(job->args, 1, ratios);
     770            psArrayAdd(job->args, 1, mask);
     771            psArrayAdd(job->args, 1, stamps);
     772            psArrayAdd(job->args, 1, models);
     773            psArrayAdd(job->args, 1, modelSums);
     774            PS_ARRAY_ADD_SCALAR(job->args, i, PS_TYPE_S32);
     775            PS_ARRAY_ADD_SCALAR(job->args, bg1, PS_TYPE_F32);
     776            PS_ARRAY_ADD_SCALAR(job->args, bg2, PS_TYPE_F32);
     777            if (!psThreadJobAddPending(job)) {
     778                psFree(job);
     779                return false;
     780            }
     781            psFree(job);
    724782        } else {
    725             ratios->data.F32[i] = (float)width1 / (float)width2;
    726             mask->data.PS_TYPE_MASK_DATA[i] = 0;
    727         }
    728     }
     783            if (!pmSubtractionOrderStamp(ratios, mask, stamps, models, modelSums, i, bg1, bg2)) {
     784                psError(PS_ERR_UNKNOWN, false, "Unable to measure PSF width for stamp %d", i);
     785                psFree(models);
     786                psFree(modelSums);
     787                psFree(ratios);
     788                psFree(mask);
     789                return false;
     790            }
     791        }
     792    }
     793
     794    if (!psThreadPoolWait(true)) {
     795        psError(PS_ERR_UNKNOWN, false, "Error waiting for threads.");
     796        psFree(models);
     797        psFree(modelSums);
     798        psFree(ratios);
     799        psFree(mask);
     800            return false;
     801    }
     802
    729803    psFree(models);
    730804    psFree(modelSums);
  • trunk/psModules/src/imcombine/pmSubtractionMatch.h

    r18287 r18962  
    1515#define PM_SUBTRACTION_ANALYSIS_STAMPS_NUM "SUBTRACTION.NUM"// Name of the number of stamps in the analysis MD
    1616#define PM_SUBTRACTION_ANALYSIS_VARFACTOR "SUBTRACTION.VARFACTOR"// Name of variance factor in the analysis MD
     17
    1718
    1819/// Match two images
     
    5152    );
    5253
     54/// Execute a thread job to measure the PSF width ratios
     55bool pmSubtractionOrderThread(const psThreadJob *job ///< Job to execute
     56    );
     57
     58/// Measure the PSF width ratio for a single stamp
     59bool pmSubtractionOrderStamp(psVector *ratios, ///< PSF width ratios
     60                             psVector *mask, ///< Mask for PSF width ratios
     61                             const pmSubtractionStampList *stamps, ///< List of stamps
     62                             const psArray *models, ///< Pre-calculated gaussian models
     63                             const psVector *modelSums, ///< Pre-calculated gaussian model sums
     64                             int index, ///< Index of stamp
     65                             float bg1, ///< Background for image 1
     66                             float bg2  ///< Background for image 2
     67    );
     68
    5369/// Determine which image to convolve
    5470pmSubtractionMode pmSubtractionOrder(pmSubtractionStampList *stamps, ///< Stamps that have been extracted
    55                                      float bg1, float bg2 // Background for each image
     71                                     float bg1, float bg2 ///< Background for each image
    5672    );
    5773
  • trunk/psModules/src/psmodules.h

    r18905 r18962  
    8585#include <pmStackReject.h>
    8686#include <pmSubtraction.h>
     87#include <pmSubtractionThreads.h>
    8788#include <pmSubtractionStamps.h>
    8889#include <pmSubtractionKernels.h>
Note: See TracChangeset for help on using the changeset viewer.