Changeset 20411 for trunk/psphot/src/psphotGuessModels.c
- Timestamp:
- Oct 26, 2008, 5:17:43 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/psphot/src/psphotGuessModels.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/psphotGuessModels.c
r19881 r20411 1 1 # include "psphotInternal.h" 2 3 bool psphotChooseCellSizes (int *Cx, int *Cy, pmReadout *readout, int nThreads); 4 psphotGuessModelForRegionArgs *psphotGuessModelForRegionArgsAlloc(); 5 bool psphotGuessModelForRegion (psphotGuessModelForRegionArgs *args); 2 6 3 7 // A guess for when the moments aren't available … … 16 20 } 17 21 22 # define NFILL 4 23 18 24 // construct an initial PSF model for each object 19 bool psphotGuessModels (pm Readout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf) {25 bool psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf) { 20 26 21 27 bool status; 22 28 23 29 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; 24 40 25 41 // bit-masks to test for good/bad pixels … … 37 53 psphotInitRadiusPSF (recipe, psf->type); 38 54 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 148 static 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 157 psphotGuessModelForRegionArgs *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 173 bool 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 39 184 for (int i = 0; i < sources->n; i++) { 40 185 pmSource *source = sources->data[i]; … … 43 188 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 44 189 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 46 199 // XXX if a source is faint, it will not have moments measured. 47 200 // it must be modelled as a PSF. In this case, we need to use … … 53 206 } else { 54 207 // use the source moments, etc to guess basic model parameters 55 modelEXT = pmSourceModelGuess (source, psf->type); 208 modelEXT = pmSourceModelGuess (source, psf->type); // ALLOC 56 209 if (!modelEXT) { 57 210 modelEXT = wildGuess(source, psf); … … 68 221 69 222 // set PSF parameters for this model (apply 2D shape model) 70 pmModel *modelPSF = pmModelFromPSF (modelEXT, psf); 223 pmModel *modelPSF = pmModelFromPSF (modelEXT, psf); // ALLOC 71 224 if (modelPSF == NULL) { 72 225 psError(PSPHOT_ERR_PSF, false, … … 92 245 // XXX need to define the guess flux? 93 246 // set the fit radius based on the object flux limit and the model 247 // this function affects the mask pixels 94 248 psphotCheckRadiusPSF (readout, source, modelPSF, markVal); 95 249 … … 99 253 100 254 pmSourceCacheModel (source, maskVal); 255 101 256 } 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); 103 259 return true; 104 260 } 105 261 106 // XXX do we always know which model is supposed to be used? 262 bool 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.
