Changeset 34404
- Timestamp:
- Sep 5, 2012, 4:19:30 PM (14 years ago)
- Location:
- trunk/psphot
- Files:
-
- 22 edited
-
. (modified) (1 prop)
-
src (modified) (1 prop)
-
src/psphot.h (modified) (3 diffs)
-
src/psphotAddNoise.c (modified) (2 diffs)
-
src/psphotApResid.c (modified) (1 diff)
-
src/psphotBlendFit.c (modified) (7 diffs)
-
src/psphotDeblendSatstars.c (modified) (3 diffs)
-
src/psphotExtendedSourceAnalysis.c (modified) (1 diff)
-
src/psphotExtendedSourceFits.c (modified) (1 diff)
-
src/psphotFindDetections.c (modified) (2 diffs)
-
src/psphotFitSourcesLinear.c (modified) (1 diff)
-
src/psphotGuessModels.c (modified) (1 diff)
-
src/psphotKronIterate.c (modified) (1 diff)
-
src/psphotMagnitudes.c (modified) (1 diff)
-
src/psphotRadialApertures.c (modified) (1 diff)
-
src/psphotRadialProfileWings.c (modified) (2 diffs)
-
src/psphotReadout.c (modified) (5 diffs)
-
src/psphotSourceSize.c (modified) (1 diff)
-
src/psphotSourceStats.c (modified) (3 diffs)
-
src/psphotStackImageLoop.c (modified) (1 prop)
-
src/psphotStackMatchPSFs.c (modified) (1 diff)
-
src/psphotVisual.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20120805/psphot (added) merged: 34360,34368-34369,34377-34378,34380,34392,34399
- Property svn:mergeinfo changed
-
trunk/psphot/src
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20120805/psphot/src (added) merged: 34360,34368-34369,34377-34378,34380,34392,34399
- Property svn:mergeinfo changed
-
trunk/psphot/src/psphot.h
r34354 r34404 281 281 bool psphotVisualShowSatStars (psMetadata *recipe, pmPSF *psf, psArray *sources); 282 282 bool psphotVisualShowPSFModel (pmReadout *readout, pmPSF *psf); 283 bool psphotVisualPlotRadialProfile (int myKapa, pmSource *source, psImageMaskType maskVal );284 bool psphotVisualPlotRadialProfiles (psMetadata *recipe, psArray *sources );283 bool psphotVisualPlotRadialProfile (int myKapa, pmSource *source, psImageMaskType maskVal, pmSourceMode showmode); 284 bool psphotVisualPlotRadialProfiles (psMetadata *recipe, psArray *sources, pmSourceMode showmode); 285 285 bool psphotVisualShowFlags (psArray *sources); 286 286 bool psphotVisualShowSourceSize (pmReadout *readout, psArray *sources); … … 295 295 bool psphotVisualClose(void); 296 296 297 int psphotKapaChannel (int channel); 298 void plotline (int myKapa, Graphdata *graphdata, float x0, float y0, float x1, float y1); 299 300 297 301 bool psphotPetrosian (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal); 298 302 bool psphotPetrosianRadialBins (pmSource *source, float radiusMax, float skynoise); … … 511 515 ); 512 516 517 bool psphotSatstarProfileModel (pmSource *source, psImageMaskType maskVal); 518 bool psphotSatstarProfileCreate (pmSource *source, psVector **logRmodelOut, psVector **logFmodelOut, psVector *logR, psVector *flux, float Rmax); 519 bool psphotSatstarProfileOp (pmSource *source, psImageMaskType maskVal, float FACTOR, pmModelOpMode mode, bool add); 520 bool psphotVisualRadialProfileSatstar (pmSource *source, psImageMaskType maskVal); 521 bool psphotAddOrSubSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int fileIndex, psMetadata *recipe, bool add); 522 bool psphotSatstarPhotometry (pmSource *source); 523 513 524 bool psphotSourceMemory(pmConfig *config, const pmFPAview *view, const char *filerule); 514 525 bool psphotSourceMemoryReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index); -
trunk/psphot/src/psphotAddNoise.c
r33980 r34404 76 76 } 77 77 78 psphotVisualShowImage (readout); 79 78 80 // loop over all source 79 81 for (int i = 0; i < sources->n; i++) { 80 82 pmSource *source = sources->data[i]; 83 84 // add or subtract noise for a saturated star. satstars modeled as a radial profile 85 // need special handling 86 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) { 87 psphotSatstarProfileOp (source, maskVal, FACTOR, PM_MODEL_OP_NOISE, add); 88 continue; 89 } 81 90 82 91 // skip sources which were not subtracted … … 92 101 } 93 102 103 psphotVisualShowImage (readout); 104 94 105 return true; 95 106 } -
trunk/psphot/src/psphotApResid.c
r34363 r34404 200 200 if (source->mode & PM_SOURCE_MODE_FAIL) SKIPSTAR ("FAIL STAR"); 201 201 if (source->mode & PM_SOURCE_MODE_POOR) SKIPSTAR ("POOR STAR"); 202 203 // skip saturated stars modeled with a radial profile 204 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) SKIPSTAR ("SATSTAR"); 202 205 203 206 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) SKIPSTAR ("EXTENDED"); -
trunk/psphot/src/psphotBlendFit.c
r34258 r34404 1 1 # include "psphotInternal.h" 2 bool psphotBlendFitSetSource(pmSource *source, psImage *IDimage, float sigSigma); 2 3 3 4 // for now, let's store the detections on the readout->analysis for each readout … … 92 93 float skySig = psMetadataLookupF32(&status, recipe, "SKY_SIG"); 93 94 assert (status && isfinite(skySig) && skySig > 0); 95 96 # if (0) 97 // **** test block : generate an ID image where pixels are set based the source models (flux > 0.1 peak && flux > 2.0 skySig) 98 psImage *IDimage = psImageAlloc (readout->image->numCols, readout->image->numRows, PS_TYPE_S32); 99 psImageInit (IDimage, 0); 100 101 // start with the currently known moments (Mxx, Myy, Mxy) and generate a window image 102 for (int i = 0; i < sources->n; i++) { 103 pmSource *source = sources->data[i]; 104 psphotBlendFitSetSource (source, IDimage, skySig); 105 } 106 psphotSaveImage (NULL, IDimage, "idimage.fits"); 107 # endif 94 108 95 109 // Define source fitting parameters for extended source fits … … 241 255 pmSource *source = sources->data[i]; 242 256 243 # if (0) 244 # define TEST_X 34245 # define TEST_ Y 28246 257 int TEST_ON = false; 258 # if (1) 259 # define TEST_X 653 260 # define TEST_Y 466 247 261 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 248 262 fprintf (stderr, "test object\n"); 249 } 250 263 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5); 264 TEST_ON = true; 265 } 251 266 # undef TEST_X 252 267 # undef TEST_Y … … 258 273 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 259 274 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 275 276 // skip saturated stars modeled with a radial profile 277 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 260 278 261 279 // skip DBL second sources (ie, added by psphotFitBlob … … 306 324 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 307 325 if (psphotFitBlob (readout, source, newSources, psf, fitOptions, maskVal, markVal)) { 326 if (TEST_ON) { 327 psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); 328 } 308 329 psTrace ("psphot", 5, "source at %7.1f, %7.1f is ext", source->peak->xf, source->peak->yf); 309 330 Next ++; … … 312 333 } else { 313 334 if (psphotFitBlend (readout, source, psf, fitOptions, maskVal, markVal)) { 335 if (TEST_ON) { 336 psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); 337 } 314 338 source->type = PM_SOURCE_TYPE_STAR; 315 339 psTrace ("psphot", 5, "source at %7.1f, %7.1f is psf", source->peak->xf, source->peak->yf); … … 349 373 } 350 374 375 bool psphotBlendFitSetSource(pmSource *source, psImage *IDimage, float skySigma) { 376 377 if (!source) return false; 378 if (!source->peak) return false; // XXX how can we have a peak-less source? 379 if (!source->moments) return false; 380 if (source->type == PM_SOURCE_TYPE_DEFECT) return false; 381 if (source->type == PM_SOURCE_TYPE_SATURATED) return false; 382 if (source->mode2 == PM_SOURCE_MODE2_MATCHED) return false; 383 psAssert(IDimage, "need a window"); 384 385 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) { 386 // find the radius at which we hit something like 0.1*SATURATION 387 return false; 388 } 389 390 if (!isfinite(source->moments->Mrf) || source->moments->Mrf < 0 ) return false; 391 392 // we have a source with moments Mx, My, Mxx, Mxy, Myy. we just need to define a Gaussian that has 393 // these values (and peak of 1.0) 394 395 int Nx = IDimage->numCols; 396 int Ny = IDimage->numRows; 397 398 float Xo = source->moments->Mx; 399 float Yo = source->moments->My; 400 401 psEllipseMoments moments; 402 moments.x2 = source->moments->Mxx; 403 moments.y2 = source->moments->Myy; 404 moments.xy = source->moments->Mxy; 405 406 psEllipseAxes axes = psEllipseMomentsToAxes(moments, 20.0); 407 if (! (isfinite(axes.major) && isfinite(axes.minor) && isfinite(axes.theta)) ) { 408 fprintf (stderr, "invalid axes found id: %4d major: %f minor: %f theta: %f\n", source->id, axes.major, axes.minor, axes.theta); 409 return false; 410 } 411 412 // Use 1st radial moment as size, not sigma. Why this factor of 0.5 ? 413 float scale = 0.5 * source->moments->Mrf / axes.major; 414 axes.major *= scale; 415 axes.minor *= scale; 416 417 psEllipseShape shape = psEllipseAxesToShape(axes); 418 if (! (isfinite(shape.sx) && isfinite(shape.sy) && isfinite(shape.sxy)) ) { 419 fprintf (stderr, "invalid shape found id: %d sx: %f sy %f sxy: %f\n", source->id, shape.sx, shape.sy, shape.sxy); 420 return false; 421 } 422 423 float Smajor = axes.major; 424 425 // we want to go to 2.15 sigma (0.1 Io) 426 int minX = PS_MIN(PS_MAX(Xo - 2.15*Smajor, 0), Nx - 1); 427 int maxX = PS_MIN(PS_MAX(Xo + 2.15*Smajor, 0), Nx - 1); 428 int minY = PS_MIN(PS_MAX(Yo - 2.15*Smajor, 0), Ny - 1); 429 int maxY = PS_MIN(PS_MAX(Yo + 2.15*Smajor, 0), Ny - 1); 430 431 float rMxx = 0.5 / PS_SQR(shape.sx); 432 float rMyy = 0.5 / PS_SQR(shape.sy); 433 float Sxy = -1. * shape.sxy; // factor of -1 is included to match the previous window function 434 // implementation. XXX: Is this correct? 435 436 int ID = source->id; 437 float Io = source->peak->rawFlux; 438 for (int iy = minY; iy < maxY; iy++) { 439 for (int ix = minX; ix < maxX; ix++) { 440 441 float dX = (ix + 0.5 - Xo); 442 float dY = (iy + 0.5 - Yo); 443 444 float z = rMxx * PS_SQR(dX) + rMyy * PS_SQR(dY) + Sxy*dX*dY; 445 446 float f = Io*exp(-z); 447 448 if (f < 2.0*skySigma) continue; 449 IDimage->data.S32[iy][ix] = ID; 450 } 451 } 452 453 return true; 454 } -
trunk/psphot/src/psphotDeblendSatstars.c
r31154 r34404 1 1 # include "psphotInternal.h" 2 3 typedef struct { 4 float min; 5 float max; 6 float lower20; 7 float upper20; 8 int Npts; 9 } QuickStats; 10 11 bool psImageQuickStats (QuickStats *stats, psImage *image, psRegion region); 12 float InterpolateValues (float X0, float Y0, float X1, float Y1, float X); 13 bool psphotVisualScaleImage (int kapaFD, psImage *inImage, psImage *inMask, const char *name, float factor, int channel); 2 14 3 15 // for now, let's store the detections on the readout->analysis for each readout … … 16 28 } 17 29 30 /** this function does 3 things: 31 32 1) choose likely saturated stars 33 - mode | SATSTAR 34 - if moments->Peak > 0.5*SATURATION, examine region of peak pixels (ensure we go down to 0.1*SAT) for SAT mask 35 36 2) adjust the window for saturated objects 37 38 3) measure the radial profile 39 40 4) subtract the radial profile 41 42 TBD: 43 44 * function to replace the radial profile for a source 45 * recenter the profile (based on cross-correlation / convolution with 1D profile) 46 47 * raise a bit somewhere for these super saturated stars (if they were so modeled) 48 * consider the subtraction bit : when to raise it? 49 50 **/ 51 18 52 bool psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int fileIndex) { 53 54 int N; 55 pmSource *source; 56 bool status; 57 58 // XXX disable this function for now 59 return true; 60 61 psTimerStart ("psphot.deblend.sat"); 62 63 // find the currently selected readout 64 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, fileIndex); // File of interest 65 psAssert (file, "missing file?"); 66 67 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 68 psAssert (readout, "missing readout?"); 69 70 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 71 psAssert (detections, "missing detections?"); 72 73 psArray *sources = detections->newSources; 74 psAssert (sources, "missing sources?"); 75 76 if (!sources->n) { 77 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping satstar blend"); 78 return true; 79 } 80 81 // select the appropriate recipe information 82 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 83 psAssert (recipe, "missing recipe?"); 84 85 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 86 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 87 assert (maskVal); 88 89 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 90 psImageMaskType maskSat = psMetadataLookupImageMask(&status, recipe, "MASK.SAT"); // Mask value for bad pixels 91 assert (maskSat); 92 93 float SATURATION = NAN; 94 { 95 // XXX do we need to set this differently from the value used to mark saturated pixels? 96 pmCell *cell = readout->parent; 97 98 // do not completely trust the values in the header... 99 float CELL_SATURATION = psMetadataLookupF32 (&status, cell->concepts, "CELL.SATURATION"); 100 float MIN_SATURATION = psMetadataLookupF32 (&status, recipe, "DEBLEND_MIN_SATURATION"); 101 if (!status || !isfinite(MIN_SATURATION)) { 102 MIN_SATURATION = 40000.0; 103 } 104 if (!isfinite(CELL_SATURATION)) { 105 SATURATION = MIN_SATURATION; 106 } else { 107 SATURATION = PS_MAX(MIN_SATURATION, CELL_SATURATION); 108 } 109 } 110 111 // source analysis is done in peak order (brightest first) 112 // we use an index for this so the spatial sorting is kept 113 psVector *SN = psVectorAlloc (sources->n, PS_DATA_F32); 114 for (int i = 0; i < SN->n; i++) { 115 source = sources->data[i]; 116 SN->data.F32[i] = source->moments->SN; 117 } 118 psVector *index = psVectorSortIndex (NULL, SN); 119 // this results in an index of increasing SN 120 121 // psphotVisualPlotRadialProfiles (recipe, sources, PM_SOURCE_MODE_SATSTAR); 122 123 int BIG_RADIUS = 250; 124 int BIG_SIGMA = BIG_RADIUS / 4.0; 125 126 int display = psphotKapaChannel (1); 127 psphotVisualScaleImage (display, (psImage *) source->pixels->parent, NULL, "image", 1.0, 0); 128 129 // examine sources in decreasing SN order 130 for (int i = sources->n - 1; i >= 0; i--) { 131 N = index->data.U32[i]; 132 source = sources->data[N]; 133 134 bool isSat = source->mode & PM_SOURCE_MODE_SATSTAR; 135 136 // for fairly bright stars, check the pixels near the peak again 137 if (source->moments->Peak > 0.5*SATURATION) { 138 // pmSourceRoughClass does this analysis, but uses a small (5x5) window. 139 // here we use a larger window since stacks can have some funny features 140 psRegion inner; 141 QuickStats stats; 142 // grow out the search radius until we have lower20 < 0.1*SATURATION 143 for (int radius = 2; radius < 30; radius ++) { 144 inner = psRegionForSquare (source->peak->x, source->peak->y, radius); 145 inner = psRegionForImage (source->maskView, inner); 146 psImageQuickStats (&stats, readout->image, inner); 147 if ((stats.Npts > 1) && (stats.lower20 < 0.1*SATURATION)) break; 148 } 149 int Nsatpix = psImageCountPixelMask (source->maskView, inner, maskSat); 150 // fprintf (stderr, "test object: %d,%d : %d vs %d : %f - %f - %f - %f\n", 151 // source->peak->x, source->peak->y, Nsatpix, stats.Npts, 152 // stats.min, stats.lower20, stats.upper20, stats.max); 153 if (Nsatpix > 1) isSat = true; 154 } 155 if (!isSat) continue; 156 157 // For saturated stars, choose a much larger box NOTE this is slightly sleazy, but 158 // only slightly: pmSourceRedefinePixels uses the readout to pass the pointers to 159 // the parent image data. I guess the API could be simplified: we could recover 160 // this from the source in the function 161 162 pmReadout tmpReadout; 163 tmpReadout.image = (psImage *)source->pixels->parent; 164 tmpReadout.mask = (psImage *)source->maskView->parent; 165 tmpReadout.variance = (psImage *)source->variance->parent; 166 167 // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS 168 pmSourceRedefinePixels (source, &tmpReadout, source->peak->x, source->peak->y, BIG_RADIUS + 2); 169 170 psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y); 171 status = pmSourceMoments (source, BIG_RADIUS, BIG_SIGMA, 0.0, 5.0, maskVal); 172 source->mode |= PM_SOURCE_MODE_BIG_RADIUS; 173 174 if (!psphotSatstarProfileModel (source, maskVal)) continue; 175 176 source->mode |= PM_SOURCE_MODE_SATSTAR; // yes, this source IS saturated 177 source->mode2 |= PM_SOURCE_MODE2_SATSTAR_PROFILE; // and we have in fact subtracted the profile 178 179 // XXX visualize, model, and subtract 180 // if (!psphotVisualRadialProfileSatstar (source, maskVal)) { 181 // break; 182 // } 183 184 // generate radial profile, store on the source structure 185 } 186 // show the image after object have been subtracted 187 psphotVisualScaleImage (display, (psImage *) source->pixels->parent, NULL, "image", 1.0, 1); 188 189 psFree (SN); 190 psFree (index); 191 192 psLogMsg ("psphot", PS_LOG_INFO, "deblend satstar: %f sec\n", psTimerMark ("psphot.deblend.sat")); 193 return true; 194 } 195 196 bool psphotDeblendSatstarsReadoutOld (pmConfig *config, const pmFPAview *view, const char *filerule, int fileIndex) { 19 197 20 198 int N; … … 219 397 return true; 220 398 } 399 400 // create a model for the radial profile of a saturated star (is this actually more generic?) 401 bool psphotSatstarProfileModel (pmSource *source, psImageMaskType maskVal) { 402 403 // XXX user define somewhere? 404 float Rmax = 320.0; 405 406 // XXX is this ever the case?? 407 bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED); 408 if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal); 409 410 int nPts = source->pixels->numRows * source->pixels->numCols; 411 psVector *logR = psVectorAllocEmpty (nPts, PS_TYPE_F32); 412 psVector *flux = psVectorAllocEmpty (nPts, PS_TYPE_F32); 413 414 int ng = 0; 415 416 // choose the best center for this profile 417 float Xo = NAN; 418 float Yo = NAN; 419 420 if (source->modelPSF) { 421 // XXX do we ever have a PSF model for a SATSTAR? 422 Xo = source->modelPSF->params->data.F32[PM_PAR_XPOS]; 423 Yo = source->modelPSF->params->data.F32[PM_PAR_YPOS]; 424 } else { 425 Xo = source->moments->Mx; 426 Yo = source->moments->My; 427 } 428 429 float Xc = Xo - source->pixels->col0 - 0.5; 430 float Yc = Yo - source->pixels->row0 - 0.5; 431 432 for (int iy = 0; iy < source->pixels->numRows; iy++) { 433 for (int ix = 0; ix < source->pixels->numCols; ix++) { 434 if ((source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & maskVal)) continue; 435 // XXX do this faster by generating R^2 and returning 0.5*log10(R^2)? 436 logR->data.F32[ng] = log10(hypot (ix - Xc, iy - Yc)); 437 flux->data.F32[ng] = source->pixels->data.F32[iy][ix]; 438 ng++; 439 } 440 } 441 logR->n = ng; 442 flux->n = ng; 443 444 // XXX do something sensible here if there are no pixels 445 446 // measure the radial profile 447 psVector *logFmodel = NULL; 448 psVector *logRmodel = NULL; 449 psphotSatstarProfileCreate (source, &logRmodel, &logFmodel, logR, flux, Rmax); 450 451 // XXX do something sensible here if the profile is crap 452 453 source->satstar = pmSourceSatstarAlloc(); 454 source->satstar->Xo = Xo; 455 source->satstar->Yo = Yo; 456 source->satstar->Rmax = Rmax; 457 source->satstar->logFmodel = logFmodel; 458 source->satstar->logRmodel = logRmodel; 459 460 // subtract the profile (false => subtract) 461 psphotSatstarProfileOp (source, maskVal, 1.0, 0, false); 462 463 psFree (logR); 464 psFree (flux); 465 466 return true; 467 } 468 469 // Take logR + flux and generate radial bins logRmodelOut, logFmodelOut 470 bool psphotSatstarProfileCreate (pmSource *source, psVector **logRmodelOut, psVector **logFmodelOut, psVector *logR, psVector *flux, float Rmax) { 471 472 // we have log(radius) & log(flux). find the median flux in log radial bins 473 474 float logRmax = log10(Rmax); 475 float logRdel = 0.1; // XXX user-define? 476 477 psVector *logRmodel = psVectorAlloc (1 + (int) (logRmax / logRdel), PS_TYPE_F32); 478 psVector *logFmodel = psVectorAlloc (1 + (int) (logRmax / logRdel), PS_TYPE_F32); 479 480 pmSourceRadialProfileSortPair (logR, flux); 481 482 psStats *fluxStats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); 483 psVector *fluxVals = psVectorAllocEmpty (100, PS_TYPE_F32); 484 485 int bin = 0; 486 for (int i = 0; i < logRmodel->n; i++) { 487 488 // bin (i) has log radius range (i*logRdel : (i+1)*logRdel) 489 float lRmin = logRdel*(i + 0); 490 float lRmax = logRdel*(i + 1); 491 492 // reset the flux vector 493 fluxVals->n = 0; 494 psStatsInit (fluxStats); 495 496 while (logR->data.F32[bin] < lRmax) { 497 if (isfinite(flux->data.F32[bin])) { 498 psVectorAppend (fluxVals, flux->data.F32[bin]); 499 } 500 bin ++; 501 } 502 503 // we have the set of fluxes for this bin; find the median values 504 505 float Rmin = pow(10.0, lRmin); 506 float Rmax = pow(10.0, lRmax); 507 508 float Rmean = (2.0/3.0) * (pow(Rmax, 3.0) - pow(Rmin, 3.0)) / (PS_SQR(Rmax) - PS_SQR(Rmin)); 509 logRmodel->data.F32[i] = log10(Rmean); 510 511 float Area = M_PI * (PS_SQR(Rmax) - PS_SQR(Rmin)); 512 if (fluxVals->n < 0.25*Area) { 513 logFmodel->data.F32[i] = NAN; 514 continue; 515 } 516 517 psVectorStats (fluxStats, fluxVals, NULL, NULL, 0); 518 if (fluxStats->robustMedian > 0.0) { 519 logFmodel->data.F32[i] = log10(fluxStats->robustMedian); 520 } else { 521 logFmodel->data.F32[i] = -3.0; 522 } 523 // fprintf (stderr, "R: %f, F: %f +/- %f\n", Rmean, fluxStats->robustMedian, fluxStats->robustStdev); 524 } 525 526 // now how do i use this to subtract a model?? 527 *logRmodelOut = logRmodel; 528 *logFmodelOut = logFmodel; 529 530 // need to free stuff 531 psFree (fluxStats); 532 psFree (fluxVals); 533 534 return true; 535 } 536 537 bool psphotSatstarProfileOp (pmSource *source, psImageMaskType maskVal, float FACTOR, pmModelOpMode mode, bool add) { 538 539 int alt; 540 float logRdel = 0.1; 541 542 float Xc = source->satstar->Xo - source->pixels->col0 - 0.5; 543 float Yc = source->satstar->Yo - source->pixels->row0 - 0.5; 544 psVector *logRmodel = source->satstar->logRmodel; 545 psVector *logFmodel = source->satstar->logFmodel; 546 547 for (int iy = 0; iy < source->pixels->numRows; iy++) { 548 for (int ix = 0; ix < source->pixels->numCols; ix++) { 549 if ((source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & maskVal)) continue; 550 551 float radius = hypot (ix - Xc, iy - Yc) ; 552 float logR = log10(radius); 553 554 int bin = (int)(logR / logRdel); 555 556 // we are going to interpolate if possible, or extrapolate if necessary 557 if (bin >= logRmodel->n - 1) bin = logRmodel->n - 1; 558 if (bin < 0) bin = 0; 559 560 // interpolate to the current radial position 561 // XXX BIG HACK : skip nan bins for now 562 563 float logF0 = logFmodel->data.F32[bin]; 564 float logR0 = logRmodel->data.F32[bin]; 565 if (!isfinite(logF0)) continue; 566 567 // interpolate between closest two bins if possible, extrapolate on ends 568 if (logR < logR0) { 569 alt = (bin > 0) ? bin - 1 : bin + 1; 570 } else { 571 alt = (bin < logRmodel->n - 1) ? bin + 1 : bin - 1; 572 } 573 574 float logF1 = logFmodel->data.F32[alt]; 575 float logR1 = logRmodel->data.F32[alt]; 576 if (!isfinite(logF1)) continue; 577 578 // XXX use linear flux, not logFlux 579 float logF = InterpolateValues (logR0, logF0, logR1, logF1, logR); 580 float flux = pow (10.0, logF); 581 582 if (mode & PM_MODEL_OP_NOISE) { 583 if (add) { 584 source->variance->data.F32[iy][ix] += FACTOR * flux; 585 } else { 586 source->variance->data.F32[iy][ix] -= FACTOR * flux; 587 } 588 } else { 589 if (add) { 590 source->pixels->data.F32[iy][ix] += flux; 591 } else { 592 source->pixels->data.F32[iy][ix] -= flux; 593 } 594 } 595 } 596 } 597 return true; 598 } 599 600 // Take logR + flux and generate radial bins logRmodelOut, logFmodelOut 601 bool psphotSatstarPhotometry (pmSource *source) { 602 603 if (!source->satstar) return false; 604 605 psVector *logRmodel = source->satstar->logRmodel; 606 psVector *logFmodel = source->satstar->logFmodel; 607 608 float fluxTotal = 0.0; 609 float logRdel = 0.1; // XXX user-define (or carry in satstar) 610 611 // integrate flux in radial bins 612 for (int i = 0; i < logRmodel->n; i++) { 613 // just add up the mean flux in each bin and multiply by the area of the bin 614 615 float logF = logFmodel->data.F32[i]; 616 if (!isfinite(logF)) continue; 617 float flux = pow(10.0, logF); // this is the mean flux per pixel (ie, surface brightness) 618 619 // bin (i) has log radius range (i*logRdel : (i+1)*logRdel) 620 float lRmin = logRdel*(i + 0); 621 float lRmax = logRdel*(i + 1); 622 623 float Rmin = pow(10.0, lRmin); 624 float Rmax = pow(10.0, lRmax); 625 626 float Area = M_PI * (PS_SQR(Rmax) - PS_SQR(Rmin)); 627 628 fluxTotal += flux * Area; 629 } 630 631 source->psfMag = -2.5*log10(fluxTotal); 632 source->psfMagErr = 0.05; 633 634 // XXX I have no idea of a realistic error on the photometry here. the bottom line is that 635 // the error is totally dominated by the loss of charge due to saturation. I am not 636 // modeling the profile in any real detail other than to follow the radial bins. 637 638 source->extMag = NAN; 639 source->apMag = NAN; 640 source->apMagRaw = NAN; 641 source->apFlux = fluxTotal; 642 source->apFluxErr = 0.05*fluxTotal; 643 644 return true; 645 } 646 647 # if (0) 648 static bool skipDisplay = false; 649 bool psphotVisualRadialProfileSatstar (pmSource *source, psImageMaskType maskVal) { 650 651 int kapaImage = -1; 652 int kapaGraph = -1; 653 Graphdata graphdata; 654 655 if (!pmVisualTestLevel("psphot.satstar", 3)) { 656 skipDisplay = true; 657 } 658 659 float Rmax = 320.0; 660 661 bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED); 662 if (subtracted) pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal); 663 664 int nPts = source->pixels->numRows * source->pixels->numCols; 665 psVector *rg = psVectorAllocEmpty (nPts, PS_TYPE_F32); 666 psVector *Rg = psVectorAllocEmpty (nPts, PS_TYPE_F32); 667 psVector *fg = psVectorAllocEmpty (nPts, PS_TYPE_F32); 668 psVector *Fg = psVectorAllocEmpty (nPts, PS_TYPE_F32); 669 psVector *rb = psVectorAllocEmpty (nPts, PS_TYPE_F32); 670 psVector *Rb = psVectorAllocEmpty (nPts, PS_TYPE_F32); 671 psVector *fb = psVectorAllocEmpty (nPts, PS_TYPE_F32); 672 673 int ng = 0; 674 int nb = 0; 675 676 float Xo = NAN; 677 float Yo = NAN; 678 679 if (source->modelPSF) { 680 Xo = source->modelPSF->params->data.F32[PM_PAR_XPOS] - source->pixels->col0; 681 Yo = source->modelPSF->params->data.F32[PM_PAR_YPOS] - source->pixels->row0; 682 } else { 683 Xo = source->moments->Mx - source->pixels->col0; 684 Yo = source->moments->My - source->pixels->row0; 685 } 686 687 for (int iy = 0; iy < source->pixels->numRows; iy++) { 688 for (int ix = 0; ix < source->pixels->numCols; ix++) { 689 if ((source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & maskVal)) { 690 rb->data.F32[nb] = hypot (ix + 0.5 - Xo, iy + 0.5 - Yo) ; 691 // rb->data.F32[nb] = hypot (ix - Xo, iy - Yo) ; 692 Rb->data.F32[nb] = log10(rb->data.F32[nb]); 693 fb->data.F32[nb] = log10(source->pixels->data.F32[iy][ix]); 694 nb++; 695 } else { 696 rg->data.F32[ng] = hypot (ix + 0.5 - Xo, iy + 0.5 - Yo) ; 697 // rg->data.F32[ng] = hypot (ix - Xo, iy - Yo) ; 698 Rg->data.F32[ng] = log10(rg->data.F32[ng]); 699 Fg->data.F32[ng] = source->pixels->data.F32[iy][ix]; 700 fg->data.F32[ng] = log10(Fg->data.F32[ng]); 701 ng++; 702 } 703 } 704 } 705 rg->n = ng; 706 Rg->n = ng; 707 fg->n = ng; 708 Fg->n = ng; 709 rb->n = nb; 710 Rb->n = nb; 711 fb->n = nb; 712 713 if (!skipDisplay) { 714 kapaImage = psphotKapaChannel (1); 715 if (kapaImage == -1) return false; 716 717 kapaGraph = psphotKapaChannel (2); 718 if (kapaGraph == -1) return false; 719 720 KapaSection section; // put the positive profile in one and the residuals in another? 721 722 // first section : mag vs CR nSigma 723 section.dx = 1.0; 724 section.dy = 0.5; 725 section.x = 0.0; 726 section.y = 0.0; 727 section.bg = -1; 728 section.name = NULL; 729 psStringAppend (§ion.name, "linlog"); 730 KapaSetSection (kapaGraph, §ion); 731 psFree (section.name); 732 733 // first section : mag vs CR nSigma 734 section.dx = 1.0; 735 section.dy = 0.5; 736 section.x = 0.0; 737 section.y = 0.5; 738 section.bg = -1; 739 section.name = NULL; 740 psStringAppend (§ion.name, "loglog"); 741 KapaSetSection (kapaGraph, §ion); 742 psFree (section.name); 743 744 KapaInitGraph (&graphdata); 745 746 // ** linlog ** 747 KapaSelectSection (kapaGraph, "linlog"); 748 749 // examine sources to set data range 750 graphdata.xmin = -0.05; 751 graphdata.xmax = Rmax + 0.05; 752 graphdata.ymin = -0.05; 753 graphdata.ymax = +8.05; 754 KapaSetLimits (kapaGraph, &graphdata); 755 756 KapaSetFont (kapaGraph, "helvetica", 14); 757 KapaBox (kapaGraph, &graphdata); 758 KapaSendLabel (kapaGraph, "radius (pixels)", KAPA_LABEL_XM); 759 KapaSendLabel (kapaGraph, "log flux (counts)", KAPA_LABEL_YM); 760 761 graphdata.color = KapaColorByName ("black"); 762 graphdata.ptype = 2; 763 graphdata.size = 0.5; 764 graphdata.style = 2; 765 KapaPrepPlot (kapaGraph, ng, &graphdata); 766 KapaPlotVector (kapaGraph, ng, rg->data.F32, "x"); 767 KapaPlotVector (kapaGraph, ng, fg->data.F32, "y"); 768 769 graphdata.color = KapaColorByName ("red"); 770 graphdata.ptype = 0; 771 graphdata.size = 0.3; 772 graphdata.style = 2; 773 KapaPrepPlot (kapaGraph, nb, &graphdata); 774 KapaPlotVector (kapaGraph, nb, rb->data.F32, "x"); 775 KapaPlotVector (kapaGraph, nb, fb->data.F32, "y"); 776 777 // ** loglog ** 778 KapaSelectSection (kapaGraph, "loglog"); 779 780 // examine sources to set data range 781 graphdata.xmin = -1.51; 782 graphdata.xmax = log10(Rmax) + 0.02; 783 graphdata.ymin = -5.05; 784 graphdata.ymax = +8.05; 785 graphdata.color = KapaColorByName ("black"); 786 KapaSetLimits (kapaGraph, &graphdata); 787 788 KapaSetFont (kapaGraph, "helvetica", 14); 789 KapaBox (kapaGraph, &graphdata); 790 KapaSendLabel (kapaGraph, "log radius (pixels)", KAPA_LABEL_XM); 791 KapaSendLabel (kapaGraph, "log flux (counts)", KAPA_LABEL_YM); 792 793 graphdata.color = KapaColorByName ("black"); 794 graphdata.ptype = 2; 795 graphdata.size = 0.5; 796 graphdata.style = 2; 797 KapaPrepPlot (kapaGraph, ng, &graphdata); 798 KapaPlotVector (kapaGraph, ng, Rg->data.F32, "x"); 799 KapaPlotVector (kapaGraph, ng, fg->data.F32, "y"); 800 801 graphdata.color = KapaColorByName ("red"); 802 graphdata.ptype = 0; 803 graphdata.size = 0.3; 804 graphdata.style = 2; 805 KapaPrepPlot (kapaGraph, nb, &graphdata); 806 KapaPlotVector (kapaGraph, nb, Rb->data.F32, "x"); 807 KapaPlotVector (kapaGraph, nb, fb->data.F32, "y"); 808 } 809 810 // measure the radial profile 811 psVector *logFmodel = NULL; 812 psVector *logRmodel = NULL; 813 psphotTestRadialModel (source, &logRmodel, &logFmodel, Rg, Fg, Rmax); 814 815 if (!skipDisplay) { 816 graphdata.color = KapaColorByName ("red"); 817 graphdata.ptype = 2; 818 graphdata.size = 1.0; 819 graphdata.style = 2; 820 KapaPrepPlot (kapaGraph, logRmodel->n, &graphdata); 821 KapaPlotVector (kapaGraph, logRmodel->n, logRmodel->data.F32, "x"); 822 KapaPlotVector (kapaGraph, logRmodel->n, logFmodel->data.F32, "y"); 823 } 824 825 // subtract the model from the images 826 psphotTestRadialModelSub (source, logRmodel, logFmodel, Xo, Yo, Rmax, maskVal); 827 828 psFree (logRmodel); 829 psFree (logFmodel); 830 831 if (!skipDisplay && source->modelPSF) { 832 // generate model profiles (major and minor axis): 833 // create a model with theta = 0.0 so major and minor axes are equiv to x and y: 834 psEllipseShape rawShape, rotShape; 835 836 rawShape.sx = source->modelPSF->params->data.F32[PM_PAR_SXX] / M_SQRT2; 837 rawShape.sy = source->modelPSF->params->data.F32[PM_PAR_SYY] / M_SQRT2; 838 rawShape.sxy = source->modelPSF->params->data.F32[PM_PAR_SXY]; 839 840 psEllipseAxes axes = psEllipseShapeToAxes (rawShape, 20.0); 841 842 axes.theta = 0.0; 843 844 rotShape = psEllipseAxesToShape (axes); 845 846 psVector *params = psVectorAlloc(source->modelPSF->params->n, PS_TYPE_F32); 847 for (int i = 0; i < source->modelPSF->params->n; i++) { 848 params->data.F32[i] = source->modelPSF->params->data.F32[i]; 849 } 850 params->data.F32[PM_PAR_SXX] = rotShape.sx * M_SQRT2; 851 params->data.F32[PM_PAR_SYY] = rotShape.sy * M_SQRT2; 852 params->data.F32[PM_PAR_SXY] = rotShape.sxy; 853 params->data.F32[PM_PAR_XPOS] = 0.0; 854 params->data.F32[PM_PAR_YPOS] = 0.0; 855 856 psVector *rmod = psVectorAlloc(Rmax*10, PS_TYPE_F32); 857 psVector *fmaj = psVectorAlloc(Rmax*10, PS_TYPE_F32); 858 psVector *fmin = psVectorAlloc(Rmax*10, PS_TYPE_F32); 859 860 psVector *coord = psVectorAlloc(2, PS_TYPE_F32); 861 862 float r = 0.0; 863 for (int i = 0; i < rmod->n; i++) { 864 r = i*0.1; 865 rmod->data.F32[i] = r; 866 867 coord->data.F32[1] = r; 868 coord->data.F32[0] = 0.0; 869 fmaj->data.F32[i] = log10(source->modelPSF->modelFunc (NULL, params, coord)); 870 871 coord->data.F32[0] = r; 872 coord->data.F32[1] = 0.0; 873 fmin->data.F32[i] = log10(source->modelPSF->modelFunc (NULL, params, coord)); 874 } 875 psFree (coord); 876 psFree (params); 877 878 float FWHM_MAJOR = 2.0*source->modelPSF->modelRadius (source->modelPSF->params, 0.5*source->modelPSF->params->data.F32[PM_PAR_I0]); 879 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major); 880 if (FWHM_MAJOR < FWHM_MINOR) PS_SWAP (FWHM_MAJOR, FWHM_MINOR); 881 882 psEllipseMoments emoments; 883 emoments.x2 = source->moments->Mxx; 884 emoments.xy = source->moments->Mxy; 885 emoments.y2 = source->moments->Myy; 886 axes = psEllipseMomentsToAxes (emoments, 20.0); 887 float MOMENTS_MAJOR = 2.355*axes.major; 888 float MOMENTS_MINOR = 2.355*axes.minor; 889 890 float logHM = log10(0.5*source->modelPSF->params->data.F32[PM_PAR_I0]); 891 892 // reset source Add/Sub state to recorded 893 if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 894 895 // ** linlog ** 896 KapaSelectSection (kapaGraph, "linlog"); 897 KapaGetGraphData (kapaGraph, &graphdata); 898 graphdata.color = KapaColorByName ("blue"); 899 graphdata.ptype = 0; 900 graphdata.size = 0.0; 901 graphdata.style = 0; 902 KapaPrepPlot (kapaGraph, rmod->n, &graphdata); 903 KapaPlotVector (kapaGraph, rmod->n, rmod->data.F32, "x"); 904 KapaPlotVector (kapaGraph, rmod->n, fmin->data.F32, "y"); 905 plotline (kapaGraph, &graphdata, graphdata.xmin, logHM, graphdata.xmax, logHM); 906 plotline (kapaGraph, &graphdata, 0.5*FWHM_MINOR, graphdata.ymin, 0.5*FWHM_MINOR, graphdata.ymax); 907 graphdata.ltype = 1; 908 plotline (kapaGraph, &graphdata, 0.5*MOMENTS_MINOR, graphdata.ymin, 0.5*MOMENTS_MINOR, graphdata.ymax); 909 graphdata.ltype = 0; 910 911 graphdata.color = KapaColorByName ("green"); 912 graphdata.ptype = 0; 913 graphdata.size = 0.0; 914 graphdata.style = 0; 915 KapaPrepPlot (kapaGraph, rmod->n, &graphdata); 916 KapaPlotVector (kapaGraph, rmod->n, rmod->data.F32, "x"); 917 KapaPlotVector (kapaGraph, rmod->n, fmaj->data.F32, "y"); 918 plotline (kapaGraph, &graphdata, 0.5*FWHM_MAJOR, graphdata.ymin, 0.5*FWHM_MAJOR, graphdata.ymax); 919 graphdata.ltype = 1; 920 plotline (kapaGraph, &graphdata, 0.5*MOMENTS_MAJOR, graphdata.ymin, 0.5*MOMENTS_MAJOR, graphdata.ymax); 921 graphdata.ltype = 0; 922 923 for (int i = 0; i < rmod->n; i++) { 924 rmod->data.F32[i] = log10(rmod->data.F32[i]); 925 } 926 927 // ** loglog ** 928 KapaSelectSection (kapaGraph, "loglog"); 929 KapaGetGraphData (kapaGraph, &graphdata); 930 graphdata.color = KapaColorByName ("blue"); 931 graphdata.ptype = 0; 932 graphdata.size = 0.0; 933 graphdata.style = 0; 934 KapaPrepPlot (kapaGraph, rmod->n, &graphdata); 935 KapaPlotVector (kapaGraph, rmod->n, rmod->data.F32, "x"); 936 KapaPlotVector (kapaGraph, rmod->n, fmin->data.F32, "y"); 937 938 graphdata.color = KapaColorByName ("green"); 939 graphdata.ptype = 0; 940 graphdata.size = 0.0; 941 graphdata.style = 0; 942 KapaPrepPlot (kapaGraph, rmod->n, &graphdata); 943 KapaPlotVector (kapaGraph, rmod->n, rmod->data.F32, "x"); 944 KapaPlotVector (kapaGraph, rmod->n, fmaj->data.F32, "y"); 945 946 psFree (rmod); 947 psFree (fmin); 948 psFree (fmaj); 949 } 950 951 if (!skipDisplay) { 952 KiiCenter (kapaImage, source->peak->xf, source->peak->yf, 1); 953 psphotVisualScaleImage (kapaImage, (psImage *) source->pixels->parent, NULL, "image", 1.0, 1); 954 KiiOverlay overlay; 955 overlay.x = source->peak->xf; 956 overlay.y = source->peak->yf; 957 overlay.dx = 5; 958 overlay.dy = 5; 959 overlay.angle = 0.0; 960 overlay.type = KiiOverlayTypeByName ("circle"); 961 KiiLoadOverlay (kapaImage, &overlay, 1, "red"); 962 overlay.x = source->moments->Mx; 963 overlay.y = source->moments->My; 964 overlay.dx = 8; 965 overlay.dy = 8; 966 overlay.angle = 0.0; 967 overlay.type = KiiOverlayTypeByName ("circle"); 968 KiiLoadOverlay (kapaImage, &overlay, 1, "blue"); 969 } 970 971 psFree (rg); 972 psFree (Rg); 973 psFree (fg); 974 psFree (Fg); 975 psFree (rb); 976 psFree (Rb); 977 psFree (fb); 978 979 if (skipDisplay) return true; 980 981 // pause and wait for user input: 982 // continue, save (provide name), ?? 983 char key[10]; 984 fprintf (stdout, "[q]uit satstar? [e]rase and continue? [o]verplot and continue? [s]kip rest of stars? : "); 985 if (!fgets(key, 8, stdin)) { 986 psWarning("Unable to read option"); 987 } 988 if (key[0] == 'e') { 989 KapaClearPlots (kapaGraph); 990 } 991 if (key[0] == 'q') { 992 return false; 993 } 994 if (key[0] == 's') { 995 skipDisplay = true; 996 } 997 return true; 998 } 999 # endif 1000 1001 // only valid for F32 1002 bool psImageQuickStats (QuickStats *stats, psImage *image, psRegion region) { 1003 1004 psAssert (image->type.type == PS_TYPE_F32, "unsupported image type"); 1005 1006 int Npix = (region.y1 - region.y0) * (region.x1 - region.x0); 1007 psVector *tmp = psVectorAllocEmpty (Npix, PS_TYPE_F32); 1008 1009 int bin = 0; 1010 for (int iy = region.y0; iy < region.y1; iy++) { 1011 for (int ix = region.x0; ix < region.x1; ix++) { 1012 if (!isfinite(image->data.F32[iy][ix])) continue; 1013 tmp->data.F32[bin] = image->data.F32[iy][ix]; 1014 bin ++; 1015 } 1016 } 1017 tmp->n = bin; 1018 1019 if (bin < 1) { 1020 stats->min = NAN; 1021 stats->lower20 = NAN; 1022 stats->upper20 = NAN; 1023 stats->max = NAN; 1024 stats->Npts = 0; 1025 psFree (tmp); 1026 return true; 1027 } 1028 1029 1030 psVectorSortInPlace (tmp); 1031 1032 int N20 = 0.2*tmp->n; 1033 int N80 = 0.8*tmp->n; 1034 int Nmax = tmp->n - 1; 1035 1036 stats->min = tmp->data.F32[0]; 1037 stats->lower20 = tmp->data.F32[N20]; 1038 stats->upper20 = tmp->data.F32[N80]; 1039 stats->max = tmp->data.F32[Nmax]; 1040 stats->Npts = bin; 1041 psFree (tmp); 1042 1043 return true; 1044 } 1045 1046 bool psphotAddOrSubSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int fileIndex, psMetadata *recipe, bool add) { 1047 1048 bool status; 1049 1050 psTimerStart ("psphot.deblend.sat"); 1051 1052 // find the currently selected readout 1053 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, fileIndex); // File of interest 1054 psAssert (file, "missing file?"); 1055 1056 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 1057 psAssert (readout, "missing readout?"); 1058 1059 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 1060 psAssert (detections, "missing detections?"); 1061 1062 psArray *sources = detections->allSources; 1063 psAssert (sources, "missing sources?"); 1064 1065 if (!sources->n) { 1066 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping satstar blend"); 1067 return true; 1068 } 1069 1070 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 1071 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 1072 assert (maskVal); 1073 1074 // examine sources in decreasing SN order 1075 for (int i = 0; i < sources->n; i++) { 1076 pmSource *source = sources->data[i]; 1077 1078 if (!(source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE)) continue; 1079 1080 if (!psphotSatstarProfileOp (source, maskVal, 1.0, 0, add)) continue; 1081 } 1082 1083 psLogMsg ("psphot", PS_LOG_DETAIL, "satstar op: %f sec\n", psTimerMark ("psphot.deblend.sat")); 1084 return true; 1085 } 1086 -
trunk/psphot/src/psphotExtendedSourceAnalysis.c
r33089 r34404 218 218 if (source->mode & PM_SOURCE_MODE_SATSTAR) continue; 219 219 220 // skip saturated stars modeled with a radial profile 221 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 222 220 223 // optionally allow non-extended objects to get petrosians as well 221 224 if (!doPetroStars) { -
trunk/psphot/src/psphotExtendedSourceFits.c
r34258 r34404 317 317 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 318 318 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 319 320 // skip saturated stars modeled with a radial profile 321 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 319 322 320 323 // XXX this should use peak? -
trunk/psphot/src/psphotFindDetections.c
r33914 r34404 120 120 if (useFootprints) { 121 121 if (replaceSourcesForFootprints) { 122 // subtract the noise for all sources including satstars 122 123 psphotAddOrSubNoiseReadout(config, view, filerule, index, recipe, false); 123 124 psphotReplaceAllSourcesReadout (config, view, filerule, index, recipe, false); 125 126 // add in the satstars 127 psphotAddOrSubSatstarsReadout (config, view, filerule, index, recipe, true); 128 124 129 psFree (significance); 125 130 significance = psphotSignificanceImage (readout, recipe, maskVal); 131 132 // display the significance image 133 psphotVisualShowSignificance (significance->variance, 0.98*threshold, 1.02*threshold); 126 134 } 127 135 … … 130 138 if (replaceSourcesForFootprints) { 131 139 psphotRemoveAllSourcesReadout (config, view, filerule, index, recipe, false); 140 141 // subtract the satstars 142 psphotAddOrSubSatstarsReadout (config, view, filerule, index, recipe, false); 132 143 } 133 144 } -
trunk/psphot/src/psphotFitSourcesLinear.c
r34274 r34404 222 222 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 223 223 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 224 225 // skip saturated stars modeled with a radial profile 226 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 224 227 225 228 // do not include CRs in the full ensemble fit -
trunk/psphot/src/psphotGuessModels.c
r33089 r34404 169 169 source->tmpFlags |= PM_SOURCE_TMPF_MODEL_GUESS; 170 170 171 // skip non-astronomical objects (very likely defects) 172 if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue; 171 // skip non-astronomical objects (very likely defects) and satstars with profiles subtracted 172 if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue; 173 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 173 174 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 174 175 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; -
trunk/psphot/src/psphotKronIterate.c
r34317 r34404 331 331 } 332 332 333 // skip saturated stars modeled with a radial profile 334 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 335 333 336 // replace object in image 334 337 bool reSubtract = false; -
trunk/psphot/src/psphotMagnitudes.c
r33089 r34404 182 182 if (saveTest) { 183 183 psphotSaveImage(NULL, testImage, "test.image.1.fits"); 184 } 185 186 // satstars modeled as a radial profile need special handling 187 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) { 188 psphotSatstarPhotometry (source); 189 continue; 184 190 } 185 191 -
trunk/psphot/src/psphotRadialApertures.c
r34136 r34404 240 240 if (source->mode & PM_SOURCE_MODE_DEFECT) continue; 241 241 242 // skip saturated stars modeled with a radial profile 243 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 244 242 245 // XXX measure radial apertures even for saturated stars 243 246 // if (source->mode & PM_SOURCE_MODE_SATSTAR) continue; -
trunk/psphot/src/psphotRadialProfileWings.c
r33839 r34404 190 190 if (!source->moments) continue; 191 191 192 // skip saturated stars modeled with a radial profile 193 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 194 195 // skip non-detected sources matched from other images 196 if (source->mode2 & PM_SOURCE_MODE2_MATCHED) return true; // skip matched sources (no signal) 197 198 // XXX unclear if I should run this analysis on both 1st and 2nd pass for 1st pass objects, 199 // or just use the 1st pass value. I think I should just use the 1st pass value, so skip 200 // any that have already been assigned 201 if (isfinite(source->skyRadius)) return true; 202 192 203 // replace object in image 193 204 bool reSubtract = false; … … 226 237 227 238 // psImageMaskType **vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA; 228 229 // XXX unclear if I should run this analysis on both 1st and 2nd pass for 1st pass objects,230 // or just use the 1st pass value. I think I should just use the 1st pass value, so skip231 // any that have already been assigned232 if (isfinite(source->skyRadius)) return true;233 234 if (source->mode2 & PM_SOURCE_MODE2_MATCHED) return true; // skip matched sources (no signal)235 239 236 240 // radii will be MIN_RADIUS to MAX_RADIUS in NN log steps: -
trunk/psphot/src/psphotReadout.c
r34317 r34404 128 128 } 129 129 130 // find blended neighbors of very saturated stars (detections->newSources)131 // if (!psphotDeblendSatstars (config, view, filerule)) {132 // psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis");133 // return psphotReadoutCleanup (config, view, filerule);134 // }135 136 130 // mark blended peaks PS_SOURCE_BLEND (detections->newSources) 137 131 // XXX I've deactivated this because it was preventing galaxies close to stars from being … … 149 143 } 150 144 145 // find and subtract radial profile models for saturated stars (XXX change name eventually) 146 if (!psphotDeblendSatstars (config, view, filerule)) { 147 psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis"); 148 return psphotReadoutCleanup (config, view, filerule); 149 } 150 151 151 // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources) 152 152 if (!psphotImageQuality (config, view, filerule)) { // pass 1 … … 221 221 // NOTE: this block performs the 2nd pass low-significance PSF detection stage 222 222 { 223 // add noise for subtracted objects 223 // add noise for subtracted objects & subtracted saturated stars 224 224 psphotAddNoise (config, view, filerule); // pass 1 (detections->allSources) 225 225 … … 253 253 // merge the newly selected sources into the existing list 254 254 // NOTE: merge OLD and NEW 255 // XXX check on free of sources...256 255 psphotMergeSources (config, view, filerule); // (detections->newSources + detections->allSources -> detections->allSources) 257 256 … … 294 293 // merge the newly selected sources into the existing list 295 294 // NOTE: merge OLD and NEW 296 // XXX check on free of sources...297 295 psphotMergeSources (config, view, filerule); // (detections->newSources + detections->allSources -> detections->allSources) 298 296 -
trunk/psphot/src/psphotSourceSize.c
r34258 r34404 498 498 continue; 499 499 } 500 501 // skip saturated stars modeled with a radial profile 502 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 500 503 501 504 // we are classifying by moments and PSF_MAG - KRON_MAG -
trunk/psphot/src/psphotSourceStats.c
r34321 r34404 447 447 } 448 448 449 // skip saturated stars modeled with a radial profile (this probably never happens, since it is set after) 450 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 451 449 452 if (!(source->peak->type == PM_PEAK_SUSPECT_SATURATION)) { 450 453 // measure basic source moments (no S/N clipping on input pixels) … … 521 524 float PSF_SN_LIM = 2.0*psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM"); 522 525 523 526 // XXX this will cause an error in the vector length is > 8 524 527 # define NSIGMA 8 525 528 // moved to config file … … 538 541 sigma[i] = sigmavec->data.F32[i]; 539 542 } 543 assert (sigmavec->n <= 8); 540 544 nsigma = sigmavec->n; 541 545 } else { -
trunk/psphot/src/psphotStackImageLoop.c
- Property svn:mergeinfo changed
/branches/eam_branches/ipp-20120805/psphot/src/psphotStackImageLoop.c (added) merged: 34399
- Property svn:mergeinfo changed
-
trunk/psphot/src/psphotStackMatchPSFs.c
r34352 r34404 46 46 } 47 47 48 // loop over the available readouts (ignore chisq image) psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Source Stats ---");48 // loop over the available readouts (ignore chisq image) 49 49 for (int i = 0; i < num; i++) { 50 50 if (!psphotStackMatchPSFsReadout (config, view, options, i)) { -
trunk/psphot/src/psphotVisual.c
r31452 r34404 262 262 } 263 263 264 static psImage *posImage = NULL; 265 static psImage *delImage = NULL; 266 264 267 bool psphotVisualShowImage (pmReadout *readout) { 265 268 … … 277 280 psphotVisualScaleImage (kapa, readout->variance, readout->mask, "variance", 1.0, 1); 278 281 psphotVisualScaleImage (kapa, readout->image, readout->mask, "image", sqrt(factor), 0); 282 283 if (posImage == NULL) { 284 posImage = psImageCopy (NULL, readout->image, PS_TYPE_F32); 285 } 279 286 280 287 pmVisualAskUser(NULL); … … 1139 1146 // after displaying (as an image) the psf stars, we cycle throught them and display their 1140 1147 // radial profiles: 1141 psphotVisualPlotRadialProfiles (recipe, sources );1148 psphotVisualPlotRadialProfiles (recipe, sources, PM_SOURCE_MODE_PSFSTAR); 1142 1149 1143 1150 return true; … … 1273 1280 } 1274 1281 1275 staticvoid plotline (int myKapa, Graphdata *graphdata, float x0, float y0, float x1, float y1)1282 void plotline (int myKapa, Graphdata *graphdata, float x0, float y0, float x1, float y1) 1276 1283 { 1277 1284 float x[2], y[2]; … … 1285 1292 } 1286 1293 1287 bool psphotVisualPlotRadialProfile (int myKapa, pmSource *source, psImageMaskType maskVal ) {1294 bool psphotVisualPlotRadialProfile (int myKapa, pmSource *source, psImageMaskType maskVal, pmSourceMode showmode) { 1288 1295 1289 1296 Graphdata graphdata; 1297 1298 float Rmax = (showmode & PM_SOURCE_MODE_SATSTAR) ? 100.0 : 30.0; 1290 1299 1291 1300 bool subtracted = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED); … … 1302 1311 int ng = 0; 1303 1312 int nb = 0; 1304 float Xo = source->modelPSF->params->data.F32[PM_PAR_XPOS] - source->pixels->col0; 1305 float Yo = source->modelPSF->params->data.F32[PM_PAR_YPOS] - source->pixels->row0; 1313 1314 float Xo = NAN; 1315 float Yo = NAN; 1316 1317 if (source->modelPSF) { 1318 Xo = source->modelPSF->params->data.F32[PM_PAR_XPOS] - source->pixels->col0; 1319 Yo = source->modelPSF->params->data.F32[PM_PAR_YPOS] - source->pixels->row0; 1320 } else { 1321 Xo = source->moments->Mx - source->pixels->col0; 1322 Yo = source->moments->My - source->pixels->row0; 1323 } 1324 1306 1325 for (int iy = 0; iy < source->pixels->numRows; iy++) { 1307 1326 for (int ix = 0; ix < source->pixels->numCols; ix++) { 1308 if ( source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) {1327 if ((source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & maskVal)) { 1309 1328 rb->data.F32[nb] = hypot (ix + 0.5 - Xo, iy + 0.5 - Yo) ; 1310 1329 // rb->data.F32[nb] = hypot (ix - Xo, iy - Yo) ; … … 1322 1341 } 1323 1342 1324 // generate model profiles (major and minor axis):1325 // create a model with theta = 0.0 so major and minor axes are equiv to x and y:1326 psEllipseShape rawShape, rotShape;1327 1328 rawShape.sx = source->modelPSF->params->data.F32[PM_PAR_SXX] / M_SQRT2;1329 rawShape.sy = source->modelPSF->params->data.F32[PM_PAR_SYY] / M_SQRT2;1330 rawShape.sxy = source->modelPSF->params->data.F32[PM_PAR_SXY];1331 1332 psEllipseAxes axes = psEllipseShapeToAxes (rawShape, 20.0);1333 1334 axes.theta = 0.0;1335 1336 rotShape = psEllipseAxesToShape (axes);1337 1338 psVector *params = psVectorAlloc(source->modelPSF->params->n, PS_TYPE_F32);1339 for (int i = 0; i < source->modelPSF->params->n; i++) {1340 params->data.F32[i] = source->modelPSF->params->data.F32[i];1341 }1342 params->data.F32[PM_PAR_SXX] = rotShape.sx * M_SQRT2;1343 params->data.F32[PM_PAR_SYY] = rotShape.sy * M_SQRT2;1344 params->data.F32[PM_PAR_SXY] = rotShape.sxy;1345 params->data.F32[PM_PAR_XPOS] = 0.0;1346 params->data.F32[PM_PAR_YPOS] = 0.0;1347 1348 psVector *rmod = psVectorAlloc(300, PS_TYPE_F32);1349 psVector *fmaj = psVectorAlloc(300, PS_TYPE_F32);1350 psVector *fmin = psVectorAlloc(300, PS_TYPE_F32);1351 1352 psVector *coord = psVectorAlloc(2, PS_TYPE_F32);1353 1354 float r = 0.0;1355 for (int i = 0; i < rmod->n; i++) {1356 r = i*0.1;1357 rmod->data.F32[i] = r;1358 1359 coord->data.F32[1] = r;1360 coord->data.F32[0] = 0.0;1361 fmaj->data.F32[i] = log10(source->modelPSF->modelFunc (NULL, params, coord));1362 1363 coord->data.F32[0] = r;1364 coord->data.F32[1] = 0.0;1365 fmin->data.F32[i] = log10(source->modelPSF->modelFunc (NULL, params, coord));1366 }1367 psFree (coord);1368 psFree (params);1369 1370 float FWHM_MAJOR = 2.0*source->modelPSF->modelRadius (source->modelPSF->params, 0.5*source->modelPSF->params->data.F32[PM_PAR_I0]);1371 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);1372 if (FWHM_MAJOR < FWHM_MINOR) PS_SWAP (FWHM_MAJOR, FWHM_MINOR);1373 1374 psEllipseMoments emoments;1375 emoments.x2 = source->moments->Mxx;1376 emoments.xy = source->moments->Mxy;1377 emoments.y2 = source->moments->Myy;1378 axes = psEllipseMomentsToAxes (emoments, 20.0);1379 float MOMENTS_MAJOR = 2.355*axes.major;1380 float MOMENTS_MINOR = 2.355*axes.minor;1381 1382 float logHM = log10(0.5*source->modelPSF->params->data.F32[PM_PAR_I0]);1383 1384 // reset source Add/Sub state to recorded1385 if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);1386 1387 1343 KapaInitGraph (&graphdata); 1388 1344 … … 1392 1348 // examine sources to set data range 1393 1349 graphdata.xmin = -0.05; 1394 graphdata.xmax = +30.05;1350 graphdata.xmax = Rmax + 0.05; 1395 1351 graphdata.ymin = -0.05; 1396 1352 graphdata.ymax = +8.05; … … 1418 1374 KapaPlotVector (myKapa, nb, fb->data.F32, "y"); 1419 1375 1420 graphdata.color = KapaColorByName ("blue");1421 graphdata.ptype = 0;1422 graphdata.size = 0.0;1423 graphdata.style = 0;1424 KapaPrepPlot (myKapa, rmod->n, &graphdata);1425 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x");1426 KapaPlotVector (myKapa, rmod->n, fmin->data.F32, "y");1427 plotline (myKapa, &graphdata, 0.0, logHM, 30.0, logHM);1428 plotline (myKapa, &graphdata, 0.5*FWHM_MINOR, 0.0, 0.5*FWHM_MINOR, 5.0);1429 graphdata.ltype = 1;1430 plotline (myKapa, &graphdata, 0.5*MOMENTS_MINOR, 0.0, 0.5*MOMENTS_MINOR, 5.0);1431 graphdata.ltype = 0;1432 1433 graphdata.color = KapaColorByName ("green");1434 graphdata.ptype = 0;1435 graphdata.size = 0.0;1436 graphdata.style = 0;1437 KapaPrepPlot (myKapa, rmod->n, &graphdata);1438 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x");1439 KapaPlotVector (myKapa, rmod->n, fmaj->data.F32, "y");1440 plotline (myKapa, &graphdata, 0.5*FWHM_MAJOR, 0.0, 0.5*FWHM_MAJOR, 5.0);1441 graphdata.ltype = 1;1442 plotline (myKapa, &graphdata, 0.5*MOMENTS_MAJOR, 0.0, 0.5*MOMENTS_MAJOR, 5.0);1443 graphdata.ltype = 0;1444 1445 for (int i = 0; i < rmod->n; i++) {1446 rmod->data.F32[i] = log10(rmod->data.F32[i]);1447 }1448 1449 1376 // ** loglog ** 1450 1377 KapaSelectSection (myKapa, "loglog"); … … 1452 1379 // examine sources to set data range 1453 1380 graphdata.xmin = -1.51; 1454 graphdata.xmax = +1.51;1381 graphdata.xmax = log10(Rmax) + 0.02; 1455 1382 graphdata.ymin = -0.05; 1456 1383 graphdata.ymax = +8.05; … … 1479 1406 KapaPlotVector (myKapa, nb, fb->data.F32, "y"); 1480 1407 1481 graphdata.color = KapaColorByName ("blue"); 1482 graphdata.ptype = 0; 1483 graphdata.size = 0.0; 1484 graphdata.style = 0; 1485 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1486 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1487 KapaPlotVector (myKapa, rmod->n, fmin->data.F32, "y"); 1488 1489 graphdata.color = KapaColorByName ("green"); 1490 graphdata.ptype = 0; 1491 graphdata.size = 0.0; 1492 graphdata.style = 0; 1493 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1494 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1495 KapaPlotVector (myKapa, rmod->n, fmaj->data.F32, "y"); 1496 1497 psFree (rmod); 1498 psFree (fmin); 1499 psFree (fmaj); 1408 if (source->modelPSF) { 1409 // generate model profiles (major and minor axis): 1410 // create a model with theta = 0.0 so major and minor axes are equiv to x and y: 1411 psEllipseShape rawShape, rotShape; 1412 1413 rawShape.sx = source->modelPSF->params->data.F32[PM_PAR_SXX] / M_SQRT2; 1414 rawShape.sy = source->modelPSF->params->data.F32[PM_PAR_SYY] / M_SQRT2; 1415 rawShape.sxy = source->modelPSF->params->data.F32[PM_PAR_SXY]; 1416 1417 psEllipseAxes axes = psEllipseShapeToAxes (rawShape, 20.0); 1418 1419 axes.theta = 0.0; 1420 1421 rotShape = psEllipseAxesToShape (axes); 1422 1423 psVector *params = psVectorAlloc(source->modelPSF->params->n, PS_TYPE_F32); 1424 for (int i = 0; i < source->modelPSF->params->n; i++) { 1425 params->data.F32[i] = source->modelPSF->params->data.F32[i]; 1426 } 1427 params->data.F32[PM_PAR_SXX] = rotShape.sx * M_SQRT2; 1428 params->data.F32[PM_PAR_SYY] = rotShape.sy * M_SQRT2; 1429 params->data.F32[PM_PAR_SXY] = rotShape.sxy; 1430 params->data.F32[PM_PAR_XPOS] = 0.0; 1431 params->data.F32[PM_PAR_YPOS] = 0.0; 1432 1433 psVector *rmod = psVectorAlloc(Rmax*10, PS_TYPE_F32); 1434 psVector *fmaj = psVectorAlloc(Rmax*10, PS_TYPE_F32); 1435 psVector *fmin = psVectorAlloc(Rmax*10, PS_TYPE_F32); 1436 1437 psVector *coord = psVectorAlloc(2, PS_TYPE_F32); 1438 1439 float r = 0.0; 1440 for (int i = 0; i < rmod->n; i++) { 1441 r = i*0.1; 1442 rmod->data.F32[i] = r; 1443 1444 coord->data.F32[1] = r; 1445 coord->data.F32[0] = 0.0; 1446 fmaj->data.F32[i] = log10(source->modelPSF->modelFunc (NULL, params, coord)); 1447 1448 coord->data.F32[0] = r; 1449 coord->data.F32[1] = 0.0; 1450 fmin->data.F32[i] = log10(source->modelPSF->modelFunc (NULL, params, coord)); 1451 } 1452 psFree (coord); 1453 psFree (params); 1454 1455 float FWHM_MAJOR = 2.0*source->modelPSF->modelRadius (source->modelPSF->params, 0.5*source->modelPSF->params->data.F32[PM_PAR_I0]); 1456 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major); 1457 if (FWHM_MAJOR < FWHM_MINOR) PS_SWAP (FWHM_MAJOR, FWHM_MINOR); 1458 1459 psEllipseMoments emoments; 1460 emoments.x2 = source->moments->Mxx; 1461 emoments.xy = source->moments->Mxy; 1462 emoments.y2 = source->moments->Myy; 1463 axes = psEllipseMomentsToAxes (emoments, 20.0); 1464 float MOMENTS_MAJOR = 2.355*axes.major; 1465 float MOMENTS_MINOR = 2.355*axes.minor; 1466 1467 float logHM = log10(0.5*source->modelPSF->params->data.F32[PM_PAR_I0]); 1468 1469 // reset source Add/Sub state to recorded 1470 if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 1471 1472 // ** linlog ** 1473 KapaSelectSection (myKapa, "linlog"); 1474 KapaGetGraphData (myKapa, &graphdata); 1475 graphdata.color = KapaColorByName ("blue"); 1476 graphdata.ptype = 0; 1477 graphdata.size = 0.0; 1478 graphdata.style = 0; 1479 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1480 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1481 KapaPlotVector (myKapa, rmod->n, fmin->data.F32, "y"); 1482 plotline (myKapa, &graphdata, graphdata.xmin, logHM, graphdata.xmax, logHM); 1483 plotline (myKapa, &graphdata, 0.5*FWHM_MINOR, graphdata.ymin, 0.5*FWHM_MINOR, graphdata.ymax); 1484 graphdata.ltype = 1; 1485 plotline (myKapa, &graphdata, 0.5*MOMENTS_MINOR, graphdata.ymin, 0.5*MOMENTS_MINOR, graphdata.ymax); 1486 graphdata.ltype = 0; 1487 1488 graphdata.color = KapaColorByName ("green"); 1489 graphdata.ptype = 0; 1490 graphdata.size = 0.0; 1491 graphdata.style = 0; 1492 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1493 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1494 KapaPlotVector (myKapa, rmod->n, fmaj->data.F32, "y"); 1495 plotline (myKapa, &graphdata, 0.5*FWHM_MAJOR, graphdata.ymin, 0.5*FWHM_MAJOR, graphdata.ymax); 1496 graphdata.ltype = 1; 1497 plotline (myKapa, &graphdata, 0.5*MOMENTS_MAJOR, graphdata.ymin, 0.5*MOMENTS_MAJOR, graphdata.ymax); 1498 graphdata.ltype = 0; 1499 1500 for (int i = 0; i < rmod->n; i++) { 1501 rmod->data.F32[i] = log10(rmod->data.F32[i]); 1502 } 1503 1504 // ** loglog ** 1505 KapaSelectSection (myKapa, "loglog"); 1506 KapaGetGraphData (myKapa, &graphdata); 1507 graphdata.color = KapaColorByName ("blue"); 1508 graphdata.ptype = 0; 1509 graphdata.size = 0.0; 1510 graphdata.style = 0; 1511 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1512 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1513 KapaPlotVector (myKapa, rmod->n, fmin->data.F32, "y"); 1514 1515 graphdata.color = KapaColorByName ("green"); 1516 graphdata.ptype = 0; 1517 graphdata.size = 0.0; 1518 graphdata.style = 0; 1519 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1520 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1521 KapaPlotVector (myKapa, rmod->n, fmaj->data.F32, "y"); 1522 1523 psFree (rmod); 1524 psFree (fmin); 1525 psFree (fmaj); 1526 } 1500 1527 1501 1528 psFree (rg); … … 1508 1535 } 1509 1536 1510 bool psphotVisualPlotRadialProfiles (psMetadata *recipe, psArray *sources ) {1537 bool psphotVisualPlotRadialProfiles (psMetadata *recipe, psArray *sources, pmSourceMode showmode) { 1511 1538 1512 1539 KapaSection section; // put the positive profile in one and the residuals in another? … … 1549 1576 1550 1577 pmSource *source = sources->data[i]; 1551 if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue; 1552 1553 psphotVisualPlotRadialProfile (myKapa, source, maskVal); 1578 if (!(source->mode & showmode)) continue; 1579 1580 psphotVisualPlotRadialProfile (myKapa, source, maskVal, showmode); 1581 1582 if (pmVisualTestLevel("psphot.image", 1)) { 1583 int display = psphotKapaChannel (1); 1584 KiiCenter (display, source->peak->xf, source->peak->yf, 1); 1585 KiiOverlay overlay; 1586 overlay.x = source->peak->xf; 1587 overlay.y = source->peak->yf; 1588 overlay.dx = 5; 1589 overlay.dy = 5; 1590 overlay.angle = 0.0; 1591 overlay.type = KiiOverlayTypeByName ("circle"); 1592 KiiLoadOverlay (display, &overlay, 1, "red"); 1593 overlay.x = source->moments->Mx; 1594 overlay.y = source->moments->My; 1595 overlay.dx = 8; 1596 overlay.dy = 8; 1597 overlay.angle = 0.0; 1598 overlay.type = KiiOverlayTypeByName ("circle"); 1599 KiiLoadOverlay (display, &overlay, 1, "blue"); 1600 } 1554 1601 1555 1602 // pause and wait for user input: … … 2540 2587 } 2541 2588 2542 if ( reshow) {2589 if (false && reshow) { 2543 2590 psphotVisualShowMask (myKapa, readout->mask, "mask", 2); 2544 2591 psphotVisualScaleImage (myKapa, readout->variance, readout->mask, "variance", 1.0, 1); 2545 2592 } 2546 psphotVisualScaleImage (myKapa, readout->image, readout->mask, "resid", sqrt(factor), 0); 2593 2594 if (posImage) { 2595 delImage = (psImage *) psBinaryOp(delImage, posImage, "-", readout->image); 2596 psphotVisualScaleImage (myKapa, posImage, readout->mask, "posimage", sqrt(factor), 0); 2597 psphotVisualScaleImage (myKapa, delImage, readout->mask, "delimage", sqrt(factor), 2); 2598 } 2599 2600 psphotVisualScaleImage (myKapa, readout->image, readout->mask, "resid", sqrt(factor), 1); 2547 2601 2548 2602 pmVisualAskUser(NULL);
Note:
See TracChangeset
for help on using the changeset viewer.
