Changeset 19862
- Timestamp:
- Oct 2, 2008, 11:00:57 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branch_20080926/psphot/src/psphotVisual.c
r19762 r19862 1 1 # include "psphotInternal.h" 2 bool psphotVisualPlotMoments (pmConfig *config, const pmFPAview *view, psArray *sources); 3 4 // this function displays representative images as the psphot analysis progresses: 5 // 0 : image, 1 : weight 6 // 0 : backsub, 1 : weight, 2 : backgnd 7 // 0 : backsub, 1 : weight, 2 : signif 8 // (overlay peaks on images) 9 // (overlay footprints on images) 10 // (overlay moments on images) 11 // (overlay rough class on images) 12 // 0 : backsub, 1 : psfpos, 2: psfsub 13 // 0 : backsub, 1 : lin_resid, 2: psfsub 2 14 3 15 # if (HAVE_KAPA) … … 9 21 static bool isVisual = false; 10 22 static int kapa = -1; 23 static int kapa2 = -1; 24 static int kapa3 = -1; 11 25 12 26 bool psphotSetVisual (bool mode) { 13 27 14 isVisual = mode; 15 return true; 16 } 17 18 bool psphotVisualShowImage (pmReadout *readout) { 19 20 KiiImage image; 21 KapaImageData data; 22 Coords coords; 23 24 if (!isVisual) return true; 25 26 if (kapa == -1) { 27 kapa = pmKapaOpen (true, "psphot"); 28 isVisual = mode; 29 return true; 30 } 31 32 bool psphotVisualScaleImage (int kapaFD, psImage *inImage, const char *name, int channel) { 33 34 KiiImage image; 35 KapaImageData data; 36 Coords coords; 37 38 strcpy (coords.ctype, "RA---TAN"); 39 40 psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 41 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); 42 if (!psImageBackground(stats, NULL, inImage, NULL, 0, rng)) { 43 fprintf (stderr, "failed to get background values\n"); 44 return false; 45 } 46 47 image.data2d = inImage->data.F32; 48 image.Nx = inImage->numCols; 49 image.Ny = inImage->numRows; 50 51 strcpy (data.name, name); 52 strcpy (data.file, name); 53 data.zero = stats->robustMedian - stats->robustStdev; 54 data.range = 5*stats->robustStdev; 55 data.logflux = 0; 56 57 KiiSetChannel (kapaFD, channel); 58 KiiNewPicture2D (kapaFD, &image, &data, &coords); 59 60 psFree (stats); 61 psFree (rng); 62 63 return true; 64 } 65 66 bool psphotVisualRangeImage (int kapaFD, psImage *inImage, const char *name, int channel, float min, float max) { 67 68 KiiImage image; 69 KapaImageData data; 70 Coords coords; 71 72 strcpy (coords.ctype, "RA---TAN"); 73 74 image.data2d = inImage->data.F32; 75 image.Nx = inImage->numCols; 76 image.Ny = inImage->numRows; 77 78 strcpy (data.name, name); 79 strcpy (data.file, name); 80 data.zero = min; 81 data.range = max - min; 82 data.logflux = 0; 83 84 KiiSetChannel (kapaFD, channel); 85 KiiNewPicture2D (kapaFD, &image, &data, &coords); 86 87 return true; 88 } 89 90 bool psphotVisualShowImage (pmConfig *config, pmReadout *readout) { 91 92 if (!isVisual) return true; 93 28 94 if (kapa == -1) { 29 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 30 isVisual = false; 31 return false; 32 } 33 } 34 35 // XXX get image stats 36 image.data2d = readout->image->data.F32; 37 image.Nx = readout->image->numCols; 38 image.Ny = readout->image->numRows; 39 40 strcpy (data.name, "image"); 41 strcpy (data.file, "image"); 42 data.zero = 0.0; 43 data.range = 1000.0; 44 data.logflux = 0; 95 kapa = KapaOpenNamedSocket ("kapa", "psphot:images"); 96 if (kapa == -1) { 97 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 98 isVisual = false; 99 return false; 100 } 101 } 102 103 // psphotVisualShowMask (kapa, readout->mask, "mask", 2); 104 psphotVisualScaleImage (kapa, readout->weight, "weight", 1); 105 psphotVisualScaleImage (kapa, readout->image, "image", 0); 106 107 // pause and wait for user input: 108 // continue, save (provide name), ?? 109 char key[10]; 110 fprintf (stdout, "[c]ontinue? "); 111 if (!fgets(key, 8, stdin)) { 112 psWarning("Unable to read option"); 113 } 114 return true; 115 } 116 117 bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout) { 118 119 pmReadout *backgnd; 120 121 if (!isVisual) return true; 122 123 if (kapa == -1) { 124 kapa = KapaOpenNamedSocket ("kapa", "psphot:images"); 125 if (kapa == -1) { 126 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 127 isVisual = false; 128 return false; 129 } 130 } 131 132 bool status = false; 133 pmFPAfile *file = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKGND"); 134 135 if (file->mode == PM_FPA_MODE_INTERNAL) { 136 backgnd = file->readout; 137 } else { 138 backgnd = pmFPAviewThisReadout (view, file->fpa); 139 } 140 141 psphotVisualScaleImage (kapa, backgnd->image, "backgnd", 2); 142 psphotVisualScaleImage (kapa, readout->image, "backsub", 0); 143 144 // pause and wait for user input: 145 // continue, save (provide name), ?? 146 char key[10]; 147 fprintf (stdout, "[c]ontinue? "); 148 if (!fgets(key, 8, stdin)) { 149 psWarning("Unable to read option"); 150 } 151 return true; 152 } 153 154 bool psphotVisualShowSignificance (psImage *image) { 155 156 if (!isVisual) return true; 157 158 if (kapa == -1) { 159 kapa = KapaOpenNamedSocket ("kapa", "psphot:images"); 160 if (kapa == -1) { 161 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 162 isVisual = false; 163 return false; 164 } 165 } 166 167 // XXX test: image->data.F32[10][10] = 10000; 168 psphotVisualRangeImage (kapa, image, "signif", 2, -1.0, 25.0*25.0); 169 170 // pause and wait for user input: 171 // continue, save (provide name), ?? 172 char key[10]; 173 fprintf (stdout, "[c]ontinue? "); 174 if (!fgets(key, 8, stdin)) { 175 psWarning("Unable to read option"); 176 } 177 return true; 178 } 179 180 bool psphotVisualShowPeaks (pmConfig *config, const pmFPAview *view, pmDetections *detections) { 181 182 int Noverlay; 183 KiiOverlay *overlay; 45 184 46 KiiSetChannel (kapa, 0); 47 KiiNewPicture2D (kapa, &image, &data, &coords); 185 if (!isVisual) return true; 186 187 if (kapa == -1) { 188 fprintf (stderr, "kapa not opened, skipping\n"); 189 return false; 190 } 191 192 psArray *peaks = detections->peaks; 193 194 // note: this uses the Ohana allocation tools: 195 // ALLOCATE (overlay, KiiOverlay, 3*peaks->n + 1); 196 ALLOCATE (overlay, KiiOverlay, peaks->n); 197 198 Noverlay = 0; 199 for (int i = 0; i < peaks->n; i++) { 200 201 pmPeak *peak = peaks->data[i]; 202 if (peak == NULL) continue; 203 204 overlay[Noverlay].type = KII_OVERLAY_BOX; 205 overlay[Noverlay].x = peak->xf; 206 overlay[Noverlay].y = peak->yf; 207 overlay[Noverlay].dx = 2.0; 208 overlay[Noverlay].dy = 2.0; 209 overlay[Noverlay].angle = 0.0; 210 overlay[Noverlay].text = NULL; 211 Noverlay ++; 212 213 # if (0) 214 overlay[Noverlay].type = KII_OVERLAY_BOX; 215 overlay[Noverlay].x = peak->x; 216 overlay[Noverlay].y = peak->y; 217 overlay[Noverlay].dx = 1.0; 218 overlay[Noverlay].dy = 1.0; 219 overlay[Noverlay].angle = 0.0; 220 overlay[Noverlay].text = NULL; 221 Noverlay ++; 222 223 overlay[Noverlay].type = KII_OVERLAY_CIRCLE; 224 overlay[Noverlay].x = peak->xf; 225 overlay[Noverlay].y = peak->yf; 226 overlay[Noverlay].dx = 2.0; 227 overlay[Noverlay].dy = 2.0; 228 overlay[Noverlay].angle = 0.0; 229 overlay[Noverlay].text = NULL; 230 Noverlay ++; 231 # endif 232 } 233 234 # if (0) 235 overlay[Noverlay].type = KII_OVERLAY_BOX; 236 overlay[Noverlay].x = 10.0; 237 overlay[Noverlay].y = 10.0; 238 overlay[Noverlay].dx = 0.5; 239 overlay[Noverlay].dy = 0.5; 240 overlay[Noverlay].angle = 0.0; 241 overlay[Noverlay].text = NULL; 242 Noverlay ++; 243 # endif 244 245 KiiLoadOverlay (kapa, overlay, Noverlay, "red"); 246 FREE (overlay); 247 248 // pause and wait for user input: 249 // continue, save (provide name), ?? 250 char key[10]; 251 fprintf (stdout, "[c]ontinue? "); 252 if (!fgets(key, 8, stdin)) { 253 psWarning("Unable to read option"); 254 } 255 return true; 256 } 257 258 // XXX this is just wrong: outlines entire image 259 bool psphotVisualShowFootprints (pmConfig *config, const pmFPAview *view, pmDetections *detections) { 260 261 int Noverlay; 262 KiiOverlay *overlay; 48 263 49 // display the weight 50 image.data2d = readout->weight->data.F32; 51 image.Nx = readout->weight->numCols; 52 image.Ny = readout->weight->numRows; 53 54 strcpy (data.name, "weight"); 55 strcpy (data.file, "weight"); 56 data.zero = 0.0; 57 data.range = 1000.0; 58 data.logflux = 0; 264 if (!isVisual) return true; 265 266 if (kapa == -1) { 267 fprintf (stderr, "kapa not opened, skipping\n"); 268 return false; 269 } 270 271 psArray *footprints = detections->footprints; 272 if (!footprints) return true; 273 274 // note: this uses the Ohana allocation tools: 275 int NOVERLAY = footprints->n; 276 ALLOCATE (overlay, KiiOverlay, NOVERLAY); 277 278 Noverlay = 0; 279 for (int i = 0; i < footprints->n; i++) { 280 281 pmSpan *span = NULL; 282 283 pmFootprint *footprint = footprints->data[i]; 284 if (footprint == NULL) continue; 285 if (footprint->spans == NULL) continue; 286 if (footprint->spans->n < 1) continue; 287 288 // draw the top 289 span = footprint->spans->data[0]; 290 overlay[Noverlay].type = KII_OVERLAY_LINE; 291 overlay[Noverlay].x = span->x0; 292 overlay[Noverlay].y = span->y; 293 overlay[Noverlay].dx = span->x1 - span->x0; 294 overlay[Noverlay].dy = 0; 295 overlay[Noverlay].angle = 0.0; 296 overlay[Noverlay].text = NULL; 297 Noverlay ++; 298 CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100); 299 300 int ys = span->y; 301 int x0s = span->x0; 302 int x1s = span->x1; 303 304 // draw the outer span edges 305 for (int j = 1; j < footprint->spans->n; j++) { 306 pmSpan *span1 = footprint->spans->data[j]; 307 308 int ye = span1->y; 309 int x0e = span1->x0; 310 int x1e = span1->x1; 311 312 // we cannot have two discontinuous spans on the top or bottom, right? (no, probably not right) 313 // find all of the spans in this row and generate x0e, x01: 314 for (int k = j + 1; k < footprint->spans->n; k++) { 315 pmSpan *span2 = footprint->spans->data[k]; 316 if (span2->y > span1->y) break; 317 x0e = PS_MIN (x0e, span2->x0); 318 x1e = PS_MAX (x1e, span2->x1); 319 j++; 320 } 321 322 overlay[Noverlay].type = KII_OVERLAY_LINE; 323 overlay[Noverlay].x = x0s; 324 overlay[Noverlay].y = ys; 325 overlay[Noverlay].dx = x0e - x0s; 326 overlay[Noverlay].dy = ye - ys; 327 overlay[Noverlay].angle = 0.0; 328 overlay[Noverlay].text = NULL; 329 Noverlay ++; 330 CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100); 331 332 overlay[Noverlay].type = KII_OVERLAY_LINE; 333 overlay[Noverlay].x = x1s; 334 overlay[Noverlay].y = ys; 335 overlay[Noverlay].dx = x1e - x1s; 336 overlay[Noverlay].dy = ye - ys; 337 overlay[Noverlay].angle = 0.0; 338 overlay[Noverlay].text = NULL; 339 Noverlay ++; 340 CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100); 341 342 ys = ye; 343 x0s = x0e; 344 x1s = x1e; 345 } 346 347 // draw the bottom 348 span = footprint->spans->data[footprint->spans->n - 1]; 349 overlay[Noverlay].type = KII_OVERLAY_LINE; 350 overlay[Noverlay].x = span->x0; 351 overlay[Noverlay].y = span->y; 352 overlay[Noverlay].dx = span->x1 - span->x0; 353 overlay[Noverlay].dy = 0; 354 overlay[Noverlay].angle = 0.0; 355 overlay[Noverlay].text = NULL; 356 Noverlay ++; 357 CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100); 358 } 359 360 KiiLoadOverlay (kapa, overlay, Noverlay, "blue"); 361 FREE (overlay); 362 363 // pause and wait for user input: 364 // continue, save (provide name), ?? 365 char key[10]; 366 fprintf (stdout, "[c]ontinue? "); 367 if (!fgets(key, 8, stdin)) { 368 psWarning("Unable to read option"); 369 } 370 return true; 371 } 372 373 bool psphotVisualShowMoments (pmConfig *config, const pmFPAview *view, psArray *sources) { 374 375 int Noverlay; 376 KiiOverlay *overlay; 59 377 60 KiiSetChannel (kapa, 0); 61 KiiNewPicture2D (kapa, &image, &data, &coords); 378 psEllipseMoments emoments; 379 psEllipseAxes axes; 380 381 if (!isVisual) return true; 382 383 if (kapa == -1) { 384 fprintf (stderr, "kapa not opened, skipping\n"); 385 return false; 386 } 387 388 // note: this uses the Ohana allocation tools: 389 ALLOCATE (overlay, KiiOverlay, sources->n); 390 391 Noverlay = 0; 392 for (int i = 0; i < sources->n; i++) { 393 394 pmSource *source = sources->data[i]; 395 if (source == NULL) continue; 396 397 pmMoments *moments = source->moments; 398 if (moments == NULL) continue; 399 400 overlay[Noverlay].type = KII_OVERLAY_CIRCLE; 401 overlay[Noverlay].x = moments->x; 402 overlay[Noverlay].y = moments->y; 403 404 emoments.x2 = moments->Sx; 405 emoments.y2 = moments->Sy; 406 emoments.xy = moments->Sxy; 407 408 axes = psEllipseMomentsToAxes (emoments, 20.0); 409 410 overlay[Noverlay].dx = 2.0*axes.major; 411 overlay[Noverlay].dy = 2.0*axes.minor; 412 overlay[Noverlay].angle = axes.theta * PS_DEG_RAD; 413 overlay[Noverlay].text = NULL; 414 Noverlay ++; 415 } 416 417 KiiLoadOverlay (kapa, overlay, Noverlay, "yellow"); 418 FREE (overlay); 419 420 // pause and wait for user input: 421 // continue, save (provide name), ?? 422 char key[10]; 423 fprintf (stdout, "[c]ontinue? "); 424 if (!fgets(key, 8, stdin)) { 425 psWarning("Unable to read option"); 426 } 427 428 return true; 429 } 430 431 bool psphotVisualPlotMoments (pmConfig *config, const pmFPAview *view, psArray *sources) { 432 433 bool status; 434 Graphdata graphdata; 435 436 if (!isVisual) return true; 437 438 if (kapa3 == -1) { 439 kapa3 = KapaOpenNamedSocket ("kapa", "psphot:plots"); 440 if (kapa3 == -1) { 441 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 442 isVisual = false; 443 return false; 444 } 445 } 446 447 // select the current recipe 448 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE); 449 if (!recipe) { 450 fprintf (stderr, "missing recipe, skipping moments plot\n"); 451 return false; 452 } 453 454 KapaClearPlots (kapa3); 455 KapaInitGraph (&graphdata); 456 457 float psfX = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.X"); 458 float psfY = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.Y"); 459 float psfdX = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.DX"); 460 float psfdY = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.DY"); 461 float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA"); 462 float Rx = psfdX * PSF_CLUMP_NSIGMA; 463 float Ry = psfdY * PSF_CLUMP_NSIGMA; 464 465 // examine sources to set data range 466 graphdata.xmin = -0.05; 467 graphdata.ymin = -0.05; 468 graphdata.xmax = 2.0*psfX; 469 graphdata.ymax = 2.0*psfY; 470 KapaSetLimits (kapa3, &graphdata); 471 472 KapaSetFont (kapa3, "helvetica", 14); 473 KapaBox (kapa3, &graphdata); 474 KapaSendLabel (kapa3, "&ss&h_x| (pixels)", KAPA_LABEL_XM); 475 KapaSendLabel (kapa3, "&ss&h_y| (pixels)", KAPA_LABEL_YM); 476 477 psVector *xBright = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 478 psVector *yBright = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 479 psVector *xFaint = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 480 psVector *yFaint = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 481 482 // construct the vectors 483 int nB = 0; 484 int nF = 0; 485 for (int i = 0; i < sources->n; i++) { 486 pmSource *source = sources->data[i]; 487 if (source->moments == NULL) 488 continue; 489 490 xFaint->data.F32[nF] = source->moments->Sx; 491 yFaint->data.F32[nF] = source->moments->Sy; 492 nF++; 493 494 // XXX make this a user-defined cutoff 495 if (source->moments->SN < 50) 496 continue; 497 498 xBright->data.F32[nB] = source->moments->Sx; 499 yBright->data.F32[nB] = source->moments->Sy; 500 nB++; 501 } 502 xFaint->n = nF; 503 yFaint->n = nF; 504 505 xBright->n = nB; 506 yBright->n = nB; 507 508 graphdata.color = KapaColorByName ("black"); 509 graphdata.ptype = 0; 510 graphdata.size = 0.3; 511 graphdata.style = 2; 512 KapaPrepPlot (kapa3, nF, &graphdata); 513 KapaPlotVector (kapa3, nF, xFaint->data.F32, "x"); 514 KapaPlotVector (kapa3, nF, yFaint->data.F32, "y"); 515 516 graphdata.color = KapaColorByName ("red"); 517 graphdata.ptype = 2; 518 graphdata.size = 0.5; 519 graphdata.style = 2; 520 KapaPrepPlot (kapa3, nB, &graphdata); 521 KapaPlotVector (kapa3, nB, xBright->data.F32, "x"); 522 KapaPlotVector (kapa3, nB, yBright->data.F32, "y"); 523 524 // draw a circle centered on psfX,Y with size of the psf limit 525 psVector *xLimit = psVectorAlloc (120, PS_TYPE_F32); 526 psVector *yLimit = psVectorAlloc (120, PS_TYPE_F32); 527 for (int i = 0; i < xLimit->n; i++) { 528 xLimit->data.F32[i] = Rx*cos(i*2.0*M_PI/120.0) + psfX; 529 yLimit->data.F32[i] = Ry*sin(i*2.0*M_PI/120.0) + psfY; 530 } 531 graphdata.color = KapaColorByName ("blue"); 532 graphdata.style = 0; 533 KapaPrepPlot (kapa3, xLimit->n, &graphdata); 534 KapaPlotVector (kapa3, xLimit->n, xLimit->data.F32, "x"); 535 KapaPlotVector (kapa3, yLimit->n, yLimit->data.F32, "y"); 536 psFree (xLimit); 537 psFree (yLimit); 538 539 # if (0) 540 // *** make a histogram of the source counts in the x and y directions 541 psHistogram *nX = psHistogramAlloc (graphdata.xmin, graphdata.xmax, 50.0); 542 psHistogram *nY = psHistogramAlloc (graphdata.ymin, graphdata.ymax, 50.0); 543 psVectorHistogram (nX, xFaint, NULL, NULL, 0); 544 psVectorHistogram (nY, yFaint, NULL, NULL, 0); 545 psVector *dX = psVectorAlloc (nX->nums->n, PS_TYPE_F32); 546 psVector *vX = psVectorAlloc (nX->nums->n, PS_TYPE_F32); 547 psVector *dY = psVectorAlloc (nY->nums->n, PS_TYPE_F32); 548 psVector *vY = psVectorAlloc (nY->nums->n, PS_TYPE_F32); 549 for (int i = 0; i < nX->nums->n; i++) { 550 dX->data.F32[i] = nX->nums->data.S32[i]; 551 vX->data.F32[i] = 0.5*(nX->bounds->data.F32[i] + nX->bounds->data.F32[i+1]); 552 } 553 for (int i = 0; i < nY->nums->n; i++) { 554 dY->data.F32[i] = nY->nums->data.S32[i]; 555 vY->data.F32[i] = 0.5*(nY->bounds->data.F32[i] + nY->bounds->data.F32[i+1]); 556 } 557 558 graphdata.color = KapaColorByName ("black"); 559 graphdata.ptype = 0; 560 graphdata.size = 0.0; 561 graphdata.style = 0; 562 KapaPrepPlot (kapa3, dX->n, &graphdata); 563 KapaPlotVector (kapa3, dX->n, dX->data.F32, "x"); 564 KapaPlotVector (kapa3, vX->n, vX->data.F32, "y"); 565 566 psFree (nX); 567 psFree (dX); 568 psFree (vX); 569 570 psFree (nY); 571 psFree (dY); 572 psFree (vY); 573 # endif 574 575 psFree (xBright); 576 psFree (yBright); 577 psFree (xFaint); 578 psFree (yFaint); 579 580 // pause and wait for user input: 581 // continue, save (provide name), ?? 582 char key[10]; 583 fprintf (stdout, "[c]ontinue? "); 584 if (!fgets(key, 8, stdin)) { 585 psWarning("Unable to read option"); 586 } 587 return true; 588 } 589 590 // assumes 'kapa' value is checked and set 591 bool psphotVisualShowRoughClass_Single (pmConfig *config, const pmFPAview *view, psArray *sources, pmSourceType type, pmSourceMode mode, char *color) { 592 593 int Noverlay; 594 KiiOverlay *overlay; 62 595 63 // display the weight 64 image.data2d = readout->weight->data.F32; 65 image.Nx = readout->weight->numCols; 66 image.Ny = readout->weight->numRows; 67 68 strcpy (data.name, "mask"); 69 strcpy (data.file, "maak"); 70 data.zero = 0.0; 71 data.range = 1000.0; 72 data.logflux = 0; 73 74 KiiSetChannel (kapa, 0); 75 KiiNewPicture2D (kapa, &image, &data, &coords); 76 } 77 596 psEllipseMoments emoments; 597 psEllipseAxes axes; 598 599 // note: this uses the Ohana allocation tools: 600 ALLOCATE (overlay, KiiOverlay, sources->n); 601 602 Noverlay = 0; 603 for (int i = 0; i < sources->n; i++) { 604 605 pmSource *source = sources->data[i]; 606 if (source == NULL) continue; 607 608 if (source->type != type) continue; 609 if (mode && !(source->mode & mode)) continue; 610 611 pmMoments *moments = source->moments; 612 if (moments == NULL) continue; 613 614 overlay[Noverlay].type = KII_OVERLAY_CIRCLE; 615 overlay[Noverlay].x = moments->x; 616 overlay[Noverlay].y = moments->y; 617 618 emoments.x2 = moments->Sx; 619 emoments.y2 = moments->Sy; 620 emoments.xy = moments->Sxy; 621 622 axes = psEllipseMomentsToAxes (emoments, 20.0); 623 624 overlay[Noverlay].dx = 2.0*axes.major; 625 overlay[Noverlay].dy = 2.0*axes.minor; 626 overlay[Noverlay].angle = axes.theta * PS_DEG_RAD; 627 overlay[Noverlay].text = NULL; 628 Noverlay ++; 629 } 630 631 KiiLoadOverlay (kapa, overlay, Noverlay, color); 632 FREE (overlay); 633 634 return true; 635 } 636 637 bool psphotVisualShowRoughClass (pmConfig *config, const pmFPAview *view, psArray *sources) { 638 639 psphotVisualPlotMoments (config, view, sources); 640 641 if (!isVisual) return true; 642 643 if (kapa == -1) { 644 fprintf (stderr, "kapa not opened, skipping\n"); 645 return false; 646 } 647 648 KiiEraseOverlay (kapa, "yellow"); // moments 649 650 psphotVisualShowRoughClass_Single (config, view, sources, PM_SOURCE_TYPE_STAR, 0, "red"); 651 psphotVisualShowRoughClass_Single (config, view, sources, PM_SOURCE_TYPE_EXTENDED, 0, "blue"); 652 psphotVisualShowRoughClass_Single (config, view, sources, PM_SOURCE_TYPE_DEFECT, 0, "blue"); 653 psphotVisualShowRoughClass_Single (config, view, sources, PM_SOURCE_TYPE_SATURATED, 0, "red"); 654 psphotVisualShowRoughClass_Single (config, view, sources, PM_SOURCE_TYPE_STAR, PM_SOURCE_MODE_PSFSTAR, "yellow"); 655 psphotVisualShowRoughClass_Single (config, view, sources, PM_SOURCE_TYPE_STAR, PM_SOURCE_MODE_SATSTAR, "green"); 656 657 // pause and wait for user input: 658 // continue, save (provide name), ?? 659 char key[10]; 660 fprintf (stdout, "red: STAR or SAT AREA; blue: EXTENDED or DEFECT; green: SATSTAR; yellow: PSFSTAR\n"); 661 fprintf (stdout, "[c]ontinue? "); 662 if (!fgets(key, 8, stdin)) { 663 psWarning("Unable to read option"); 664 } 665 return true; 666 } 667 668 bool psphotVisualShowPSFStars (pmConfig *config, const pmFPAview *view, pmPSF *psf, psArray *sources) { 669 670 bool status; 671 672 if (!isVisual) return true; 673 674 if (kapa2 == -1) { 675 kapa2 = KapaOpenNamedSocket ("kapa", "psphot:psfstars"); 676 if (kapa2 == -1) { 677 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 678 isVisual = false; 679 return false; 680 } 681 } 682 683 // select the current recipe 684 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE); 685 if (!recipe) { 686 psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE); 687 return false; 688 } 689 690 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 691 psMaskType maskVal = psMetadataLookupU8(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 692 assert (maskVal); 693 694 // the source images are written to an image 10x the size of a PSF object 695 // float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 696 // PS_ASSERT (status, false); 697 698 int DX = 21; 699 int DY = 21; 700 701 // examine PSF sources in S/N order (brightest first) 702 sources = psArraySort (sources, pmSourceSortBySN); 703 704 // counters to track the size of the image and area used in a row 705 int dX = 0; // starting corner of next box 706 int dY = 0; // height of row so far 707 int NX = 20*DX; // full width of output image 708 int NY = 0; // total height of output image 709 710 // first, examine the PSF stars: 711 // - determine bounding boxes for summary image 712 for (int i = 0; i < sources->n; i++) { 713 714 pmSource *source = sources->data[i]; 715 716 bool keep = false; 717 keep |= (source->mode & PM_SOURCE_MODE_PSFSTAR); 718 if (!keep) continue; 719 720 // how does this subimage get placed into the output image? 721 // DX = source->pixels->numCols 722 // DY = source->pixels->numRows 723 724 if (dX + DX > NX) { 725 // too wide for the rest of this row 726 if (dX == 0) { 727 // alone on this row 728 NY += DY; 729 dX = 0; 730 dY = 0; 731 } else { 732 // start the next row 733 NY += dY; 734 dX = DX; 735 dY = DY; 736 } 737 } else { 738 // extend this row 739 dX += DX; 740 dY = PS_MAX (dY, DY); 741 } 742 } 743 NY += DY; 744 745 // allocate output image 746 psImage *outpos = psImageAlloc (NX, NY, PS_TYPE_F32); 747 psImage *outsub = psImageAlloc (NX, NY, PS_TYPE_F32); 748 749 int Xo = 0; // starting corner of next box 750 int Yo = 0; // starting corner of next box 751 dY = 0; // height of row so far 752 753 int nPSF = 0; 754 755 // next, examine the PSF stars: 756 // - create output image array 757 for (int i = 0; i < sources->n; i++) { 758 759 pmSource *source = sources->data[i]; 760 761 bool keep = false; 762 if (source->mode & PM_SOURCE_MODE_PSFSTAR) { 763 nPSF ++; 764 keep = true; 765 } 766 if (!keep) continue; 767 768 if (Xo + DX > NX) { 769 // too wide for the rest of this row 770 if (Xo == 0) { 771 // place source alone on this row 772 psphotAddWithTest (source, true, maskVal); // replace source if subtracted 773 psphotMosaicSubimage (outpos, source, Xo, Yo, DX, DY, true); 774 775 psphotSubWithTest (source, false, maskVal); // remove source (force) 776 psphotMosaicSubimage (outsub, source, Xo, Yo, DX, DY, true); 777 psphotSetState (source, false, maskVal); // reset source Add/Sub state to recorded 778 779 Yo += DY; 780 Xo = 0; 781 dY = 0; 782 } else { 783 // start the next row 784 Yo += dY; 785 Xo = 0; 786 787 psphotAddWithTest (source, true, maskVal); // replace source if subtracted 788 psphotMosaicSubimage (outpos, source, Xo, Yo, DX, DY, true); 789 790 psphotSubWithTest (source, false, maskVal); // remove source (force) 791 psphotMosaicSubimage (outsub, source, Xo, Yo, DX, DY, true); 792 psphotSetState (source, false, maskVal); // replace source (has been subtracted) 793 794 Xo = DX; 795 dY = DY; 796 } 797 } else { 798 // extend this row 799 psphotAddWithTest (source, true, maskVal); // replace source if subtracted 800 psphotMosaicSubimage (outpos, source, Xo, Yo, DX, DY, true); 801 802 psphotSubWithTest (source, false, maskVal); // remove source (force) 803 psphotMosaicSubimage (outsub, source, Xo, Yo, DX, DY, true); 804 psphotSetState (source, false, maskVal); // replace source (has been subtracted) 805 806 Xo += DX; 807 dY = PS_MAX (dY, DY); 808 } 809 } 810 811 psphotVisualScaleImage (kapa2, outpos, "psfpos", 0); 812 psphotVisualScaleImage (kapa2, outsub, "psfsub", 1); 813 814 // pause and wait for user input: 815 // continue, save (provide name), ?? 816 char key[10]; 817 fprintf (stdout, "[c]ontinue? "); 818 if (!fgets(key, 8, stdin)) { 819 psWarning("Unable to read option"); 820 } 821 822 psFree (outpos); 823 psFree (outsub); 824 return true; 825 } 826 827 bool psphotVisualShowSatStars (pmConfig *config, const pmFPAview *view, pmPSF *psf, psArray *sources) { 828 829 bool status; 830 831 if (!isVisual) return true; 832 833 if (kapa2 == -1) { 834 kapa2 = KapaOpenNamedSocket ("kapa", "psphot:images"); 835 if (kapa2 == -1) { 836 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 837 isVisual = false; 838 return false; 839 } 840 } 841 842 // select the current recipe 843 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE); 844 if (!recipe) { 845 psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE); 846 return false; 847 } 848 849 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 850 psMaskType maskVal = psMetadataLookupU8(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 851 assert (maskVal); 852 853 // the source images are written to an image 10x the size of a PSF object 854 // float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 855 // PS_ASSERT (status, false); 856 857 int DX = 41; 858 int DY = 41; 859 860 // examine PSF sources in S/N order (brightest first) 861 sources = psArraySort (sources, pmSourceSortBySN); 862 863 // counters to track the size of the image and area used in a row 864 int dX = 0; // starting corner of next box 865 int dY = 0; // height of row so far 866 int NX = 10*DX; // full width of output image 867 int NY = 0; // total height of output image 868 869 // first, examine the PSF and SAT stars: 870 // - determine bounding boxes for summary image 871 for (int i = 0; i < sources->n; i++) { 872 873 pmSource *source = sources->data[i]; 874 875 bool keep = false; 876 keep |= (source->mode & PM_SOURCE_MODE_SATSTAR); 877 if (!keep) continue; 878 879 // how does this subimage get placed into the output image? 880 // DX = source->pixels->numCols 881 // DY = source->pixels->numRows 882 883 if (dX + DX > NX) { 884 // too wide for the rest of this row 885 if (dX == 0) { 886 // alone on this row 887 NY += DY; 888 dX = 0; 889 dY = 0; 890 } else { 891 // start the next row 892 NY += dY; 893 dX = DX; 894 dY = DY; 895 } 896 } else { 897 // extend this row 898 dX += DX; 899 dY = PS_MAX (dY, DY); 900 } 901 } 902 NY += DY; 903 904 // allocate output image 905 psImage *outsat = psImageAlloc (NX, NY, PS_TYPE_F32); 906 907 int Xo = 0; // starting corner of next box 908 int Yo = 0; // starting corner of next box 909 dY = 0; // height of row so far 910 911 int nSAT = 0; 912 913 // next, examine the SAT stars: 914 // - create output image array 915 for (int i = 0; i < sources->n; i++) { 916 917 pmSource *source = sources->data[i]; 918 919 bool keep = false; 920 if (source->mode & PM_SOURCE_MODE_SATSTAR) { 921 nSAT ++; 922 keep = true; 923 } 924 if (!keep) continue; 925 926 if (Xo + DX > NX) { 927 // too wide for the rest of this row 928 if (Xo == 0) { 929 // place source alone on this row 930 psphotAddWithTest (source, true, maskVal); // replace source if subtracted 931 psphotMosaicSubimage (outsat, source, Xo, Yo, DX, DY, false); 932 psphotSetState (source, true, maskVal); // reset source Add/Sub state to recorded 933 934 Yo += DY; 935 Xo = 0; 936 dY = 0; 937 } else { 938 // start the next row 939 Yo += dY; 940 Xo = 0; 941 psphotAddWithTest (source, true, maskVal); // replace source if subtracted 942 psphotMosaicSubimage (outsat, source, Xo, Yo, DX, DY, false); 943 psphotSetState (source, true, maskVal); // replace source (has been subtracted) 944 945 Xo = DX; 946 dY = DY; 947 } 948 } else { 949 // extend this row 950 psphotAddWithTest (source, true, maskVal); // replace source if subtracted 951 psphotMosaicSubimage (outsat, source, Xo, Yo, DX, DY, false); 952 psphotSetState (source, true, maskVal); // replace source (has been subtracted) 953 954 Xo += DX; 955 dY = PS_MAX (dY, DY); 956 } 957 } 958 959 psphotVisualScaleImage (kapa2, outsat, "satstar", 2); 960 961 // pause and wait for user input: 962 // continue, save (provide name), ?? 963 char key[10]; 964 fprintf (stdout, "[c]ontinue? "); 965 if (!fgets(key, 8, stdin)) { 966 psWarning("Unable to read option"); 967 } 968 969 psFree (outsat); 970 return true; 971 } 972 973 bool psphotVisualShowPSFModel (pmConfig *config, pmReadout *readout, pmPSF *psf) { 974 975 if (!isVisual) return true; 976 977 if (kapa2 == -1) { 978 kapa2 = KapaOpenNamedSocket ("kapa", "psphot:psfstars"); 979 if (kapa2 == -1) { 980 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 981 isVisual = false; 982 return false; 983 } 984 } 985 986 int DX = 64; 987 int DY = 64; 988 989 psImage *psfMosaic = psImageAlloc (3*DX, 3*DY, PS_TYPE_F32); 990 psImageInit (psfMosaic, 0.0); 991 992 pmModel *modelRef = pmModelAlloc(psf->type); 993 994 # if (1) 995 // generate a fake model at each of the 3x3 image grid positions 996 for (int x = -1; x <= +1; x ++) { 997 for (int y = -1; y <= +1; y ++) { 998 // use the center of the center pixel of the image 999 float xc = (0.5 + 0.45*x)*readout->image->numCols + readout->image->col0; 1000 float yc = (0.5 + 0.45*y)*readout->image->numRows + readout->image->row0; 1001 1002 // assign the x and y coords to the image center 1003 // create an object with center intensity of 1000 1004 modelRef->params->data.F32[PM_PAR_SKY] = 0; 1005 modelRef->params->data.F32[PM_PAR_I0] = 1000; 1006 modelRef->params->data.F32[PM_PAR_XPOS] = xc; 1007 modelRef->params->data.F32[PM_PAR_YPOS] = yc; 1008 1009 // create modelPSF from this model 1010 pmModel *model = pmModelFromPSF (modelRef, psf); 1011 1012 // place the reference object in the image center 1013 // no need to mask the source here 1014 // XXX should we measure this for the analytical model only or the full model? 1015 pmModelAddWithOffset (psfMosaic, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_CENTER, 0, -x*DX, -y*DY); 1016 } 1017 } 1018 # else 1019 { 1020 // use the center of the center pixel of the image 1021 float xc = 0.5*readout->image->numCols + readout->image->col0 + 0.5; 1022 float yc = 0.5*readout->image->numRows + readout->image->row0 + 0.5; 1023 1024 // assign the x and y coords to the image center 1025 // create an object with center intensity of 1000 1026 modelRef->params->data.F32[PM_PAR_SKY] = 0; 1027 modelRef->params->data.F32[PM_PAR_I0] = 1000; 1028 modelRef->params->data.F32[PM_PAR_XPOS] = xc; 1029 modelRef->params->data.F32[PM_PAR_YPOS] = yc; 1030 1031 // create modelPSF from this model 1032 pmModel *model = pmModelFromPSF (modelRef, psf); 1033 1034 // place the reference object in the image center 1035 // no need to mask the source here 1036 // XXX should we measure this for the analytical model only or the full model? 1037 pmModelAddWithOffset (psfMosaic, NULL, model, PM_MODEL_OP_FULL | PM_MODEL_OP_CENTER, 0, 32.0, 16.0); 1038 } 1039 # endif 1040 1041 psImage *psfLogFlux = (psImage *) psUnaryOp (NULL, psfMosaic, "log"); 1042 psphotVisualRangeImage (kapa2, psfLogFlux, "psf_mosaic", 1, -2.0, 3.0); 1043 1044 // pause and wait for user input: 1045 // continue, save (provide name), ?? 1046 char key[10]; 1047 fprintf (stdout, "[c]ontinue? "); 1048 if (!fgets(key, 8, stdin)) { 1049 psWarning("Unable to read option"); 1050 } 1051 return true; 1052 } 1053 1054 bool psphotVisualShowLinearFit (pmConfig *config, pmReadout *readout) { 1055 1056 if (!isVisual) return true; 1057 1058 if (kapa == -1) { 1059 kapa = KapaOpenNamedSocket ("kapa", "psphot:images"); 1060 if (kapa == -1) { 1061 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 1062 isVisual = false; 1063 return false; 1064 } 1065 } 1066 1067 psphotVisualScaleImage (kapa, readout->image, "lin_resid", 1); 1068 1069 // pause and wait for user input: 1070 // continue, save (provide name), ?? 1071 char key[10]; 1072 fprintf (stdout, "[c]ontinue? "); 1073 if (!fgets(key, 8, stdin)) { 1074 psWarning("Unable to read option"); 1075 } 1076 return true; 1077 } 1078 1079 # else 1080 1081 bool psphotSetVisual (bool mode){} 1082 bool psphotVisualShowImage (pmConfig *config, pmReadout *readout){} 1083 bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout){} 1084 bool psphotVisualShowSignificance (psImage *image){} 1085 bool psphotVisualShowPeaks (pmConfig *config, const pmFPAview *view, pmDetections *detections){} 1086 bool psphotVisualShowFootprints (pmConfig *config, const pmFPAview *view, pmDetections *detections){} 1087 bool psphotVisualShowMoments (pmConfig *config, const pmFPAview *view, psArray *sources){} 1088 bool psphotVisualShowRoughClass (pmConfig *config, const pmFPAview *view, psArray *sources){} 1089 bool psphotVisualShowPSF (pmConfig *config, const pmFPAview *view, pmPSF *psf, psArray *sources){} 1090 bool psphotVisualShowLinearFit (pmConfig *config, pmReadout *readout){} 1091 1092 # endif
Note:
See TracChangeset
for help on using the changeset viewer.
