IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Oct 26, 2008, 5:17:43 PM (18 years ago)
Author:
eugene
Message:

adding threading option (not quite ready; disabled), new psphotInit function

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src/psphotGuessModels.c

    r19881 r20411  
    11# include "psphotInternal.h"
     2
     3bool psphotChooseCellSizes (int *Cx, int *Cy, pmReadout *readout, int nThreads);
     4psphotGuessModelForRegionArgs *psphotGuessModelForRegionArgsAlloc();
     5bool psphotGuessModelForRegion (psphotGuessModelForRegionArgs *args);
    26
    37// A guess for when the moments aren't available
     
    1620}
    1721
     22# define NFILL 4
     23
    1824// construct an initial PSF model for each object
    19 bool psphotGuessModels (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf) {
     25bool psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf) {
    2026
    2127    bool status;
    2228
    2329    psTimerStart ("psphot");
     30
     31    // select the appropriate recipe information
     32    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     33    assert (recipe);
     34
     35    // int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads
     36    // if (!status) {
     37    // nThreads = 0;
     38    // }
     39    int nThreads = 0;
    2440
    2541    // bit-masks to test for good/bad pixels
     
    3753    psphotInitRadiusPSF (recipe, psf->type);
    3854
     55    // the strategy here is to divide the image into 2x2 blocks of cells and cycle through
     56    // the four discontiguous sets of cells, threading all within a set and blocking between
     57    // sets
     58
     59    // we divide the image region into 2*2 blocks of size Nx*Ny, the image will have
     60    // Cx*Cy blocks so that (2Nx)Cx = numCols, (2Ny)Cy = numRows.  We want to choose Cx and
     61    // Cy so that (2Nx)Cx * (2Ny)Cy = 4 * NFILL * nThreads -- each of the four sets of cells
     62    // has enough cells to allow NFILL cells for each thread (to better distribute heavy and
     63    // light load cells
     64   
     65    // choose Cx, Cy:
     66    int Cx = 1, Cy = 1;
     67    psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);
     68
     69    // the array runs from readout->image->col0 to readout->image->col0 + readout->image->numCols
     70    int Xo = readout->image->col0;
     71    int Yo = readout->image->row0;
     72    int Nx = readout->image->numCols / (2*Cx);
     73    int Ny = readout->image->numRows / (2*Cy);
     74
     75    // we can thread all of the cells within a set, but need to block between sets
     76    for (int jy = 0; jy < 2; jy++) {
     77        for (int jx = 0; jx < 2; jx++) {
     78
     79            // generate jobs for all of the Cx*Cy cells in this set
     80            for (int ix = 0; ix < Cx; ix++) {
     81                for (int iy = 0; iy < Cy; iy++) {
     82               
     83                    int x0 = (2*ix + jx)*Nx + Xo;
     84                    int x1 = x0 + Nx;
     85
     86                    int y0 = (2*iy + jy)*Ny + Yo;
     87                    int y1 = y0 + Ny;
     88
     89                    if (readout->image->numCols + Xo - x1 < Nx) {
     90                        x1 = readout->image->numCols + Xo;
     91                    }
     92                    if (readout->image->numRows + Yo - y1 < Ny) {
     93                        y1 = readout->image->numRows + Yo;
     94                    }
     95
     96                    // fprintf (stderr, "launch %d,%d - %d,%d\n", x0, y0, x1, y1);
     97                   
     98                    psRegion *cellRegion = psRegionAlloc (x0, x1, y0, y1);
     99                    *cellRegion = psRegionForImage (readout->image, *cellRegion);
     100                    // if we got the math above right, this should be a NOP
     101                                                                             
     102                    psphotGuessModelForRegionArgs *args = psphotGuessModelForRegionArgsAlloc();
     103                    args->readout = psMemIncrRefCounter(readout);
     104                    args->sources = psMemIncrRefCounter(sources);
     105                    args->psf     = psMemIncrRefCounter(psf);
     106                    args->region  = psMemIncrRefCounter(cellRegion);
     107
     108                    args->maskVal = maskVal;
     109                    args->markVal = markVal;
     110
     111                    // allocate a job -- if threads are not defined, this just runs the job
     112                    psThreadJob *job = psThreadJobAlloc ("PSPHOT_GUESS_MODEL");
     113                    psArrayAdd(job->args, 1, args);
     114                    if (!psThreadJobAddPending(job)) {
     115                        psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     116                        return false;
     117                    }
     118                    psFree(cellRegion);
     119                    psFree(job);
     120                    psFree(args);
     121                }
     122            }
     123
     124            // wait for the threads to finish and manage results
     125            // wait here for the threaded jobs to finish
     126            // fprintf (stderr, "wait for threads (%d, %d)\n", jx, jy);
     127            if (!psThreadPoolWait (false)) {
     128                psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");
     129                return false;
     130            }
     131
     132            // we have only supplied one type of job, so we can assume the types here
     133            psThreadJob *job = NULL;
     134            while ((job = psThreadJobGetDone()) != NULL) {
     135                // we have no returned data from this operation
     136                if (job->args->n < 1) {
     137                    fprintf (stderr, "error with job\n");
     138                }
     139                psFree(job);
     140            }
     141        }
     142    }
     143   
     144    psLogMsg ("psphot.models", 4, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot"));
     145    return true;
     146}
     147
     148static void psphotGuessModelForRegionArgsFree(psphotGuessModelForRegionArgs *args)
     149{
     150    psFree(args->readout);
     151    psFree(args->sources);
     152    psFree(args->psf);
     153    psFree(args->region);
     154    return;
     155}
     156
     157psphotGuessModelForRegionArgs *psphotGuessModelForRegionArgsAlloc()
     158{
     159    psphotGuessModelForRegionArgs *args = psAlloc(sizeof(psphotGuessModelForRegionArgs));
     160    psMemSetDeallocator(args, (psFreeFunc)psphotGuessModelForRegionArgsFree);
     161
     162    args->readout = NULL;
     163    args->sources = NULL;
     164    args->psf = NULL;
     165    args->region = NULL;
     166
     167    args->maskVal = 0;
     168    args->markVal = 0;
     169    return args;
     170}
     171
     172// construct models only for sources in the specified region
     173bool psphotGuessModelForRegion (psphotGuessModelForRegionArgs *args) {
     174
     175    pmReadout *readout = args->readout;
     176    psArray *sources = args->sources;
     177    pmPSF *psf = args->psf;
     178    psRegion *region = args->region;
     179    psMaskType maskVal = args->maskVal;
     180    psMaskType markVal = args->markVal;
     181
     182    int nSrc = 0;
     183
    39184    for (int i = 0; i < sources->n; i++) {
    40185        pmSource *source = sources->data[i];
     
    43188        if (source->type == PM_SOURCE_TYPE_DEFECT) continue;
    44189        if (source->type == PM_SOURCE_TYPE_SATURATED) continue;
    45 
     190        if (!source->peak) continue;
     191
     192        if (source->peak->xf <  region->x0) continue;
     193        if (source->peak->yf <  region->y0) continue;
     194        if (source->peak->xf >= region->x1) continue;
     195        if (source->peak->yf >= region->y1) continue;
     196
     197        nSrc ++;
     198       
    46199        // XXX if a source is faint, it will not have moments measured.
    47200        // it must be modelled as a PSF.  In this case, we need to use
     
    53206        } else {
    54207            // use the source moments, etc to guess basic model parameters
    55             modelEXT = pmSourceModelGuess (source, psf->type);
     208            modelEXT = pmSourceModelGuess (source, psf->type); // ALLOC
    56209            if (!modelEXT) {
    57210                modelEXT = wildGuess(source, psf);
     
    68221
    69222        // set PSF parameters for this model (apply 2D shape model)
    70         pmModel *modelPSF = pmModelFromPSF (modelEXT, psf);
     223        pmModel *modelPSF = pmModelFromPSF (modelEXT, psf); // ALLOC
    71224        if (modelPSF == NULL) {
    72225            psError(PSPHOT_ERR_PSF, false,
     
    92245        // XXX need to define the guess flux?
    93246        // set the fit radius based on the object flux limit and the model
     247        // this function affects the mask pixels
    94248        psphotCheckRadiusPSF (readout, source, modelPSF, markVal);
    95249
     
    99253
    100254        pmSourceCacheModel (source, maskVal);
     255
    101256    }
    102     psLogMsg ("psphot.models", 4, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot"));
     257
     258    // fprintf (stderr, "%d for region %lf,%lf - %lf,%lf\n", nSrc, region->x0, region->y0, region->x1, region->y1);
    103259    return true;
    104260}
    105261
    106 // XXX do we always know which model is supposed to be used?
     262bool psphotChooseCellSizes (int *Cx, int *Cy, pmReadout *readout, int nThreads) {
     263
     264    int nCells = nThreads * NFILL; // number of cells in a single set
     265    int C = sqrt(nCells) + 0.5;
     266   
     267    // we need to assign Cx and Cy based on the dimensionality of the image
     268    // crude way to find most evenly balanced factors of nCells:
     269    for (int i = C; i >= 1; i--) {
     270        int C1 = nCells / C;
     271        int C2 = nCells / C1;
     272        if (C1*C2 != nCells) continue;
     273
     274        if (readout->image->numRows > readout->image->numCols) {
     275            *Cx = PS_MAX (C1, C2);
     276            *Cy = PS_MIN (C1, C2);
     277        } else {
     278            *Cx = PS_MAX (C1, C2);
     279            *Cy = PS_MIN (C1, C2);
     280        }
     281        return true;
     282    }
     283    *Cx = 1;
     284    *Cy = 1;
     285
     286    return true;
     287}
Note: See TracChangeset for help on using the changeset viewer.