Changeset 20335
- Timestamp:
- Oct 22, 2008, 1:35:13 PM (18 years ago)
- Location:
- branches/cnb_branch_20081011
- Files:
-
- 9 edited
-
ippconfig/recipes/psastro.config (modified) (1 diff)
-
psModules/src/astrom/Makefile.am (modified) (2 diffs)
-
psModules/src/astrom/pmAstrometryObjects.c (modified) (10 diffs)
-
psModules/src/astrom/pmAstrometryObjects.h (modified) (3 diffs)
-
psModules/src/psmodules.h (modified) (1 diff)
-
psastro/src/psastro.h (modified) (2 diffs)
-
psastro/src/psastroMosaicOneChip.c (modified) (10 diffs)
-
psastro/src/psastroMosaicSetMatch.c (modified) (2 diffs)
-
psastro/src/psastroVisual.c (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/cnb_branch_20081011/ippconfig/recipes/psastro.config
r19499 r20335 75 75 PSASTRO.MAX.INST.MAG.RAW F32 0.0 # max instrumental magnitude for stars accepted for fitting 76 76 77 PSASTRO.MATCH.LUMFUNC BOOL FALSE77 PSASTRO.MATCH.LUMFUNC BOOL TRUE 78 78 79 79 # option may be MAX, MIN, or VALUE. for VALUE, look up -
branches/cnb_branch_20081011/psModules/src/astrom/Makefile.am
r17036 r20335 10 10 pmAstrometryModel.c \ 11 11 pmAstrometryRefstars.c \ 12 pmAstrometryWCS.c 12 pmAstrometryWCS.c \ 13 pmAstrometryVisual.c 13 14 14 15 pkginclude_HEADERS = \ … … 19 20 pmAstrometryModel.h \ 20 21 pmAstrometryRefstars.h \ 21 pmAstrometryWCS.h 22 pmAstrometryWCS.h \ 23 pmAstrometryVisual.h 22 24 23 25 CLEANFILES = *~ -
branches/cnb_branch_20081011/psModules/src/astrom/pmAstrometryObjects.c
r20039 r20335 8 8 * @author EAM, IfA 9 9 * 10 * @version $Revision: 1.41 $ $Name: not supported by cvs2svn $11 * @date $Date: 2008-10- 10 02:33:35$10 * @version $Revision: 1.41.4.1 $ $Name: not supported by cvs2svn $ 11 * @date $Date: 2008-10-22 23:35:13 $ 12 12 * 13 13 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 29 29 #include <unistd.h> // for unlink 30 30 #include <pslib.h> 31 #include <kapa.h> // cnb: do I need an IFDEF?32 31 33 32 #include "pmHDU.h" … … 35 34 #include "pmAstrometryObjects.h" 36 35 #include "pmKapaPlots.h" 36 #include "pmAstrometryVisual.h" 37 37 38 38 #define PM_ASTROMETRYOBJECTS_DEBUG 1 … … 564 564 psF32 **D2 = gridD2->data.F32; 565 565 566 #ifdef PLOTS567 // vectors to hold dX and dY568 int nplot = raw->n * ref->n;569 float dXplot[nplot];570 float dYplot[nplot];571 #endif572 566 573 567 // accumulate grids for focal plane (L,M) matches … … 579 573 dY = ob1->FP->y - ob2->FP->y; 580 574 581 #ifdef PLOTS582 dXplot[(i * ref->n) + j] = dX;583 dYplot[(i * ref->n) + j] = dY;584 // fprintf (f, "dX,dY: %8.2f %8.2f : %8.2f %8.2f : %8.2f %8.2f\n", dX, dY, ob1->FP->x, ob2->FP->x, ob1->FP->y, ob2->FP->y);585 #endif586 575 // find bin coordinates for this delta-delta 587 576 if (!AstromGridBin (&iX, &iY, dX, dY)) { … … 618 607 } 619 608 620 # if 0609 # if 0 621 610 char line[16]; 622 611 psFits *fits = psFitsOpen ("grid.image.fits", "w"); … … 625 614 fprintf (stderr, "wrote grid image, press return to continue\n"); 626 615 fgets (line, 15, stdin); 627 # endif616 # endif 628 617 629 618 // only check bins with at least 1/2 of max bin … … 670 659 } 671 660 661 pmAstromVisualPlotGridMatch (raw, ref,gridNP, stats->offset.x, stats->offset.y, 662 maxOffpix, Scale, Offset); 663 672 664 psFree (imStats); 673 665 // XXX EAM : This routine, and pmAstromGridMatch, need to handle failure cases better … … 689 681 // fprintf (stderr, "sigma: nMatch: %d, nTest: %d, nTen: %d\n", stats->nMatch, stats->nTest, sort->data.U32[sort->n - 10]); 690 682 691 #ifdef PLOTS692 /*** plot DXs and DYs ***/693 KapaSection section = {"s1", 0.00, 0.00, 1.0, 1.0};694 //KapaSection left = {"s2", 0.05, 0.05, 0.35, 0.8};695 //KapaSection right = {"s3", 0.55, 0.05, 0.35, 0.8};696 //KapaSection yprof = {"s4", 0.45, 0.05, 0.10, 0.9};697 //KapaSection xprof = {"s5", .05, .90, .35, .1};698 699 Graphdata graphdata;700 int kapa = pmKapaOpen(true);701 KapaClearPlots(kapa);702 KapaInitGraph(&graphdata);703 KapaSetSection(kapa, §ion);704 graphdata.xmin = stats->offset.x - 1.5 * maxOffpix;705 graphdata.xmax = stats->offset.x + 1.5 * maxOffpix;706 graphdata.ymin = stats->offset.y - 1.5 * maxOffpix;707 graphdata.ymax = stats->offset.y + 1.5 * maxOffpix;708 709 KapaSetLimits(kapa, &graphdata);710 KapaSetFont(kapa, "helvetica", 14);711 KapaBox(kapa, &graphdata);712 KapaSendLabel (kapa, "X offset", KAPA_LABEL_XM);713 KapaSendLabel (kapa, "Y offset", KAPA_LABEL_YM);714 KapaSendLabel (kapa, "pmAstromGridAngle residuals. Big Box: Serach Region. Small Box: Correlation Peak.",715 KAPA_LABEL_XP);716 graphdata.style = 2;717 graphdata.ptype = 0;718 graphdata.size = 0.4;719 graphdata.color = KapaColorByName ("black");720 KapaPrepPlot(kapa, nplot, &graphdata);721 KapaPlotVector (kapa, nplot, dXplot, "x");722 KapaPlotVector (kapa, nplot, dYplot, "y");723 724 //Overplot bounding box, peak of distribution725 float xbound[5] = { -maxOffpix, maxOffpix, maxOffpix, -maxOffpix, -maxOffpix};726 float ybound[5] = { -maxOffpix, -maxOffpix, maxOffpix, maxOffpix, -maxOffpix};727 float xbin[5] = {stats->offset.x - 0.5 * Scale, stats->offset.x + 0.5 * Scale, stats->offset.x + 0.5 * Scale,728 stats->offset.x - 0.5 * Scale, stats->offset.x - 0.5 * Scale};729 float ybin[5] = {stats->offset.y - 0.5 * Scale, stats->offset.y - 0.5 * Scale, stats->offset.y + 0.5 * Scale,730 stats->offset.y + 0.5 * Scale, stats->offset.y - 0.5 * Scale};731 graphdata.color = KapaColorByName("red");732 graphdata.style = 0;733 graphdata.size = 1.0;734 KapaPrepPlot(kapa, 5, &graphdata);735 KapaPlotVector (kapa, 5, xbound, "x");736 KapaPlotVector (kapa, 5, ybound, "y");737 KapaPrepPlot(kapa, 5, &graphdata);738 KapaPlotVector (kapa, 5, xbin, "x");739 KapaPlotVector (kapa, 5, ybin, "y");740 741 KapaPNG(kapa, "dXdY.png");742 char c;743 fscanf(stdin, "%c", &c);744 /*** end ***/745 #endif746 683 747 684 psFree (sort); … … 767 704 PS_ASSERT_PTR_NON_NULL(ref, NULL); 768 705 PS_ASSERT_PTR_NON_NULL(config, NULL); 769 770 706 bool status; 771 707 double xMin, xMax, yMin, yMax; -
branches/cnb_branch_20081011/psModules/src/astrom/pmAstrometryObjects.h
r15665 r20335 4 4 * @author EAM, IfA 5 5 * 6 * @version $Revision: 1.17 $ $Name: not supported by cvs2svn $7 * @date $Date: 200 7-11-21 07:02:55$6 * @version $Revision: 1.17.42.1 $ $Name: not supported by cvs2svn $ 7 * @date $Date: 2008-10-22 23:35:13 $ 8 8 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii 9 9 */ … … 238 238 * 239 239 */ 240 bool pmAstromFitFPA( 241 pmFPA *fpa, 242 psArray *st1, 243 psArray *st2, 244 psArray *match, 245 psMetadata *config 246 ); 240 bool pmAstromFitFPA(pmFPA *fpa, 241 psArray *st1, 242 psArray *st2, 243 psArray *match, 244 psMetadata *config); 247 245 248 246 … … 269 267 psArray *st2, 270 268 psArray *match, 271 psMetadata *config 272 ); 269 psMetadata *config); 273 270 274 271 -
branches/cnb_branch_20081011/psModules/src/psmodules.h
r20067 r20335 81 81 #include <pmAstrometryRefstars.h> 82 82 #include <pmAstrometryDistortion.h> 83 #include <pmAstrometryVisual.h> 83 84 84 85 // the following headers are from psModule:imcombine -
branches/cnb_branch_20081011/psastro/src/psastro.h
r20263 r20335 51 51 psArray *psastroRemoveClumps (psArray *input, int scale); 52 52 53 53 54 // utility functions: 54 55 bool psastroUpdateChipToFPA (pmFPA *fpa, pmChip *chip, psArray *rawstars, psArray *refstars); … … 84 85 bool psastroVisualPlotOneChipFit (psArray *rawstars, psArray *refstars, psArray *match, psMetadata *recipe); 85 86 bool psastroVisualPlotAstromGuessCheck (psVector *cornerPo, psVector *cornerQo, psVector *cornerPn, psVector *cornerQn, psVector *cornerPd, psVector *cornerQd); 87 bool psastroVisualPlotMosaicOneChip (psArray *rawstars, psArray *refstars, psArray *match, psMetadata *recipe); 88 bool psastroVisualPlotMosaicMatches (psArray *rawstars, psArray *refstars, psArray *match, int iteration, psMetadata *recipe); 86 89 87 90 // demo plots -
branches/cnb_branch_20081011/psastro/src/psastroMosaicOneChip.c
r20067 r20335 5 5 if (!status) { \ 6 6 psError(PSASTRO_ERR_CONFIG, false, MESSAGE); \ 7 return false; } 7 return false; } 8 8 9 9 bool psastroMosaicOneChip (pmChip *chip, pmReadout *readout, psMetadata *recipe, psMetadata *updates, int iteration) { … … 29 29 30 30 // correct radius to FP units (physical pixel scale in microns per pixel) 31 REQUIRED_RECIPE_VALUE (double pixelScale, "PSASTRO.PIXEL.SCALE", F32, "Failed to lookup pixel scale"); 31 REQUIRED_RECIPE_VALUE (double pixelScale, "PSASTRO.PIXEL.SCALE", F32, "Failed to lookup pixel scale"); 32 32 33 33 // allowed limits for valid solutions … … 42 42 int order = psMetadataLookupS32 (&status, recipe, orderWord); 43 43 if (!status || (order == -1)) { 44 order = defaultOrder;44 order = defaultOrder; 45 45 } 46 46 … … 50 50 if ((match->n < 8) && (order >= 1)) order = 0; 51 51 if ((match->n < 3) || (order < 0) || (order > 3)) { 52 psLogMsg ("psastro", 3, "insufficient stars (%ld) or invalid order (%d)", match->n, order); 53 return false; 54 } 52 psLogMsg ("psastro", 3, "insufficient stars (%ld) or invalid order (%d)", match->n, order); 53 return false; 54 } 55 55 56 56 psLogMsg ("psastro", PS_LOG_DETAIL, "mosaic fit chip order %d", order); … … 60 60 // coefficients frozen to the current values 61 61 if (order == 0) { 62 // set FIT mask for all higher order terms of the existing solution63 // any existing SET masks will be retained.64 for (int i = 0; i <= chip->toFPA->x->nX; i++) {65 for (int j = 0; j <= chip->toFPA->x->nY; j++) {66 if (i + j > 0) {67 chip->toFPA->x->coeffMask[i][j] |= PS_POLY_MASK_FIT;68 chip->toFPA->y->coeffMask[i][j] |= PS_POLY_MASK_FIT;69 }70 }71 }62 // set FIT mask for all higher order terms of the existing solution 63 // any existing SET masks will be retained. 64 for (int i = 0; i <= chip->toFPA->x->nX; i++) { 65 for (int j = 0; j <= chip->toFPA->x->nY; j++) { 66 if (i + j > 0) { 67 chip->toFPA->x->coeffMask[i][j] |= PS_POLY_MASK_FIT; 68 chip->toFPA->y->coeffMask[i][j] |= PS_POLY_MASK_FIT; 69 } 70 } 71 } 72 72 } else { 73 psFree (chip->toFPA);74 chip->toFPA = psPlaneTransformAlloc (order, order);75 for (int i = 0; i <= chip->toFPA->x->nX; i++) {76 for (int j = 0; j <= chip->toFPA->x->nY; j++) {77 if (i + j > order) {78 chip->toFPA->x->coeffMask[i][j] = PS_POLY_MASK_SET;79 chip->toFPA->y->coeffMask[i][j] = PS_POLY_MASK_SET;80 }81 }82 }73 psFree (chip->toFPA); 74 chip->toFPA = psPlaneTransformAlloc (order, order); 75 for (int i = 0; i <= chip->toFPA->x->nX; i++) { 76 for (int j = 0; j <= chip->toFPA->x->nY; j++) { 77 if (i + j > order) { 78 chip->toFPA->x->coeffMask[i][j] = PS_POLY_MASK_SET; 79 chip->toFPA->y->coeffMask[i][j] = PS_POLY_MASK_SET; 80 } 81 } 82 } 83 83 } 84 84 … … 87 87 psStats *fitStats = NULL; 88 88 // if (order == 0) { 89 // fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);90 // fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NSIGMA");91 // fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NITER");89 // fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV); 90 // fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NSIGMA"); 91 // fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NITER"); 92 92 // } else { 93 fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);94 fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NSIGMA");95 fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NITER");93 fitStats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV); 94 fitStats->clipSigma = psMetadataLookupF32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NSIGMA"); 95 fitStats->clipIter = psMetadataLookupS32 (&status, recipe, "PSASTRO.MOSAIC.CHIP.NITER"); 96 96 // } 97 97 … … 99 99 pmAstromFitResults *results = pmAstromMatchFit (chip->toFPA, rawstars, refstars, match, fitStats); 100 100 if (!results) { 101 psError(PSASTRO_ERR_DATA, false, "failed to perform the matched fit\n");102 return false;101 psError(PSASTRO_ERR_DATA, false, "failed to perform the matched fit\n"); 102 return false; 103 103 } 104 104 … … 124 124 psLogMsg ("psastro", PS_LOG_INFO, "astrometry solution: error: %f arcsec, Nstars: %d", astError, astNstar); 125 125 if ((maxError > 0) && (astError > maxError)) { 126 psLogMsg("psastro", PS_LOG_INFO, "residual error is too large, failed to find a solution: %f > %f", astError, maxError);127 validSolution = false;126 psLogMsg("psastro", PS_LOG_INFO, "residual error is too large, failed to find a solution: %f > %f", astError, maxError); 127 validSolution = false; 128 128 } 129 129 if (astNstar < minNstar) { 130 psLogMsg("psastro", PS_LOG_INFO, "solution uses too few stars: %d < %d", astNstar, minNstar);131 validSolution = false;130 psLogMsg("psastro", PS_LOG_INFO, "solution uses too few stars: %d < %d", astNstar, minNstar); 131 validSolution = false; 132 132 } 133 133 … … 136 136 psMetadataAddF32 (updates, PS_LIST_TAIL, "CERROR", PS_META_REPLACE, "astrometry error (arcsec)", astError); 137 137 if (validSolution) { 138 psMetadataAddF32 (updates, PS_LIST_TAIL, "CPRECISE", PS_META_REPLACE, "astrometry precision (arcsec)", astError/sqrt(astNstar));139 psMetadataAddS32 (updates, PS_LIST_TAIL, "NASTRO", PS_META_REPLACE, "number of astrometry stars", astNstar);138 psMetadataAddF32 (updates, PS_LIST_TAIL, "CPRECISE", PS_META_REPLACE, "astrometry precision (arcsec)", astError/sqrt(astNstar)); 139 psMetadataAddS32 (updates, PS_LIST_TAIL, "NASTRO", PS_META_REPLACE, "number of astrometry stars", astNstar); 140 140 } else { 141 psMetadataAddF32 (updates, PS_LIST_TAIL, "CPRECISE", PS_META_REPLACE, "astrometry precision (arcsec)", 0.0);142 psMetadataAddS32 (updates, PS_LIST_TAIL, "NASTRO", PS_META_REPLACE, "number of astrometry stars", 0);141 psMetadataAddF32 (updates, PS_LIST_TAIL, "CPRECISE", PS_META_REPLACE, "astrometry precision (arcsec)", 0.0); 142 psMetadataAddS32 (updates, PS_LIST_TAIL, "NASTRO", PS_META_REPLACE, "number of astrometry stars", 0); 143 143 } 144 144 psMetadataAddF32 (updates, PS_LIST_TAIL, "EQUINOX", PS_META_REPLACE, "", 2000.0); // XXX this is bogus: should be defined based on equinox of refstars … … 147 147 psastroUpdateChipToFPA (fpa, chip, rawstars, refstars); 148 148 149 //plot results 150 psastroVisualPlotMosaicOneChip(rawstars, refstars, match, recipe); 151 149 152 psFree (fitStats); 150 153 psFree (results); -
branches/cnb_branch_20081011/psastro/src/psastroMosaicSetMatch.c
r17108 r20335 10 10 11 11 // use small radius to match stars (assume starting astrometry is good) 12 bool status = false; 12 bool status = false; 13 13 sprintf (radiusWord, "PSASTRO.MOSAIC.RADIUS.N%d", iteration); 14 double RADIUS = psMetadataLookupF32 (&status, recipe, radiusWord); 15 if (!status) { 16 psError(PS_ERR_IO, false, "Failed to lookup matching radius: %s", radiusWord); 17 psFree (view);18 return false; 19 } 14 double RADIUS = psMetadataLookupF32 (&status, recipe, radiusWord); 15 if (!status) { 16 psError(PS_ERR_IO, false, "Failed to lookup matching radius: %s", radiusWord); 17 psFree (view); 18 return false; 19 } 20 20 21 21 if (RADIUS <= 0.0) { 22 if (iteration == 0) {23 psError(PS_ERR_IO, false, "Invalid match radius for first iteration: %s", radiusWord); 24 psFree (view);25 return false; 26 } 27 psWarning ("skipping match for iteration %d\n", iteration);28 psFree (view);29 return true;22 if (iteration == 0) { 23 psError(PS_ERR_IO, false, "Invalid match radius for first iteration: %s", radiusWord); 24 psFree (view); 25 return false; 26 } 27 psWarning ("skipping match for iteration %d\n", iteration); 28 psFree (view); 29 return true; 30 30 } 31 31 … … 34 34 psTrace ("psastro", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process); 35 35 if (!chip->process || !chip->file_exists) { continue; } 36 if (!chip->fromFPA) { continue; }37 38 while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) {36 if (!chip->fromFPA) { continue; } 37 38 while ((cell = pmFPAviewNextCell (view, fpa, 1)) != NULL) { 39 39 psTrace ("psastro", 4, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process); 40 40 if (!cell->process || !cell->file_exists) { continue; } 41 41 42 // process each of the readouts43 // XXX there can only be one readout per chip, right?44 while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) {45 if (! readout->data_exists) { continue; }42 // process each of the readouts 43 // XXX there can only be one readout per chip, right? 44 while ((readout = pmFPAviewNextReadout (view, fpa, 1)) != NULL) { 45 if (! readout->data_exists) { continue; } 46 46 47 // select the raw objects for this readout48 psArray *rawstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.RAWSTARS");49 if (rawstars == NULL) { continue; }47 // select the raw objects for this readout 48 psArray *rawstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.RAWSTARS"); 49 if (rawstars == NULL) { continue; } 50 50 51 // select the raw objects for this readout52 psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS");53 if (refstars == NULL) { continue; }54 psTrace ("psastro", 4, "Trying %ld refstars\n", refstars->n);51 // select the raw objects for this readout 52 psArray *refstars = psMetadataLookupPtr (NULL, readout->analysis, "PSASTRO.REFSTARS"); 53 if (refstars == NULL) { continue; } 54 psTrace ("psastro", 4, "Trying %ld refstars\n", refstars->n); 55 55 56 psArray *matches = pmAstromRadiusMatchChip (rawstars, refstars, RADIUS);57 psTrace ("psastro", 4, "Matched %ld refstars\n", matches->n);56 psArray *matches = pmAstromRadiusMatchChip (rawstars, refstars, RADIUS); 57 psTrace ("psastro", 4, "Matched %ld refstars\n", matches->n); 58 58 59 // XXX drop the old one 60 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSASTRO.MATCH", PS_DATA_ARRAY | PS_META_REPLACE, "astrometry matches", matches); 61 psFree (matches); 62 } 63 } 59 psastroVisualPlotMosaicMatches(rawstars, refstars, matches, iteration, recipe); 60 61 // XXX drop the old one 62 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSASTRO.MATCH", PS_DATA_ARRAY | PS_META_REPLACE, "astrometry matches", matches); 63 psFree (matches); 64 } 65 } 64 66 } 65 67 psFree (view); -
branches/cnb_branch_20081011/psastro/src/psastroVisual.c
r20264 r20335 1 /***Diagnostic plots for psastro***/ 2 1 /***********************************/ 2 /***Diagnostic plots for psastro****/ 3 /***********************************/ 3 4 # include "psastroInternal.h" 5 # include <string.h> 6 # include <stdlib.h> 7 # include <stdio.h> 4 8 5 9 # if (HAVE_KAPA) … … 11 15 //variables to determine when things are plotted 12 16 static bool isVisual = false; 13 static bool plotRawStars = false;14 static bool plotRefStars = false;15 static bool plotLumFunc = false;17 static bool plotRawStars = true; 18 static bool plotRefStars = true; 19 static bool plotLumFunc = true; 16 20 static bool plotRemoveClumps = true; 17 static bool plotOneChipFit = false; 18 static bool plotAstromGuessCheck = false; 21 static bool plotOneChipFit = true; 22 static bool plotAstromGuessCheck = true; 23 static bool plotMosaicMatches = true; 24 static bool plotMosaicOneChip = true; 19 25 20 26 // variables to store plotting window indices 21 static int kapa = -1; //for plots22 static int kapa2 = -1; //also for plots27 static int kapa = -1; 28 static int kapa2 = -1; 23 29 24 30 // helper routine prototypes … … 27 33 bool psastroVisualTripleOverplot (int kapa, Graphdata *graphdata, psVector *xVec, psVector *yVec, psVector *zVec, bool increasing); 28 34 bool psastroVisualCreateScaleVec (psVector *zVec, psVector *zScale, bool increasing); 29 30 35 bool psastroVisualResidPlot (psArray *rawstars, psArray *refstars, psArray *match, psMetadata *recipe, char *title); 36 37 38 /*****************************/ 31 39 /** Initialization Routines **/ 32 33 34 /** 35 * start or stop plotting 36 */ 40 /*****************************/ 41 42 /** start or stop plotting */ 37 43 bool psastroSetVisual (bool mode) { 38 44 isVisual = mode; … … 41 47 42 48 43 /** 44 * open, name, and resize a window if necessary 45 */ 49 /** open, name, and resize a window if necessary*/ 46 50 bool psastroVisualInitWindow( int *kapid, char *name ) { 47 51 if (*kapid == -1) { … … 58 62 59 63 60 /** 61 * ask the user how to proceed 62 */ 64 /** ask the user how to proceed*/ 63 65 bool psastroVisualAskUser( bool *plotflag ) { 64 66 char key[10]; … … 77 79 78 80 79 /** 80 * destroy windows at the end of a run 81 */ 81 /** destroy windows at the end of a run*/ 82 82 bool psastroVisualClose() { 83 83 if(kapa != -1) … … 88 88 } 89 89 90 91 /***********************/ 90 92 /** Plotting Routines **/ 91 92 /* psastroVisualPlotRawStars */ 93 // Show raw star astrometry as determined from first pass fit 94 // Invoked from within psastroAstromGuess 93 /***********************/ 94 95 96 /** psastroVisualPlotRawStars 97 * Plot raw stars as determined from first pass astrometry fit 98 * Called within psastroAstromGeuss 99 */ 95 100 bool psastroVisualPlotRawStars (psArray *rawstars, pmFPA *fpa, pmChip *chip, psMetadata *recipe) 96 101 { 97 102 // make sure we want to plot this 98 103 if (!plotRawStars || !isVisual) return true; 104 105 //set up plot region 99 106 if (!psastroVisualInitWindow (&kapa, "psastro:plots")) 100 107 return false; 101 102 108 Graphdata graphdata; 103 109 KapaSection section; 104 105 bool status = false;106 float iMagMin = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.INST.MAG.MIN");107 float iMagMax = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.INST.MAG.MAX");108 110 109 111 KapaInitGraph (&graphdata); … … 118 120 section.dy = 0.4; 119 121 122 //initialize and populate plotting vectors 123 bool status = false; 124 float iMagMin = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.INST.MAG.MIN"); 125 float iMagMax = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.INST.MAG.MAX"); 126 120 127 psVector *xVec = psVectorAlloc (rawstars->n, PS_TYPE_F32); 121 128 psVector *yVec = psVectorAlloc (rawstars->n, PS_TYPE_F32); … … 128 135 KapaSetSection (kapa, §ion); 129 136 psFree (section.name); 137 138 //Chip coordinates 130 139 int n = 0; 131 140 for (int i = 0; i < rawstars->n; i++) { … … 147 156 psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false); 148 157 158 //Focal Plane Coordinates 149 159 section.x = 0.5; 150 160 section.y = 0.5; … … 173 183 psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false); 174 184 185 // Tangent Plane Coordinates 175 186 section.x = 0.0; 176 187 section.y = 0.0; … … 199 210 psastroVisualTriplePlot (kapa, &graphdata, xVec, yVec, zVec, false); 200 211 212 //sky coordinates 201 213 section.x = 0.5; 202 214 section.y = 0.0; … … 250 262 251 263 252 /* psastroVisualPlotRefStars */ 253 // plot the location of references stars over the entire fpa 254 // invoked during psastroChooseRefStars 264 /** psastroVisualPlotRefStars 265 * plot the location of references stars over the entire fpa 266 * invoked during psastroChooseRefStars 267 */ 255 268 bool psastroVisualPlotRefStars (psArray *refstars, psMetadata *recipe) 256 269 { 270 //make sure we want to plot this 257 271 if (!isVisual || !plotRefStars) return true; 258 272 Graphdata graphdata; 273 274 //set up plotting variables 259 275 if (!psastroVisualInitWindow (&kapa, "psastro:plots")) 260 276 return false; 261 262 bool status = false;263 float rMagMin = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.REF.MAG.MIN");264 float rMagMax = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.REF.MAG.MAX");265 277 266 278 KapaInitGraph (&graphdata); … … 271 283 graphdata.size = 0.5; 272 284 graphdata.style = 2; 285 286 //initialize and populate plot vectors 287 bool status = false; 288 float rMagMin = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.REF.MAG.MIN"); 289 float rMagMax = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.REF.MAG.MAX"); 273 290 274 291 psVector *xVec = psVectorAlloc (refstars->n, PS_TYPE_F32); … … 309 326 310 327 311 /* psastroVisualPlotLuminosityFunction */312 // Plot the two luminosity functions created. 313 // Called from psastroRefStarSubset. 314 // The luminosity functions are used to select a subset of reference stars, 315 // so we plot the cutoff that defines this subset 328 /** psastroVisualPlotLuminosityFunction 329 * Plot the two luminosity functions created within psastroRefStarSubset 330 * The luminosity functions are used to select a subset of reference stars, 331 * so we plot the cutoff that defines this subset 332 */ 316 333 bool psastroVisualPlotLuminosityFunction (psVector *lnMag, psVector *Mag, 317 334 pmLumFunc *lumFunc, pmLumFunc *rawFunc) { 318 335 336 // make sure we want to plot this 319 337 if ( !isVisual || !plotLumFunc ) return true; 338 339 //set up plotting variables 320 340 if ( !psastroVisualInitWindow (&kapa, "psastro:plots")) 321 341 return false; 322 342 323 //Set up graph window324 343 Graphdata graphdata; 325 344 KapaSection section1 = {"s1", .1, .1, .85, .35}; … … 396 415 397 416 398 /** 417 /** psastroVisualPlotRemoveClumps 399 418 * Plot the stars in a region, and indicate which stars are part of 'clumps' 400 419 * These stars are flagged during astrometric fitting, since dense regions are 401 420 * harder to cross-match than sparse ones. Called during psastroRemoveClumps. 402 421 */ 403 404 422 bool psastroVisualPlotRemoveClumps (psArray *input, psImage *count, int scale, float limit) { 423 424 //make sure we want to plot this 405 425 if (!isVisual || !plotRemoveClumps) return true; 426 427 //set up plot variables 406 428 if ( !psastroVisualInitWindow (&kapa, "psastro:plots")) return false; 407 429 408 430 KapaSection section; 409 431 Graphdata graphdata; 410 411 //initialize graph information412 432 section.x = 0; 413 433 section.dx = .9; … … 419 439 KapaSetSection(kapa, §ion); 420 440 psFree(section.name); 441 421 442 graphdata.ptype = 7; 422 443 graphdata.size = 0.5; 423 444 graphdata.style = 2; 424 445 graphdata.color = KapaColorByName ("black"); 425 446 KapaClearPlots(kapa); 426 447 427 448 //set up plot vectors … … 486 507 } 487 508 } 509 510 //ask for user input and finish 488 511 psastroVisualAskUser (&plotRemoveClumps); 489 512 psFree (xVec); … … 494 517 495 518 496 /* psastroVisualPlotOneChipFit */ 497 // assess the goodness of fit for a signle chip by 498 // plotting the fit residuals 499 // invoked during psastroOneChipFit 519 /** psastroVisualPlotOneChipFit 520 * assess the goodness of fit for a signle chip by 521 * plotting the fit residuals 522 * invoked during psastroOneChipFit 523 */ 500 524 bool psastroVisualPlotOneChipFit (psArray *rawstars, psArray *refstars, psArray *match, psMetadata *recipe) { 525 526 //make sure we want to plot this 501 527 if (!isVisual || !plotOneChipFit) 502 528 return true; 503 529 504 if (!psastroVisualInitWindow (&kapa, "psastro:plots")) 530 //plot the residuals 531 if (!psastroVisualResidPlot(rawstars, refstars, match, recipe, "Single Chip Fit Residuals (Chip Coordinates)")) 505 532 return false; 506 533 534 //ask for user input and finish 535 psastroVisualAskUser(&plotOneChipFit); 536 return true; 537 } 538 539 540 /** 541 * Plots the fpa chip corners projected on to the tangential plane before and after 542 * the astrometry solution has been applied. In psastroAstromGuessCheck, the old corners 543 * are then fit to the new corners to get a sense at how far off the initial WCS info was 544 * in offset, rotation, and scale. This procedure also plots the residuals of the fit from 545 * old to new coordinates 546 */ 547 bool psastroVisualPlotAstromGuessCheck (psVector *cornerPo, psVector *cornerQo, 548 psVector *cornerPn, psVector *cornerQn, 549 psVector *cornerPd, psVector *cornerQd) { 550 551 //make sure we want to plot this 552 if (!isVisual || !plotAstromGuessCheck) return true; 553 554 //set up graph window 555 if ( !psastroVisualInitWindow (&kapa, "psastro:plots")) 556 return false; 557 Graphdata graphdata; 558 KapaSection section; 559 KapaInitGraph(&graphdata); 560 KapaClearPlots (kapa); 561 562 graphdata.color = KapaColorByName ("black"); 563 graphdata.ptype = 2; 564 graphdata.size = 0.5; 565 graphdata.style = 2; 566 567 section.dx = 0.4; 568 section.dy = 0.4; 569 570 //Old Corners 571 section.x = 0.30; 572 section.y = 0.50; 573 section.name = NULL; 574 psStringAppend (§ion.name, "a0"); 575 KapaSetSection (kapa, §ion); 576 psFree(section.name); 577 578 psastroVisualScaleGraphdata (&graphdata, cornerPo, cornerPo); 579 KapaSetLimits (kapa, &graphdata); 580 KapaBox (kapa, &graphdata); 581 KapaSendLabel (kapa, "P (Pixels)", KAPA_LABEL_XM); 582 KapaSendLabel (kapa, "Q (Pixels)", KAPA_LABEL_YM); 583 KapaSendLabel (kapa, 584 "Fiducial Points in the Tangent Plane. Black: Initial Astrometry. Red: Final Astrometry", 585 KAPA_LABEL_XP); 586 KapaPrepPlot (kapa, cornerPo->n, &graphdata); 587 KapaPlotVector (kapa, cornerPo->n, cornerPo->data.F32, "x"); 588 KapaPlotVector (kapa, cornerQo->n, cornerQo->data.F32, "y"); 589 590 // New Corners 591 graphdata.color = KapaColorByName("red"); 592 graphdata.ptype = 7; 593 graphdata.size = 1.5; 594 KapaPrepPlot (kapa, cornerPn->n, &graphdata); 595 KapaPlotVector (kapa, cornerPn->n, cornerPn->data.F32, "x"); 596 KapaPlotVector (kapa, cornerQn->n, cornerQn->data.F32, "y"); 597 598 // Residuals 599 psVector *xResid = psVectorAlloc(cornerPn->n, PS_DATA_F32); 600 psVector *yResid = psVectorAlloc(cornerQn->n, PS_DATA_F32); 601 for(int i=0; i < cornerPn->n; i++) { 602 xResid->data.F32[i] = (cornerPd->data.F32[i]); 603 yResid->data.F32[i] = (cornerQd->data.F32[i]); 604 } 605 606 graphdata.color = KapaColorByName("black"); 607 graphdata.size=0.5; 608 section.x = 0.3; 609 section.y = 0.0; 610 section.name = NULL; 611 psStringAppend (§ion.name, "a1"); 612 KapaSetSection (kapa, §ion); 613 psFree(section.name); 614 615 psastroVisualScaleGraphdata (&graphdata, xResid, yResid); 616 KapaSetLimits (kapa, &graphdata); 617 KapaBox (kapa, &graphdata); 618 KapaSendLabel (kapa, "dP", KAPA_LABEL_XM); 619 KapaSendLabel (kapa, "dQ", KAPA_LABEL_YM); 620 KapaSendLabel (kapa, 621 "Residual of the Fit from the Initial Astrometry to the Final Astrometry", 622 KAPA_LABEL_XP); 623 KapaPrepPlot (kapa, cornerPd->n, &graphdata); 624 KapaPlotVector (kapa, cornerPd->n, xResid->data.F32, "x"); 625 KapaPlotVector (kapa, cornerQd->n, yResid->data.F32, "y"); 626 627 psFree(xResid); 628 psFree(yResid); 629 psastroVisualAskUser (&plotAstromGuessCheck); 630 return true; 631 } 632 633 634 /** 635 * psastroVisualPlotMosaicOneChip (rawstars, refstars, match); 636 * plot the residuals between raw stars and ref stars after 637 * fitting in psastroMosaicOneChip 638 */ 639 bool psastroVisualPlotMosaicOneChip (psArray *rawstars, psArray *refstars, 640 psArray *match, psMetadata *recipe) 641 { 642 643 //make sure we want to plot this 644 if (!isVisual || !plotMosaicOneChip) return false; 645 646 //plot the residuals 647 if (!psastroVisualResidPlot(rawstars, refstars, match, recipe, "Single Chip Fit Residuals - Mosaic Mode")) 648 return false; 649 650 //ask for user input and finish 651 psastroVisualAskUser(&plotMosaicOneChip); 652 653 return true; 654 } 655 656 /** psastroVisualPlotMosaicMatches 657 * Plot the matches between raw and reference stars during psastroVisualMosaicSetMatch 658 */ 659 bool psastroVisualPlotMosaicMatches( psArray *rawstars, psArray *refstars, 660 psArray *match, int iteration, 661 psMetadata *recipe) 662 { 663 //make sure we want to plot this 664 if (!isVisual || !plotMosaicMatches) return true; 665 char *title; 666 switch(iteration) { 667 case 0: 668 title = "Matches found during psastroMosaicSetMatch iteration 0"; 669 break; 670 case 1 : 671 title = "Matches found during psastroMosaicSetMatch iteration 1"; 672 break; 673 case 2: 674 title = "Matches found during psastroMosaicSetMatch iteration 2"; 675 break; 676 case 3: 677 title = "Matches found during psastroMosaicSetMatch iteration 3"; 678 break; 679 case 4: 680 title = "Matches found during psastroMosaicSetMatch iteration 4"; 681 break; 682 default: 683 title = "Matches found during psastroMosaicSetMatch"; 684 break; 685 } 686 687 if (!psastroVisualResidPlot(rawstars, refstars, match, recipe, title)) 688 return false; 689 690 //ask for user input 691 psastroVisualAskUser (&plotMosaicMatches); 692 return true; 693 } 694 695 696 /*********************/ 697 /** Helper Routines **/ 698 /*********************/ 699 700 701 /** psastroVisualTriplePlot 702 * plot 2 vectors whose point sizes are scaled by a third vector 703 * autoscales the plot 704 */ 705 bool psastroVisualTriplePlot (int kapid, Graphdata *graphdata, psVector *xVec, psVector *yVec, psVector *zVec, bool increasing) 706 { 707 psastroVisualScaleGraphdata (graphdata, xVec, yVec); 708 //printf("%f %f %f %f \n",graphdata->xmin, graphdata->xmax, graphdata->ymin, graphdata->ymax); 709 // set the scale vector 710 psVector *zScale = psVectorAlloc (zVec->n, PS_DATA_F32); 711 psastroVisualCreateScaleVec (zVec, zScale, increasing); 712 713 KapaSetFont (kapid, "helvetica", 14); 714 KapaSetLimits(kapid, graphdata); 715 KapaBox (kapid, graphdata); 716 717 // the point size will be scaled from the z vector 718 graphdata->size = -1; 719 KapaPrepPlot (kapid, xVec->n, graphdata); 720 KapaPlotVector (kapid, xVec->n, xVec->data.F32, "x"); 721 KapaPlotVector (kapid, yVec->n, yVec->data.F32, "y"); 722 KapaPlotVector (kapid, zVec->n, zScale->data.F32, "z"); 723 psFree (zScale); 724 return true; 725 } 726 727 728 /** psastroVisualTripleOverplot 729 * same as above, but does not rescale the plot or redraw the bounding box 730 */ 731 bool psastroVisualTripleOverplot (int kapid, Graphdata *graphdata, psVector *xVec, psVector *yVec, psVector *zVec, bool increasing) { 732 733 // set the scale vector 734 psVector *zScale = psVectorAlloc (zVec->n, PS_DATA_F32); 735 psastroVisualCreateScaleVec (zVec, zScale, increasing); 736 737 KapaSetFont (kapid, "helvetica", 14); 738 739 // the point size will be scaled from the z vector 740 graphdata->size = -1; 741 KapaPrepPlot (kapid, xVec->n, graphdata); 742 KapaPlotVector (kapid, xVec->n, xVec->data.F32, "x"); 743 KapaPlotVector (kapid, yVec->n, yVec->data.F32, "y"); 744 KapaPlotVector (kapid, zVec->n, zScale->data.F32, "z"); 745 psFree (zScale); 746 return true; 747 } 748 749 750 /** psastroVisualCreateScaleVec 751 * create a vector of plot point sizes from a vector 752 */ 753 bool psastroVisualCreateScaleVec (psVector *zVec, psVector *zScale, bool increasing) { 754 // set limits based on data values 755 float zmin = +FLT_MAX; 756 float zmax = -FLT_MAX; 757 758 for (int i = 0; i < zVec->n; i++) { 759 zmin = PS_MIN (zmin, zVec->data.F32[i]); 760 zmax = PS_MAX (zmax, zVec->data.F32[i]); 761 } 762 763 float range = zmax - zmin; 764 if (range == 0.0) { 765 psVectorInit (zScale, 1.0); 766 } else { 767 for (int i = 0; i < zVec->n; i++) { 768 if (increasing) { 769 zScale->data.F32[i] = PS_MIN (1.5, PS_MAX(0.05, 1.5*(zVec->data.F32[i] - zmin)/range)); 770 } else { 771 zScale->data.F32[i] = PS_MIN (1.5, PS_MAX(0.05, 1.5*(zmax - zVec->data.F32[i])/range)); 772 } 773 } 774 } 775 return true; 776 } 777 778 779 /** psastroVisualScaleGraphdata 780 * Scale the graphdata structure based on x and y coordinates. Use sigma clipping to 781 * prevent outliers from making te plot region too big. 782 */ 783 bool psastroVisualScaleGraphdata(Graphdata *graphdata, psVector *xVec, psVector *yVec) { 784 785 graphdata->xmin = +FLT_MAX; 786 graphdata->xmax = -FLT_MAX; 787 graphdata->ymin = +FLT_MAX; 788 graphdata->ymax = -FLT_MAX; 789 790 //determine standard deviation of xVec and yVec 791 psStats *statsX = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 792 psStats *statsY = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 793 psVectorStats (statsX, xVec, NULL, NULL, 0); 794 psVectorStats (statsY, yVec, NULL, NULL, 0); 795 796 float xhi = statsX->sampleMedian + 3 *statsX->sampleStdev; 797 float xlo = statsX->sampleMedian - 3 *statsX->sampleStdev; 798 float yhi = statsY->sampleMedian + 3 *statsY->sampleStdev; 799 float ylo = statsY->sampleMedian - 3 *statsY->sampleStdev; 800 801 // abort if there is no good data 802 if (!isfinite(xhi) || !isfinite(xlo) || !isfinite(yhi) || !isfinite(ylo)) { 803 graphdata->xmin = -1; 804 graphdata->ymin = -1; 805 graphdata->xmax = 1; 806 graphdata->ymax = 1; 807 psFree(statsX); 808 psFree(statsY); 809 return false; 810 } 811 812 for(int i = 0; i < xVec->n; i++) { 813 if (!isfinite(xVec->data.F32[i])) continue; 814 if (xVec->data.F32[i] > xhi || xVec->data.F32[i] < xlo) continue; 815 graphdata->xmin = PS_MIN (graphdata->xmin, xVec->data.F32[i]); 816 graphdata->xmax = PS_MAX (graphdata->xmax, xVec->data.F32[i]); 817 } 818 819 for (int i = 0; i < yVec->n; i++) { 820 if (!isfinite(xVec->data.F32[i])) continue; 821 if (yVec->data.F32[i] > yhi || yVec->data.F32[i] < ylo) continue; 822 graphdata->ymin = PS_MIN (graphdata->ymin, yVec->data.F32[i]); 823 graphdata->ymax = PS_MAX (graphdata->ymax, yVec->data.F32[i]); 824 } 825 826 // add a whitespace border 827 float range = graphdata->xmax - graphdata->xmin; 828 if (range == 0) range = 1; 829 graphdata->xmin -= .05 * range; 830 graphdata->xmax += .05 * range; 831 832 range = graphdata->ymax - graphdata->ymin; 833 if (range == 0) range = 1; 834 graphdata->ymin -= .05 * range; 835 graphdata->ymax += .05 * range; 836 837 psFree (statsX); 838 psFree (statsY); 839 return true; 840 } 841 842 843 /** psastroVisualResdiPlot 844 * Plots the residuals between matched raw and reference stars. Used to assess the quality of an 845 * astrometry solution 846 */ 847 bool psastroVisualResidPlot (psArray *rawstars, psArray *refstars, psArray *match, psMetadata *recipe, char *title) { 848 849 //set up the first window 850 if (!psastroVisualInitWindow( &kapa, "psastro:plots")) return false; 851 852 //initialize graph information 853 Graphdata graphdata; 854 KapaSection section; 855 856 KapaInitGraph (&graphdata); 857 KapaClearPlots (kapa); 858 859 graphdata.color = KapaColorByName ("black"); 860 graphdata.ptype = 7; 861 graphdata.size = 0.5; 862 graphdata.style = 2; 863 864 section.dx = 0.4; 865 section.dy = 0.4; 866 867 //initialize and populate the plotting vectors 507 868 bool status = false; 508 869 float iMagMin = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.INST.MAG.MIN"); … … 511 872 float rMagMax = psMetadataLookupF32 (&status, recipe, "PSASTRO.PLOT.REF.MAG.MAX"); 512 873 513 //initialize graph information514 Graphdata graphdata;515 KapaSection section;516 517 KapaInitGraph (&graphdata);518 KapaClearPlots (kapa);519 520 graphdata.color = KapaColorByName ("black");521 graphdata.ptype = 7;522 graphdata.size = 0.5;523 graphdata.style = 2;524 525 section.dx = 0.4;526 section.dy = 0.4;527 528 874 psVector *xVec = psVectorAlloc (match->n, PS_TYPE_F32); 529 875 psVector *yVec = psVectorAlloc (match->n, PS_TYPE_F32); … … 661 1007 psStringAppend (§ion.name, "a5"); 662 1008 KapaSetSection (kapa, §ion); 663 KapaSendLabel (kapa, "Single Chip Fit Residuals (Chip Coordinates)", KAPA_LABEL_XP);1009 KapaSendLabel (kapa, title, KAPA_LABEL_XP); 664 1010 psFree (section.name); 665 1011 666 1012 667 // ***X vs Y plot (different window)1013 // X vs Y plot (different window) 668 1014 if (!psastroVisualInitWindow( &kapa2, "psastro:plots")) 669 1015 return false; … … 774 1120 psastroVisualTripleOverplot (kapa2, &graphdata, xVec, yVec, zVec, false); 775 1121 776 psastroVisualAskUser (&plotOneChipFit);777 778 1122 psFree (xVec); 779 1123 psFree (yVec); … … 782 1126 } 783 1127 784 785 /**786 * Plots the fpa chip corners projected on to the tangential plane before and after787 * the astrometry solution has been applied. In psastroAstromGuessCheck, the old corners788 * are then fit to the new corners to get a sense at how far off the initial WCS info was789 * in offset, rotation, and scale. This procedure also plots the residuals of the fit from790 * old to new coordinates791 */792 bool psastroVisualPlotAstromGuessCheck (psVector *cornerPo, psVector *cornerQo,793 psVector *cornerPn, psVector *cornerQn,794 psVector *cornerPd, psVector *cornerQd) {795 796 if (!isVisual || !plotAstromGuessCheck) return true;797 if ( !psastroVisualInitWindow (&kapa, "psastro:plots"))798 return false;799 800 //set up graph window801 Graphdata graphdata;802 KapaSection section;803 KapaInitGraph(&graphdata);804 KapaClearPlots (kapa);805 806 graphdata.color = KapaColorByName ("black");807 graphdata.ptype = 2;808 graphdata.size = 0.5;809 graphdata.style = 2;810 811 section.dx = 0.4;812 section.dy = 0.4;813 814 //Old Corners815 section.x = 0.30;816 section.y = 0.50;817 section.name = NULL;818 psStringAppend (§ion.name, "a0");819 KapaSetSection (kapa, §ion);820 psFree(section.name);821 822 psastroVisualScaleGraphdata (&graphdata, cornerPo, cornerPo);823 KapaSetLimits (kapa, &graphdata);824 KapaBox (kapa, &graphdata);825 KapaSendLabel (kapa, "P (Pixels)", KAPA_LABEL_XM);826 KapaSendLabel (kapa, "Q (Pixels)", KAPA_LABEL_YM);827 KapaSendLabel (kapa,828 "Fiducial Points in the Tangent Plane. Black: Initial Astrometry. Red: Final Astrometry",829 KAPA_LABEL_XP);830 KapaPrepPlot (kapa, cornerPo->n, &graphdata);831 KapaPlotVector (kapa, cornerPo->n, cornerPo->data.F32, "x");832 KapaPlotVector (kapa, cornerQo->n, cornerQo->data.F32, "y");833 834 // New Corners835 graphdata.color = KapaColorByName("red");836 graphdata.ptype = 7;837 graphdata.size = 1.5;838 KapaPrepPlot (kapa, cornerPn->n, &graphdata);839 KapaPlotVector (kapa, cornerPn->n, cornerPn->data.F32, "x");840 KapaPlotVector (kapa, cornerQn->n, cornerQn->data.F32, "y");841 842 // Residuals843 psVector *xResid = psVectorAlloc(cornerPn->n, PS_DATA_F32);844 psVector *yResid = psVectorAlloc(cornerQn->n, PS_DATA_F32);845 for(int i=0; i < cornerPn->n; i++) {846 xResid->data.F32[i] = (cornerPd->data.F32[i] / cornerPn->data.F32[i]);847 yResid->data.F32[i] = (cornerQd->data.F32[i] / cornerQn->data.F32[i]);848 }849 850 graphdata.color = KapaColorByName("black");851 graphdata.size=0.5;852 section.x = 0.3;853 section.y = 0.0;854 section.name = NULL;855 psStringAppend (§ion.name, "a1");856 KapaSetSection (kapa, §ion);857 psFree(section.name);858 859 psastroVisualScaleGraphdata (&graphdata, xResid, yResid);860 KapaSetLimits (kapa, &graphdata);861 KapaBox (kapa, &graphdata);862 KapaSendLabel (kapa, "dP / P", KAPA_LABEL_XM);863 KapaSendLabel (kapa, "dQ / Q", KAPA_LABEL_YM);864 KapaSendLabel (kapa,865 "Residual of the Fit from the Initial Astrometry to the Final Astrometry",866 KAPA_LABEL_XP);867 KapaPrepPlot (kapa, cornerPd->n, &graphdata);868 KapaPlotVector (kapa, cornerPd->n, xResid->data.F32, "x");869 KapaPlotVector (kapa, cornerQd->n, yResid->data.F32, "y");870 871 psFree(xResid);872 psFree(yResid);873 psastroVisualAskUser (&plotAstromGuessCheck);874 return true;875 }876 877 /** Helper Routines **/878 879 880 /* psastroVisualTriplePlot */881 // plot 2 vectors whose point sizes are scaled by a third vector882 // autoscales the plot883 bool psastroVisualTriplePlot (int kapid, Graphdata *graphdata, psVector *xVec, psVector *yVec, psVector *zVec, bool increasing)884 {885 psastroVisualScaleGraphdata (graphdata, xVec, yVec);886 887 // set the scale vector888 psVector *zScale = psVectorAlloc (zVec->n, PS_DATA_F32);889 psastroVisualCreateScaleVec (zVec, zScale, increasing);890 891 KapaSetFont (kapid, "helvetica", 14);892 KapaSetLimits(kapid, graphdata);893 KapaBox (kapid, graphdata);894 895 // the point size will be scaled from the z vector896 graphdata->size = -1;897 KapaPrepPlot (kapid, xVec->n, graphdata);898 KapaPlotVector (kapid, xVec->n, xVec->data.F32, "x");899 KapaPlotVector (kapid, yVec->n, yVec->data.F32, "y");900 KapaPlotVector (kapid, zVec->n, zScale->data.F32, "z");901 psFree (zScale);902 return true;903 }904 905 906 /* psastroVisualTripleOverplot */907 // same as above, but does not rescale the plot or redraw the bounding box908 bool psastroVisualTripleOverplot (int kapid, Graphdata *graphdata, psVector *xVec, psVector *yVec, psVector *zVec, bool increasing) {909 910 // set the scale vector911 psVector *zScale = psVectorAlloc (zVec->n, PS_DATA_F32);912 psastroVisualCreateScaleVec (zVec, zScale, increasing);913 914 KapaSetFont (kapid, "helvetica", 14);915 916 // the point size will be scaled from the z vector917 graphdata->size = -1;918 KapaPrepPlot (kapid, xVec->n, graphdata);919 KapaPlotVector (kapid, xVec->n, xVec->data.F32, "x");920 KapaPlotVector (kapid, yVec->n, yVec->data.F32, "y");921 KapaPlotVector (kapid, zVec->n, zScale->data.F32, "z");922 psFree (zScale);923 return true;924 }925 926 927 /* psastroVisualCreateScaleVec */928 //create a vector of plot point sizes from a vector929 bool psastroVisualCreateScaleVec (psVector *zVec, psVector *zScale, bool increasing) {930 // set limits based on data values931 float zmin = +FLT_MAX;932 float zmax = -FLT_MAX;933 934 for (int i = 0; i < zVec->n; i++) {935 zmin = PS_MIN (zmin, zVec->data.F32[i]);936 zmax = PS_MAX (zmax, zVec->data.F32[i]);937 }938 939 float range = zmax - zmin;940 if (range == 0.0) {941 psVectorInit (zScale, 1.0);942 } else {943 for (int i = 0; i < zVec->n; i++) {944 if (increasing) {945 zScale->data.F32[i] = PS_MIN (1.5, PS_MAX(0.05, 1.5*(zVec->data.F32[i] - zmin)/range));946 } else {947 zScale->data.F32[i] = PS_MIN (1.5, PS_MAX(0.05, 1.5*(zmax - zVec->data.F32[i])/range));948 }949 }950 }951 return true;952 }953 954 955 /** psastroVisualScaleGraphdata956 * Scale the graphdata structure based on x and y coordinates. Use sigma clipping to957 * prevent outliers from making te plot region too big.958 */959 bool psastroVisualScaleGraphdata(Graphdata *graphdata, psVector *xVec, psVector *yVec) {960 graphdata->xmin = +FLT_MAX;961 graphdata->xmax = -FLT_MAX;962 graphdata->ymin = +FLT_MAX;963 graphdata->ymax = -FLT_MAX;964 bool baddataX = true;965 bool baddataY = true;966 967 //determine standard deviation of xVec and yVec968 psStats *statsX = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);969 psStats *statsY = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);970 psVectorStats (statsX, xVec, NULL, NULL, 0);971 psVectorStats (statsY, yVec, NULL, NULL, 0);972 973 float xhi = statsX->sampleMedian + 3 *statsX->sampleStdev;974 float xlo = statsX->sampleMedian - 3 *statsX->sampleStdev;975 float yhi = statsY->sampleMedian + 3 *statsY->sampleStdev;976 float ylo = statsY->sampleMedian - 3 *statsY->sampleStdev;977 978 for(int i = 0; i < xVec->n; i++) {979 if (!isfinite(xVec->data.F32[i])) continue;980 if (xVec->data.F32[i] > xhi || xVec->data.F32[i] < xlo) continue;981 baddataX = false;982 graphdata->xmin = PS_MIN (graphdata->xmin, xVec->data.F32[i]);983 graphdata->xmax = PS_MAX (graphdata->xmax, xVec->data.F32[i]);984 }985 986 for (int i = 0; i < yVec->n; i++) {987 if (!isfinite(yVec->data.F32[i])) continue;988 if (yVec->data.F32[i] > yhi || yVec->data.F32[i] < ylo) continue;989 baddataY = false;990 graphdata->ymin = PS_MIN (graphdata->ymin, yVec->data.F32[i]);991 graphdata->ymax = PS_MAX (graphdata->ymax, yVec->data.F32[i]);992 }993 994 // check to see if there was no good data995 if ( baddataX || baddataY) {996 graphdata->xmin = -1;997 graphdata->ymin = -1;998 graphdata->xmax = 1;999 graphdata->ymax = 1;1000 return false;1001 }1002 float range = graphdata->xmax - graphdata->xmin;1003 if (range == 0) range = 1;1004 graphdata->xmin -= .05 * range;1005 graphdata->xmax += .05 * range;1006 1007 range = graphdata->ymax - graphdata->ymin;1008 if (range == 0) range = 1;1009 graphdata->ymin -= .05 * range;1010 graphdata->ymax += .05 * range;1011 1012 psFree (statsX);1013 psFree (statsY);1014 return true;1015 }1016 1017 1128 # endif 1018 1129
Note:
See TracChangeset
for help on using the changeset viewer.
