Changeset 32616
- Timestamp:
- Nov 5, 2011, 2:30:17 PM (15 years ago)
- Location:
- branches/eam_branches/ipp-20110906/psphot/src
- Files:
-
- 9 edited
-
Makefile.am (modified) (1 diff)
-
psphot.h (modified) (1 diff)
-
psphotKronIterate.c (modified) (2 diffs)
-
psphotRadialApertures.c (modified) (17 diffs)
-
psphotRadialProfileWings.c (modified) (2 diffs)
-
psphotReadout.c (modified) (1 diff)
-
psphotSetThreads.c (modified) (1 diff)
-
psphotSourceSize.c (modified) (1 diff)
-
psphotStackReadout.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110906/psphot/src/Makefile.am
r32606 r32616 202 202 psphotRadialBins.c \ 203 203 psphotRadialApertures.c \ 204 psphotRadialAperturesByObject.c \205 204 psphotPetrosian.c \ 206 205 psphotPetrosianRadialBins.c \ -
branches/eam_branches/ipp-20110906/psphot/src/psphot.h
r32606 r32616 428 428 bool psphotRadialAperturesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, int entry); 429 429 bool psphotRadialApertures_Threaded (psThreadJob *job); 430 bool psphotRadialApertureSource (pmSource *source, psMetadata *recipe, psImageMaskType maskVal, const psVector *radMax, int entry); 430 bool psphotRadialApertureSource (pmSource *source, pmReadout *readout, int entry, psVector *pixRadius2, psVector *pixFlux, psVector *pixVer); 431 // bool psphotRadialApertureSource (pmSource *source, int entry); 431 432 432 433 bool psphotExtendedSourceAnalysisByObject (pmConfig *config, psArray *objects, const pmFPAview *view, const char *filerule); -
branches/eam_branches/ipp-20110906/psphot/src/psphotKronIterate.c
r32605 r32616 192 192 float MIN_KRON_RADIUS = PS_SCALAR_VALUE(job->args->data[6],F32); 193 193 194 for (int j = 0; j < 5; j++) { 194 // XXX TEST : set iteration to 1 195 for (int j = 0; j < 1; j++) { 195 196 for (int i = 0; i < sources->n; i++) { 196 197 … … 209 210 210 211 // use S/N to control max window size 211 float kronSN = source->moments->KronFlux / source->moments->KronFluxErr;212 // float kronSN = source->moments->KronFlux / source->moments->KronFluxErr; 212 213 213 214 // maxWindow -> 1.5*RADIUS for kronSN = 5.0, keeping S.B. constant (kronSN ~ flux) 214 215 // (kronSN / maxWindow^2) = (5.0 / (1.5 RADIUS)^2) 215 216 // maxWindow = 1.5 * RADIUS * sqrt(kronSN / 5.0) 216 float maxWindow = (isfinite(kronSN) && (kronSN > 5.0)) ? 1.5 * RADIUS * sqrt(kronSN / 5.0) : 1.5*RADIUS;217 // XXX float maxWindow = (isfinite(kronSN) && (kronSN > 5.0)) ? 1.5 * RADIUS * sqrt(kronSN / 5.0) : 1.5*RADIUS; 217 218 218 219 // iterate to the window radius 219 float windowRadius = PS_MIN(PS_MAX(RADIUS, 4.0*source->moments->Mrf), maxWindow); 220 // XXX float windowRadius = PS_MIN(PS_MAX(RADIUS, 4.0*source->moments->Mrf), maxWindow); 221 222 // XXX TEST : use a window based on the radial profile numbers: max is skyRadius, min is RADIUS 223 float maxWindow = source->skyRadius; 224 float windowRadius = PS_MAX(RADIUS, maxWindow); 220 225 221 226 // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS -
branches/eam_branches/ipp-20110906/psphot/src/psphotRadialApertures.c
r32348 r32616 36 36 } 37 37 38 // these values are used by all threads repeatedly (and are not modified) 39 static psVector *aperRadii = NULL; 40 static psVector *aperRadii2 = NULL; 41 static float outerRadius = NAN; 42 static float SN_LIM = NAN; 43 static psImageMaskType maskVal = 0; 44 38 45 // aperture-like measurements for extended sources 39 46 // flux in simple, circular apertures … … 75 82 nThreads = 0; 76 83 } 84 85 // aperRadii stores the upper bounds of the annuli 86 // XXX keep the same name here as for the petrosian / elliptical apertures? 87 aperRadii = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER"); 88 psAssert (aperRadii, "annular bins (RADIAL.ANNULAR.BINS.UPPER) are not defined in the recipe"); 89 psAssert (aperRadii->n, "no valid annular bins (RADIAL.ANNULAR.BINS.UPPER) are define"); 90 91 outerRadius = aperRadii->data.F32[aperRadii->n - 1]; 92 93 // save the R^2 values as well for quicker comparison 94 aperRadii2 = psVectorAlloc(aperRadii->n, PS_TYPE_F32); 95 for (int i = 0; i < aperRadii->n; i++) { 96 aperRadii2->data.F32[i] = PS_SQR(aperRadii->data.F32[i]); 97 } 98 99 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 100 maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 101 assert (maskVal); 102 103 // S/N limit to perform full non-linear fits 104 SN_LIM = psMetadataLookupF32 (&status, recipe, "RADIAL_APERTURES_SN_LIM"); 77 105 78 106 // source analysis is done in S/N order (brightest first) … … 117 145 psArrayAdd(job->args, 1, cells->data[j]); // sources 118 146 psArrayAdd(job->args, 1, AnalysisRegion); 119 psArrayAdd(job->args, 1, recipe);120 121 147 PS_ARRAY_ADD_SCALAR(job->args, entry, PS_TYPE_S32); 122 148 PS_ARRAY_ADD_SCALAR(job->args, nEntry, PS_TYPE_S32); 123 124 149 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nradial 125 150 126 // set this to 0 to run without threading151 // set this to 0 to run without threading 127 152 # if (1) 128 153 if (!psThreadJobAddPending(job)) { … … 138 163 } 139 164 psScalar *scalar = NULL; 140 scalar = job->args->data[ 6];165 scalar = job->args->data[5]; 141 166 Nradial += scalar->data.S32; 142 167 psFree(job); … … 158 183 } else { 159 184 psScalar *scalar = NULL; 160 scalar = job->args->data[ 6];185 scalar = job->args->data[5]; 161 186 Nradial += scalar->data.S32; 162 187 } … … 166 191 psFree (cellGroups); 167 192 psFree(AnalysisRegion); 193 psFree (aperRadii2); 168 194 169 195 psLogMsg ("psphot", PS_LOG_WARN, "radial source apertures: %f sec for %d objects\n", psTimerMark ("psphot.radial"), Nradial); … … 173 199 bool psphotRadialApertures_Threaded (psThreadJob *job) { 174 200 175 bool status;176 201 int Nradial = 0; 177 202 … … 180 205 psArray *sources = job->args->data[1]; 181 206 psRegion *region = job->args->data[2]; 182 psMetadata *recipe = job->args->data[3]; 183 184 int entry = PS_SCALAR_VALUE(job->args->data[4],S32); // which psf-matched image are we working on? (0 == unmatched) 185 int nEntry = PS_SCALAR_VALUE(job->args->data[5],S32); // total number of psf-matched images + 1 unmatched 186 187 // radMax stores the upper bounds of the annuli 188 // XXX keep the same name here as for the petrosian / elliptical apertures? 189 psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER"); 190 psAssert (radMax, "annular bins (RADIAL.ANNULAR.BINS.UPPER) are not defined in the recipe"); 191 psAssert (radMax->n, "no valid annular bins (RADIAL.ANNULAR.BINS.UPPER) are define"); 192 193 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 194 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 195 assert (maskVal); 196 197 // S/N limit to perform full non-linear fits 198 float SN_LIM = psMetadataLookupF32 (&status, recipe, "RADIAL_APERTURES_SN_LIM"); 199 200 float outerRadius = radMax->data.F32[radMax->n - 1]; 207 int entry = PS_SCALAR_VALUE(job->args->data[3],S32); // which psf-matched image are we working on? (0 == unmatched) 208 int nEntry = PS_SCALAR_VALUE(job->args->data[4],S32); // total number of psf-matched images + 1 unmatched 209 210 // storage for the derived pixel values (these are passed into psphotRadialApertureSource) 211 psVector *pixRadius2 = psVectorAllocEmpty(100, PS_TYPE_F32); 212 psVector *pixFlux = psVectorAllocEmpty(100, PS_TYPE_F32); 213 psVector *pixVar = psVectorAllocEmpty(100, PS_TYPE_F32); 201 214 202 215 // choose the sources of interest … … 240 253 } 241 254 242 // we need to change the view for the radial aperture analysis, but we want to recover exactly243 // the original view; the following elements get destroyed by pmSourceRedefinePixels so save them:244 psImage *oldMaskObj = psMemIncrRefCounter(source->maskObj);245 psImage *oldModelFlux = psMemIncrRefCounter(source->modelFlux);246 psImage *oldPSFimage = psMemIncrRefCounter(source->psfImage);247 psRegion oldRegion = source->region;248 249 255 Nradial ++; 250 256 251 // force source image to be a bit larger... 252 pmSourceRedefinePixels (source, readout, source->peak->xf, source->peak->yf, outerRadius + 2); 253 254 if (!psphotRadialApertureSource (source, recipe, maskVal, radMax, entry)) { 257 if (!psphotRadialApertureSource (source, readout, entry, pixRadius2, pixFlux, pixVar)) { 255 258 psTrace ("psphot", 5, "failed to extract radial profile for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); 256 259 } else { … … 258 261 } 259 262 260 pmSourceRedefinePixelsByRegion (source, readout, oldRegion);261 psFree(source->maskObj); source->maskObj = oldMaskObj;262 psFree(source->modelFlux); source->modelFlux = oldModelFlux;263 psFree(source->psfImage); source->psfImage = oldPSFimage;264 265 263 // re-subtract the object, leave local sky 266 264 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 267 265 } 268 psScalar *scalar = job->args->data[ 6];266 psScalar *scalar = job->args->data[5]; 269 267 scalar->data.S32 = Nradial; 268 269 psFree (pixRadius2); 270 psFree (pixFlux); 271 psFree (pixVar); 270 272 271 273 return true; 272 274 } 273 275 274 bool psphotRadialApertureSource (pmSource *source, p sMetadata *recipe, psImageMaskType maskVal, const psVector *aperRadii, int entry) {275 276 bool psphotRadialApertureSource (pmSource *source, pmReadout *readout, int entry, psVector *pixRadius2, psVector *pixFlux, psVector *pixVar) { 277 276 278 // if we are a child source, save the results to the parent source radial aperture array 277 279 psArray *radialAperSet = source->radialAper; … … 285 287 radialAperSet->data[entry] = radialAper; 286 288 287 // storage for the derived pixel values 288 psVector *pixRadius2 = psVectorAllocEmpty(100, PS_TYPE_F32); 289 psVector *pixFlux = psVectorAllocEmpty(100, PS_TYPE_F32); 290 psVector *pixVar = psVectorAllocEmpty(100, PS_TYPE_F32); 289 // find the largest aperture of interest (use only apertures with inner radii <= 290 // source->skyRadius) 291 int lastAp = aperRadii->n; 292 for (int i = 0; i < aperRadii->n; i++) { 293 if (aperRadii->data.F32[i] < source->skyRadius) continue; 294 lastAp = i + 1; 295 break; 296 } 291 297 292 298 // outer-most radius for initial truncation 293 float Rmax = aperRadii->data.F32[ aperRadii->n- 1];299 float Rmax = aperRadii->data.F32[lastAp - 1]; 294 300 float Rmax2 = PS_SQR(Rmax); 295 301 296 // store the R^2 values for the apertures 297 psVector *aperRadii2 = psVectorAlloc(aperRadii->n, PS_TYPE_F32); 298 for (int i = 0; i < aperRadii->n; i++) { 299 aperRadii2->data.F32[i] = PS_SQR(aperRadii->data.F32[i]); 300 } 302 // in this function, the operatins are relative to the full image (readout->image, etc) 301 303 302 304 float xCM = NAN, yCM = NAN; 303 305 if (pmSourcePositionUseMoments(source)) { 304 xCM = source->moments->Mx - 0.5 - source->pixels->col0; // coord of peak in subimage305 yCM = source->moments->My - 0.5 - source->pixels->row0; // coord of peak in subimage306 xCM = source->moments->Mx; // index coord of peak in readout 307 yCM = source->moments->My; // index coord of peak in readout 306 308 } else { 307 xCM = source->peak->xf - 0.5 - source->pixels->col0; // coord of peak in subimage 308 yCM = source->peak->yf - 0.5 - source->pixels->row0; // coord of peak in subimage 309 } 309 xCM = source->peak->xf; // index coord of peak in readout 310 yCM = source->peak->yf; // index coord of peak in readout 311 } 312 313 int Nx = readout->image->numCols; 314 int Ny = readout->image->numRows; 315 316 pixRadius2->n = 0; 317 pixFlux->n = 0; 318 pixVar->n = 0; 310 319 311 320 // one pass through the pixels to select the valid pixels and calculate R^2 312 for (int iy = 0; iy < source->pixels->numRows; iy++) { 313 314 float yDiff = iy - yCM; 315 if (fabs(yDiff) > Rmax) continue; 316 317 float *vPix = source->pixels->data.F32[iy]; 318 float *vWgt = source->variance->data.F32[iy]; 319 psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy]; 320 321 for (int ix = 0; ix < source->pixels->numCols; ix++, vPix++, vWgt++) { 322 323 if (vMsk) { 324 if (*vMsk & maskVal) { 325 vMsk++; 326 continue; 327 } 328 vMsk++; 329 } 330 if (isnan(*vPix)) continue; 331 332 float xDiff = ix - xCM; 333 if (fabs(xDiff) > Rmax) continue; 321 for (int iy = -Rmax; iy < Rmax + 1; iy++) { 322 323 float yDiff = iy + 0.5 + yCM; // y-coordinate at this offse 324 int yPix = (int) yDiff; 325 326 if (yPix < 0) continue; 327 if (yPix > Ny - 1) continue; 328 if (fabs(iy) > Rmax) continue; 329 330 float *vPix = readout->image->data.F32[yPix]; 331 float *vWgt = readout->variance->data.F32[yPix]; 332 psImageMaskType *vMsk = readout->mask->data.PS_TYPE_IMAGE_MASK_DATA[yPix]; 333 334 for (int ix = -Rmax; ix < Rmax + 1; ix++) { 335 336 float xDiff = ix + 0.5 + xCM; // x-coordinate at this offse 337 int xPix = (int) xDiff; 338 339 if (xPix < 0) continue; 340 if (xPix > Nx - 1) continue; 341 if (fabs(ix) > Rmax) continue; 342 343 if (vMsk[xPix] & maskVal) continue; 344 if (isnan(vPix[xPix])) continue; 334 345 335 346 // radius is just a function of (xDiff, yDiff) 336 float r2 = PS_SQR( xDiff) + PS_SQR(yDiff);347 float r2 = PS_SQR(ix) + PS_SQR(iy); 337 348 if (r2 > Rmax2) continue; 338 349 339 350 psVectorAppend(pixRadius2, r2); 340 psVectorAppend(pixFlux, *vPix);341 psVectorAppend(pixVar, *vWgt);351 psVectorAppend(pixFlux, vPix[xPix]); 352 psVectorAppend(pixVar, vWgt[xPix]); 342 353 } 343 354 } … … 348 359 psVector *fill = psVectorAlloc(aperRadii->n, PS_TYPE_F32); // surface brightness of radial bin 349 360 361 // init the apertures of interest to 0.0, the rest go to NAN 350 362 psVectorInit (flux, 0.0); 351 363 psVectorInit (fluxStd, 0.0); 352 364 psVectorInit (fluxErr, 0.0); 353 365 psVectorInit (fill, 0.0); 366 for (int i = lastAp; i < flux->n; i++) { 367 flux->data.F32[i] = NAN; 368 fluxStd->data.F32[i] = NAN; 369 fluxErr->data.F32[i] = NAN; 370 fill->data.F32[i] = NAN; 371 } 354 372 355 373 float *rPix2 = pixRadius2->data.F32; … … 358 376 int j = 0; 359 377 float *aRad2 = aperRadii2->data.F32; 360 for (; (*aRad2 < *rPix2) && (j < aperRadii2->n); j++, aRad2++); 361 for (; j < aperRadii2->n; j++, aRad2++) { 378 for (; (*aRad2 < *rPix2) && (j < lastAp); j++, aRad2++); 379 380 // XXX I can speed this up by only saving this single aperture 381 for (; j < lastAp; j++, aRad2++) { 362 382 flux->data.F32[j] += pixFlux->data.F32[i]; 363 383 fluxStd->data.F32[j] += PS_SQR(pixFlux->data.F32[i]); … … 371 391 2) the fractional fill factor (count of valid pixels / effective area of the aperture 372 392 3) the error on the flux within that aperture 373 */374 375 for (int i = 0; i < flux->n; i++) {393 */ 394 395 for (int i = 0; i < lastAp; i++) { 376 396 // calculate the total flux for bin 'nOut' 377 397 float Area = M_PI*aperRadii2->data.F32[i]; … … 383 403 // XXX report the total flux or the mask-corrected flux? 384 404 // flux->data.F32[i] = SBmean * Area; 385 // fluxErr->data.F32[i] = sqrt(fluxErr->data.F32[i]) * Area / nPix;405 // fluxErr->data.F32[i] = sqrt(fluxErr->data.F32[i]) * Area / Pinx; 386 406 387 407 fluxErr->data.F32[i] = sqrt(fluxErr->data.F32[i]); … … 393 413 } 394 414 415 # if (1) 395 416 radialAper->flux = flux; 396 417 radialAper->fluxStdev = fluxStd; 397 418 radialAper->fluxErr = fluxErr; 398 419 radialAper->fill = fill; 399 400 psFree (aperRadii2); 401 psFree (pixRadius2); 402 psFree (pixFlux); 403 psFree (pixVar); 420 # else 421 // XXX TEST 422 psFree(flux); 423 psFree(fluxStd); 424 psFree(fluxErr); 425 psFree(fill); 426 # endif 404 427 405 428 return true; 406 429 } 430 431 /*** below is a test to use a sort to speed this up, not very successfully ***/ 407 432 408 433 static int nCalls = 0; … … 495 520 // *** pmSourceRadialProfileSortPair is a utility function for sorting a pair of vectors 496 521 # define COMPARE_VECT(A,B) (radius->data.F32[A] < radius->data.F32[B]) 497 # define SWAP_VECT(TYPE,A,B) { \498 float tmp;\499 if (A != B) {\500 tmp = radius->data.F32[A];\501 radius->data.F32[A] = radius->data.F32[B];\502 radius->data.F32[B] = tmp;\503 tmp = pixFlux->data.F32[A];\504 pixFlux->data.F32[A] = pixFlux->data.F32[B];\505 pixFlux->data.F32[B] = tmp;\506 tmp = pixVar->data.F32[A];\507 pixVar->data.F32[A] = pixVar->data.F32[B];\508 pixVar->data.F32[B] = tmp;\509 }\510 }522 # define SWAP_VECT(TYPE,A,B) { \ 523 float tmp; \ 524 if (A != B) { \ 525 tmp = radius->data.F32[A]; \ 526 radius->data.F32[A] = radius->data.F32[B]; \ 527 radius->data.F32[B] = tmp; \ 528 tmp = pixFlux->data.F32[A]; \ 529 pixFlux->data.F32[A] = pixFlux->data.F32[B]; \ 530 pixFlux->data.F32[B] = tmp; \ 531 tmp = pixVar->data.F32[A]; \ 532 pixVar->data.F32[A] = pixVar->data.F32[B]; \ 533 pixVar->data.F32[B] = tmp; \ 534 } \ 535 } 511 536 512 537 bool psphotRadialAperturesSortFlux (psVector *radius, psVector *pixFlux, psVector *pixVar) { -
branches/eam_branches/ipp-20110906/psphot/src/psphotRadialProfileWings.c
r32612 r32616 132 132 133 133 // set this to 0 to run without threading 134 # if ( 0)134 # if (1) 135 135 if (!psThreadJobAddPending(job)) { 136 136 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); … … 217 217 218 218 // psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA; 219 220 // XXX unclear if I should run this analysis on both 1st and 2nd pass for 1st pass objects, 221 // or just use the 1st pass value. I think I should just use the 1st pass value, so skip 222 // any that have already been assigned 223 if (isfinite(source->skyRadius)) return true; 219 224 220 225 // radii will be MIN_RADIUS to MAX_RADIUS in NN log steps: -
branches/eam_branches/ipp-20110906/psphot/src/psphotReadout.c
r32606 r32616 308 308 pass1finish: 309 309 310 // measure the radial profiles to the sky (only measures new objects) 311 psphotRadialProfileWings (config, view, filerule); 312 310 313 // re-measure the kron mags with models subtracted 311 314 // psphotKronMasked(config, view, filerule); -
branches/eam_branches/ipp-20110906/psphot/src/psphotSetThreads.c
r32613 r32616 50 50 psFree(task); 51 51 52 task = psThreadTaskAlloc("PSPHOT_RADIAL_APERTURES", 7);52 task = psThreadTaskAlloc("PSPHOT_RADIAL_APERTURES", 6); 53 53 task->function = &psphotRadialApertures_Threaded; 54 54 psThreadTaskAdd(task); -
branches/eam_branches/ipp-20110906/psphot/src/psphotSourceSize.c
r32348 r32616 156 156 157 157 // XXX fix this (was source->n - first) 158 psLogMsg ("psphot.size", PS_LOG_ INFO, "measure source sizes for %ld sources: %f sec\n", sources->n, psTimerMark ("psphot.size"));158 psLogMsg ("psphot.size", PS_LOG_WARN, "measure source sizes for %ld sources: %f sec\n", sources->n, psTimerMark ("psphot.size")); 159 159 160 160 psphotVisualPlotSourceSize (recipe, readout->analysis, sources); -
branches/eam_branches/ipp-20110906/psphot/src/psphotStackReadout.c
r32348 r32616 168 168 psphotFitSourcesLinear (config, view, STACK_SRC, false); 169 169 psphotStackVisualFilerule(config, view, STACK_SRC); 170 171 // measure the radial profiles to the sky 172 psphotRadialProfileWings (config, view, STACK_SRC); 170 173 171 174 // re-measure the kron mags with models subtracted. this pass starts with a circular … … 245 248 pass1finish: 246 249 250 // measure the radial profiles to the sky (only measures new objects) 251 psphotRadialProfileWings (config, view, STACK_SRC); 252 247 253 // re-measure the kron mags with models subtracted 248 254 // psphotKronMasked(config, view, STACK_SRC); … … 254 260 255 261 psMemDump("psfstats"); 262 263 // XXX *** NOTE : this should happen above before the last psphotFitSourcesLinear in order 264 // to generate psf forced photometry for the undetected sources 256 265 257 266 // generate the objects (objects unify the sources from the different images) … … 281 290 282 291 // measure circular, radial apertures (objects sorted by S/N) 283 // XXX can we just use psphotRadialApertures 284 // XXX make sure the headers are consistent with this (which PSF convolutions, ie mark 'none') 285 // psphotRadialAperturesByObject (config, objectsRadial, view, STACK_SRC, nMatchedPSF); 292 // this forces photometry on the undetected sources from other images 286 293 psphotRadialApertures (config, view, STACK_SRC, 0); // XXX entry 0 == unmatched? 287 294 psMemDump("extmeas");
Note:
See TracChangeset
for help on using the changeset viewer.
