IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jul 31, 2008, 2:13:59 PM (18 years ago)
Author:
eugene
Message:

adding multithread capability

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/pswarp/src/pswarpTransformReadout.c

    r12744 r18839  
    11# include "pswarp.h"
    22
    3 bool pswarpTransformReadout (pmReadout *output, pmReadout *input, pmConfig *config) {
    4 
     3// NOTE: in this function, the coordinates are transformed from the OUTPUT to the INPUT
     4bool pswarpTransformReadout(pmReadout *output, pmReadout *input, pmConfig *config)
     5{
    56    // XXX this implementation currently ignores the use of the region
    67    psImage *region = NULL;
    7     pmCell *cell = NULL;
    88
    9     // select the current recipe
    10     // psMetadata *recipe  = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
     9    psTimerStart ("warp");
    1110
    12     int outNx = output->image->numCols;
    13     int outNy = output->image->numRows;
     11    // Get warp parameters
     12    bool mdok;
     13    int nGridX = psMetadataLookupS32(NULL, config->arguments, "GRID.NX");
     14    int nGridY = psMetadataLookupS32(NULL, config->arguments, "GRID.NY");
     15    psImageInterpolateMode interpolationMode = psMetadataLookupS32(NULL, config->arguments, "INTERPOLATION.MODE");
    1416
    15     psPlane *inPix = psPlaneAlloc();    // Coordinates on the input detector
    16     psPlane *outPix = psPlaneAlloc();   // Coordinates on the output detector
     17    // load the recipe
     18    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE);
     19    psAssert (recipe, "missing recipe %s", PSWARP_RECIPE);
    1720
    18     psPlane *FP = psPlaneAlloc();       // Coordinates on the focal plane
    19     psPlane *TP = psPlaneAlloc();       // Coordinates on the tangent plane
    20     psSphere *sky = psSphereAlloc();    // Coordinates on the sky
     21    // output mask bits
     22    psMaskType maskIn   = psMetadataLookupU8(&mdok, recipe, "MASK.INPUT");
     23    psMaskType maskPoor = pmConfigMaskGet("POOR.WARP", config);
     24    psMaskType maskBad  = pmConfigMaskGet("BAD.WARP", config);
     25    psAssert (mdok, "MASK.INPUT was not defined");
    2126
    22     cell = input->parent;
    23     pmChip *chipInput = cell->parent;
    24     pmFPA *fpaInput = chipInput->parent;
     27    int nThreads = psMetadataLookupS32 (&mdok, config->arguments, "NTHREADS");
     28    if (!mdok) nThreads = 0;
    2529
    26     cell = output->parent;
    27     pmChip *chipOutput = cell->parent;
    28     pmFPA *fpaOutput = chipOutput->parent;
     30    // Flux fraction for "poor"
     31    float poorFrac = psMetadataLookupF32(NULL, config->arguments, "POOR.FRAC");
    2932
    30     psF32 **outData = output->image->data.F32;
    31     psImage *inImage = input->image;
     33    // pswarpMapGridFromImage builds a set of locally-linear maps which convert the
     34    // output coordinates to input coordinates
     35    pswarpMapGrid *grid = pswarpMapGridFromImage (input, output, nGridX, nGridY);
    3236
    33     psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(PS_INTERPOLATE_BILINEAR, inImage,
    34                                                                        NULL, NULL, 0, NAN, NAN, 0, 0, 0.0);
     37    // XXX optionally modify the grid based on this result and force the maxError < XXX
     38    double maxError = pswarpMapGridMaxError (grid);
     39    psLogMsg ("pswarp", 3, "maximum error using this grid sampling: %f\n", maxError);
    3540
    36     // Iterate over the output image pixels
    37     for (int y = 0; y < outNy; y++) {
    38         for (int x = 0; x < outNx; x++) {
    39             // Only transform those pixels requested
    40             if (region && region->data.U8[y][x]) continue;
     41    // Interpolation options : move these from the arguments to explicit assignments
     42    psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(interpolationMode, input->image, input->weight, input->mask, maskIn, NAN, NAN, maskBad, maskPoor, poorFrac);
    4143
    42             // XXX double check this 1/2 pixel offset
    43             outPix->x = (double)x + 0.5;
    44             outPix->y = (double)y + 0.5;
     44    if (input->weight && !output->weight) {
     45        output->weight = psImageAlloc(output->image->numCols, output->image->numRows, PS_TYPE_F32);
     46        psImageInit(output->weight, NAN);
     47    }
     48    if ((input->mask || maskPoor || maskBad) && !output->mask) {
     49        output->mask = psImageAlloc(output->image->numCols, output->image->numRows, PS_TYPE_MASK);
     50        psImageInit(output->mask, maskBad);
     51    }
    4552
    46             psPlaneTransformApply(FP, chipOutput->toFPA, outPix);
    47             psPlaneTransformApply (TP, fpaOutput->toTPA, FP);
    48             psDeproject (sky, TP, fpaOutput->toSky);
     53    // total number of good pixels across all tiles (summed below)
     54    int goodPixels = 0;
    4955
    50             psProject (TP, sky, fpaInput->toSky);
    51             psPlaneTransformApply (FP, fpaInput->fromTPA, TP);
    52             psPlaneTransformApply (inPix, chipInput->fromFPA, FP);
     56    // create jobs and supply them to the threads
     57    for (int gridY = 0; gridY < grid->nYpts; gridY++) {
     58        for (int gridX = 0; gridX < grid->nXpts; gridX++) {
    5359
    54             // XXX get interpolation method from the recipe
    55             double value;
    56             if (!psImageInterpolate(&value, NULL, NULL, inPix->x, inPix->y, interp)) {
    57                 psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image.");
    58                 psFree(interp);
    59                 psFree(inPix);
    60                 psFree(outPix);
    61                 psFree(FP);
    62                 psFree(TP);
    63                 psFree(sky);
    64                 return false;
    65             }
     60            pswarpTransformTileArgs *args = pswarpTransformTileArgsAlloc();
    6661
    67             outData[y][x] = value;
    68             // modify zero and scale?
     62            // these items are just views to the data; they are not freed with args
     63            args->input = input;
     64            args->output = output;
     65            args->grid = grid;
     66            args->interp = interp;
     67            args->region = region;
     68
     69            args->gridX = gridX;
     70            args->gridY = gridY;
     71            args->goodPixels = 0;
     72
     73            // allocate a job
     74            psThreadJob *job = psThreadJobAlloc ("PSWARP_TRANSFORM_TILE");
     75
     76            // construct the arguments for this job
     77            // job is pswarpTransformTile (gridX, gridY);
     78            psArrayAdd (job->args, 1, args);
     79            // fprintf (stderr, "adding job %d,%d, Nargs: %ld\n", gridX, gridY, job->args->n);
     80
     81            // call: pswarpTransformTile (args);
     82            if (!psThreadJobAddPending (job)) {
     83                psError(PS_ERR_UNKNOWN, false, "Unable to warp image.");
     84                return false;
     85            }
     86            psFree (args);
     87        }
     88    }
     89
     90    // wait for the threads to finish and manage results
     91    // wait here for the threaded jobs to finish
     92    if (!psThreadPoolWait ()) {
     93        psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image.");
     94        return false;
     95    }
     96    fprintf (stderr, "success for threaded jobs\n");
     97
     98    // each job records its own goodPixel values; sum them here
     99    // we have only supplied one type of job, so we can assume the types here
     100    psThreadJob *job = NULL;
     101    while ((job = psThreadJobGetDone()) != NULL) {
     102        if (job->args->n < 1) {
     103            fprintf (stderr, "error with job\n");
     104        } else {
     105            pswarpTransformTileArgs *args = job->args->data[0];
     106            // fprintf (stderr, "finished job %d,%d, Nargs: %ld\n", args->gridX, args->gridY, job->args->n);
     107            goodPixels += args->goodPixels;
     108        }
     109        psFree (job);
     110    }
     111    psFree(interp);
     112    psFree(grid);
     113
     114
     115    // Store the variance factor and number of good pixels
     116    if (goodPixels > 0) {
     117        // Variance factor: large factor --> small scale
     118        float varFactor = psImageInterpolateVarianceFactor(input->image->numCols / 2.0 + input->image->col0, input->image->numRows / 2.0 + input->image->row0, interp);
     119        psMetadataItem *vfItem = psMetadataLookup(output->analysis, PSWARP_ANALYSIS_VARFACTOR);
     120        if (vfItem) {
     121            psMetadataItem *goodpixItem = psMetadataLookup(output->analysis, PSWARP_ANALYSIS_GOODPIX);
     122            psAssert(goodpixItem, "It should be where we left it!");
     123            psAssert(vfItem->type == PS_TYPE_F32 && goodpixItem->type == PS_TYPE_S64,
     124                     "Should be the type we said.");
     125
     126            vfItem->data.F32 += varFactor * goodPixels;
     127            goodpixItem->data.S64 += goodPixels;
     128        } else {
     129            psMetadataAddF32(output->analysis, PS_LIST_TAIL, PSWARP_ANALYSIS_VARFACTOR, 0,
     130                             "Variance factor weighted by the good pixels", varFactor * goodPixels);
     131            psMetadataAddS64(output->analysis, PS_LIST_TAIL, PSWARP_ANALYSIS_GOODPIX, 0,
     132                             "Number of good pixels", goodPixels);
    69133        }
    70134    }
    71     psFree(interp);
    72     psFree(inPix);
    73     psFree(outPix);
    74     psFree(FP);
    75     psFree(TP);
    76     psFree(sky);
     135
     136    if (goodPixels > 0) {
     137        if (!pswarpTransformSources (output, input, config)) {
     138            psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image.");
     139            return false;
     140        }
     141    }
     142
     143    // XXX should we not write anything out if there are no good pixels?
     144    output->data_exists = true;
     145    output->parent->data_exists = true;
     146    output->parent->parent->data_exists = true;
     147
     148    psLogMsg ("pswarp", 3, "warping analysis: %f sec\n", psTimerMark ("warp"));
    77149
    78150    return true;
Note: See TracChangeset for help on using the changeset viewer.