Changeset 18839
- Timestamp:
- Jul 31, 2008, 2:13:59 PM (18 years ago)
- Location:
- trunk
- Files:
-
- 8 added
- 14 edited
-
ppMerge/src/Makefile.am (modified) (1 diff)
-
ppMerge/src/ppMerge.c (modified) (1 diff)
-
ppMerge/src/ppMerge.h (modified) (3 diffs)
-
ppMerge/src/ppMergeArguments.c (modified) (2 diffs)
-
ppMerge/src/ppMergeLoop_Threaded.c (modified) (5 diffs)
-
ppMerge/src/ppMergeReadChunk.c (modified) (4 diffs)
-
ppMerge/src/ppMergeSetThreads.c (added)
-
ppMerge/src/ppMergeThreadLauncher.c (modified) (1 diff)
-
pswarp/src/Makefile.am (modified) (1 diff)
-
pswarp/src/pswarp.h (modified) (5 diffs)
-
pswarp/src/pswarpArguments.c (modified) (1 diff)
-
pswarp/src/pswarpCleanup.c (modified) (1 diff)
-
pswarp/src/pswarpLoop.c (modified) (1 diff)
-
pswarp/src/pswarpMapGrid.c (modified) (3 diffs)
-
pswarp/src/pswarpSetThreads.c (added)
-
pswarp/src/pswarpThreadLauncher.c (added)
-
pswarp/src/pswarpThreads.c (added)
-
pswarp/src/pswarpTransformReadout.c (modified) (1 diff)
-
pswarp/src/pswarpTransformReadout_Threaded.c (added)
-
pswarp/src/pswarpTransformReadout_Unthreaded.c (added)
-
pswarp/src/pswarpTransformSources.c (added)
-
pswarp/src/pswarpTransformTile.c (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppMerge/src/Makefile.am
r18758 r18839 10 10 ppMergeFiles.c \ 11 11 ppMergeScaleZero.c \ 12 ppMergeLoop.c \13 12 ppMergeFileGroup.c \ 13 ppMergeReadChunk.c \ 14 ppMergeLoop_Threaded.c \ 15 ppMergeSetThreads.c \ 14 16 ppMergeMask.c 15 17 16 # ppMergeLoop_Threaded.c 17 # ppMergeThreadLauncher.c 18 18 # ppMergeLoop.c 19 19 20 20 noinst_HEADERS = \ -
trunk/ppMerge/src/ppMerge.c
r18757 r18839 10 10 { 11 11 psLibInit(NULL); 12 psMemSetThreadSafety(false);13 12 psTimerStart(TIMERNAME); 14 13 -
trunk/ppMerge/src/ppMerge.h
r18758 r18839 15 15 #define TIMERNAME "ppMerge" // Name for timer 16 16 #define PPMERGE_RECIPE "PPMERGE" // Recipe name 17 #define THREADED 017 #define THREADED 1 18 18 19 19 // Type of frame to merge … … 39 39 bool read; 40 40 bool busy; 41 int firstScan; 42 int lastScan; 41 43 } ppMergeFileGroup; 42 44 … … 100 102 101 103 ppMergeFileGroup *ppMergeFileGroupAlloc(); 102 ppMergeFileGroup *ppMergeReadChunk ( psArray *fileGroups, pmConfig *config, int numChunk);104 ppMergeFileGroup *ppMergeReadChunk (bool *status, psArray *fileGroups, pmConfig *config, int numChunk); 103 105 void *ppMergeThreadLauncher (void *data); 104 106 107 bool ppMergeSetThreads (); 108 105 109 #endif -
trunk/ppMerge/src/ppMergeArguments.c
r18758 r18839 171 171 } 172 172 173 # if (THREADED)174 173 // Number of threads 175 174 if ((argnum = psArgumentGet(argc, argv, "-threads"))) { … … 181 180 // create the thread pool with number of desired threads, supplying our thread launcher function 182 181 // XXX need to determine the number of threads from the config data 183 psThreadPoolInit (nThreads , &ppMergeThreadLauncher);184 } 185 # endif 182 psThreadPoolInit (nThreads); 183 } 184 ppMergeSetThreads(); 186 185 187 186 if (argc == 1 || !psArgumentParse(arguments, &argc, argv) || argc != 3) { -
trunk/ppMerge/src/ppMergeLoop_Threaded.c
r18757 r18839 36 36 37 37 // General combination parameters 38 int rows = psMetadataLookupS32(NULL, arguments, "ROWS"); // Number of rows to read per chunk39 38 int iter = psMetadataLookupS32(NULL, arguments, "ITER"); // Number of rejection iterations 40 39 float rej = psMetadataLookupF32(NULL, arguments, "REJ"); // Rejection level … … 175 174 fileGroup->read = false; 176 175 fileGroup->busy = false; 176 fileGroup->lastScan = 0; 177 fileGroup->firstScan = 0; 177 178 fileGroups->data[i] = fileGroup; 178 179 } 179 180 181 // call the init functions 182 switch (type) { 183 case PPMERGE_TYPE_BIAS: 184 case PPMERGE_TYPE_FLAT: 185 case PPMERGE_TYPE_FRINGE: 186 psAssert (fileGroups->n > 0, "no valid file groups defined"); 187 ppMergeFileGroup *fileGroup = fileGroups->data[0]; 188 if (!pmReadoutCombinePrepare(outRO, fileGroup->readouts, combination)) { 189 goto ERROR; 190 } 191 break; 192 193 default: 194 fprintf (stderr, "not yet ready"); 195 goto ERROR; 196 } 197 180 198 // Read input data by chunks 199 // psTimerStart ("ppMergeLoop"); 181 200 for (int numChunk = 0; true; numChunk++) { 182 201 202 bool status = false; 183 203 ppMergeFileGroup *fileGroup = ppMergeReadChunk (&status, fileGroups, config, numChunk); 184 204 if (!status) goto ERROR; 185 205 if (!fileGroup) break; 186 206 207 psThreadJob *job = NULL; 208 187 209 switch (type) { 188 210 case PPMERGE_TYPE_SHUTTER: 189 if (nThreads) { 190 // allocate a job 191 psThreadJob *job = psThreadJobAlloc ("PPMERGE_SHUTTER_CORRECTION", 0); 192 193 // construct the arguments for this job 194 psArrayAdd (job->args, 1, outRO); 195 psArrayAdd (job->args, 1, fileGroup); 196 psArrayAdd (job->args, 1, psScalarAlloc(shutterRef, PS_TYPE_F32)) 197 psArrayAdd (job->args, 1, shutters->data[cellNum]); 198 psArrayAdd (job->args, 1, psScalarAlloc(iter, PS_TYPE_S32)); 199 psArrayAdd (job->args, 1, psScalarAlloc(rej, PS_TYPE_F32)); 200 psArrayAdd (job->args, 1, psScalarAlloc(maskVal, PS_TYPE_U8)); 201 202 psThreadJobAddPending (job); 203 } else { 204 if (!pmShutterCorrectionGenerate(outRO, NULL, fileGroup->readouts, shutterRef, shutters->data[cellNum], iter, rej, maskVal)) { 205 goto ERROR; 206 } 207 fileGroup->busy = false; 211 // allocate a job 212 job = psThreadJobAlloc ("PPMERGE_SHUTTER_CORRECTION"); 213 214 // construct the arguments for this job 215 psArrayAdd (job->args, 1, outRO); 216 psArrayAdd (job->args, 1, fileGroup); 217 psArrayAdd (job->args, 1, psScalarAlloc(shutterRef, PS_TYPE_F32)); 218 psArrayAdd (job->args, 1, shutters->data[cellNum]); 219 psArrayAdd (job->args, 1, psScalarAlloc(iter, PS_TYPE_S32)); 220 psArrayAdd (job->args, 1, psScalarAlloc(rej, PS_TYPE_F32)); 221 psArrayAdd (job->args, 1, psScalarAlloc(maskVal, PS_TYPE_U8)); 222 223 // call: pmShutterCorrectionGenerate(outRO, NULL, fileGroup->readouts, shutterRef, shutters->data[cellNum], iter, rej, maskVal) 224 if (!psThreadJobAddPending (job)) { 225 goto ERROR; 208 226 } 209 227 break; 210 228 case PPMERGE_TYPE_DARK: 211 if (nThreads) { 212 // allocate a job 213 psThreadJob *job = psThreadJobAlloc ("PPMERGE_DARK_COMBINE", 0); 214 215 // construct the arguments for this job 216 psArrayAdd (job->args, 1, outCell); 217 psArrayAdd (job->args, 1, fileGroup); 218 psArrayAdd (job->args, 1, darkOrdinates); 219 psArrayAdd (job->args, 1, darkNorm); 220 psArrayAdd (job->args, 1, psScalarAlloc(iter, PS_TYPE_S32)); 221 psArrayAdd (job->args, 1, psScalarAlloc(rej, PS_TYPE_F32)); 222 psArrayAdd (job->args, 1, psScalarAlloc(maskVal, PS_TYPE_U8)); 223 224 psThreadJobAddPending (job); 225 } else { 226 if (!pmDarkCombine(outCell, fileGroup->readouts, darkOrdinates, darkNorm, iter, rej, maskVal)) { 227 goto ERROR; 228 } 229 fileGroup->busy = false; 229 // allocate a job 230 job = psThreadJobAlloc ("PPMERGE_DARK_COMBINE"); 231 232 // construct the arguments for this job 233 psArrayAdd (job->args, 1, outCell); 234 psArrayAdd (job->args, 1, fileGroup); 235 psArrayAdd (job->args, 1, darkOrdinates); 236 psArrayAdd (job->args, 1, darkNorm); 237 psArrayAdd (job->args, 1, psScalarAlloc(iter, PS_TYPE_S32)); 238 psArrayAdd (job->args, 1, psScalarAlloc(rej, PS_TYPE_F32)); 239 psArrayAdd (job->args, 1, psScalarAlloc(maskVal, PS_TYPE_U8)); 240 241 // call: pmDarkCombine(outCell, fileGroup->readouts, darkOrdinates, darkNorm, iter, rej, maskVal); 242 if (!psThreadJobAddPending (job)) { 243 goto ERROR; 230 244 } 231 245 break; … … 233 247 case PPMERGE_TYPE_FLAT: 234 248 case PPMERGE_TYPE_FRINGE: 235 if (nThreads) { 236 // allocate a job 237 psThreadJob *job = psThreadJobAlloc ("PPMERGE_READOUT_COMBINE", 0); 238 239 // construct the arguments for this job 240 psArrayAdd (job->args, 1, outRO); 241 psArrayAdd (job->args, 1, fileGroup); 242 psArrayAdd (job->args, 1, zeros); 243 psArrayAdd (job->args, 1, scales); 244 psArrayAdd (job->args, 1, combination); 245 246 psThreadJobAddPending (job); 247 } else { 248 if (!pmReadoutCombine(outRO, fileGroup->readouts, zeros, scales, combination)) { 249 goto ERROR; 250 } 251 fileGroup->busy = false; 249 // allocate a job 250 job = psThreadJobAlloc ("PPMERGE_READOUT_COMBINE"); 251 252 // construct the arguments for this job 253 psArrayAdd (job->args, 1, outRO); 254 psArrayAdd (job->args, 1, fileGroup); 255 psArrayAdd (job->args, 1, zeros); 256 psArrayAdd (job->args, 1, scales); 257 psArrayAdd (job->args, 1, combination); 258 259 // call: pmReadoutCombine(outRO, fileGroup->readouts, zeros, scales, combination); 260 if (!psThreadJobAddPending (job)) { 261 goto ERROR; 252 262 } 253 263 break; … … 258 268 259 269 // wait for the threads to finish and manage results 260 if (nThreads) { 261 // wait here for the threaded jobs to finish 262 if (!psThreadPoolWait ()) { 263 psError(PS_ERR_UNKNOWN, false, "Unable to interpolate image."); 264 return false; 265 } 266 fprintf (stderr, "success for threaded jobs\n"); 267 268 // we don't care about the results, just dump the done queue jobs 269 psThreadJob *job = NULL; 270 while ((job = psThreadJobGetDone()) != NULL) { 271 psFree (job); 272 } 270 if (!psThreadPoolWait ()) { 271 psError(PS_ERR_UNKNOWN, false, "Unable to combine images."); 272 return false; 273 273 } 274 275 // we don't care about the results, just dump the done queue jobs 276 psThreadJob *job = NULL; 277 while ((job = psThreadJobGetDone()) != NULL) { 278 psFree (job); 279 } 280 281 psFree(fileGroups); 274 282 275 283 // Get list of cells for concepts averaging 276 284 psList *inCells = psListAlloc(NULL); // List of cells 277 285 for (int i = 0; i < numFiles; i++) { 278 pmReadout *readout = readouts->data[i]; // Readout of interest 279 psListAdd(inCells, PS_LIST_TAIL, readout->parent); 286 pmFPAfile *input = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT", i); 287 pmCell *inCell = pmFPAviewThisCell(view, input->fpa); // Input cell 288 psListAdd(inCells, PS_LIST_TAIL, inCell); 280 289 } 281 290 if (!pmConceptsAverageCells(outCell, inCells, NULL, NULL, true)) { … … 286 295 } 287 296 psFree(inCells); 288 289 psFree(fileGroups); 297 // fprintf (stdout, "done ppMergeLoop for cell : %f\n", psTimerMark ("ppMergeLoop")); 290 298 291 299 // Plug supplementary images into their own FPAs -
trunk/ppMerge/src/ppMergeReadChunk.c
r18757 r18839 1 1 # include "ppMerge.h" 2 2 3 ppMergeFileGroup *ppMergeReadChunk (psArray *fileGroups, pmConfig *config, int numChunk) { 3 ppMergeFileGroup *ppMergeReadChunk (bool *status, psArray *fileGroups, pmConfig *config, int numChunk) { 4 5 *status = true; 6 7 bool mdok; 8 bool haveMasks = psMetadataLookupBool(&mdok, config->arguments, "INPUTS.MASKS"); // Do we have masks? 9 bool haveWeights = psMetadataLookupBool(&mdok, config->arguments, "INPUTS.WEIGHTS"); // Do we have weights? 10 int rows = psMetadataLookupS32(NULL, config->arguments, "ROWS"); // Number of rows to read per chunk 4 11 5 12 // select an available fileGroup 6 7 bool haveMasks = psMetadataLookupBool(&mdok, arguments, "INPUTS.MASKS"); // Do we have masks?8 bool haveWeights = psMetadataLookupBool(&mdok, arguments, "INPUTS.WEIGHTS"); // Do we have weights?9 10 13 while (1) { 11 14 // check for any fileGroups which can read data … … 14 17 if (fileGroup->read) continue; 15 18 19 // find max last scan so far 20 int lastScan = 0; 21 for (int i = 0; i < fileGroups->n; i++) { 22 ppMergeFileGroup *fileGroup = fileGroups->data[i]; 23 lastScan = PS_MAX (fileGroup->lastScan, lastScan); 24 } 25 fileGroup->firstScan = lastScan; 26 fileGroup->lastScan = lastScan + rows; 27 16 28 psArray *readouts = fileGroup->readouts; 29 30 psTimerStart ("ppMergeReadChunk"); 17 31 18 32 psTrace("ppStack", 2, "Reading data for chunk %d into fileGroup %d....n", numChunk, j); … … 20 34 pmReadout *inRO = readouts->data[i]; // Input readout 21 35 36 // override the recorded last scan 37 inRO->thisImageScan = fileGroup->firstScan; 38 inRO->thisWeightScan = fileGroup->firstScan; 39 inRO->thisMaskScan = fileGroup->firstScan; 40 22 41 // Read a chunk from a file 23 42 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT", i); 24 if (!pmReadoutReadChunk(inRO, file->fits, 0, rows, 0, config)) {25 psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPMERGE.INPUT %d", numChunk, i);26 return NULL;27 }28 43 29 if (haveMasks) { 30 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.MASK", i); 31 if (!pmReadoutReadChunkMask(inRO, file->fits, 0, rows, 0, config)) { 32 psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPMERGE.INPUT.MASK %d", numChunk, NAME, i); 44 bool keepReading = false; 45 if (pmReadoutMore(inRO, file->fits, 0, rows, config)) { 46 keepReading = true; 47 if (!pmReadoutReadChunk(inRO, file->fits, 0, rows, 0, config)) { 48 psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPMERGE.INPUT %d", numChunk, i); 49 *status = false; 33 50 return NULL; 34 51 } 35 52 } 36 53 37 if (haveWeights) { 38 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.WEIGHT", i); 39 if (!pmReadoutReadChunkWeight(inRO, file->fits, 0, rows, 0, config)) { 40 psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPMERGE.INPUT.WEIGHT %d", numChunk, NAME, i); 54 if (haveMasks && pmReadoutMoreMask(inRO, file->fits, 0, rows, config)) { 55 keepReading = true; 56 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.MASK", i); 57 if (!pmReadoutReadChunkMask(inRO, file->fits, 0, rows, 0, config)) { 58 psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPMERGE.INPUT.MASK %d", numChunk, i); 59 *status = false; 41 60 return NULL; 42 61 } 43 62 } 63 64 if (haveWeights && pmReadoutMoreWeight(inRO, file->fits, 0, rows, config)) { 65 keepReading = true; 66 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.WEIGHT", i); 67 if (!pmReadoutReadChunkWeight(inRO, file->fits, 0, rows, 0, config)) { 68 psError(PS_ERR_IO, false, "Unable to read chunk %d for file PPMERGE.INPUT.WEIGHT %d", numChunk, i); 69 *status = false; 70 return NULL; 71 } 72 } 73 if (!keepReading) { 74 return NULL; 75 } 44 76 } 77 45 78 fileGroup->read = fileGroup->busy = true; 46 79 return fileGroup; … … 48 81 49 82 // check for any fileGroups which are done processing 50 bool wait = true; 51 bool more = true; 83 bool wait = false; 52 84 for (int j = 0; j < fileGroups->n; j++) { 53 85 ppMergeFileGroup *fileGroup = fileGroups->data[j]; 54 86 if (!fileGroup->read || fileGroup->busy) continue; 55 56 wait = false;57 psArray *readouts = fileGroup->readouts;58 // any more data to be read?59 for (int i = 0; i < readouts->n && more; i++) {60 pmReadout *inRO = readouts->data[i];61 62 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT", i);63 more &= pmReadoutMore(inRO, file->fits, 0, rows, config);64 65 if (haveMasks) {66 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.MASK", i);67 more &= pmReadoutMoreMask(inRO, file->fits, 0, rows, config);68 }69 if (haveWeights) {70 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPMERGE.INPUT.WEIGHT", i);71 more &= pmReadoutMoreWeight(inRO, file->fits, 0, rows, config);72 }73 }74 87 fileGroup->read = false; 88 wait = true; 75 89 } 76 if (!more) return NULL;77 78 90 if (wait) usleep (10000); 79 91 } -
trunk/ppMerge/src/ppMergeThreadLauncher.c
r18757 r18839 41 41 self->fault = true; 42 42 } 43 43 44 // we do not have to lock here because this transition is not tied to the job queue 44 45 fileGroup->busy = false; -
trunk/pswarp/src/Makefile.am
r18558 r18839 16 16 pswarpPixelFraction.c \ 17 17 pswarpSetMaskBits.c \ 18 pswarpTransformReadout_Opt.c \ 18 pswarpSetThreads.c \ 19 pswarpTransformReadout.c \ 20 pswarpTransformSources.c \ 21 pswarpTransformTile.c \ 19 22 pswarpVersion.c 20 23 -
trunk/pswarp/src/pswarp.h
r18558 r18839 10 10 #include <psmodules.h> 11 11 #include <psphot.h> 12 13 #define THREADED 1 12 14 13 15 #include "pswarpErrorCodes.h" … … 33 35 int nXpts, nYpts; // number of x,y samples in the grid 34 36 int nXpix, nYpix; // x,y spacing in src image pixels of grid samples 35 int xMin, yMin;// coordinate of first grid sample37 double xMin, yMin; // coordinate of first grid sample 36 38 } pswarpMapGrid; 39 40 typedef struct { 41 // values which are common to all tiles 42 pmReadout *input; 43 pmReadout *output; 44 pswarpMapGrid *grid; 45 psImageInterpolateOptions *interp; 46 psImage *region; 47 48 // input values for this tile 49 int gridX; 50 int gridY; 51 52 // output values for this tile 53 long goodPixels; 54 } pswarpTransformTileArgs; 55 56 pswarpTransformTileArgs *pswarpTransformTileArgsAlloc(); 57 bool pswarpTransformTile (pswarpTransformTileArgs *args); 37 58 38 59 pmConfig *pswarpArguments (int argc, char **argv); … … 44 65 void pswarpCleanup (pmConfig *config); 45 66 bool pswarpTransformReadout (pmReadout *output, pmReadout *input, pmConfig *config); 46 bool pswarpTransform Readout_Opt(pmReadout *output, pmReadout *input, pmConfig *config);67 bool pswarpTransformSources(pmReadout *output, pmReadout *input, pmConfig *config); 47 68 48 69 bool pswarpMatchRange (int *minX, int *minY, int *maxX, int *maxY, pmReadout *dest, pmReadout *src); … … 53 74 pswarpMapGrid *pswarpMapGridFromImage (pmReadout *dest, pmReadout *src, int nXpix, int nYpix); 54 75 bool pswarpMapGridSetGrid (pswarpMapGrid *grid, int ix, int iy, int *gridX, int *gridY); 76 bool pswarpMapGridCoordRange (pswarpMapGrid *grid, int gridX, int gridY, psPlane *min, psPlane *max); 55 77 int pswarpMapGridNextGrid_X (pswarpMapGrid *grid, int gridX); 56 78 int pswarpMapGridNextGrid_Y (pswarpMapGrid *grid, int gridY); … … 68 90 ); 69 91 92 // define threads for this program 93 bool pswarpSetThreads (); -
trunk/pswarp/src/pswarpArguments.c
r18558 r18839 40 40 psArgumentRemove(N, &argc, argv); 41 41 } 42 43 // Number of threads 44 if ((N = psArgumentGet(argc, argv, "-threads"))) { 45 psArgumentRemove(N, &argc, argv); 46 int nThreads = atoi(argv[N]); 47 psMetadataAddS32(config->arguments, PS_LIST_TAIL, "NTHREADS", 0, "number of warp threads", nThreads); 48 psArgumentRemove(N, &argc, argv); 49 50 // create the thread pool with number of desired threads, supplying our thread launcher function 51 // XXX need to determine the number of threads from the config data 52 psThreadPoolInit (nThreads); 53 } 54 pswarpSetThreads (); 42 55 43 56 // PSF determination? -
trunk/pswarp/src/pswarpCleanup.c
r14641 r18839 9 9 pmModelClassCleanup (); 10 10 psTimeFinalize (); 11 psThreadPoolFinalize (); 11 12 pmConceptsDone (); 12 13 pmConfigDone (); -
trunk/pswarp/src/pswarpLoop.c
r18558 r18839 241 241 } 242 242 243 pswarpTransformReadout _Opt(output, readout, config);243 pswarpTransformReadout(output, readout, config); 244 244 245 245 pmFPAfileIOChecks(config, view, PM_FPA_AFTER); -
trunk/pswarp/src/pswarpMapGrid.c
r12523 r18839 4 4 // coordinates (src) to destination coordinates (dest). we construct a grid with superpixel 5 5 // spacing of nXpix, nYpix. The transformation for each grid cell is valid for the superpixel. 6 // The grid over-fills the source image so ever source image pixel is guaranteed to have a map.6 // The grid over-fills the source image so every source image pixel is guaranteed to have a map. 7 7 pswarpMapGrid *pswarpMapGridFromImage (pmReadout *dest, pmReadout *src, int nXpix, int nYpix) { 8 8 … … 11 11 12 12 // start counting from the center of the superpixels 13 intxMin = 0.5*nXpix;14 intyMin = 0.5*nYpix;13 double xMin = 0.5*nXpix; 14 double yMin = 0.5*nYpix; 15 15 16 16 // the map is defined for coordinates in the image parent frame. … … 42 42 43 43 // set the grid coordinate (gridX,gridY) for the given source image coordinate (ix,iy) 44 // XXX return true if the result is on the src image, false otherwise (???) 44 45 bool pswarpMapGridSetGrid (pswarpMapGrid *grid, int ix, int iy, int *gridX, int *gridY) { 45 46 46 47 *gridX = 0.5 + (ix - grid->xMin) / (double) grid->nXpix; 47 48 *gridY = 0.5 + (iy - grid->yMin) / (double) grid->nYpix; 49 50 return true; 51 } 52 53 // given the specified grid coordinate (gridX, gridY), return the min and max coordinates for the tile 54 bool pswarpMapGridCoordRange (pswarpMapGrid *grid, int gridX, int gridY, psPlane *min, psPlane *max) { 55 56 min->x = (gridX - 0.5)*grid->nXpix + grid->xMin; 57 min->y = (gridY - 0.5)*grid->nYpix + grid->yMin; 58 59 max->x = min->x + grid->nXpix; 60 max->y = min->y + grid->nYpix; 61 48 62 return true; 49 63 } -
trunk/pswarp/src/pswarpTransformReadout.c
r12744 r18839 1 1 # include "pswarp.h" 2 2 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 4 bool pswarpTransformReadout(pmReadout *output, pmReadout *input, pmConfig *config) 5 { 5 6 // XXX this implementation currently ignores the use of the region 6 7 psImage *region = NULL; 7 pmCell *cell = NULL;8 8 9 // select the current recipe 10 // psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSWARP_RECIPE); 9 psTimerStart ("warp"); 11 10 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"); 14 16 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); 17 20 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"); 21 26 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; 25 29 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"); 29 32 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); 32 36 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); 35 40 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); 41 43 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 } 45 52 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; 49 55 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++) { 53 59 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(); 66 61 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); 69 133 } 70 134 } 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")); 77 149 78 150 return true;
Note:
See TracChangeset
for help on using the changeset viewer.
