Changeset 27838 for branches/tap_branches/psphot
- Timestamp:
- May 3, 2010, 8:41:49 AM (16 years ago)
- Location:
- branches/tap_branches
- Files:
-
- 69 edited
- 19 copied
-
. (modified) (1 prop)
-
psphot (modified) (1 prop)
-
psphot/doc/efficiency.txt (modified) (1 prop)
-
psphot/doc/footprints.txt (modified) (1 diff)
-
psphot/doc/notes.20091026.txt (copied) (copied from trunk/psphot/doc/notes.20091026.txt )
-
psphot/doc/notes.20100131.txt (copied) (copied from trunk/psphot/doc/notes.20100131.txt )
-
psphot/doc/stack.txt (modified) (1 diff)
-
psphot/src (modified) (1 prop)
-
psphot/src/Makefile.am (modified) (7 diffs)
-
psphot/src/psphot.h (modified) (11 diffs)
-
psphot/src/psphotAddNoise.c (modified) (3 diffs)
-
psphot/src/psphotApResid.c (modified) (7 diffs)
-
psphot/src/psphotArguments.c (modified) (2 diffs)
-
psphot/src/psphotBasicDeblend.c (modified) (2 diffs)
-
psphot/src/psphotBlendFit.c (modified) (5 diffs)
-
psphot/src/psphotChoosePSF.c (modified) (16 diffs)
-
psphot/src/psphotCleanup.c (modified) (1 diff)
-
psphot/src/psphotCullPeaks.c (modified) (2 diffs)
-
psphot/src/psphotDeblendSatstars.c (modified) (2 diffs)
-
psphot/src/psphotDefineFiles.c (modified) (1 diff)
-
psphot/src/psphotEfficiency.c (modified) (15 diffs, 1 prop)
-
psphot/src/psphotEllipticalContour.c (modified) (2 diffs)
-
psphot/src/psphotEllipticalProfile.c (modified) (4 diffs)
-
psphot/src/psphotErrorCodes.dat (modified) (1 diff)
-
psphot/src/psphotExtendedSourceAnalysis.c (modified) (7 diffs)
-
psphot/src/psphotExtendedSourceFits.c (modified) (3 diffs)
-
psphot/src/psphotFake.c (modified) (2 diffs, 1 prop)
-
psphot/src/psphotFindDetections.c (modified) (5 diffs)
-
psphot/src/psphotFindFootprints.c (modified) (4 diffs)
-
psphot/src/psphotFindPeaks.c (modified) (1 diff)
-
psphot/src/psphotFitSourcesLinear.c (modified) (10 diffs)
-
psphot/src/psphotFitSourcesLinearStack.c (modified) (11 diffs)
-
psphot/src/psphotForced.c (copied) (copied from trunk/psphot/src/psphotForced.c )
-
psphot/src/psphotForcedArguments.c (copied) (copied from trunk/psphot/src/psphotForcedArguments.c )
-
psphot/src/psphotForcedImageLoop.c (copied) (copied from trunk/psphot/src/psphotForcedImageLoop.c )
-
psphot/src/psphotForcedReadout.c (copied) (copied from trunk/psphot/src/psphotForcedReadout.c )
-
psphot/src/psphotGuessModels.c (modified) (7 diffs)
-
psphot/src/psphotImageLoop.c (modified) (1 diff)
-
psphot/src/psphotImageQuality.c (modified) (16 diffs)
-
psphot/src/psphotKernelFromPSF.c (modified) (2 diffs)
-
psphot/src/psphotLoadPSF.c (modified) (1 diff)
-
psphot/src/psphotLoadSRCTEXT.c (copied) (copied from trunk/psphot/src/psphotLoadSRCTEXT.c )
-
psphot/src/psphotMagnitudes.c (modified) (4 diffs)
-
psphot/src/psphotMakePSF.c (copied) (copied from trunk/psphot/src/psphotMakePSF.c )
-
psphot/src/psphotMakePSFArguments.c (copied) (copied from trunk/psphot/src/psphotMakePSFArguments.c )
-
psphot/src/psphotMakePSFImageLoop.c (copied) (copied from trunk/psphot/src/psphotMakePSFImageLoop.c )
-
psphot/src/psphotMakePSFReadout.c (copied) (copied from trunk/psphot/src/psphotMakePSFReadout.c )
-
psphot/src/psphotMakeResiduals.c (modified) (1 diff)
-
psphot/src/psphotMaskReadout.c (modified) (3 diffs)
-
psphot/src/psphotMergeSources.c (modified) (9 diffs)
-
psphot/src/psphotModelBackground.c (modified) (11 diffs)
-
psphot/src/psphotModelTest.c (modified) (1 diff)
-
psphot/src/psphotMomentsStudy.c (modified) (1 diff)
-
psphot/src/psphotOutput.c (modified) (3 diffs)
-
psphot/src/psphotPSFConvModel.c (modified) (1 diff)
-
psphot/src/psphotParseCamera.c (modified) (1 diff)
-
psphot/src/psphotPetrosian.c (modified) (2 diffs)
-
psphot/src/psphotPetrosianRadialBins.c (modified) (7 diffs)
-
psphot/src/psphotPetrosianStats.c (modified) (4 diffs)
-
psphot/src/psphotPetrosianVisual.c (modified) (6 diffs)
-
psphot/src/psphotRadialBins.c (copied) (copied from trunk/psphot/src/psphotRadialBins.c )
-
psphot/src/psphotRadialProfile.c (modified) (4 diffs)
-
psphot/src/psphotRadialProfileByAngles.c (modified) (2 diffs)
-
psphot/src/psphotRadiiFromProfiles.c (modified) (3 diffs)
-
psphot/src/psphotRadiusChecks.c (modified) (1 diff)
-
psphot/src/psphotReadout.c (modified) (5 diffs)
-
psphot/src/psphotReadoutCleanup.c (modified) (5 diffs)
-
psphot/src/psphotReadoutFindPSF.c (modified) (2 diffs)
-
psphot/src/psphotReadoutKnownSources.c (modified) (2 diffs)
-
psphot/src/psphotReadoutMinimal.c (modified) (3 diffs)
-
psphot/src/psphotReplaceUnfit.c (modified) (3 diffs)
-
psphot/src/psphotRoughClass.c (modified) (6 diffs)
-
psphot/src/psphotSetThreads.c (modified) (1 diff)
-
psphot/src/psphotSignificanceImage.c (modified) (4 diffs)
-
psphot/src/psphotSkyReplace.c (modified) (1 diff)
-
psphot/src/psphotSourceFits.c (modified) (6 diffs)
-
psphot/src/psphotSourceFreePixels.c (modified) (2 diffs)
-
psphot/src/psphotSourceMatch.c (copied) (copied from trunk/psphot/src/psphotSourceMatch.c )
-
psphot/src/psphotSourceSize.c (modified) (11 diffs)
-
psphot/src/psphotSourceStats.c (modified) (18 diffs)
-
psphot/src/psphotStack.c (copied) (copied from trunk/psphot/src/psphotStack.c )
-
psphot/src/psphotStackArguments.c (copied) (copied from trunk/psphot/src/psphotStackArguments.c )
-
psphot/src/psphotStackChisqImage.c (copied) (copied from trunk/psphot/src/psphotStackChisqImage.c )
-
psphot/src/psphotStackImageLoop.c (copied) (copied from trunk/psphot/src/psphotStackImageLoop.c )
-
psphot/src/psphotStackParseCamera.c (copied) (copied from trunk/psphot/src/psphotStackParseCamera.c )
-
psphot/src/psphotStackReadout.c (copied) (copied from trunk/psphot/src/psphotStackReadout.c )
-
psphot/src/psphotSubtractBackground.c (modified) (6 diffs)
-
psphot/src/psphotVisual.c (modified) (43 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/tap_branches
- Property svn:mergeinfo changed
-
branches/tap_branches/psphot
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psphot merged eligible /branches/eam_branches/stackphot.20100406/psphot 27622-27655 /branches/pap_delete/psphot 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/tap_branches/psphot/doc/efficiency.txt
- Property svn:mergeinfo deleted
-
branches/tap_branches/psphot/doc/footprints.txt
r17710 r27838 1 2 2010.01.18 3 4 * we are having some problems with footprints being freed to early in the second pass 5 6 * footprint memory history: 7 8 * entering psphotFindFootprints, on the first pass, we have an 9 array of detected peak in detections->peaks 10 11 * in pmFootprintsFind, footprints array owns allocated footprints 12 footprints each own their spans 13 14 * from pmFootprintAssignPeaks: 15 * the footprints have an array of peaks with valid memory references 16 * the peaks have just the pointer to the corresponding footprint (not owned) 17 * all peaks get assigned to a footprint 18 * at end of pmFootprintAssignPeaks, only a single copy of each peak is/should be available from the collection of footprints 1 19 2 20 pmFootprintCullPeaks is very expensive (15 - 30 msec per object) and -
branches/tap_branches/psphot/doc/stack.txt
r24583 r27838 1 2 20100126: 3 4 * watch out for psphotSetMomentsWindow & MOMENTS_SX_MAX,etc 5 * watch out for psphotSignificanceImage.c:,psphotEfficiency using the FWHM_MAJ from psphotChoosePSF 6 * ppSimDetections.c : SIGMA_SMOOTH 7 ppSmooth/src/ppSmoothReadout.c: psMetadataAddF32(recipe, PS_LIST_TAIL, "EFFECTIVE_AREA", PS_META_REPLACE, "Effective Area", effArea); 8 ppSmooth/src/ppSmoothReadout.c: psMetadataAddF32(recipe, PS_LIST_TAIL, "SIGNIFICANCE_SCALE_FACTOR", PS_META_REPLACE, "Signicance scale factor", factor); 9 10 11 20100120 : more stack processing mods: 12 13 there are a number of data collections generated during psphotReadout: 14 15 * detections (currently a structure containing multiple arrays) 16 * sources (a psArray) 17 * psf (the psf model structure) 18 19 * new sources vs old sources: 20 there is a sequence on the second pass in which we need to distinguish the sources 21 from the first pass from those on the second pass: 22 23 - add noise (old sources only) 24 - find detections 25 - subtract noise (old sources only) 26 - generate sources (new detections only) 27 - source classifications (new sources only) 28 - guess models (new sources only) 29 - replace sources (old sources only) 30 - merge sources (new + old -> sources) 31 32 currently we are distiguishing the old vs new based on different arrays. 33 can we use the processing flags to distinguish the these cases and carry around 34 only a single source list? 35 36 * detections->peaks holds the most recently detected set of peaks 37 detections->oldPeaks holds the previous collection 38 39 detections->footprints holds the full set of merged footprints, 40 including assigned peaks from the old and new set. 41 42 20100107 : updates for stack processing 43 44 I am building a new version of psphot that operates on a set of 45 images (eg, multi-filter or multi-epoch). The assumptions are: 46 47 * each input image represents the same sky pixels : they are warped to a common frame. 48 * each image has been previously processed, with the background 49 subtracted (and the psf model determined?) 50 * all planes are / can be loaded into memory at once (otherwise I 51 need to add a lot of I/O layers) 52 53 psphot currently expects the pmFPAfile of interest to be available in 54 config->files with the name PSPHOT.INPUT. To update the code for 55 stacks, I am extending this concept with the pmFPAfileSelectSingle 56 API: config->files may contain multiple PSPHOT.INPUT entries, and 57 functions which access this file / these files need to specify 58 *which* image they want. The number of PSPHOT.INPUT entries is 59 saved in config->arguments as PSPHOT.INPUT.NUM (this can be 60 generated from the filerule PSPHOT.INPUT for extension). 61 62 As a result, we need a number of wrapper functions which loop over 63 all PSPHOT.INPUT.NUM entries and perform a particular operation on 64 one of the entries. Here are the functions which I have modified 65 in this way (function -> child) 66 67 * psphotAddPhotcode -> psphotAddPhotcodeReadout 68 * note that the photcode is now saved on readout->analysis 69 * psphotSetMaskAndVariance -> psphotSetMaskAndVarianceReadout 70 * psphotModelBackground -> psphotModelBackgroundReadoutFileIndex 71 * psphotSubtractBackground -> psphotSubtractBackgroundReadout 72 73 side notes on 74 75 * psphotModelBackground vs psphotBackgroundModel : I've renamed 76 psphotBackgroundModel (used only by ppStack for now) to 77 psphotModelBackgroundReadoutNoFile. I've also named the 78 single-readout version used by psphotModelBackground to 79 psphotModelBackgroundReadoutFileIndex. These two functions do the 80 same thing, but psphotModelBackgroundReadoutNoFile does not save 81 a pmFPAfile on config->files 82 1 83 2 84 20090606 : design notes on the multi-image photometry analysis -
branches/tap_branches/psphot/src
- Property svn:ignore
-
old new 19 19 psphotMomentsStudy 20 20 psphotPetrosianStudy 21 psphotForced 22 psphotMakePSF 23 psphotStack
-
- Property svn:ignore
-
branches/tap_branches/psphot/src/Makefile.am
r25755 r27838 25 25 libpsphot_la_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 26 26 27 bin_PROGRAMS = psphot psphotTest psphotMomentsStudy 28 # bin_PROGRAMS = psphotPetrosianStudy 29 # bin_PROGRAMS = psphot 27 bin_PROGRAMS = psphot psphotForced psphotMakePSF psphotStack 28 # bin_PROGRAMS = psphotPetrosianStudy psphotTest psphotMomentsStudy 30 29 31 30 psphot_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) … … 33 32 psphot_LDADD = libpsphot.la 34 33 35 psphotTest_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 36 psphotTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 37 psphotTest_LDADD = libpsphot.la 38 39 psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 40 psphotMomentsStudy_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 41 psphotMomentsStudy_LDADD = libpsphot.la 34 psphotForced_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 35 psphotForced_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 36 psphotForced_LDADD = libpsphot.la 37 38 psphotMakePSF_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 39 psphotMakePSF_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 40 psphotMakePSF_LDADD = libpsphot.la 41 42 psphotStack_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 43 psphotStack_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 44 psphotStack_LDADD = libpsphot.la 45 46 # psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 47 # psphotMomentsStudy_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 48 # psphotMomentsStudy_LDADD = libpsphot.la 42 49 43 50 # psphotPetrosianStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) … … 45 52 # psphotPetrosianStudy_LDADD = libpsphot.la 46 53 54 # psphotTest_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 55 # psphotTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 56 # psphotTest_LDADD = libpsphot.la 57 58 # standard psphot for generic photometry 47 59 psphot_SOURCES = \ 48 60 psphot.c \ 49 61 psphotArguments.c \ 50 psphot Cleanup.c\62 psphotParseCamera.c \ 51 63 psphotImageLoop.c \ 52 64 psphotMosaicChip.c \ 53 psphotParseCamera.c 54 55 psphotDetect_SOURCES = \ 56 psphotDetect.c \ 57 psphotDetectArguments.c \ 58 psphotDetectParseCamera.c \ 59 psphotDetectImageLoop.c \ 60 psphotDetectReadout.c \ 61 psphotMosaicChip.c \ 62 psphotCleanup.c 63 64 psphotTest_SOURCES = \ 65 psphotTest.c 66 67 psphotMomentsStudy_SOURCES = \ 68 psphotMomentsStudy.c 69 65 psphotCleanup.c 66 67 # forced photometry of specified positions given a specified psf 68 psphotForced_SOURCES = \ 69 psphotForced.c \ 70 psphotForcedArguments.c \ 71 psphotForcedImageLoop.c \ 72 psphotForcedReadout.c \ 73 psphotParseCamera.c \ 74 psphotMosaicChip.c \ 75 psphotCleanup.c 76 77 # a psphot-variant that simply generates the PSF model 78 psphotMakePSF_SOURCES = \ 79 psphotMakePSF.c \ 80 psphotMakePSFArguments.c \ 81 psphotMakePSFImageLoop.c \ 82 psphotMakePSFReadout.c \ 83 psphotParseCamera.c \ 84 psphotMosaicChip.c \ 85 psphotCleanup.c 86 87 # a psphot-variant for stack photometry 88 psphotStack_SOURCES = \ 89 psphotStack.c \ 90 psphotStackArguments.c \ 91 psphotStackParseCamera.c \ 92 psphotStackImageLoop.c \ 93 psphotStackReadout.c \ 94 psphotStackChisqImage.c \ 95 psphotFitSourcesLinearStack.c \ 96 psphotSourceMatch.c \ 97 psphotCleanup.c 98 99 100 101 # # psphot analysis of the detectability of specified positions 102 # psphotDetect_SOURCES = \ 103 # psphotDetect.c \ 104 # psphotDetectArguments.c \ 105 # psphotDetectParseCamera.c \ 106 # psphotDetectImageLoop.c \ 107 # psphotDetectReadout.c \ 108 # psphotMosaicChip.c \ 109 # psphotCleanup.c 110 111 # psphotTest_SOURCES = \ 112 # psphotTest.c 113 # 114 # psphotMomentsStudy_SOURCES = \ 115 # psphotMomentsStudy.c 116 # 70 117 # psphotPetrosianStudy_SOURCES = \ 71 118 # psphotPetrosianStudy.c … … 115 162 psphotKernelFromPSF.c \ 116 163 psphotPSFConvModel.c \ 117 psphotModelTest.c \118 164 psphotFitSet.c \ 119 165 psphotSourceFreePixels.c \ … … 121 167 psphotMergeSources.c \ 122 168 psphotLoadPSF.c \ 169 psphotLoadSRCTEXT.c \ 123 170 psphotReadoutCleanup.c \ 124 171 psphotSourcePlots.c \ … … 138 185 psphotEllipticalContour.c \ 139 186 psphotEllipticalProfile.c \ 187 psphotRadialBins.c \ 140 188 psphotPetrosian.c \ 141 189 psphotPetrosianRadialBins.c \ 142 190 psphotPetrosianStats.c \ 191 psphotPetrosianVisual.c \ 143 192 psphotEfficiency.c 193 194 # XXX need to fix this for the new apis 195 # psphotModelTest.c 144 196 145 197 # re-instate these … … 147 199 # psphotAnnuli.c \ 148 200 # psphotKron.c \ 149 # psphotPetrosianVisual.c \150 201 # 151 202 -
branches/tap_branches/psphot/src/psphot.h
r25852 r27838 12 12 13 13 #define PSPHOT_RECIPE_PSF_FAKE_ALLOW "PSF.FAKE.ALLOW" // Name for recipe component permitting fake PSFs 14 15 // pmPCMData : PSF Convolved Model data storage structure 16 typedef struct { 17 psImage *model; 18 psArray *dmodels; 19 psImage *modelConv; 20 psArray *dmodelsConv; 21 } pmPCMData; 14 22 15 23 // top-level psphot functions … … 29 37 bool psphotReadoutMinimal(pmConfig *config, const pmFPAview *view); 30 38 31 bool psphotReadoutCleanup (pmConfig *config, pmReadout *readout, psMetadata *recipe, pmDetections *detections, pmPSF *psf, psArray *sources); 39 bool psphotReadoutCleanup (pmConfig *config, const pmFPAview *view); 40 bool psphotReadoutCleanupReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 41 32 42 bool psphotDefineFiles (pmConfig *config, pmFPAfile *input); 33 43 void psphotFilesActivate(pmConfig *config, bool state); … … 38 48 // XXX test functions 39 49 psArray *psphotFakeSources (void); 50 bool psphotMaskCosmicRayFootprintCheck (psArray *sources); 40 51 41 52 // psphotReadout functions 42 bool psphotModelBackground (pmConfig *config, const pmFPAview *view, const char *filename); 43 bool psphotSubtractBackground (pmConfig *config, const pmFPAview *view, const char *filename) ; 44 pmDetections *psphotFindDetections (pmDetections *detections, pmReadout *readout, psMetadata *recipe); 45 46 bool psphotRoughClass (pmReadout *readout, psArray *sources, psMetadata *recipe, const bool findPsfClump); 47 bool psphotBasicDeblend (psArray *sources, psMetadata *recipe); 48 pmPSF *psphotChoosePSF (pmReadout *readout, psArray *sources, psMetadata *recipe); 49 bool psphotPSFstats (pmReadout *readout, psMetadata *recipe, pmPSF *psf); 50 bool psphotMomentsStats (pmReadout *readout, psMetadata *recipe, psArray *sources); 51 bool psphotFitSourcesLinear (pmReadout *readout, psArray *sources, const psMetadata *recipe, const pmPSF *psf, bool final); 52 bool psphotReplaceUnfitSources (psArray *sources, psImageMaskType maskVal); 53 54 bool psphotReplaceAllSources (psArray *sources, psMetadata *recipe); 55 bool psphotRemoveAllSources (const psArray *sources, const psMetadata *recipe); 56 57 bool psphotBlendFit (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf); 53 bool psphotAddPhotcode (pmConfig *config, const pmFPAview *view); 54 bool psphotAddPhotcodeReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index); 55 56 bool psphotSetMaskAndVariance (pmConfig *config, const pmFPAview *view); 57 bool psphotSetMaskAndVarianceReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 58 59 bool psphotModelBackground (pmConfig *config, const pmFPAview *view); 60 bool psphotModelBackgroundReadoutFileIndex (pmConfig *config, const pmFPAview *view, const char *filename, int index); 61 62 bool psphotSubtractBackground (pmConfig *config, const pmFPAview *view); 63 bool psphotSubtractBackgroundReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 64 65 bool psphotFindDetections (pmConfig *config, const pmFPAview *view, bool firstPass); 66 bool psphotFindDetectionsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool firstPass); 67 68 bool psphotSourceStats (pmConfig *config, const pmFPAview *view, bool setWindow); 69 bool psphotSourceStatsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool setWindow); 70 71 bool psphotDeblendSatstars (pmConfig *config, const pmFPAview *view); 72 bool psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index); 73 74 bool psphotBasicDeblend (pmConfig *config, const pmFPAview *view); 75 bool psphotBasicDeblendReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index); 76 77 bool psphotRoughClass (pmConfig *config, const pmFPAview *view); 78 bool psphotRoughClassReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 79 bool psphotRoughClassRegion (int nRegion, psRegion *region, psArray *sources, psMetadata *analysis, psMetadata *recipe, const bool havePSF); 80 81 bool psphotImageQuality (pmConfig *config, const pmFPAview *view); 82 bool psphotImageQualityReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 83 84 bool psphotChoosePSF (pmConfig *config, const pmFPAview *view); 85 bool psphotChoosePSFReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 86 87 bool psphotGuessModels (pmConfig *config, const pmFPAview *view); 88 bool psphotGuessModelsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index); 89 90 bool psphotMergeSources (pmConfig *config, const pmFPAview *view); 91 bool psphotMergeSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index); 92 93 bool psphotFitSourcesLinear (pmConfig *config, const pmFPAview *view, bool final); 94 bool psphotFitSourcesLinearReadout (psMetadata *recipe, pmReadout *readout, psArray *sources, pmPSF *psf, bool final); 95 96 bool psphotSourceSize (pmConfig *config, const pmFPAview *view, bool getPSFsize); 97 bool psphotSourceSizeReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool getPSFsize); 98 99 bool psphotBlendFit (pmConfig *config, const pmFPAview *view); 100 bool psphotBlendFitReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 58 101 bool psphotBlendFit_Threaded (psThreadJob *job); 59 102 60 psArray *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections, bool setWindow); 61 bool psphotSourceStats_Threaded (psThreadJob *job); 62 63 bool psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf); 64 bool psphotGuessModel_Threaded (psThreadJob *job); 65 66 bool psphotMagnitudes (pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources, const pmPSF *psf); 103 bool psphotReplaceAllSources (pmConfig *config, const pmFPAview *view); 104 bool psphotReplaceAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 105 106 bool psphotAddNoise (pmConfig *config, const pmFPAview *view); 107 bool psphotSubNoise (pmConfig *config, const pmFPAview *view); 108 bool psphotAddOrSubNoise (pmConfig *config, const pmFPAview *view, bool add); 109 bool psphotAddOrSubNoiseReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool add); 110 111 bool psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view); 112 bool psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 113 114 bool psphotExtendedSourceFits (pmConfig *config, const pmFPAview *view); 115 bool psphotExtendedSourceFitsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 116 117 bool psphotApResid (pmConfig *config, const pmFPAview *view); 118 bool psphotApResidReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 119 120 bool psphotMagnitudes (pmConfig *config, const pmFPAview *view); 121 bool psphotMagnitudesReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf); 67 122 bool psphotMagnitudes_Threaded (psThreadJob *job); 123 124 bool psphotEfficiency (pmConfig *config, const pmFPAview *view); 125 bool psphotEfficiencyReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 68 126 69 127 bool psphotPSFWeights(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources); 70 128 bool psphotPSFWeights_Threaded (psThreadJob *job); 71 129 72 bool psphotApResid (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf);73 74 130 bool psphotSkyReplace (pmConfig *config, const pmFPAview *view); 75 bool psphotExtendedSourceAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe); 76 bool psphotExtendedSourceFits (pmReadout *readout, psArray *sources, psMetadata *recipe); 77 bool psphotEfficiency(pmConfig *config, pmReadout *readout, const pmFPAview *view, const pmPSF *psf, psMetadata *recipe, const psArray *realSources); 131 bool psphotSkyReplaceReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index); 132 133 bool psphotSourceFreePixels (pmConfig *config, const pmFPAview *view); 134 bool psphotSourceFreePixelsReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index); 135 136 // in psphotSourceStats.c: 137 bool psphotSourceStats_Threaded (psThreadJob *job); 138 bool psphotSourceStatsUpdate (psArray *sources, pmConfig *config, pmReadout *readout); 139 bool psphotSetMomentsWindow (psMetadata *recipe, psMetadata *analysis, psArray *sources); 140 141 // in psphotChoosePSF.c: 142 bool psphotPSFstats (pmReadout *readout, pmPSF *psf); 143 bool psphotMomentsStats (pmReadout *readout, psArray *sources); 144 145 // in psphotGuessModel.c 146 bool psphotGuessModel_Threaded (psThreadJob *job); 147 148 // in psphotMergeSources.c: 149 bool psphotLoadExtSources (pmConfig *config, const pmFPAview *view); 150 psArray *psphotLoadPSFSources (pmConfig *config, const pmFPAview *view); 151 bool psphotRepairLoadedSources (pmConfig *config, const pmFPAview *view); 152 bool psphotCheckExtSources (pmConfig *config, const pmFPAview *view); 153 154 // generate the detection structure for the supplied array of sources 155 bool psphotDetectionsFromSources (pmConfig *config, const pmFPAview *view, psArray *sources); 156 157 // generate the detection structure for the supplied array of sources 158 bool psphotSetSourceParams (pmConfig *config, psArray *sources, pmPSF *psf); 159 160 // in psphotModelBackground.c: 161 // Create a background model for a readout, without saving the result as a pmFPAfile on config->files. Otherwise identical to psphotModelBackgroundFileIndex. 162 psImage *psphotModelBackgroundReadoutNoFile(pmReadout *readout, const pmConfig *config); 163 psImageBinning *psphotBackgroundBinning(const psImage *image, const pmConfig *config); 164 165 // in psphotReplaceUnfit.c: 166 bool psphotRemoveAllSources (const psArray *sources, const psMetadata *recipe); 167 bool psphotReplaceUnfitSources (psArray *sources, psImageMaskType maskVal); 78 168 79 169 // thread-related: … … 87 177 psArray *psphotFindPeaks (psImage *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int nMax); 88 178 bool psphotFindFootprints (pmDetections *detections, psImage *significance, pmReadout *readout, psMetadata *recipe, const float threshold, const int pass, psImageMaskType maskVal); 89 psErrorCode psphotCullPeaks(const psImage *img, const psImage *weight, const psMetadata *recipe, psArray *footprints); 90 91 // generate the detection structure for the supplied array of sources 92 pmDetections *psphotDetectionsFromSources (pmConfig *config, psArray *sources); 93 94 // used by ApResid 179 psErrorCode psphotCullPeaks(const pmReadout *readout, const psMetadata *recipe, psArray *footprints); 180 181 // in psphotApResid.c: 95 182 pmTrend2D *psphotApResidTrend (float *apResidSysErr, pmReadout *readout, int Nx, int Ny, psVector *xPos, psVector *yPos, psVector *apResid, psVector *dMag); 96 183 bool psphotApResidMags_Threaded (psThreadJob *job); … … 99 186 void psphotModelClassInit (void); 100 187 bool psphotGrowthCurve (pmReadout *readout, pmPSF *psf, bool ignore, psImageMaskType maskVal); 101 bool psphotSetMaskAndVariance (pmConfig *config, pmReadout *readout, psMetadata *recipe);102 void psphotSourceFreePixels (psArray *sources);103 188 104 189 // functions to set the correct source pixels 105 bool psphotInitRadiusPSF (const psMetadata *recipe, const pmModelType type); 190 bool psphotInitRadiusPSF(const psMetadata *recipe, const psMetadata *analysis, const pmModelType type); 191 106 192 bool psphotCheckRadiusPSF (pmReadout *readout, pmSource *source, pmModel *model, psImageMaskType markVal); 107 193 bool psphotCheckRadiusPSFBlend (pmReadout *readout, pmSource *source, pmModel *model, psImageMaskType markVal, float dR); … … 110 196 float psphotSetRadiusEXT (pmReadout *readout, pmSource *source, psImageMaskType markVal); 111 197 112 // output functions113 bool psphotAddPhotcode (psMetadata *recipe, pmConfig *config, const pmFPAview *view, const char *filerule);114 198 bool psphotDumpMoments (psMetadata *recipe, psArray *sources); 115 199 psMetadata *psphotDefineHeader (psMetadata *recipe); … … 142 226 bool psphotFitSummary (void); 143 227 144 bool psphotMergeSources (psArray *oldSources, psArray *newSources); 145 bool psphotLoadExtSources (pmConfig *config, const pmFPAview *view, psArray *sources); 146 psArray *psphotLoadPSFSources (pmConfig *config, const pmFPAview *view); 147 148 pmPSF *psphotLoadPSF (pmConfig *config, const pmFPAview *view, psMetadata *recipe); 228 bool psphotLoadPSF (pmConfig *config, const pmFPAview *view); 229 bool psphotLoadPSFReadout (pmConfig *config, const pmFPAview *view, const char *outFilename, const char *inFilename, int index); 230 149 231 bool psphotSetHeaderNstars (psMetadata *recipe, psArray *sources); 150 bool psphotAddNoise (pmReadout *readout, const psArray *sources, const psMetadata *recipe);151 bool psphotSubNoise (pmReadout *readout, const psArray *sources, const psMetadata *recipe);152 bool psphotAddOrSubNoise (pmReadout *readout, const psArray *sources, const psMetadata *recipe, bool add);153 232 bool psphotRadialPlot (int *kapa, const char *filename, pmSource *source); 154 233 bool psphotSourcePlots (pmReadout *readout, psArray *sources, psMetadata *recipe); 155 234 bool psphotMosaicSubimage (psImage *outImage, pmSource *source, int Xo, int Yo, int DX, int DY, bool normalize); 156 235 157 bool psphotAddWithTest (pmSource *source, bool useState, psImageMaskType maskVal);158 bool psphotSubWithTest (pmSource *source, bool useState, psImageMaskType maskVal);159 bool psphotSetState (pmSource *source, bool curState, psImageMaskType maskVal);160 bool psphotDeblendSatstars (pmReadout *readout, psArray *sources, psMetadata *recipe);161 bool psphotSourceSize (pmConfig *config, pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, long first);162 163 236 bool psphotMakeResiduals (psArray *sources, psMetadata *recipe, pmPSF *psf, psImageMaskType maskVal); 164 237 … … 168 241 169 242 // functions related to extended source analysis 170 bool psphotRadialProfile (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal);171 bool psphotRadialProfilesByAngles (pmSource *source, int Nsec, float Rmax);172 float psphotRadiusFromProfile (pmSource *source, psVector *radius, psVector *flux, float fluxMin, float fluxMax);173 bool psphotRadiiFromProfiles (pmSource *source, float fluxMin, float fluxMax);174 bool psphotEllipticalProfile (pmSource *source);175 bool psphotEllipticalContour (pmSource *source);243 bool psphotRadialProfile (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal); 244 bool psphotRadialProfilesByAngles (pmSource *source, int Nsec, float Rmax); 245 float psphotRadiusFromProfile (pmSource *source, psVector *radius, psVector *flux, float fluxMin, float fluxMax); 246 bool psphotRadiiFromProfiles (pmSource *source, float fluxMin, float fluxMax); 247 bool psphotEllipticalProfile (pmSource *source, bool RAW_RADIUS); 248 bool psphotEllipticalContour (pmSource *source); 176 249 177 250 // psphotVisual functions 178 bool psphotVisualShowImage (pmReadout *readout); 179 bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout); 180 bool psphotVisualShowSignificance (psImage *image); 181 bool psphotVisualShowPeaks (pmDetections *detections); 182 bool psphotVisualShowFootprints (pmDetections *detections); 183 bool psphotVisualShowMoments (psArray *sources); 184 bool psphotVisualPlotMoments (psMetadata *recipe, psMetadata *analysis, psArray *sources); 185 bool psphotVisualShowRoughClass (psArray *sources); 186 bool psphotVisualShowPSFStars (psMetadata *recipe, pmPSF *psf, psArray *sources); 187 bool psphotVisualShowSatStars (psMetadata *recipe, pmPSF *psf, psArray *sources); 188 bool psphotVisualShowPSFModel (pmReadout *readout, pmPSF *psf); 189 bool psphotVisualPlotRadialProfile (int myKapa, pmSource *source, psImageMaskType maskVal); 190 bool psphotVisualPlotRadialProfiles (psMetadata *recipe, psArray *sources); 191 bool psphotVisualShowFlags (psArray *sources); 192 bool psphotVisualShowSourceSize (pmReadout *readout, psArray *sources); 193 bool psphotVisualShowResidualImage (pmReadout *readout); 194 bool psphotVisualPlotApResid (psArray *sources, float mean, float error); 195 bool psphotVisualPlotSourceSize (psMetadata *recipe, psMetadata *analysis, psArray *sources); 196 bool psphotVisualShowPetrosians (psArray *sources); 197 198 // bool psphotPetrosianAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe); 199 // bool psphotPetrosianProfile (pmReadout *readout, pmSource *source, float skynoise); 251 bool psphotVisualShowImage (pmReadout *readout); 252 bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout); 253 bool psphotVisualShowSignificance (psImage *image, float min, float max); 254 bool psphotVisualShowPeaks (pmDetections *detections); 255 bool psphotVisualShowFootprints (pmDetections *detections); 256 bool psphotVisualShowMoments (psArray *sources); 257 bool psphotVisualPlotMoments (psMetadata *recipe, psMetadata *analysis, psArray *sources); 258 bool psphotVisualShowRoughClass (psArray *sources); 259 bool psphotVisualShowPSFStars (psMetadata *recipe, pmPSF *psf, psArray *sources); 260 bool psphotVisualShowSatStars (psMetadata *recipe, pmPSF *psf, psArray *sources); 261 bool psphotVisualShowPSFModel (pmReadout *readout, pmPSF *psf); 262 bool psphotVisualPlotRadialProfile (int myKapa, pmSource *source, psImageMaskType maskVal); 263 bool psphotVisualPlotRadialProfiles (psMetadata *recipe, psArray *sources); 264 bool psphotVisualShowFlags (psArray *sources); 265 bool psphotVisualShowSourceSize (pmReadout *readout, psArray *sources); 266 bool psphotVisualShowResidualImage (pmReadout *readout); 267 bool psphotVisualPlotApResid (psArray *sources, float mean, float error); 268 bool psphotVisualPlotChisq (psArray *sources); 269 bool psphotVisualPlotSourceSize (psMetadata *recipe, psMetadata *analysis, psArray *sources); 270 bool psphotVisualShowPetrosians (psArray *sources); 271 bool psphotVisualEraseOverlays (int channel, char *overlay); 200 272 201 273 bool psphotPetrosian (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal); … … 203 275 bool psphotPetrosianStats (pmSource *source); 204 276 205 // XXX old versions, currently disabled277 // currently disabled: 206 278 // bool psphotIsophotal (pmSource *source, psMetadata *recipe, psImageMaskType maskVal); 207 279 // bool psphotAnnuli (pmSource *source, psMetadata *recipe, psImageMaskType maskVal); … … 209 281 210 282 // XXX visualization functions related to radial profiles (disabled) 211 //bool psphotPetrosianVisualProfileByAngle (psVector *radius, psVector *flux);212 //bool psphotPetrosianVisualProfileRadii (psVector *radius, psVector *flux, psVector *radiusBin, psVector *fluxBin, float peakFlux, float RadiusRef);213 // bool psphotPetrosianVisualEllipticalContour (pmPetrosian *petrosian);214 //bool psphotPetrosianVisualStats (psVector *radBin, psVector *fluxBin,215 //psVector *refRadius, psVector *meanSB,216 //psVector *petRatio, psVector *petRatioErr, psVector *fluxSum,217 //float petRadius, float ratioForRadius,218 //float petFlux, float radiusForFlux);219 220 bool psphot ImageQuality (psMetadata *recipe, psArray *sources);283 bool psphotPetrosianVisualProfileByAngle (psVector *radius, psVector *flux); 284 bool psphotPetrosianVisualProfileRadii (psVector *radius, psVector *flux, psVector *radiusBin, psVector *fluxBin, float peakFlux, float RadiusRef); 285 bool psphotPetrosianVisualEllipticalContour (pmSourceRadialFlux *radFlux, pmSourceExtendedPars *extpars); 286 bool psphotPetrosianVisualStats (psVector *radBin, psVector *fluxBin, 287 psVector *refRadius, psVector *meanSB, 288 psVector *petRatio, psVector *petRatioErr, psVector *fluxSum, 289 float petRadius, float ratioForRadius, 290 float petFlux, float radiusForFlux); 291 292 bool psphotRadialBins (psMetadata *recipe, pmSource *source, float radiusMax, float skynoise); 221 293 222 294 // structures & functions to support psf-convolved model fitting 223 224 // pmPCMData : PSF Convolved Model data storage structure225 typedef struct {226 psImage *model;227 psArray *dmodels;228 psImage *modelConv;229 psArray *dmodelsConv;230 } pmPCMData;231 232 295 233 296 // psf-convolved model fitting … … 267 330 bool psphotDumpPSFStars (pmReadout *readout, pmPSFtry *try, float radius, psImageMaskType maskVal, psImageMaskType markVal); 268 331 332 bool psphotLoadSRCTEXT (pmFPA *fpa, pmConfig *config); 333 269 334 bool psphotCheckStarDistribution (psArray *sources, psArray *stars, pmPSFOptions *options); 270 335 int psphotSupplementStars (psArray *stars, psArray *sources, psImageBinning *binning, int ix, int iy); 271 336 272 273 // Create a background model for a readout 274 // Essentially identical to psphotModelBackground, but with a more convenient API for outsiders. 275 psImage *psphotBackgroundModel(pmReadout *ro, // Readout for which to generate background model 276 const pmConfig *config // Configuration 277 ); 278 337 pmConfig *psphotForcedArguments(int argc, char **argv); 338 bool psphotForcedImageLoop (pmConfig *config); 339 bool psphotForcedReadout(pmConfig *config, const pmFPAview *view); 340 341 pmConfig *psphotMakePSFArguments(int argc, char **argv); 342 bool psphotMakePSFImageLoop (pmConfig *config); 343 bool psphotMakePSFReadout(pmConfig *config, const pmFPAview *view); 344 345 /**** psphotStack prototypes ****/ 346 347 pmConfig *psphotStackArguments(int argc, char **argv); 348 bool psphotStackParseCamera (pmConfig *config); 349 bool psphotStackImageLoop (pmConfig *config); 350 bool psphotStackReadout (pmConfig *config, const pmFPAview *view); 351 bool psphotStackChisqImage (pmConfig *config, const pmFPAview *view); 352 bool psphotStackChisqImageAddReadout(const pmConfig *config, // Configuration 353 const pmFPAview *view, 354 pmReadout **chiReadout, 355 char *filename, 356 int index); 357 358 bool psphotStackRemoveChisqFromInputs (pmConfig *config); 359 bool pmFPAfileRemoveSingle(psMetadata *files, const char *name, int num); 360 361 psArray *psphotMatchSources (pmConfig *config, const pmFPAview *view); 362 bool psphotMatchSourcesReadout (psArray *objects, pmConfig *config, const pmFPAview *view, char *filename, int index); 363 bool psphotMatchSourcesToObjects (psArray *objects, psArray *sources, float RADIUS); 364 365 bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final); 366 int pmPhotObjSortBySN (const void **a, const void **b); 367 int pmPhotObjSortByX (const void **a, const void **b); 279 368 280 369 #endif -
branches/tap_branches/psphot/src/psphotAddNoise.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 bool psphotAddNoise (pm Readout *readout, const psArray *sources, const psMetadata *recipe) {4 return psphotAddOrSubNoise (readout, sources, recipe, true);3 bool psphotAddNoise (pmConfig *config, const pmFPAview *view) { 4 return psphotAddOrSubNoise (config, view, true); 5 5 } 6 6 7 bool psphotSubNoise (pm Readout *readout, const psArray *sources, const psMetadata *recipe) {8 return psphotAddOrSubNoise (readout, sources, recipe, false);7 bool psphotSubNoise (pmConfig *config, const pmFPAview *view) { 8 return psphotAddOrSubNoise (config, view, false); 9 9 } 10 10 11 bool psphotAddOrSubNoise (pmReadout *readout, const psArray *sources, const psMetadata *recipe, bool add) { 11 // for now, let's store the detections on the readout->analysis for each readout 12 bool psphotAddOrSubNoise (pmConfig *config, const pmFPAview *view, bool add) 13 { 14 bool status = true; 15 16 // select the appropriate recipe information 17 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 18 psAssert (recipe, "missing recipe?"); 19 20 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 21 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 22 23 // loop over the available readouts 24 for (int i = 0; i < num; i++) { 25 if (!psphotAddOrSubNoiseReadout (config, view, "PSPHOT.INPUT", i, recipe, add)) { 26 psError (PSPHOT_ERR_CONFIG, false, "failed on to modify noise for PSPHOT.INPUT entry %d", i); 27 return false; 28 } 29 } 30 return true; 31 } 32 33 bool psphotAddOrSubNoiseReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool add) { 12 34 13 35 bool status = false; … … 16 38 psEllipseAxes axes; 17 39 18 PS_ASSERT (readout, false); 19 PS_ASSERT (readout->parent, false); 20 PS_ASSERT (readout->parent->concepts, false); 40 // find the currently selected readout 41 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 42 psAssert (file, "missing file?"); 43 44 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 45 psAssert (readout, "missing readout?"); 46 psAssert (readout->parent, "missing cell?"); 47 psAssert (readout->parent->concepts, "missing concepts?"); 48 49 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 50 psAssert (detections, "missing detections?"); 51 52 psArray *sources = detections->allSources; 53 psAssert (sources, "missing sources?"); 21 54 22 55 psTimerStart ("psphot.noise"); … … 24 57 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 25 58 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 26 assert (maskVal);59 psAssert (maskVal, "missing mask value?"); 27 60 28 61 // increase variance by factor*(object noise): -
branches/tap_branches/psphot/src/psphotApResid.c
r25755 r27838 4 4 // measure the aperture residual statistics and 2D variations 5 5 6 bool psphotApResid (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf) 6 // for now, let's store the detections on the readout->analysis for each readout 7 bool psphotApResid (pmConfig *config, const pmFPAview *view) 8 { 9 bool status = true; 10 11 // select the appropriate recipe information 12 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 13 psAssert (recipe, "missing recipe?"); 14 15 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 16 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 17 18 // skip the chisq image (optionally?) 19 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 20 if (!status) chisqNum = -1; 21 22 // loop over the available readouts 23 for (int i = 0; i < num; i++) { 24 if (i == chisqNum) continue; // skip chisq image 25 if (!psphotApResidReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 26 psError (PSPHOT_ERR_CONFIG, false, "failed to measure aperture residual for PSPHOT.INPUT entry %d", i); 27 return false; 28 } 29 } 30 return true; 31 } 32 33 bool psphotApResidReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) 7 34 { 8 35 int Nfail = 0; … … 13 40 pmSource *source; 14 41 15 PS_ASSERT_PTR_NON_NULL(config, false);16 PS_ASSERT_PTR_NON_NULL(readout, false);17 PS_ASSERT_PTR_NON_NULL(sources, false);18 PS_ASSERT_PTR_NON_NULL(psf, false);19 20 42 psTimerStart ("psphot.apresid"); 21 43 22 // select the appropriate recipe information 23 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 24 assert (recipe); 44 // find the currently selected readout 45 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 46 psAssert (file, "missing file?"); 47 48 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 49 psAssert (readout, "missing readout?"); 50 51 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 52 psAssert (detections, "missing detections?"); 53 54 psArray *sources = detections->allSources; 55 psAssert (sources, "missing sources?"); 56 57 if (!sources->n) { 58 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping ap resid"); 59 return true; 60 } 61 62 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 63 psAssert (psf, "missing psf?"); 25 64 26 65 // determine the number of allowed threads … … 33 72 if (!measureAptrend) { 34 73 // save nan values since these were not calculated 35 psMetadataAdd (re cipe, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", NAN);36 psMetadataAdd (re cipe, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", NAN);37 psMetadataAdd (re cipe, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", 0);38 psMetadataAdd (re cipe, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", NAN);74 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", NAN); 75 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", NAN); 76 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", 0); 77 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", NAN); 39 78 return true; 40 79 } … … 217 256 } 218 257 219 // XXX set the min number of needed source more carefully 220 if ((Npsf < 15) && (APTREND_ORDER_MAX >= 4)) APTREND_ORDER_MAX = 3; 221 if ((Npsf < 11) && (APTREND_ORDER_MAX >= 3)) APTREND_ORDER_MAX = 2; 222 if ((Npsf < 8) && (APTREND_ORDER_MAX >= 2)) APTREND_ORDER_MAX = 1; 258 // this is a bit tricky, because we have two cases (MAP vs POLY), and they have a different 259 // definition for 'order' (order_MAP = order_POLY + 1). in addition, we have a 260 // user-specified MAX order, which we should respect, regardless of the mode 261 262 // set the max order (0 = constant) which the number of psf stars can support: 263 // rule of thumb: require 3 stars per 'cell' (order+1)^2 264 int MaxOrderForStars = 0; 265 if (Npsf >= 12) MaxOrderForStars = 1; // 4 cells 266 if (Npsf >= 27) MaxOrderForStars = 2; // 9 cells 267 if (Npsf >= 48) MaxOrderForStars = 3; // 16 cells 268 if (Npsf > 75) MaxOrderForStars = 4; // 25 cells 269 270 pmTrend2DMode mode = PM_TREND_MAP; 271 if (mode == PM_TREND_MAP) { 272 MaxOrderForStars ++; 273 } 274 APTREND_ORDER_MAX = PS_MIN (APTREND_ORDER_MAX, MaxOrderForStars); 223 275 224 276 psFree (psf->ApTrend); … … 275 327 276 328 // save results for later output 277 psMetadataAdd (re cipe, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", psf->ApResid);278 psMetadataAdd (re cipe, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", psf->dApResid);279 psMetadataAdd (re cipe, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", psf->nApResid);280 psMetadataAdd (re cipe, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", psf->growth->apLoss);329 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", psf->ApResid); 330 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", psf->dApResid); 331 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", psf->nApResid); 332 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", psf->growth->apLoss); 281 333 282 334 psLogMsg ("psphot.apresid", PS_LOG_DETAIL, "aperture residual: %f +/- %f\n", psf->ApResid, psf->dApResid); … … 295 347 escape: 296 348 // save nan values since these were not calculated 297 psMetadataAdd (re cipe, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", NAN);298 psMetadataAdd (re cipe, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", NAN);299 psMetadataAdd (re cipe, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", 0);300 psMetadataAdd (re cipe, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", NAN);349 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", NAN); 350 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", NAN); 351 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", 0); 352 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", NAN); 301 353 302 354 psFree (xPos); … … 305 357 psFree (mag); 306 358 psFree (dMag); 307 return false; 359 return true; 360 // this is a quality error, not a programming error 308 361 } 309 362 -
branches/tap_branches/psphot/src/psphotArguments.c
r24587 r27838 218 218 // override any configuration-specified source for these files 219 219 // 220 pmConfigFileSetsMD (config->arguments, &argc, argv, "MASK", "-mask","-masklist");221 pmConfigFileSetsMD (config->arguments, &argc, argv, "VARIANCE", "-variance", "-variancelist");222 pmConfigFileSetsMD (config->arguments, &argc, argv, "PSPHOT.PSF", "-psf", "-psflist");223 pmConfigFileSetsMD (config->arguments, &argc, argv, "SRC", "-src","-srclist");220 pmConfigFileSetsMD (config->arguments, &argc, argv, "MASK", "-mask", "-masklist"); 221 pmConfigFileSetsMD (config->arguments, &argc, argv, "VARIANCE", "-variance", "-variancelist"); 222 pmConfigFileSetsMD (config->arguments, &argc, argv, "PSPHOT.PSF", "-psf", "-psflist"); 223 pmConfigFileSetsMD (config->arguments, &argc, argv, "SRC", "-src", "-srclist"); 224 224 225 225 if (argc == 1) { … … 228 228 } 229 229 230 if (psArgumentGet(argc, argv, "-help") 231 ||psArgumentGet(argc, argv, "-h"))230 if (psArgumentGet(argc, argv, "-help") || 231 psArgumentGet(argc, argv, "-h")) 232 232 writeHelpInfo(argv[0], config, stdout); 233 233 -
branches/tap_branches/psphot/src/psphotBasicDeblend.c
r20453 r27838 1 1 # include "psphotInternal.h" 2 2 3 bool psphotBasicDeblend (psArray *sources, psMetadata *recipe) { 3 // for now, let's store the detections on the readout->analysis for each readout 4 bool psphotBasicDeblend (pmConfig *config, const pmFPAview *view) 5 { 6 bool status = true; 7 8 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 9 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 10 11 // loop over the available readouts 12 for (int i = 0; i < num; i++) { 13 if (!psphotBasicDeblendReadout (config, view, "PSPHOT.INPUT", i)) { 14 psError (PSPHOT_ERR_CONFIG, false, "failed on basic deblend analysis for PSPHOT.INPUT entry %d", i); 15 return false; 16 } 17 } 18 return true; 19 } 20 21 bool psphotBasicDeblendReadout (pmConfig *config, const pmFPAview *view, const char *filename, int fileIndex) { 4 22 5 23 int N; … … 8 26 pmSource *source, *testSource; 9 27 28 psTimerStart ("psphot.deblend.basic"); 29 10 30 int Nblend = 0; 11 31 12 psTimerStart ("psphot.deblend.basic"); 32 // find the currently selected readout 33 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, fileIndex); // File of interest 34 psAssert (file, "missing file?"); 35 36 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 37 psAssert (readout, "missing readout?"); 38 39 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 40 psAssert (detections, "missing detections?"); 41 42 psArray *sources = detections->newSources; 43 psAssert (sources, "missing sources?"); 44 45 if (!sources->n) { 46 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping basic deblend"); 47 return true; 48 } 49 50 // select the appropriate recipe information 51 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 52 psAssert (recipe, "missing recipe?"); 13 53 14 54 float FRACTION = psMetadataLookupF32 (&status, recipe, "DEBLEND_PEAK_FRACTION"); -
branches/tap_branches/psphot/src/psphotBlendFit.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 // for now, let's store the detections on the readout->analysis for each readout 4 bool psphotBlendFit (pmConfig *config, const pmFPAview *view) 5 { 6 bool status = true; 7 8 // select the appropriate recipe information 9 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 10 psAssert (recipe, "missing recipe?"); 11 12 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 13 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 14 15 // loop over the available readouts 16 for (int i = 0; i < num; i++) { 17 if (!psphotBlendFitReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 18 psError (PSPHOT_ERR_CONFIG, false, "failed to fit sources (non-linear) for PSPHOT.INPUT entry %d", i); 19 return false; 20 } 21 } 22 return true; 23 } 24 3 25 // XXX I don't like this name 4 bool psphotBlendFit (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf) {26 bool psphotBlendFitReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 5 27 6 28 int Nfit = 0; … … 12 34 psTimerStart ("psphot.fit.nonlinear"); 13 35 14 // select the appropriate recipe information 15 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 16 assert (recipe); 36 // find the currently selected readout 37 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 38 psAssert (file, "missing file?"); 39 40 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 41 psAssert (readout, "missing readout?"); 42 43 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 44 psAssert (detections, "missing detections?"); 45 46 psArray *sources = detections->allSources; 47 psAssert (sources, "missing sources?"); 48 49 if (!sources->n) { 50 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping blend fit"); 51 return true; 52 } 53 54 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 55 psAssert (psf, "missing psf?"); 17 56 18 57 // determine the number of allowed threads … … 40 79 psphotInitLimitsPSF (recipe, readout); 41 80 psphotInitLimitsEXT (recipe); 42 psphotInitRadiusPSF (recipe, psf->type);81 psphotInitRadiusPSF (recipe, readout->analysis, psf->type); 43 82 44 83 // starts the timer, sets up the array of fitSets … … 47 86 // source analysis is done in S/N order (brightest first) 48 87 sources = psArraySort (sources, pmSourceSortBySN); 88 if (!sources->n) { 89 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping blend"); 90 return true; 91 } 49 92 50 93 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) … … 272 315 } 273 316 274 # if (0)275 bool psphotBlendFit_Unthreaded (int *nfit, int *npsf, int *next, int *nfail, pmReadout *readout, psMetadata *recipe, psArray *sources, pmPSF *psf, psArray *newSources) {276 277 bool status = false;278 int Nfit = 0;279 int Npsf = 0;280 int Next = 0;281 int Nfail = 0;282 283 // bit-masks to test for good/bad pixels284 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");285 assert (maskVal);286 287 // bit-mask to mark pixels not used in analysis288 psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT");289 assert (markVal);290 291 // maskVal is used to test for rejected pixels, and must include markVal292 maskVal |= markVal;293 294 // S/N limit to perform full non-linear fits295 float FIT_SN_LIM = psMetadataLookupF32 (&status, recipe, "FULL_FIT_SN_LIM");296 297 // option to limit analysis to a specific region298 char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");299 psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));300 if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");301 302 for (int i = 0; i < sources->n; i++) {303 pmSource *source = sources->data[i];304 305 // skip non-astronomical objects (very likely defects)306 if (source->mode & PM_SOURCE_MODE_BLEND) continue;307 if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue;308 if (source->type == PM_SOURCE_TYPE_DEFECT) continue;309 if (source->type == PM_SOURCE_TYPE_SATURATED) continue;310 311 // skip DBL second sources (ie, added by psphotFitBlob)312 if (source->mode & PM_SOURCE_MODE_PAIR) continue;313 314 // limit selection to some SN limit315 if (source->peak->SN < FIT_SN_LIM) continue;316 317 // exclude sources outside optional analysis region318 if (source->peak->xf < AnalysisRegion.x0) continue;319 if (source->peak->yf < AnalysisRegion.y0) continue;320 if (source->peak->xf > AnalysisRegion.x1) continue;321 if (source->peak->yf > AnalysisRegion.y1) continue;322 323 // if model is NULL, we don't have a starting guess324 if (source->modelPSF == NULL) continue;325 326 // skip sources which are insignificant flux?327 // XXX this is somewhat ad-hoc328 if (source->modelPSF->params->data.F32[1] < 0.1) {329 psTrace ("psphot", 5, "skipping near-zero source: %f, %f : %f\n",330 source->modelPSF->params->data.F32[1],331 source->modelPSF->params->data.F32[2],332 source->modelPSF->params->data.F32[3]);333 continue;334 }335 336 // replace object in image337 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {338 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);339 }340 Nfit ++;341 342 // try fitting PSFs or extended sources depending on source->mode343 // these functions subtract the resulting fitted source344 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) {345 if (psphotFitBlob (readout, source, newSources, psf, maskVal, markVal)) {346 source->type = PM_SOURCE_TYPE_EXTENDED;347 psTrace ("psphot", 5, "source at %7.1f, %7.1f is ext", source->peak->xf, source->peak->yf);348 Next ++;349 continue;350 }351 } else {352 if (psphotFitBlend (readout, source, psf, maskVal, markVal)) {353 source->type = PM_SOURCE_TYPE_STAR;354 psTrace ("psphot", 5, "source at %7.1f, %7.1f is psf", source->peak->xf, source->peak->yf);355 Npsf ++;356 continue;357 }358 }359 360 psTrace ("psphot", 5, "source at %7.1f, %7.1f failed", source->peak->xf, source->peak->yf);361 Nfail ++;362 363 // re-subtract the object, leave local sky364 pmSourceCacheModel (source, maskVal);365 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);366 }367 368 // change the value of a scalar on the array (wrap this and put it in psArray.h)369 *nfit = Nfit;370 *npsf = Npsf;371 *next = Next;372 *nfail = Nfail;373 374 // moments are modified by the fit; re-display375 psphotVisualPlotMoments (recipe, sources);376 psphotVisualShowResidualImage (readout);377 378 return true;379 }380 # endif -
branches/tap_branches/psphot/src/psphotChoosePSF.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 // generate a PSF model for inputs without PSF models already loaded 4 bool psphotChoosePSF (pmConfig *config, const pmFPAview *view) 5 { 6 bool status = true; 7 8 // select the appropriate recipe information 9 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 10 psAssert (recipe, "missing recipe?"); 11 12 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 13 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 14 15 // skip the chisq image (optionally?) 16 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 17 if (!status) chisqNum = -1; 18 19 // loop over the available readouts 20 for (int i = 0; i < num; i++) { 21 if (i == chisqNum) continue; // skip chisq image 22 if (!psphotChoosePSFReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 23 psError (PSPHOT_ERR_CONFIG, false, "failed to choose a psf model for PSPHOT.INPUT entry %d", i); 24 return false; 25 } 26 } 27 return true; 28 } 29 3 30 // try PSF models and select best option 4 pmPSF *psphotChoosePSF (pmReadout *readout, psArray *sources, psMetadata *recipe) {31 bool psphotChoosePSFReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 5 32 6 33 bool status; 7 34 8 35 psTimerStart ("psphot.choose.psf"); 36 37 // find the currently selected readout 38 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 39 psAssert (file, "missing file?"); 40 41 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 42 psAssert (readout, "missing readout?"); 43 44 // do not generate a PSF if we already were supplied one 45 if (psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF")) { 46 psLogMsg ("psphot", PS_LOG_DETAIL, "psf model supplied for input file %d", index); 47 return true; 48 } 49 50 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 51 psAssert (detections, "missing detections?"); 52 53 psArray *sources = detections->newSources; 54 psAssert (sources, "missing sources?"); 55 56 if (!sources->n) { 57 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping PSF model"); 58 return false; 59 } 9 60 10 61 // bit-masks to test for good/bad pixels 11 62 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); 12 assert (maskVal);63 psAssert (maskVal, "missing mask value?"); 13 64 14 65 // bit-mask to mark pixels not used in analysis 15 66 psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); 16 assert (markVal);67 psAssert (markVal, "missing mark value?"); 17 68 18 69 // maskVal is used to test for rejected pixels, and must include markVal … … 61 112 // assert (status); 62 113 63 // We have calculated a Gaussian window function, use that for both the PSF fit radius and 64 // the aperture radius (scaling SIGMA) 65 float gaussSigma = psMetadataLookupF32(&status, recipe, "MOMENTS_GAUSS_SIGMA"); 114 // values on readout->analysis if we have calculated a Gaussian window function, use that 115 // for both the PSF fit radius and the aperture radius (scaling SIGMA), otherwise base the value on the recipe value for MOMENTS_GAUSS_SIGMA 116 float gaussSigma = psMetadataLookupF32 (&status, readout->analysis, "MOMENTS_GAUSS_SIGMA"); 117 if (!status) { 118 gaussSigma = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA"); 119 } 66 120 float fitScale = psMetadataLookupF32(&status, recipe, "PSF_FIT_RADIUS_SCALE"); 67 121 float apScale = psMetadataLookupF32(&status, recipe, "PSF_APERTURE_SCALE"); … … 70 124 71 125 // XXX use the same radii for standard analysis as for the PSF creation 72 psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_FIT_RADIUS", PS_META_REPLACE, "fit radius", options->fitRadius); 73 psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_APERTURE", PS_META_REPLACE, "psf aperture", options->apRadius); 74 75 // XXX ROBUST seems to be too agressive given the small numbers. 76 // options->stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 77 options->stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 126 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PSF_FIT_RADIUS", PS_META_REPLACE, "fit radius", options->fitRadius); 127 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PSF_APERTURE", PS_META_REPLACE, "psf aperture", options->apRadius); 78 128 79 129 // dimensions of the field for which the PSF is defined … … 116 166 psLogMsg ("psphot.pspsf", PS_LOG_DETAIL, "selected candidate %ld PSF objects\n", stars->n); 117 167 168 if (stars->n < 50) { 169 // ROBUST is too agressive if we only have a small number of PSF stars 170 options->stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 171 } else { 172 options->stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 173 } 174 118 175 // get the list pointers for the PSF_MODEL entries 119 176 psArray *modelNames = NULL; … … 155 212 bool status = true; 156 213 status &= psphotMakeFluxScale (readout->image, recipe, psf); 157 status &= psphotPSFstats (readout, recipe,psf);214 status &= psphotPSFstats (readout, psf); 158 215 if (!status) { 159 216 psError(PSPHOT_ERR_PSF, false, "Failed to fit any models when choosing PSF"); … … 230 287 bool status = true; 231 288 status &= psphotMakeFluxScale (readout->image, recipe, psf); 232 status &= psphotPSFstats (readout, recipe,psf);289 status &= psphotPSFstats (readout, psf); 233 290 if (!status) { 234 291 psError(PSPHOT_ERR_PSF, false, "Failed to fit any models when choosing PSF"); … … 287 344 psFree (models); 288 345 289 if (!psphotPSFstats (readout, recipe,psf)) {346 if (!psphotPSFstats (readout, psf)) { 290 347 psError(PSPHOT_ERR_PSF, false, "cannot measure PSF shape terms"); 291 348 psFree(options); … … 299 356 300 357 psFree (options); 301 return (psf); 358 359 // save PSF on readout->analysis 360 if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot psf model", psf)) { 361 psError (PSPHOT_ERR_UNKNOWN, false, "problem saving sources on readout"); 362 return false; 363 } 364 psFree (psf); // XXX double-check 365 366 // move into psphotChoosePSF 367 psphotVisualShowPSFModel (readout, psf); 368 369 return true; 302 370 } 303 371 304 372 // measure average parameters of the PSF model 305 bool psphotPSFstats (pmReadout *readout, p sMetadata *recipe, pmPSF *psf) {373 bool psphotPSFstats (pmReadout *readout, pmPSF *psf) { 306 374 307 375 psEllipseShape shape; … … 309 377 310 378 PS_ASSERT_PTR_NON_NULL(readout, false); 311 PS_ASSERT_PTR_NON_NULL(recipe, false);312 379 PS_ASSERT_PTR_NON_NULL(psf, false); 313 380 … … 329 396 pmModel *modelPSF = pmModelFromPSFforXY (psf, xc, yc, 1.0); 330 397 if (!modelPSF) { 331 fprintf (stderr, "?");332 continue;333 }398 fprintf (stderr, "?"); 399 continue; 400 } 334 401 335 402 // get the model full-width at half-max … … 345 412 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major); 346 413 if (!isfinite(FWHM_MAJOR) || !isfinite(FWHM_MINOR)) { 347 fprintf (stderr, "!");348 continue;349 }414 fprintf (stderr, "!"); 415 continue; 416 } 350 417 psVectorAppend (fwhmMajor, FWHM_MAJOR); 351 418 psVectorAppend (fwhmMinor, FWHM_MINOR); … … 359 426 } 360 427 361 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FWHM_MAJ", PS_META_REPLACE, "PSF FWHM Major axis (mean)", stats->sampleMean); 362 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MJ_SG", PS_META_REPLACE, "PSF FWHM Major axis (sigma)", stats->sampleStdev); 363 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MJ_LQ", PS_META_REPLACE, "PSF FWHM Major axis (lower quartile)", stats->sampleLQ); 364 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MJ_UQ", PS_META_REPLACE, "PSF FWHM Major axis (upper quartile)", stats->sampleUQ); 428 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FWHM_MAJ", PS_META_REPLACE, "PSF FWHM Major axis (mean)", stats->sampleMean); 429 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_SG", PS_META_REPLACE, "PSF FWHM Major axis (sigma)", stats->sampleStdev); 430 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_LQ", PS_META_REPLACE, "PSF FWHM Major axis (lower quartile)", stats->sampleLQ); 431 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_UQ", PS_META_REPLACE, "PSF FWHM Major axis (upper quartile)", stats->sampleUQ); 432 433 float fwhmMaj = stats->sampleMean; // FWHM on major axis 365 434 366 435 if (!psVectorStats (stats, fwhmMinor, NULL, NULL, 0)) { … … 368 437 return false; 369 438 } 370 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FWHM_MIN", PS_META_REPLACE, "PSF FWHM Minor axis (mean)", stats->sampleMean); 371 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MN_SG", PS_META_REPLACE, "PSF FWHM Minor axis (sigma)", stats->sampleStdev); 372 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MN_LQ", PS_META_REPLACE, "PSF FWHM Minor axis (lower quartile)", stats->sampleLQ); 373 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MN_UQ", PS_META_REPLACE, "PSF FWHM Minor axis (upper quartile)", stats->sampleUQ); 374 375 psMetadataAddF32 (recipe, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", axes.theta); 376 psMetadataAddS32 (recipe, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", psf->nPSFstars); 377 psMetadataAddBool(recipe, PS_LIST_TAIL, "PSFMODEL", PS_META_REPLACE, "Valid PSF Model?", true); 439 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FWHM_MIN", PS_META_REPLACE, "PSF FWHM Minor axis (mean)", stats->sampleMean); 440 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_SG", PS_META_REPLACE, "PSF FWHM Minor axis (sigma)", stats->sampleStdev); 441 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_LQ", PS_META_REPLACE, "PSF FWHM Minor axis (lower quartile)", stats->sampleLQ); 442 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_UQ", PS_META_REPLACE, "PSF FWHM Minor axis (upper quartile)", stats->sampleUQ); 443 444 float fwhmMin = stats->sampleMean; // FWHM on minor axis 445 if (readout->parent) { 446 pmChip *chip = readout->parent->parent; // Parent chip 447 psAssert(chip, "Cell should be attached to a chip."); 448 psMetadataItem *item = psMetadataLookup(chip->concepts, "CHIP.SEEING"); // Item with chip 449 item->data.F32 = 0.5 * (fwhmMaj + fwhmMin); 450 } 451 452 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", axes.theta); 453 psMetadataAddS32 (readout->analysis, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", psf->nPSFstars); 454 psMetadataAddBool(readout->analysis, PS_LIST_TAIL, "PSFMODEL", PS_META_REPLACE, "Valid PSF Model?", true); 378 455 379 456 psFree (fwhmMajor); … … 384 461 385 462 // determine approximate PSF shape parameters based on the moments 386 bool psphotMomentsStats (pmReadout *readout, ps Metadata *recipe, psArray *sources) {463 bool psphotMomentsStats (pmReadout *readout, psArray *sources) { 387 464 388 465 // without the PSF model, we can only rely on the source->moments … … 398 475 399 476 PS_ASSERT_PTR_NON_NULL(readout, false); 400 PS_ASSERT_PTR_NON_NULL(recipe, false);401 477 PS_ASSERT_PTR_NON_NULL(sources, false); 402 478 … … 426 502 FWHM_T /= FWHM_N; 427 503 428 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FWHM_MAJ", PS_META_REPLACE, "PSF FWHM Major axis (mean)", FWHM_X); 429 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MJ_SG", PS_META_REPLACE, "PSF FWHM Major axis (sigma)", 0); 430 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MJ_LQ", PS_META_REPLACE, "PSF FWHM Major axis (lower quartile)", 0); 431 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MJ_UQ", PS_META_REPLACE, "PSF FWHM Major axis (upper quartile)", 0); 432 433 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FWHM_MIN", PS_META_REPLACE, "PSF FWHM Minor axis (mean)", FWHM_Y); 434 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MN_SG", PS_META_REPLACE, "PSF FWHM Minor axis (sigma)", 0); 435 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MN_LQ", PS_META_REPLACE, "PSF FWHM Minor axis (lower quartile)", 0); 436 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MN_UQ", PS_META_REPLACE, "PSF FWHM Minor axis (upper quartile)", 0); 437 438 psMetadataAddF32 (recipe, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", FWHM_T); 439 psMetadataAddS32 (recipe, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", 0); 440 psMetadataAddBool(recipe, PS_LIST_TAIL, "PSFMODEL", PS_META_REPLACE, "Valid PSF Model?", false); 504 if (readout->parent) { 505 pmChip *chip = readout->parent->parent; // Parent chip 506 psAssert(chip, "Cell should be attached to a chip."); 507 psMetadataItem *item = psMetadataLookup(chip->concepts, "CHIP.SEEING"); // Item with chip 508 item->data.F32 = 0.5 * (FWHM_X + FWHM_Y); 509 } 510 511 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FWHM_MAJ", PS_META_REPLACE, "PSF FWHM Major axis (mean)", FWHM_X); 512 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_SG", PS_META_REPLACE, "PSF FWHM Major axis (sigma)", 0); 513 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_LQ", PS_META_REPLACE, "PSF FWHM Major axis (lower quartile)", 0); 514 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_UQ", PS_META_REPLACE, "PSF FWHM Major axis (upper quartile)", 0); 515 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FWHM_MIN", PS_META_REPLACE, "PSF FWHM Minor axis (mean)", FWHM_Y); 516 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_SG", PS_META_REPLACE, "PSF FWHM Minor axis (sigma)", 0); 517 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_LQ", PS_META_REPLACE, "PSF FWHM Minor axis (lower quartile)", 0); 518 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_UQ", PS_META_REPLACE, "PSF FWHM Minor axis (upper quartile)", 0); 519 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", FWHM_T); 520 psMetadataAddS32 (readout->analysis, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", 0); 521 psMetadataAddBool(readout->analysis, PS_LIST_TAIL, "PSFMODEL", PS_META_REPLACE, "Valid PSF Model?", false); 441 522 442 523 return true; -
branches/tap_branches/psphot/src/psphotCleanup.c
r24144 r27838 14 14 psFree (config); 15 15 16 psThreadPoolFinalize ();17 psTimerStop ();18 16 psMemCheckCorruption (stderr, true); 19 17 pmModelClassCleanup (); 20 psTimeFinalize ();21 18 pmSourceFitSetDone (); 22 19 pmConceptsDone (); -
branches/tap_branches/psphot/src/psphotCullPeaks.c
r24877 r27838 5 5 */ 6 6 psErrorCode 7 psphotCullPeaks(const psImage *image, // the image wherein lives the footprint 8 const psImage *weight, // corresponding variance image 7 psphotCullPeaks(const pmReadout *readout, // the image wherein lives the footprint 9 8 const psMetadata *recipe, 10 9 psArray *footprints) { // array of pmFootprints 10 11 11 bool status = false; 12 12 13 float nsigma_delta = psMetadataLookupF32(&status, recipe, "FOOTPRINT_CULL_NSIGMA_DELTA"); 13 14 if (!status) { … … 22 23 fPadding = 0; 23 24 } 24 const float skyStdev = psMetadataLookupF32(NULL, recipe, "SKY_STDEV"); 25 const float skyStdev = psMetadataLookupF32(&status, readout->analysis, "SKY_STDEV"); 26 psAssert (status, "cannot find SKY_STDEV in readout->analysis"); 27 25 28 const float min_threshold = nsigma_min*skyStdev; 26 29 27 30 for (int i = 0; i < footprints->n; i++) { 31 // if (i % 50 == 0) fprintf (stderr, "cull %d\n", i); 28 32 pmFootprint *fp = footprints->data[i]; 29 if (pmFootprintCullPeaks(image, weight, fp, nsigma_delta, fPadding, min_threshold) != PS_ERR_NONE) { 33 if (fp->npix > 30000) { 34 fprintf (stderr, "big footprint: %f %f to %f %f (%d pix)\n", fp->bbox.x0, fp->bbox.y0, fp->bbox.x1, fp->bbox.y1, fp->npix); 35 } 36 psTimerStart ("psphot.cull.footprints"); 37 if (pmFootprintCullPeaks(readout->image, readout->variance, fp, nsigma_delta, fPadding, min_threshold) != PS_ERR_NONE) { 30 38 return psError(PS_ERR_UNKNOWN, false, "Culling pmFootprint %d", fp->id); 31 39 } 40 float dtime = psTimerMark ("psphot.cull.footprints"); 41 if (dtime > 1.0) { 42 fprintf (stderr, "slow cull for %d (%f sec)\n", i, dtime); 43 } 32 44 } 33 34 45 return PS_ERR_NONE; 35 46 } 47 48 // psLogMsg ("psphot", PS_LOG_INFO, "%ld peaks, %ld total footprints: %f sec\n", detections->peaks->n, detections->footprints->n, -
branches/tap_branches/psphot/src/psphotDeblendSatstars.c
r25885 r27838 1 1 # include "psphotInternal.h" 2 2 3 bool psphotDeblendSatstars (pmReadout *readout, psArray *sources, psMetadata *recipe) { 3 // for now, let's store the detections on the readout->analysis for each readout 4 bool psphotDeblendSatstars (pmConfig *config, const pmFPAview *view) 5 { 6 bool status = true; 7 8 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 9 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 10 11 // loop over the available readouts 12 for (int i = 0; i < num; i++) { 13 if (!psphotDeblendSatstarsReadout (config, view, "PSPHOT.INPUT", i)) { 14 psError (PSPHOT_ERR_CONFIG, false, "failed on saturated star deblend analysis for PSPHOT.INPUT entry %d", i); 15 return false; 16 } 17 } 18 return true; 19 } 20 21 bool psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int fileIndex) { 4 22 5 23 int N; 6 24 pmSource *source; 25 bool status; 7 26 8 27 psTimerStart ("psphot.deblend.sat"); … … 11 30 float SAT_MIN_RADIUS = 5.0; 12 31 13 bool status; 32 // find the currently selected readout 33 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, fileIndex); // File of interest 34 psAssert (file, "missing file?"); 35 36 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 37 psAssert (readout, "missing readout?"); 38 39 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 40 psAssert (detections, "missing detections?"); 41 42 psArray *sources = detections->newSources; 43 psAssert (sources, "missing sources?"); 44 45 if (!sources->n) { 46 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping satstar blend"); 47 return true; 48 } 49 50 // select the appropriate recipe information 51 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 52 psAssert (recipe, "missing recipe?"); 53 14 54 pmCell *cell = readout->parent; 15 55 float SATURATION = 0.75*psMetadataLookupF32 (&status, cell->concepts, "CELL.SATURATION"); -
branches/tap_branches/psphot/src/psphotDefineFiles.c
r23688 r27838 126 126 } 127 127 128 if (psMetadataLookupPtr(NULL, config->arguments, "SRCTEXT")) { 129 // XXX cannot use pmFPAfileDefineFromArgs: this is explicitly a FITS-based I/O function 130 // supply the attach the 131 if (!psphotLoadSRCTEXT(input->fpa, config)) { 132 psError(PSPHOT_ERR_CONFIG, false, "Failed to load PSPHOT.INPUT.TEXT"); 133 return status; 134 } 135 } 136 128 137 if (psMetadataLookupPtr(NULL, config->arguments, "PSPHOT.PSF")) { 129 138 pmFPAfileBindFromArgs(&status, input, config, "PSPHOT.PSF.LOAD", "PSPHOT.PSF"); -
branches/tap_branches/psphot/src/psphotEfficiency.c
- Property svn:mergeinfo deleted
r25890 r27838 4 4 PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models 5 5 6 //#define TESTING 7 6 # define TESTING 0 8 7 9 8 // Calculate the limiting magnitude for an image … … 17 16 float *covarFactor,// Covariance factor 18 17 const pmReadout *ro, // Readout of interest 19 const pmPSF *psf,// Point-spread function18 pmPSF *psf, // Point-spread function 20 19 float thresh, // Threshold for source identification 21 20 float smoothSigma, // Gaussian smoothing sigma … … 33 32 34 33 psKernel *kernel = psImageSmoothKernel(smoothSigma, smoothNsigma); // Kernel used for smoothing 35 psKernel *newCovar = psImageCovarianceCalculate(kernel, ro->covariance); // Covariance matrix34 *covarFactor = psImageCovarianceCalculateFactor(kernel, ro->covariance); 36 35 psFree(kernel); 37 *covarFactor = psImageCovarianceFactor(newCovar); // Variance factor38 psFree(newCovar);39 36 40 37 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); // Statistics for variance … … 128 125 psFree(rng); 129 126 127 bool oldThreads = pmReadoutFakeThreads(true); // Old threading status 128 130 129 pmReadout *fakeRO = pmReadoutAlloc(NULL); // Fake readout 131 130 if (!pmReadoutFakeFromVectors(fakeRO, numCols, numRows, xAll, yAll, magAll, … … 142 141 psFree(yAll); 143 142 143 pmReadoutFakeThreads(oldThreads); 144 144 145 psBinaryOp(ro->image, ro->image, "+", fakeRO->image); 145 146 psFree(fakeRO); … … 148 149 } 149 150 151 bool psphotEfficiency (pmConfig *config, const pmFPAview *view) 152 { 153 bool status = true; 154 155 // select the appropriate recipe information 156 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 157 psAssert (recipe, "missing recipe?"); 158 159 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 160 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 161 162 // skip the chisq image (optionally?) 163 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 164 if (!status) chisqNum = -1; 165 166 // loop over the available readouts 167 for (int i = 0; i < num; i++) { 168 if (i == chisqNum) continue; // skip chisq image 169 if (!psphotEfficiencyReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 170 psError (PSPHOT_ERR_CONFIG, false, "failed to measure detection efficiency for PSPHOT.INPUT entry %d", i); 171 return false; 172 } 173 } 174 return true; 175 } 150 176 151 177 // Determine detection efficiency 152 bool psphotEfficiency(pmConfig *config, pmReadout *readout, const pmFPAview *view, const pmPSF *psf, 153 psMetadata *recipe, const psArray *realSources) 178 bool psphotEfficiencyReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) 154 179 { 180 bool status = true; 181 182 psTimerStart("psphot.fake"); 183 184 // find the currently selected readout 185 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 186 psAssert (file, "missing file?"); 187 188 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 189 psAssert (readout, "missing readout?"); 190 191 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 192 psAssert (detections, "missing detections?"); 193 194 psArray *realSources = detections->allSources; 195 psAssert (realSources, "missing sources?"); 196 197 // XXX do we need to skip this step if we do not have a psf? 198 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 199 psAssert (psf, "missing psf?"); 200 155 201 PM_ASSERT_READOUT_NON_NULL(readout, false); 156 202 PM_ASSERT_READOUT_IMAGE(readout, false); 157 203 PS_ASSERT_PTR_NON_NULL(psf, false); 158 204 PS_ASSERT_METADATA_NON_NULL(recipe, false); 159 PS_ASSERT_ARRAY_NON_NULL(realSources, false);160 161 psTimerStart("psphot.fake");162 205 163 206 // Collect recipe information 164 float fwhmMajor = psMetadataLookupF32(NULL, recipe, "FWHM_MAJ"); // PSF size in x 165 float fwhmMinor = psMetadataLookupF32(NULL, recipe, "FWHM_MIN"); // PSF size in y 207 float smoothNsigma = psMetadataLookupF32(&status, recipe, "PEAKS_SMOOTH_NSIGMA"); // Smoothing limit 208 psAssert (status && isfinite(smoothNsigma), "Unable to find PEAKS_SMOOTH_NSIGMA in recipe (or invalid value)"); 209 210 float thresh = psMetadataLookupF32(&status, recipe, "PEAKS_NSIGMA_LIMIT_2"); 211 psAssert (status && isfinite(thresh), "Unable to find PEAKS_NSIGMA_LIMIT_2 in recipe (or invalid value)"); 212 213 psVector *magOffsets = psMetadataLookupVector(&status, recipe, "EFF.MAG"); // Magnitude offsets 214 psAssert (status, "Unable to find EFF.MAG F32 vector in recipe"); 215 psAssert (magOffsets->type.type == PS_TYPE_F32, "Unable to find EFF.MAG F32 vector in recipe"); 216 217 int numSources = psMetadataLookupS32(&status, recipe, "EFF.NUM"); // Number of sources for each bin 218 psAssert (status && (numSources > 0), "Unable to find EFF.NUM in recipe (or invalid value)"); 219 220 float minGauss = psMetadataLookupF32(&status, recipe, "PEAKS_MIN_GAUSS"); // Minimum valid fraction of kernel 221 psAssert (status && isfinite(minGauss), "PEAKS_MIN_GAUSS is not set in recipe (or invalid)"); 222 223 // find the PSF size information (why is this not part of the psf structure?) 224 float fwhmMajor = psMetadataLookupF32(NULL, readout->analysis, "FWHM_MAJ"); // PSF size in x 225 float fwhmMinor = psMetadataLookupF32(NULL, readout->analysis, "FWHM_MIN"); // PSF size in y 166 226 if (!isfinite(fwhmMajor) || !isfinite(fwhmMinor) || fwhmMajor == 0.0 || fwhmMinor == 0.0) { 167 psError(PSPHOT_ERR_CONFIG, false, "Unable to find FWHM_MAJ and FWHM_MIN in recipe"); 168 return false; 169 } 170 float smoothNsigma = psMetadataLookupF32(NULL, recipe, "PEAKS_SMOOTH_NSIGMA"); // Smoothing limit 171 if (!isfinite(smoothNsigma)) { 172 psError(PSPHOT_ERR_CONFIG, false, "Unable to find PEAKS_SMOOTH_NSIGMA in recipe"); 173 return false; 174 } 175 float thresh = psMetadataLookupF32(NULL, recipe, "PEAKS_NSIGMA_LIMIT_2"); 176 if (!isfinite(thresh)) { 177 psError(PSPHOT_ERR_CONFIG, false, "Unable to find PEAKS_NSIGMA_LIMIT_2 in recipe"); 178 return false; 179 } 180 psVector *magOffsets = psMetadataLookupVector(NULL, recipe, "EFF.MAG"); // Magnitude offsets 181 if (!magOffsets || magOffsets->type.type != PS_TYPE_F32) { 182 psError(PSPHOT_ERR_CONFIG, false, "Unable to find EFF.MAG F32 vector in recipe"); 183 return NULL; 184 } 185 int numSources = psMetadataLookupS32(NULL, recipe, "EFF.NUM"); // Number of sources for each bin 186 if (numSources == 0) { 187 psError(PSPHOT_ERR_CONFIG, false, "Unable to find EFF.NUM in recipe"); 188 return NULL; 189 } 190 float minGauss = psMetadataLookupF32(NULL, recipe, "PEAKS_MIN_GAUSS"); // Minimum valid fraction of kernel 191 if (!isfinite(minGauss)) { 192 psWarning("PEAKS_MIN_GAUSS is not set in recipe; using default value"); 193 minGauss = 0.5; 227 psError(PSPHOT_ERR_CONFIG, false, "Unable to find FWHM_MAJ and FWHM_MIN in readout->analysis"); 228 return false; 194 229 } 195 230 … … 202 237 // remove all sources, adding noise for subtracted sources 203 238 psphotRemoveAllSources(realSources, recipe); 204 // psphotAddNoise(readout, realSources, recipe); 205 206 207 #if defined(TESTING) && 0 239 240 #if TESTING 208 241 { 209 242 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); … … 234 267 } 235 268 236 #if defTESTING269 #if TESTING 237 270 psphotSaveImage(NULL, readout->image, "orig_image.fits"); 238 271 psphotSaveImage(NULL, readout->variance, "orig_variance.fits"); … … 249 282 } 250 283 251 #if defTESTING284 #if TESTING 252 285 psphotSaveImage(NULL, readout->image, "fake_image.fits"); 253 286 psphotSaveImage(NULL, readout->variance, "fake_variance.fits"); … … 364 397 psFree(significance); 365 398 366 if (!psphotFitSourcesLinear (readout, fakeSourcesAll, recipe, psf, true)) {399 if (!psphotFitSourcesLinearReadout(recipe, readout, fakeSourcesAll, psf, true)) { 367 400 psError(PS_ERR_UNKNOWN, false, "Unable to perform linear fit on fake sources."); 368 401 psFree(fakeSources); … … 371 404 } 372 405 373 // Disable aperture corrections ; casting away const!406 // Disable aperture corrections (save current value) 374 407 pmTrend2D *apTrend = psf->ApTrend; // Aperture trend 375 ((pmPSF*)psf)->ApTrend = NULL;376 377 if (!psphotMagnitudes (config, readout, view, fakeSourcesAll, psf)) {408 psf->ApTrend = NULL; 409 410 if (!psphotMagnitudesReadout(config, recipe, view, readout, fakeSourcesAll, psf)) { 378 411 psError(PS_ERR_UNKNOWN, false, "Unable to measure magnitudes of fake sources."); 379 412 psFree(fakeSources); 380 413 psFree(count); 381 ((pmPSF*)psf)->ApTrend = apTrend; // Casting away const!414 psf->ApTrend = apTrend; // Casting away const! 382 415 return false; 383 416 } 384 417 psFree(fakeSourcesAll); 385 418 386 // Re -enable aperture corrections; casting away const!387 ((pmPSF*)psf)->ApTrend = apTrend;419 // Replace aperture corrections 420 psf->ApTrend = apTrend; 388 421 389 422 psVector *magDiffMean = psVectorAlloc(numBins, PS_TYPE_F32); // Mean difference in magnitude for each bin … … 399 432 psVectorInit(magMask, 0); 400 433 401 #if defTESTING434 #if TESTING 402 435 psString name = NULL; 403 436 psStringAppend(&name, "fake_%d.dat", i); … … 415 448 } 416 449 417 #if defTESTING450 #if TESTING 418 451 fprintf(file, "%f %f %f %f %f %f %f\n", source->peak->xf, source->peak->yf, 419 452 source->modelPSF->params->data.F32[PM_PAR_XPOS], … … 451 484 } 452 485 453 #if defTESTING486 #if TESTING 454 487 fclose(file); 455 488 #endif … … 476 509 psLogMsg("psphot", PS_LOG_INFO, "Detection efficiency: %lf sec\n", psTimerClear("psphot.fake")); 477 510 478 479 511 return true; 480 512 } -
branches/tap_branches/psphot/src/psphotEllipticalContour.c
r25755 r27838 7 7 bool psphotEllipticalContour (pmSource *source) { 8 8 9 pmSourceRadialProfile *profile = source->extpars->profile; 9 psAssert (source, "missing source"); 10 psAssert (source->extpars, "missing extpars"); 11 psAssert (source->extpars->radFlux, "missing radFlux"); 12 13 pmSourceRadialFlux *profile = source->extpars->radFlux; 14 pmSourceExtendedPars *extpars = source->extpars; 10 15 11 16 // use LMM to fit theta vs radius to an ellipse … … 85 90 /// XXX rationalize? if epsilon > 1, flip major and minor axes (rotate by 90 degrees) 86 91 if (params->data.F32[PAR_EPSILON] < 1.0) { 87 profile->axes.major = params->data.F32[PAR_RMIN] / params->data.F32[PAR_EPSILON];88 profile->axes.minor = params->data.F32[PAR_RMIN];89 profile->axes.theta = params->data.F32[PAR_PHI];92 extpars->axes.major = params->data.F32[PAR_RMIN] / params->data.F32[PAR_EPSILON]; 93 extpars->axes.minor = params->data.F32[PAR_RMIN]; 94 extpars->axes.theta = params->data.F32[PAR_PHI]; 90 95 } else { 91 profile->axes.major = params->data.F32[PAR_RMIN];92 profile->axes.minor = params->data.F32[PAR_RMIN] / params->data.F32[PAR_EPSILON];93 profile->axes.theta = params->data.F32[PAR_PHI] + 0.5*M_PI;96 extpars->axes.major = params->data.F32[PAR_RMIN]; 97 extpars->axes.minor = params->data.F32[PAR_RMIN] / params->data.F32[PAR_EPSILON]; 98 extpars->axes.theta = params->data.F32[PAR_PHI] + 0.5*M_PI; 94 99 } 95 100 96 101 psTrace ("psphot", 4, "# fitted values:\n"); 97 psTrace ("psphot", 4, "Phi: %f\n", profile->axes.theta*PS_DEG_RAD);98 psTrace ("psphot", 4, "Rmaj: %f\n", profile->axes.major);99 psTrace ("psphot", 4, "Rmin: %f\n", profile->axes.minor);102 psTrace ("psphot", 4, "Phi: %f\n", extpars->axes.theta*PS_DEG_RAD); 103 psTrace ("psphot", 4, "Rmaj: %f\n", extpars->axes.major); 104 psTrace ("psphot", 4, "Rmin: %f\n", extpars->axes.minor); 100 105 101 106 // show the results 102 // psphotPetrosianVisualEllipticalContour (p etrosian);107 // psphotPetrosianVisualEllipticalContour (profile, extpars); 103 108 104 109 psFree (x); -
branches/tap_branches/psphot/src/psphotEllipticalProfile.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 bool psphotEllipticalProfile (pmSource *source ) {3 bool psphotEllipticalProfile (pmSource *source, bool RAW_RADIUS) { 4 4 5 pmSourceRadialProfile *profile = source->extpars->profile; 5 psAssert (source, "missing source"); 6 psAssert (source->extpars, "missing extpars"); 7 psAssert (source->pixels, "missing pixels"); 8 9 pmSourceExtendedPars *extpars = source->extpars; 10 11 if (!source->extpars->ellipticalFlux) { 12 source->extpars->ellipticalFlux = pmSourceEllipticalFluxAlloc(); 13 } 14 pmSourceEllipticalFlux *profile = source->extpars->ellipticalFlux; 6 15 7 16 profile->radiusElliptical = psVectorAllocEmpty(100, PS_TYPE_F32); … … 21 30 22 31 psEllipseAxes axes; 23 axes.major = M_SQRT1_2; 24 axes.minor = M_SQRT1_2 * (profile->axes.minor / profile->axes.major); 32 if (RAW_RADIUS) { 33 // force circular profile 34 axes.major = M_SQRT1_2; 35 axes.minor = M_SQRT1_2; 36 } else { 37 axes.major = M_SQRT1_2; 38 axes.minor = M_SQRT1_2 * (extpars->axes.minor / extpars->axes.major); 39 } 25 40 26 41 // axes.major = 1.0; 27 // axes.minor = profile->axes.minor / profile->axes.major;42 // axes.minor = extpars->axes.minor / extpars->axes.major; 28 43 29 axes.theta = profile->axes.theta;44 axes.theta = extpars->axes.theta; 30 45 psEllipseShape shape = psEllipseAxesToShape (axes); 31 46 … … 46 61 47 62 float r2 = 0.5*PS_SQR(x/Sxx) + 0.5*PS_SQR(y/Syy) + x*y*Sxy; 63 float Rraw = hypot(x, y); 48 64 49 65 psVectorAppend(radius, sqrt(r2)); 50 66 psVectorAppend(flux, source->pixels->data.F32[iy][ix]); 51 67 52 float Rraw = hypot(x, y);53 68 psVectorAppend(radiusRaw, Rraw); 54 69 psVectorAppend(fluxRaw, source->pixels->data.F32[iy][ix]); … … 67 82 // } 68 83 69 // psphotPetrosianVisualProfileRadii (radius, flux, radiusRaw, fluxRaw, 0.0);84 psphotPetrosianVisualProfileRadii (radius, flux, radiusRaw, fluxRaw, source->peak->flux, 0.0); 70 85 // psphotPetrosianVisualProfileByAngle (radius, flux); 71 86 -
branches/tap_branches/psphot/src/psphotErrorCodes.dat
r11308 r27838 2 2 # This file is used to generate psphotErrorClasses.h 3 3 # 4 BASE = 3000 First value we use 4 5 UNKNOWN Unknown PM error code 5 6 NOT_IMPLEMENTED Desired feature is not yet implemented -
branches/tap_branches/psphot/src/psphotExtendedSourceAnalysis.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 // for now, let's store the detections on the readout->analysis for each readout 4 bool psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view) 5 { 6 bool status = true; 7 8 // select the appropriate recipe information 9 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 10 psAssert (recipe, "missing recipe?"); 11 12 // perform full non-linear fits / extended source analysis? 13 if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANALYSIS")) { 14 psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n"); 15 return true; 16 } 17 18 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 19 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 20 21 // loop over the available readouts 22 for (int i = 0; i < num; i++) { 23 if (!psphotExtendedSourceAnalysisReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 24 psError (PSPHOT_ERR_CONFIG, false, "failed on measure extended source aperture-like parameters for PSPHOT.INPUT entry %d", i); 25 return false; 26 } 27 } 28 return true; 29 } 30 3 31 // aperture-like measurements for extended sources 4 bool psphotExtendedSourceAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe) {32 bool psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 5 33 6 34 bool status; … … 11 39 int Nkron = 0; 12 40 41 psTimerStart ("psphot.extended"); 42 43 // find the currently selected readout 44 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 45 psAssert (file, "missing file?"); 46 47 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 48 psAssert (readout, "missing readout?"); 49 50 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 51 psAssert (detections, "missing detections?"); 52 53 psArray *sources = detections->allSources; 54 psAssert (sources, "missing sources?"); 55 56 if (!sources->n) { 57 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size"); 58 return true; 59 } 60 13 61 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 14 62 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 15 63 assert (maskVal); 16 17 // perform full non-linear fits / extended source analysis?18 if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANALYSIS")) {19 psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");20 return true;21 }22 64 23 65 // XXX require petrosian analysis for non-linear fits? … … 25 67 // XXX temporary user-supplied systematic sky noise measurement (derive from background model) 26 68 float skynoise = psMetadataLookupF32 (&status, recipe, "SKY.NOISE"); 27 28 # if (0)29 // if backModel or backStdev are missing, the values of sky and/or skyErr will be set to NAN30 // XXX use this to set skynoise31 pmReadout *backModel = psphotSelectBackground (config, view);32 pmReadout *backStdev = psphotSelectBackgroundStdev (config, view);33 # endif34 69 35 70 // S/N limit to perform full non-linear fits … … 41 76 bool doAnnuli = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI"); 42 77 bool doKron = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_KRON"); 78 79 # if (0) 80 // if backModel or backStdev are missing, the values of sky and/or skyErr will be set to NAN 81 // XXX use this to set skynoise 82 pmReadout *backModel = psphotSelectBackground (config, view); 83 pmReadout *backStdev = psphotSelectBackgroundStdev (config, view); 84 # endif 43 85 44 86 // source analysis is done in S/N order (brightest first) … … 79 121 Next ++; 80 122 123 // force source image to be a bit larger... 124 float radius = source->peak->xf - source->pixels->col0; 125 radius = PS_MAX (radius, source->peak->yf - source->pixels->row0); 126 radius = PS_MAX (radius, source->pixels->numRows - source->peak->yf + source->pixels->row0); 127 radius = PS_MAX (radius, source->pixels->numCols - source->peak->xf + source->pixels->col0); 128 pmSourceRedefinePixels (source, readout, source->peak->xf, source->peak->yf, 1.5*radius); 129 81 130 // if we request any of these measurements, we require the radial profile 82 131 if (doPetrosian || doIsophotal || doAnnuli || doKron) { … … 94 143 if (doPetrosian) { 95 144 if (!psphotPetrosian (source, recipe, skynoise, maskVal)) { 96 psTrace ("psphot", 5, " measuredpetrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);145 psTrace ("psphot", 5, "FAILED petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); 97 146 } else { 98 147 psTrace ("psphot", 5, "measured petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); … … 129 178 130 179 if (source->extpars) { 131 pmSourceRadialProfileFreeVectors(source->extpars->profile); 180 psFree(source->extpars->radFlux); 181 psFree(source->extpars->ellipticalFlux); 132 182 } 133 183 } 134 184 135 psLogMsg ("psphot", PS_LOG_INFO, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot "), Next);185 psLogMsg ("psphot", PS_LOG_INFO, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next); 136 186 psLogMsg ("psphot", PS_LOG_INFO, " %d petrosian\n", Npetro); 137 187 psLogMsg ("psphot", PS_LOG_INFO, " %d isophotal\n", Nisophot); -
branches/tap_branches/psphot/src/psphotExtendedSourceFits.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 // for now, let's store the detections on the readout->analysis for each readout 4 bool psphotExtendedSourceFits (pmConfig *config, const pmFPAview *view) 5 { 6 bool status = true; 7 8 // select the appropriate recipe information 9 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 10 psAssert (recipe, "missing recipe?"); 11 12 // perform full extended source non-linear fits? 13 if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS")) { 14 psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n"); 15 return true; 16 } 17 18 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 19 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 20 21 // loop over the available readouts 22 for (int i = 0; i < num; i++) { 23 if (!psphotExtendedSourceFitsReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 24 psError (PSPHOT_ERR_CONFIG, false, "failed on to fit extended sources for PSPHOT.INPUT entry %d", i); 25 return false; 26 } 27 } 28 return true; 29 } 30 3 31 // non-linear model fitting for extended sources 4 bool psphotExtendedSourceFits (pmReadout *readout, psArray *sources, psMetadata *recipe) {32 bool psphotExtendedSourceFitsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 5 33 6 34 bool status; … … 12 40 bool savePics = false; 13 41 42 // find the currently selected readout 43 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 44 psAssert (file, "missing file?"); 45 46 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 47 psAssert (readout, "missing readout?"); 48 49 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 50 psAssert (detections, "missing detections?"); 51 52 psArray *sources = detections->allSources; 53 psAssert (sources, "missing sources?"); 54 55 if (!sources->n) { 56 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size"); 57 return true; 58 } 59 14 60 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 15 61 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels … … 21 67 // maskVal is used to test for rejected pixels, and must include markVal 22 68 maskVal |= markVal; 23 24 // perform full extended source non-linear fits?25 if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS")) {26 psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");27 return true;28 }29 69 30 70 // select the collection of desired models -
branches/tap_branches/psphot/src/psphotFake.c
- Property svn:mergeinfo deleted
r25890 r27838 28 28 float smoothSigma = 0.5*(FWHM_X + FWHM_Y) / (2.0*sqrtf(2.0*log(2.0))); 29 29 psKernel *kernel = psImageSmoothKernel(smoothSigma, smoothNsigma); // Kernel used for smoothing 30 psKernel *newCovar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix30 float factor = psImageCovarianceCalculateFactor(kernel, readout->covariance); // Covariance matrix 31 31 psFree(kernel); 32 float factor = psImageCovarianceFactor(newCovar); // Variance factor33 psFree(newCovar);34 32 35 33 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); // Statistics for variance … … 213 211 214 212 // Putting results on recipe because that appears to be the psphot standard, but it's not a good idea 215 psMetadataAddVector(recipe, PS_LIST_TAIL, "FAKE.EFF", PS_META_REPLACE, 216 "Efficiency fractions", frac); 217 psMetadataAddVector(recipe, PS_LIST_TAIL, "FAKE.MAG", PS_META_REPLACE, 218 "Efficiency magnitudes", magOffsets); 219 psMetadataAddF32(recipe, PS_LIST_TAIL, "FAKE.REF", PS_META_REPLACE, 220 "Efficiency reference magnitude", magLim); 213 psMetadataAddVector(readout->analysis, PS_LIST_TAIL, "FAKE.EFF", PS_META_REPLACE, "Efficiency fractions", frac); 214 psMetadataAddVector(readout->analysis, PS_LIST_TAIL, "FAKE.MAG", PS_META_REPLACE, "Efficiency magnitudes", magOffsets); 215 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "FAKE.REF", PS_META_REPLACE, "Efficiency reference magnitude", magLim); 221 216 222 217 psFree(frac); -
branches/tap_branches/psphot/src/psphotFindDetections.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 // we store the detections on the readout->analysis for each readout this function finds new 4 // peaks and new footprints. any old peaks are saved on oldPeaks. the resulting footprint set 5 // contains all footprints (old and new) 6 bool psphotFindDetections (pmConfig *config, const pmFPAview *view, bool firstPass) 7 { 8 bool status = true; 9 10 // select the appropriate recipe information 11 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 12 psAssert (recipe, "missing recipe?"); 13 14 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 15 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 16 17 // loop over the available readouts 18 for (int i = 0; i < num; i++) { 19 if (!psphotFindDetectionsReadout (config, view, "PSPHOT.INPUT", i, recipe, firstPass)) { 20 psError (PSPHOT_ERR_CONFIG, false, "failed to find initial detections for PSPHOT.INPUT entry %d", i); 21 return false; 22 } 23 } 24 return true; 25 } 26 3 27 // smooth the image, search for peaks, optionally define footprints based on the peaks 4 pmDetections *psphotFindDetections (pmDetections *detections, pmReadout *readout, psMetadata *recipe) {28 bool psphotFindDetectionsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool firstPass) { 5 29 6 30 bool status; … … 9 33 int NMAX = 0; 10 34 35 // find the currently selected readout 36 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 37 psAssert (file, "missing file?"); 38 39 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 40 psAssert (readout, "missing readout?"); 41 11 42 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 12 43 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 13 assert (maskVal);44 psAssert (maskVal, "missing mask value?"); 14 45 15 46 // Use the new pmFootprints approach? 16 47 const bool useFootprints = psMetadataLookupBool(NULL, recipe, "USE_FOOTPRINTS"); 17 48 18 // on first pass, detections have not yet been allocated 49 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 50 // on the initial pass, detections have not yet been allocated or saved on readout->analysis 19 51 if (!detections) { 52 // create the container 20 53 detections = pmDetectionsAlloc(); 54 55 // save detections on the readout->analysis 56 if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot detections", detections)) { 57 psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout"); 58 return false; 59 } 60 } else { 61 psMemIncrRefCounter(detections); // so we can free the detections below 62 } 63 64 if (firstPass) { 21 65 pass = 1; 22 66 NSIGMA_PEAK = psMetadataLookupF32 (&status, recipe, "PEAKS_NSIGMA_LIMIT"); PS_ASSERT (status, NULL); … … 30 74 float threshold = PS_SQR(NSIGMA_PEAK); 31 75 32 // move the old peaks array (if it exists) to oldPeaks 33 // XXX generically, we should be able to call this function an arbitrary number of times 76 // move the old peaks array (if it exists) to oldPeaks XXX generically, we should be able 77 // to call this function an arbitrary number of times the old peaks are saved so they can 78 // be freed later -- the have to be freed after psphotFindFootprints is called below, since 79 // they are also owned by the oldFootprints, which are in turn merged into the new 80 // footprints. (what about the source->peak entry?) 81 34 82 assert (detections->oldPeaks == NULL); 35 83 detections->oldPeaks = detections->peaks; … … 39 87 psImage *significance = psphotSignificanceImage (readout, recipe, pass, maskVal); 40 88 41 // display the backsub and backgnd images 42 psphotVisualShowSignificance (significance); 89 // display the significance image 90 psphotVisualShowSignificance (significance, -1.0, PS_SQR(3.0*NSIGMA_PEAK)); 91 92 // XXX getting some strange results from significance image 93 if (0) { 94 psImage *lsig = (psImage *) psUnaryOp (NULL, significance, "log"); 95 psphotVisualShowSignificance (lsig, 0.0, 4.0); 96 psFree (lsig); 97 } 43 98 44 99 // detect the peaks in the significance image 45 100 detections->peaks = psphotFindPeaks (significance, readout, recipe, threshold, NMAX); 46 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "PEAK_THRESHOLD", PS_META_REPLACE, "Peak Detection Threshold", threshold);101 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "PEAK_THRESHOLD", PS_META_REPLACE, "Peak Detection Threshold", threshold); 47 102 if (!detections->peaks) { 48 // No peaks found 49 return NULL; 103 // we only get a NULL peaks array due to a programming or config error. 104 // this will result in a failure. 105 psFree (detections); 106 psError (PSPHOT_ERR_CONFIG, false, "failed on peak search"); 107 return false; 50 108 } 51 109 52 110 // optionally merge peaks into footprints 53 111 if (useFootprints) { 54 psphotFindFootprints (detections, significance, readout, recipe, threshold, pass, maskVal);112 psphotFindFootprints (detections, significance, readout, recipe, threshold, pass, maskVal); 55 113 } 56 114 … … 61 119 psphotVisualShowFootprints (detections); 62 120 63 return detections; 121 psFree (detections); 122 123 return true; 64 124 } 65 125 -
branches/tap_branches/psphot/src/psphotFindFootprints.c
r25755 r27838 41 41 if (pass == 2) { 42 42 // merge in old peaks; 43 const int includePeaks = 0x0 | 0x2; // i.e. just from newFootprints 44 45 // XXX EAM : still not sure I understand this: are we double-couning or undercounting peaks 43 const int includePeaks = 0x1 | 0x2; // i.e. both new and old footprints 46 44 47 45 psArray *mergedFootprints = pmFootprintArraysMerge(detections->footprints, footprints, includePeaks); … … 50 48 psFree(footprints); 51 49 psFree(detections->footprints); 50 51 // replace the merged footprints on the detection structure 52 52 detections->footprints = mergedFootprints; 53 53 } else { … … 55 55 } 56 56 57 psphotCullPeaks(readout ->image, readout->variance, recipe, detections->footprints);57 psphotCullPeaks(readout, recipe, detections->footprints); 58 58 detections->peaks = pmFootprintArrayToPeaks(detections->footprints); 59 59 psLogMsg ("psphot", PS_LOG_INFO, "%ld peaks, %ld total footprints: %f sec\n", detections->peaks->n, detections->footprints->n, psTimerMark ("psphot.footprints")); … … 61 61 return detections; 62 62 } 63 64 bool psphotCheckFootprints (pmDetections *detections) { 65 66 // check for messed up footprints in the old peaks 67 for (int i = 0; i < detections->oldPeaks->n; i++) { 68 pmPeak *peak = detections->oldPeaks->data[i]; 69 pmFootprint *footprint = peak->footprint; 70 if (!footprint) continue; 71 for (int j = 0; j < footprint->spans->n; j++) { 72 pmSpan *sp = footprint->spans->data[j]; 73 psAssert (sp, "missing span"); 74 } 75 } 76 return true; 77 } -
branches/tap_branches/psphot/src/psphotFindPeaks.c
r25755 r27838 13 13 psArray *peaks = pmPeaksInImage (significance, threshold); 14 14 if (peaks == NULL) { 15 // XXX should we be sending back an empty array instead of NULL? 16 // XXX this may also be due to a programming or config error 15 // we only get a NULL peaks array due to a programming or config error. 16 // this will result in a failure. 17 psError(PSPHOT_ERR_DATA, false, "no peaks found in this image"); 18 return NULL; 19 } 20 21 if (peaks->n == 0) { 17 22 // XXX do we need to set something in the readout->analysis to indicate that 18 23 // we tried and failed to find peaks (something in the header data) 19 psError(PSPHOT_ERR_DATA, false, "no peaks found in this image");20 return false;24 psLogMsg ("psphot", PS_LOG_INFO, "no peaks found in this image"); 25 return peaks; 21 26 } 22 27 -
branches/tap_branches/psphot/src/psphotFitSourcesLinear.c
r25755 r27838 12 12 static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, int SKY_FIT_ORDER, psImageMaskType markVal); 13 13 14 bool psphotFitSourcesLinear (pmReadout *readout, psArray *sources, const psMetadata *recipe, const pmPSF *psf, bool final) { 14 // for now, let's store the detections on the readout->analysis for each readout 15 bool psphotFitSourcesLinear (pmConfig *config, const pmFPAview *view, bool final) 16 { 17 bool status = true; 18 19 // select the appropriate recipe information 20 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 21 assert (recipe); 22 23 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 24 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 25 26 // loop over the available readouts 27 for (int i = 0; i < num; i++) { 28 29 // find the currently selected readout 30 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", i); // File of interest 31 psAssert (file, "missing file?"); 32 33 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 34 psAssert (readout, "missing readout?"); 35 36 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 37 psAssert (detections, "missing detections?"); 38 39 psArray *sources = detections->allSources; 40 psAssert (sources, "missing sources?"); 41 42 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 43 psAssert (psf, "missing psf?"); 44 45 if (!psphotFitSourcesLinearReadout (recipe, readout, sources, psf, final)) { 46 psError (PSPHOT_ERR_CONFIG, false, "failed to fit sources (linear) for PSPHOT.INPUT entry %d", i); 47 return false; 48 } 49 } 50 return true; 51 } 52 53 bool psphotFitSourcesLinearReadout (psMetadata *recipe, pmReadout *readout, psArray *sources, pmPSF *psf, bool final) { 15 54 16 55 bool status; … … 18 57 float y; 19 58 float f; 20 // float r; 59 60 if (!sources->n) { 61 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping linear fit"); 62 return true; 63 } 21 64 22 65 psTimerStart ("psphot.linear"); … … 59 102 } 60 103 104 // XXX test: choose a larger-than expected radius: 105 float covarFactor = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix 106 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "covariance factor: %f\n", covarFactor); 107 108 // XXX do not apply covarFactor for the moment... 109 // covarFactor = 1.0; 110 61 111 // select the sources which will be used for the fitting analysis 62 112 for (int i = 0; i < sources->n; i++) { … … 120 170 121 171 // diagonal elements of the sparse matrix (auto-cross-product) 122 f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS );172 f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor); 123 173 psSparseMatrixElement (sparse, i, i, f); 124 174 125 175 // the formal error depends on the weighting scheme 126 176 if (CONSTANT_PHOTOMETRIC_WEIGHTS) { 127 float var = pmSourceModelDotModel (SRCi, SRCi, false );177 float var = pmSourceModelDotModel (SRCi, SRCi, false, covarFactor); 128 178 errors->data.F32[i] = 1.0 / sqrt(var); 129 179 } else { … … 133 183 134 184 // find the image x model value 135 f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS );185 f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor); 136 186 psSparseVectorElement (sparse, i, f); 137 187 … … 139 189 switch (SKY_FIT_ORDER) { 140 190 case 1: 141 f = pmSourceModelWeight (SRCi, 1, CONSTANT_PHOTOMETRIC_WEIGHTS );191 f = pmSourceModelWeight (SRCi, 1, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor); 142 192 psSparseBorderElementB (border, i, 1, f); 143 f = pmSourceModelWeight (SRCi, 2, CONSTANT_PHOTOMETRIC_WEIGHTS );193 f = pmSourceModelWeight (SRCi, 2, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor); 144 194 psSparseBorderElementB (border, i, 2, f); 145 195 146 196 case 0: 147 f = pmSourceModelWeight (SRCi, 0, CONSTANT_PHOTOMETRIC_WEIGHTS );197 f = pmSourceModelWeight (SRCi, 0, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor); 148 198 psSparseBorderElementB (border, i, 0, f); 149 199 break; … … 165 215 166 216 // got an overlap; calculate cross-product and add to output array 167 f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS );217 f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor); 168 218 psSparseMatrixElement (sparse, j, i, f); 169 219 } … … 219 269 220 270 // measure chisq for each source 221 for (int i = 0; final && (i < fitSources->n); i++) { 271 // for (int i = 0; final && (i < fitSources->n); i++) { 272 for (int i = 0; i < fitSources->n; i++) { 222 273 pmSource *source = fitSources->data[i]; 223 274 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) continue; 224 275 pmModel *model = pmSourceGetModel (NULL, source); 225 pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal );276 pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal, covarFactor); 226 277 } 227 278 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "get chisqs: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); … … 238 289 239 290 psphotVisualShowResidualImage (readout); 291 psphotVisualPlotChisq (sources); 240 292 // psphotVisualShowFlags (sources); 293 294 // We have to place this visualization here because the models are not realized until 295 // psphotGuessModels or fitted until psphotFitSourcesLinear. 296 psphotVisualShowPSFStars (recipe, psf, sources); 241 297 242 298 return true; … … 244 300 245 301 // XXX do we need this? 302 // XXX disallow the simultaneous sky fit and remove this code... 246 303 247 304 // Calculate the weight terms for the sky fit component of the matrix. This function operates -
branches/tap_branches/psphot/src/psphotFitSourcesLinearStack.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 // XXX need array of covar factors for each image 3 // XXX define the 'good' / 'bad' flags? 2 4 3 // fit flux (and optionally sky model) to all reasonable sources 4 // with the linear fitting process. sources must have an associated 5 // model with selected pixels, and the fit radius must be defined 5 # define COVAR_FACTOR 1.0 6 6 7 // given the set of sources, each of which points to the pixels in the 8 // science image, we construct a set of simulated sources with their own pixels. 9 // these are used to determine the simultaneous linear fit of fluxes. 10 // the analysis is performed wrt the simulated pixel values 11 12 static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, psImageMaskType markVal); 13 14 bool psphotFitSourcesLinear (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final) { 7 bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final) { 15 8 16 9 bool status; 17 float x;18 float y;19 10 float f; 20 // float r; 11 12 // select the appropriate recipe information 13 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 14 assert (recipe); 21 15 22 16 psTimerStart ("psphot.linear"); … … 33 27 maskVal |= markVal; 34 28 35 // source analysis is done in spatial order 36 sources = psArraySort (sources, pmSourceSortByY); 29 // analysis is done in spatial order (to speed up overlap search) 30 // sort by first element in each source list 31 objects = psArraySort (objects, pmPhotObjSortByX); 37 32 38 33 // storage array for fitSources 39 psArray *fitSources = psArrayAllocEmpty ( sources->n);34 psArray *fitSources = psArrayAllocEmpty (objects->n); 40 35 41 bool CONSTANT_PHOTOMETRIC_WEIGHTS = 42 psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS"); 43 if (!status) { 44 psAbort("You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS"); 45 } 36 bool CONSTANT_PHOTOMETRIC_WEIGHTS = psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS"); 37 psAssert (status, "You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS"); 38 39 // XXX store a local static array of covar factors for each of the images (by image ID) 40 // float covarFactor = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix 41 // psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "covariance factor: %f\n", covarFactor); 46 42 47 43 // select the sources which will be used for the fitting analysis 48 for (int i = 0; i < sources->n; i++) { 49 pmSource *source = sources->data[i]; 44 for (int i = 0; i < objects->n; i++) { 45 pmPhotObj *object = objects->data[i]; 46 if (!object) continue; 47 if (!object->sources) continue; 50 48 51 // turn this bit off and turn it on again if we pass this test52 source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT;49 // XXX check an element of the group to see if we should use it 50 // if (!object->flags & PM_PHOT_OBJ_BAD) continue; 53 51 54 // skip non-astronomical objects (very likely defects) 55 if (source->type == PM_SOURCE_TYPE_DEFECT) continue;56 if (source->type == PM_SOURCE_TYPE_SATURATED) continue;52 for (int j = 0; j < object->sources->n; j++) { 53 pmSource *source = object->sources->data[j]; 54 if (!source) continue; 57 55 58 // do not include CRs in the full ensemble fit 59 if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue;56 // turn this bit off and turn it on again if we keep this source 57 source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT; 60 58 61 if (final) { 62 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue; 63 } else { 64 if (source->mode & PM_SOURCE_MODE_BLEND) continue; 65 } 59 // generate model for sources without, or skip if we can't 60 if (!source->modelFlux) { 61 if (!pmSourceCacheModel (source, maskVal)) continue; 62 } 66 63 67 // generate model for sources without, or skip if we can't 68 if (!source->modelFlux) { 69 if (!pmSourceCacheModel (source, maskVal)) continue; 70 } 71 72 source->mode |= PM_SOURCE_MODE_LINEAR_FIT; 73 psArrayAdd (fitSources, 100, source); 64 source->mode |= PM_SOURCE_MODE_LINEAR_FIT; 65 psArrayAdd (fitSources, 100, source); 66 } 74 67 } 75 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), sources->n);68 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), objects->n); 76 69 77 70 if (fitSources->n == 0) { … … 83 76 psVector *errors = psVectorAlloc (fitSources->n, PS_TYPE_F32); 84 77 85 // create the border matrix (includes the sparse matrix) 86 // for just sky: 1 row; for x,y terms: 3 rows 78 // create the sparse matrix 87 79 psSparse *sparse = psSparseAlloc (fitSources->n, 100); 88 psSparseBorder *border = psSparseBorderAlloc (sparse, 1);89 80 90 81 // fill out the sparse matrix elements and border elements (B) … … 95 86 96 87 // diagonal elements of the sparse matrix (auto-cross-product) 97 f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS );88 f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR); 98 89 psSparseMatrixElement (sparse, i, i, f); 99 90 100 91 // the formal error depends on the weighting scheme 101 92 if (CONSTANT_PHOTOMETRIC_WEIGHTS) { 102 float var = pmSourceModelDotModel (SRCi, SRCi, false );93 float var = pmSourceModelDotModel (SRCi, SRCi, false, COVAR_FACTOR); 103 94 errors->data.F32[i] = 1.0 / sqrt(var); 104 95 } else { … … 106 97 } 107 98 108 109 99 // find the image x model value 110 f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS );100 f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR); 111 101 psSparseVectorElement (sparse, i, f); 112 113 f = pmSourceModelWeight (SRCi, 0, CONSTANT_PHOTOMETRIC_WEIGHTS);114 psSparseBorderElementB (border, i, 0, f);115 102 116 103 // loop over all other stars following this one … … 118 105 pmSource *SRCj = fitSources->data[j]; 119 106 107 // we only need to generate dot terms for source on the same image 108 if (SRCj->imageID != SRCi->imageID) { continue; } 109 120 110 // skip over disjoint source images, break after last possible overlap 121 if (SRC i->pixels->row0 + SRCi->pixels->numRows < SRCj->pixels->row0) break;122 if (SRC j->pixels->row0 + SRCj->pixels->numRows < SRCi->pixels->row0) continue;123 if (SRC i->pixels->col0 + SRCi->pixels->numCols < SRCj->pixels->col0) continue;124 if (SRC j->pixels->col0 + SRCj->pixels->numCols < SRCi->pixels->col0) continue;111 if (SRCj->pixels->row0 + SRCj->pixels->numRows < SRCi->pixels->row0) continue; // source(i) is above source(j) 112 if (SRCi->pixels->row0 + SRCi->pixels->numRows < SRCj->pixels->row0) continue; // source(i) is below source(j) 113 if (SRCj->pixels->col0 + SRCj->pixels->numCols < SRCi->pixels->col0) continue; // source(i) is right of source(j) 114 if (SRCi->pixels->col0 + SRCi->pixels->numCols < SRCj->pixels->col0) break; // source(i) is left of source(j) [no other source(j) can overlap source(i)] 125 115 126 116 // got an overlap; calculate cross-product and add to output array 127 f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS );117 f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR); 128 118 psSparseMatrixElement (sparse, j, i, f); 129 119 } … … 133 123 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); 134 124 135 // set the sky, sky_x, sky_y components of border matrix136 SetBorderMatrixElements (border, readout, fitSources, CONSTANT_PHOTOMETRIC_WEIGHTS, SKY_FIT_ORDER, markVal);137 138 125 psSparseConstraint constraint; 139 126 constraint.paramMin = 0.0; … … 142 129 143 130 // solve for normalization terms (need include local sky?) 144 psVector *norm = psSparseSolve (NULL, constraint, sparse, 5);145 131 psVector *norm = NULL; 132 norm = psSparseSolve (NULL, constraint, sparse, 5); 146 133 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "solve matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); 147 148 // XXXX **** philosophical question:149 // we measure bright objects in three passes: 1) linear fit; 2) non-linear fit; 3) linear fit:150 // should retain the chisq and errors from the intermediate non-linear fit?151 // the non-linear fit provides better values for the position errors, and for152 // extended sources, the shape errors153 134 154 135 // adjust I0 for fitSources and subtract … … 164 145 model->params->data.F32[PM_PAR_I0] = norm->data.F32[i]; 165 146 model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i]; 166 // XXX is the value of 'errors' modified by the sky fit?167 147 168 148 // subtract object … … 172 152 173 153 // measure chisq for each source 174 for (int i = 0; final && (i < fitSources->n); i++) { 154 // for (int i = 0; final && (i < fitSources->n); i++) { 155 for (int i = 0; i < fitSources->n; i++) { 175 156 pmSource *source = fitSources->data[i]; 176 157 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) continue; 177 158 pmModel *model = pmSourceGetModel (NULL, source); 178 pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal );159 pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal, COVAR_FACTOR); 179 160 } 180 161 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "get chisqs: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); … … 185 166 psFree (norm); 186 167 psFree (errors); 187 psFree (border);188 168 189 169 psLogMsg ("psphot.ensemble", PS_LOG_INFO, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear")); 190 191 psphotVisualShowResidualImage (readout);192 psphotVisualShowFlags (sources);193 170 194 171 return true; 195 172 } 196 173 197 // Calculate the weight terms for the sky fit component of the matrix. This function operates 198 // on the pixels which correspond to all of the sources of interest. These elements fill in 199 // the border matrix components in the sparse matrix equation. 200 static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, psImageMaskType markVal) { 174 // sort by X (ascending) 175 int pmPhotObjSortByX (const void **a, const void **b) 176 { 177 pmPhotObj *objA = *(pmPhotObj **)a; 178 pmPhotObj *objB = *(pmPhotObj **)b; 201 179 202 // generate the image-wide weight terms 203 // turn on MARK for all image pixels 204 psRegion fullArray = psRegionSet (0, 0, 0, 0); 205 fullArray = psRegionForImage (readout->mask, fullArray); 206 psImageMaskRegion (readout->mask, fullArray, "OR", markVal); 180 psF32 fA = objA->x; 181 psF32 fB = objB->x; 207 182 208 // turn off MARK for all object pixels 209 for (int i = 0; i < sources->n; i++) { 210 pmSource *source = sources->data[i]; 211 pmModel *model = pmSourceGetModel (NULL, source); 212 if (model == NULL) continue; 213 float x = model->params->data.F32[PM_PAR_XPOS]; 214 float y = model->params->data.F32[PM_PAR_YPOS]; 215 psImageMaskCircle (source->maskView, x, y, model->radiusFit, "AND", PS_NOT_IMAGE_MASK(markVal)); 216 } 217 218 // accumulate the image statistics from the masked regions 219 psF32 **image = readout->image->data.F32; 220 psF32 **variance = readout->variance->data.F32; 221 psImageMaskType **mask = readout->mask->data.PS_TYPE_IMAGE_MASK_DATA; 222 223 double w, x, y, x2, xy, y2, xc, yc, wt, f, fo, fx, fy; 224 w = x = y = x2 = xy = y2 = fo = fx = fy = 0; 225 226 int col0 = readout->image->col0; 227 int row0 = readout->image->row0; 228 229 for (int j = 0; j < readout->image->numRows; j++) { 230 for (int i = 0; i < readout->image->numCols; i++) { 231 if (mask[j][i]) continue; 232 if (constant_weights) { 233 wt = 1.0; 234 } else { 235 wt = variance[j][i]; 236 } 237 f = image[j][i]; 238 w += 1/wt; 239 fo += f/wt; 240 } 241 } 242 243 // turn off MARK for all image pixels 244 psImageMaskRegion (readout->mask, fullArray, "AND", PS_NOT_IMAGE_MASK(markVal)); 245 246 // set the Border T elements 247 psSparseBorderElementG (border, 0, fo); 248 psSparseBorderElementT (border, 0, 0, w); 249 250 return true; 183 psF32 diff = fA - fB; 184 if (diff > FLT_EPSILON) return (+1); 185 if (diff < FLT_EPSILON) return (-1); 186 return (0); 251 187 } -
branches/tap_branches/psphot/src/psphotGuessModels.c
r25755 r27838 3 3 // XXX : the threading here is not great. this may be due to blocks between elements, but 4 4 // the selection of the objects in a cell is not optimal. To fix: 5 // 1) define the boundaries of the cells up front 5 // 1) define the boundaries of the cells up front 6 6 // 2) loop over the sources once and associate them with their cell 7 7 // 3) define the threaded function to work with sources for a given cell 8 8 9 // construct an initial PSF model for each object 10 bool psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf) { 9 // for now, let's store the detections on the readout->analysis for each readout 10 bool psphotGuessModels (pmConfig *config, const pmFPAview *view) 11 { 12 bool status = true; 13 14 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 15 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 16 17 // skip the chisq image (optionally?) 18 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 19 if (!status) chisqNum = -1; 20 21 // loop over the available readouts 22 for (int i = 0; i < num; i++) { 23 if (i == chisqNum) continue; // skip chisq image 24 if (!psphotGuessModelsReadout (config, view, "PSPHOT.INPUT", i)) { 25 psError (PSPHOT_ERR_CONFIG, false, "failed on to guess models for PSPHOT.INPUT entry %d", i); 26 return false; 27 } 28 } 29 return true; 30 } 31 32 // construct an initial PSF model for each object (new sources only) 33 bool psphotGuessModelsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index) { 11 34 12 35 bool status; 13 36 14 37 psTimerStart ("psphot.models"); 38 39 // find the currently selected readout 40 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 41 psAssert (file, "missing file?"); 42 43 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 44 psAssert (readout, "missing readout?"); 45 46 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 47 psAssert (detections, "missing detections?"); 48 49 psArray *sources = detections->newSources; 50 psAssert (sources, "missing sources?"); 51 52 if (!sources->n) { 53 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping model guess"); 54 return true; 55 } 56 57 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 58 psAssert (psf, "missing psf?"); 15 59 16 60 // select the appropriate recipe information … … 21 65 int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads 22 66 if (!status) { 23 nThreads = 0;67 nThreads = 0; 24 68 } 25 69 … … 36 80 37 81 // setup the PSF fit radius details 38 psphotInitRadiusPSF (recipe, psf->type);82 psphotInitRadiusPSF (recipe, readout->analysis, psf->type); 39 83 40 84 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) … … 46 90 for (int i = 0; i < cellGroups->n; i++) { 47 91 48 psArray *cells = cellGroups->data[i];49 50 for (int j = 0; j < cells->n; j++) {51 52 // allocate a job -- if threads are not defined, this just runs the job53 psThreadJob *job = psThreadJobAlloc ("PSPHOT_GUESS_MODEL");54 psArrayAdd(job->args, 1, readout);55 psArrayAdd(job->args, 1, cells->data[j]); // sources56 psArrayAdd(job->args, 1, psf);57 58 // XXX change these to use abstract mask type info59 PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK);60 PS_ARRAY_ADD_SCALAR(job->args, markVal, PS_TYPE_IMAGE_MASK);61 62 if (!psThreadJobAddPending(job)) {63 psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");64 psFree (job);65 return false;66 }67 psFree(job);68 }69 70 // wait for the threads to finish and manage results71 // wait here for the threaded jobs to finish72 // fprintf (stderr, "wait for threads (%d, %d)\n", jx, jy);73 if (!psThreadPoolWait (false)) {74 psError(PS_ERR_UNKNOWN, false, "Unable to guess model.");75 return false;76 }77 78 // we have only supplied one type of job, so we can assume the types here79 psThreadJob *job = NULL;80 while ((job = psThreadJobGetDone()) != NULL) {81 // we have no returned data from this operation82 if (job->args->n < 1) {83 fprintf (stderr, "error with job\n");84 }85 psFree(job);86 }92 psArray *cells = cellGroups->data[i]; 93 94 for (int j = 0; j < cells->n; j++) { 95 96 // allocate a job -- if threads are not defined, this just runs the job 97 psThreadJob *job = psThreadJobAlloc ("PSPHOT_GUESS_MODEL"); 98 psArrayAdd(job->args, 1, readout); 99 psArrayAdd(job->args, 1, cells->data[j]); // sources 100 psArrayAdd(job->args, 1, psf); 101 102 // XXX change these to use abstract mask type info 103 PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK); 104 PS_ARRAY_ADD_SCALAR(job->args, markVal, PS_TYPE_IMAGE_MASK); 105 106 if (!psThreadJobAddPending(job)) { 107 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 108 psFree (job); 109 return false; 110 } 111 psFree(job); 112 } 113 114 // wait for the threads to finish and manage results 115 // wait here for the threaded jobs to finish 116 // fprintf (stderr, "wait for threads (%d, %d)\n", jx, jy); 117 if (!psThreadPoolWait (false)) { 118 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 119 return false; 120 } 121 122 // we have only supplied one type of job, so we can assume the types here 123 psThreadJob *job = NULL; 124 while ((job = psThreadJobGetDone()) != NULL) { 125 // we have no returned data from this operation 126 if (job->args->n < 1) { 127 fprintf (stderr, "error with job\n"); 128 } 129 psFree(job); 130 } 87 131 } 88 132 … … 90 134 int nMiss = 0; 91 135 for (int i = 0; i < sources->n; i++) { 92 pmSource *source = sources->data[i];93 if (source->tmpFlags & PM_SOURCE_TMPF_MODEL_GUESS) {94 continue;95 }96 nMiss ++;136 pmSource *source = sources->data[i]; 137 if (source->tmpFlags & PM_SOURCE_TMPF_MODEL_GUESS) { 138 continue; 139 } 140 nMiss ++; 97 141 } 98 142 psAssert (nMiss == 0, "failed to attempt to build models for %d objects\n", nMiss); … … 110 154 psArray *sources = job->args->data[1]; 111 155 pmPSF *psf = job->args->data[2]; 112 156 113 157 psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[3],PS_TYPE_IMAGE_MASK_DATA); 114 158 psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA); … … 117 161 118 162 for (int i = 0; i < sources->n; i++) { 119 pmSource *source = sources->data[i];120 121 // this is used to mark sources for which the model is measured. We check later that122 // all are used.123 source->tmpFlags |= PM_SOURCE_TMPF_MODEL_GUESS;124 125 // skip non-astronomical objects (very likely defects)126 if (source->type == PM_SOURCE_TYPE_DEFECT) continue;127 if (source->type == PM_SOURCE_TYPE_SATURATED) continue;128 if (!source->peak) continue;129 130 nSrc ++;131 132 // the guess central intensity comes from the peak:133 float Io = source->peak->flux;134 135 // We have two options to get a guess for the object position: the position from the136 // peak and the position from the moments. Use the peak position if (a) there are no137 // moments and (b) the sources is not saturated138 139 bool useMoments = false;140 useMoments = (source->mode & PM_SOURCE_MODE_SATSTAR); // we only want to try if SATSTAR is set, but..141 useMoments = (useMoments && source->moments);// can't if there are no moments142 useMoments = (useMoments && source->moments->nPixels); // can't if the moments were not measured143 useMoments = (useMoments && !(source->mode && PM_SOURCE_MODE_MOMENTS_FAILURE)); // can't if the moments failed...144 145 float Xo, Yo;146 if (useMoments) {147 Xo = source->moments->Mx;148 Yo = source->moments->My;149 } else {150 Xo = source->peak->xf;151 Yo = source->peak->yf;152 }153 154 // set PSF parameters for this model (apply 2D shape model to coordinates Xo, Yo)155 pmModel *modelPSF = pmModelFromPSFforXY(psf, Xo, Yo, Io);156 157 if (modelPSF == NULL) {158 psWarning ("Failed to determine PSF model at (%f,%f); trying image center", Xo, Yo);159 160 float Xc = 0.5*readout->image->numCols;161 float Yc = 0.5*readout->image->numRows;162 pmModel *modelPSF = pmModelFromPSFforXY(psf, Xc, Yc, Io);163 if (modelPSF == NULL) {164 psError(PSPHOT_ERR_PSF, false, "Failed to determine PSF model at center of image");165 return false;166 }167 168 // Now set the object position at the expected location:169 modelPSF->params->data.F32[PM_PAR_XPOS] = Xo;170 modelPSF->params->data.F32[PM_PAR_YPOS] = Yo;171 source->mode |= PM_SOURCE_MODE_BADPSF;172 }173 174 // set the fit radius based on the object flux limit and the model175 // this function affects the mask pixels176 psphotCheckRadiusPSF (readout, source, modelPSF, markVal);177 178 // set the source PSF model179 psAssert (source->modelPSF == NULL, "failed to free one of the models?");180 source->modelPSF = modelPSF;181 source->modelPSF->residuals = psf->residuals;182 183 pmSourceCacheModel (source, maskVal); // ALLOC x14 (!)163 pmSource *source = sources->data[i]; 164 165 // this is used to mark sources for which the model is measured. We check later that 166 // all are used. 167 source->tmpFlags |= PM_SOURCE_TMPF_MODEL_GUESS; 168 169 // skip non-astronomical objects (very likely defects) 170 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 171 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 172 if (!source->peak) continue; 173 174 nSrc ++; 175 176 // the guess central intensity comes from the peak: 177 float Io = source->peak->flux; 178 179 // We have two options to get a guess for the object position: the position from the 180 // peak and the position from the moments. Use the peak position if (a) there are no 181 // moments and (b) the sources is not saturated 182 183 bool useMoments = false; 184 useMoments = (source->mode & PM_SOURCE_MODE_SATSTAR); // we only want to try if SATSTAR is set, but.. 185 useMoments = (useMoments && source->moments); // can't if there are no moments 186 useMoments = (useMoments && source->moments->nPixels); // can't if the moments were not measured 187 useMoments = (useMoments && !(source->mode && PM_SOURCE_MODE_MOMENTS_FAILURE)); // can't if the moments failed... 188 189 float Xo, Yo; 190 if (useMoments) { 191 Xo = source->moments->Mx; 192 Yo = source->moments->My; 193 } else { 194 Xo = source->peak->xf; 195 Yo = source->peak->yf; 196 } 197 198 // set PSF parameters for this model (apply 2D shape model to coordinates Xo, Yo) 199 pmModel *modelPSF = pmModelFromPSFforXY(psf, Xo, Yo, Io); 200 201 if (modelPSF == NULL) { 202 psWarning ("Failed to determine PSF model at (%f,%f); trying image center", Xo, Yo); 203 204 float Xc = 0.5*readout->image->numCols; 205 float Yc = 0.5*readout->image->numRows; 206 pmModel *modelPSF = pmModelFromPSFforXY(psf, Xc, Yc, Io); 207 if (modelPSF == NULL) { 208 psError(PSPHOT_ERR_PSF, false, "Failed to determine PSF model at center of image"); 209 return false; 210 } 211 212 // Now set the object position at the expected location: 213 modelPSF->params->data.F32[PM_PAR_XPOS] = Xo; 214 modelPSF->params->data.F32[PM_PAR_YPOS] = Yo; 215 source->mode |= PM_SOURCE_MODE_BADPSF; 216 } 217 218 // set the fit radius based on the object flux limit and the model 219 // this function affects the mask pixels 220 psphotCheckRadiusPSF (readout, source, modelPSF, markVal); 221 222 // set the source PSF model 223 psAssert (source->modelPSF == NULL, "failed to free one of the models?"); 224 source->modelPSF = modelPSF; 225 source->modelPSF->residuals = psf->residuals; 226 227 pmSourceCacheModel (source, maskVal); // ALLOC x14 (!) 184 228 } 185 229 -
branches/tap_branches/psphot/src/psphotImageLoop.c
r25755 r27838 91 91 } 92 92 93 status = true; 94 status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL"); 95 status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV"); 96 status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND"); 97 if (!status) { 98 psError(PSPHOT_ERR_PROG, false, "trouble dropping internal files"); 99 psFree (view); 100 return false; 101 } 93 // drop all versions of the internal files 94 status = true; 95 status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL"); 96 status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV"); 97 status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND"); 98 if (!status) { 99 psError(PSPHOT_ERR_PROG, false, "trouble dropping internal files"); 100 psFree (view); 101 return false; 102 } 102 103 } 103 104 104 // save output which is saved at the chip level 105 105 if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE ("failed output for Chip in psphot."); -
branches/tap_branches/psphot/src/psphotImageQuality.c
r25755 r27838 4 4 // XXX Lots of code duplication here 5 5 6 // for now, let's store the detections on the readout->analysis for each readout 7 bool psphotImageQuality (pmConfig *config, const pmFPAview *view) 8 { 9 bool status = true; 10 11 // select the appropriate recipe information 12 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 13 psAssert (recipe, "missing recipe?"); 14 15 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 16 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 17 18 // skip the chisq image (optionally?) 19 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 20 if (!status) chisqNum = -1; 21 22 // loop over the available readouts 23 for (int i = 0; i < num; i++) { 24 if (i == chisqNum) continue; // skip chisq image 25 if (!psphotImageQualityReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 26 psError (PSPHOT_ERR_CONFIG, false, "failed on to measure image quality for PSPHOT.INPUT entry %d", i); 27 return false; 28 } 29 } 30 return true; 31 } 32 6 33 // selecting the 'good' stars (likely to be psf stars), measure the M_cn, M_sn terms for n = 2,3,4 7 bool psphotImageQuality (psMetadata *recipe, psArray *sources)34 bool psphotImageQualityReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) 8 35 { 36 bool status = true; 37 38 // find the currently selected readout 39 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 40 psAssert (file, "missing file?"); 41 42 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 43 psAssert (readout, "missing readout?"); 44 45 // if we have a PSF, skip this analysis 46 if (psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF")) { 47 return true; 48 } 49 50 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 51 psAssert (detections, "missing detections?"); 52 53 psArray *sources = detections->newSources; 54 psAssert (sources, "missing sources?"); 55 56 if (!sources->n) { 57 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping image quality"); 58 return true; 59 } 60 9 61 psVector *FWHM_MAJOR = psVectorAllocEmpty(100, PS_TYPE_F32); 10 62 psVector *FWHM_MINOR = psVectorAllocEmpty(100, PS_TYPE_F32); … … 81 133 82 134 if (num == 0) { 83 psWarning("Unable to find sources from which to measure image quality"); 84 return false; 85 } 86 87 psMetadataAddS32(recipe, PS_LIST_TAIL, "IQ_NSTAR", PS_META_REPLACE, 88 "Number of stars used for IQ measurements", M2->n); 135 psLogMsg ("psphot", PS_LOG_INFO, "no valid sources for image quality, skipping"); 136 return true; 137 } 138 139 psMetadataAddS32(readout->analysis, PS_LIST_TAIL, "IQ_NSTAR", PS_META_REPLACE, "Number of stars used for IQ measurements", M2->n); 89 140 90 141 // XXX make this a recipe option … … 98 149 99 150 float fwhm_major = stats->sampleMean; 100 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_FW1", PS_META_REPLACE, 101 "FWHM of Major Axis from moments", stats->sampleMean); 102 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_FW1_E", PS_META_REPLACE, 103 "FWHM scatter (Major) from moments", stats->sampleStdev); 151 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW1", PS_META_REPLACE, "FWHM of Major Axis from moments", stats->sampleMean); 152 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW1_E", PS_META_REPLACE, "FWHM scatter (Major) from moments", stats->sampleStdev); 104 153 105 154 if (!psVectorStats(stats, FWHM_MINOR, NULL, NULL, 0)) { … … 108 157 } 109 158 float fwhm_minor = stats->sampleMean; 110 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_FW2", PS_META_REPLACE, 111 "FWHM of Minor Axis from moments", stats->sampleMean); 112 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_FW2_E", PS_META_REPLACE, 113 "FWHM scatter (Minor) from moments", stats->sampleStdev); 159 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW2", PS_META_REPLACE, "FWHM of Minor Axis from moments", stats->sampleMean); 160 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW2_E", PS_META_REPLACE, "FWHM scatter (Minor) from moments", stats->sampleStdev); 114 161 115 162 if (!psVectorStats(stats, M2, NULL, NULL, 0)) { … … 119 166 float vM2 = stats->sampleMean; 120 167 float dM2 = stats->sampleStdev; 121 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2", PS_META_REPLACE, 122 "M_2 = sqrt (M_c2^2 + M_s2^2)", vM2); 123 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2_ER", PS_META_REPLACE, 124 "Stdev of M_2", dM2); 125 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2_LQ", PS_META_REPLACE, 126 "Lower Quartile of M_2", stats->sampleLQ); 127 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2_UQ", PS_META_REPLACE, 128 "Upper Quartile of M_2", stats->sampleUQ); 168 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2", PS_META_REPLACE, "M_2 = sqrt (M_c2^2 + M_s2^2)", vM2); 169 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_ER", PS_META_REPLACE, "Stdev of M_2", dM2); 170 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_LQ", PS_META_REPLACE, "Lower Quartile of M_2", stats->sampleLQ); 171 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_UQ", PS_META_REPLACE, "Upper Quartile of M_2", stats->sampleUQ); 129 172 130 173 if (!psVectorStats(stats, M2c, NULL, NULL, 0)) { … … 132 175 goto FAIL; 133 176 } 134 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2C", PS_META_REPLACE, 135 "M_2c = sum f r^2 cos(2phi) / sum f", stats->sampleMean); 136 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2C_E", PS_META_REPLACE, 137 "Stdev of M_2c", stats->sampleStdev); 138 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2C_L", PS_META_REPLACE, 139 "Lower Quartile of M_2c", stats->sampleLQ); 140 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2C_U", PS_META_REPLACE, 141 "Upper Quartile of M_2c", stats->sampleUQ); 177 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C", PS_META_REPLACE, "M_2c = sum f r^2 cos(2phi) / sum f", stats->sampleMean); 178 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_E", PS_META_REPLACE, "Stdev of M_2c", stats->sampleStdev); 179 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_L", PS_META_REPLACE, "Lower Quartile of M_2c", stats->sampleLQ); 180 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_U", PS_META_REPLACE, "Upper Quartile of M_2c", stats->sampleUQ); 142 181 143 182 if (!psVectorStats(stats, M2s, NULL, NULL, 0)) { … … 145 184 goto FAIL; 146 185 } 147 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2S", PS_META_REPLACE, 148 "M_2s = sum f r^2 cos(2phi) / sum f", stats->sampleMean); 149 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2S_E", PS_META_REPLACE, 150 "Stdev of M_2s", stats->sampleStdev); 151 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2S_L", PS_META_REPLACE, 152 "Lower Quartile of M_2s", stats->sampleLQ); 153 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2S_U", PS_META_REPLACE, 154 "Upper Quartile of M_2s", stats->sampleUQ); 186 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S", PS_META_REPLACE, "M_2s = sum f r^2 cos(2phi) / sum f", stats->sampleMean); 187 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_E", PS_META_REPLACE, "Stdev of M_2s", stats->sampleStdev); 188 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_L", PS_META_REPLACE, "Lower Quartile of M_2s", stats->sampleLQ); 189 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_U", PS_META_REPLACE, "Upper Quartile of M_2s", stats->sampleUQ); 155 190 156 191 if (!psVectorStats(stats, M3, NULL, NULL, 0)) { … … 160 195 float vM3 = stats->sampleMean; 161 196 float dM3 = stats->sampleStdev; 162 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M3", PS_META_REPLACE, 163 "M_3 = sqrt (M_c3^2 + M_s3^2)", vM3); 164 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M3_ER", PS_META_REPLACE, 165 "Stdev of M_3", dM3); 166 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M3_LQ", PS_META_REPLACE, 167 "Lower Quartile of M_3", stats->sampleLQ); 168 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M3_UQ", PS_META_REPLACE, 169 "Upper Quartile of M_3", stats->sampleUQ); 197 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3", PS_META_REPLACE, "M_3 = sqrt (M_c3^2 + M_s3^2)", vM3); 198 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_ER", PS_META_REPLACE, "Stdev of M_3", dM3); 199 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_LQ", PS_META_REPLACE, "Lower Quartile of M_3", stats->sampleLQ); 200 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_UQ", PS_META_REPLACE, "Upper Quartile of M_3", stats->sampleUQ); 170 201 171 202 if (!psVectorStats(stats, M4, NULL, NULL, 0)) { … … 175 206 float vM4 = stats->sampleMean; 176 207 float dM4 = stats->sampleStdev; 177 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M4", PS_META_REPLACE, 178 "M_4 = sqrt (M_c4^2 + M_s4^2)", vM4); 179 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M4_ER", PS_META_REPLACE, 180 "Stdev of M_4", dM4); 181 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M4_LQ", PS_META_REPLACE, 182 "Lower Quartile of M_4", stats->sampleLQ); 183 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M4_UQ", PS_META_REPLACE, 184 "Upper Quartile of M_4", stats->sampleUQ); 208 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4", PS_META_REPLACE, "M_4 = sqrt (M_c4^2 + M_s4^2)", vM4); 209 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_ER", PS_META_REPLACE, "Stdev of M_4", dM4); 210 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_LQ", PS_META_REPLACE, "Lower Quartile of M_4", stats->sampleLQ); 211 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_UQ", PS_META_REPLACE, "Upper Quartile of M_4", stats->sampleUQ); 185 212 186 213 #else … … 192 219 } 193 220 float fwhm_major = stats->robustMedian; 194 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_FW1", PS_META_REPLACE, 195 "FWHM of Major Axis from moments", stats->robustMedian); 196 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_FW1_E", PS_META_REPLACE, 197 "FWHM scatter (Major) from moments", stats->robustStdev); 221 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW1", PS_META_REPLACE, "FWHM of Major Axis from moments", stats->robustMedian); 222 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW1_E", PS_META_REPLACE, "FWHM scatter (Major) from moments", stats->robustStdev); 198 223 199 224 if (!psVectorStats(stats, FWHM_MINOR, NULL, NULL, 0)) { … … 202 227 } 203 228 float fwhm_minor = stats->robustMedian; 204 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_FW2", PS_META_REPLACE, 205 "FWHM of Minor Axis from moments", stats->robustMedian); 206 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_FW2_E", PS_META_REPLACE, 207 "FWHM scatter (Minor) from moments", stats->robustStdev); 229 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW2", PS_META_REPLACE, "FWHM of Minor Axis from moments", stats->robustMedian); 230 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW2_E", PS_META_REPLACE, "FWHM scatter (Minor) from moments", stats->robustStdev); 208 231 209 232 if (!psVectorStats(stats, M2, NULL, NULL, 0)) { … … 213 236 float vM2 = stats->robustMedian; 214 237 float dM2 = stats->robustStdev; 215 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2", PS_META_REPLACE, 216 "M_2 = sqrt (M_c2^2 + M_s2^2)", vM2); 217 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2_ER", PS_META_REPLACE, 218 "Stdev of M_2", dM2); 219 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2_LQ", PS_META_REPLACE, 220 "Lower Quartile of M_2", stats->robustLQ); 221 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2_UQ", PS_META_REPLACE, 222 "Upper Quartile of M_2", stats->robustUQ); 238 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2", PS_META_REPLACE, "M_2 = sqrt (M_c2^2 + M_s2^2)", vM2); 239 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_ER", PS_META_REPLACE, "Stdev of M_2", dM2); 240 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_LQ", PS_META_REPLACE, "Lower Quartile of M_2", stats->robustLQ); 241 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_UQ", PS_META_REPLACE, "Upper Quartile of M_2", stats->robustUQ); 223 242 224 243 if (!psVectorStats(stats, M2c, NULL, NULL, 0)) { … … 226 245 goto FAIL; 227 246 } 228 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2C", PS_META_REPLACE, 229 "M_2c = sum f r^2 cos(2phi) / sum f", stats->robustMedian); 230 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2C_E", PS_META_REPLACE, 231 "Stdev of M_2c", stats->robustStdev); 232 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2C_L", PS_META_REPLACE, 233 "Lower Quartile of M_2c", stats->robustLQ); 234 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2C_U", PS_META_REPLACE, 235 "Upper Quartile of M_2c", stats->robustUQ); 247 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C", PS_META_REPLACE, "M_2c = sum f r^2 cos(2phi) / sum f", stats->robustMedian); 248 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_E", PS_META_REPLACE, "Stdev of M_2c", stats->robustStdev); 249 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_L", PS_META_REPLACE, "Lower Quartile of M_2c", stats->robustLQ); 250 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_U", PS_META_REPLACE, "Upper Quartile of M_2c", stats->robustUQ); 236 251 237 252 if (!psVectorStats(stats, M2s, NULL, NULL, 0)) { … … 239 254 goto FAIL; 240 255 } 241 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2S", PS_META_REPLACE, 242 "M_2s = sum f r^2 cos(2phi) / sum f", stats->robustMedian); 243 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2S_E", PS_META_REPLACE, 244 "Stdev of M_2s", stats->robustStdev); 245 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2S_L", PS_META_REPLACE, 246 "Lower Quartile of M_2s", stats->robustLQ); 247 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M2S_U", PS_META_REPLACE, 248 "Upper Quartile of M_2s", stats->robustUQ); 256 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S", PS_META_REPLACE, "M_2s = sum f r^2 cos(2phi) / sum f", stats->robustMedian); 257 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_E", PS_META_REPLACE, "Stdev of M_2s", stats->robustStdev); 258 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_L", PS_META_REPLACE, "Lower Quartile of M_2s", stats->robustLQ); 259 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_U", PS_META_REPLACE, "Upper Quartile of M_2s", stats->robustUQ); 249 260 250 261 if (!psVectorStats(stats, M3, NULL, NULL, 0)) { … … 254 265 float vM3 = stats->robustMedian; 255 266 float dM3 = stats->robustStdev; 256 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M3", PS_META_REPLACE, 257 "M_3 = sqrt (M_c3^2 + M_s3^2)", vM3); 258 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M3_ER", PS_META_REPLACE, 259 "Stdev of M_3", dM3); 260 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M3_LQ", PS_META_REPLACE, 261 "Lower Quartile of M_3", stats->robustLQ); 262 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M3_UQ", PS_META_REPLACE, 263 "Upper Quartile of M_3", stats->robustUQ); 267 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3", PS_META_REPLACE, "M_3 = sqrt (M_c3^2 + M_s3^2)", vM3); 268 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_ER", PS_META_REPLACE, "Stdev of M_3", dM3); 269 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_LQ", PS_META_REPLACE, "Lower Quartile of M_3", stats->robustLQ); 270 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_UQ", PS_META_REPLACE, "Upper Quartile of M_3", stats->robustUQ); 264 271 265 272 if (!psVectorStats(stats, M4, NULL, NULL, 0)) { … … 269 276 float vM4 = stats->robustMedian; 270 277 float dM4 = stats->robustStdev; 271 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M4", PS_META_REPLACE, 272 "M_4 = sqrt (M_c4^2 + M_s4^2)", vM4); 273 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M4_ER", PS_META_REPLACE, 274 "Stdev of M_4", dM4); 275 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M4_LQ", PS_META_REPLACE, 276 "Lower Quartile of M_4", stats->robustLQ); 277 psMetadataAddF32(recipe, PS_LIST_TAIL, "IQ_M4_UQ", PS_META_REPLACE, 278 "Upper Quartile of M_4", stats->robustUQ); 278 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4", PS_META_REPLACE, "M_4 = sqrt (M_c4^2 + M_s4^2)", vM4); 279 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_ER", PS_META_REPLACE, "Stdev of M_4", dM4); 280 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_LQ", PS_META_REPLACE, "Lower Quartile of M_4", stats->robustLQ); 281 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_UQ", PS_META_REPLACE, "Upper Quartile of M_4", stats->robustUQ); 279 282 #endif 280 283 -
branches/tap_branches/psphot/src/psphotKernelFromPSF.c
r17396 r27838 4 4 5 5 assert (source); 6 assert (source->psf Flux); // XXX build if needed?6 assert (source->psfImage); // XXX build if needed? 7 7 8 int x0 = source->peak->xf - source->psf Flux->col0;9 int y0 = source->peak->yf - source->psf Flux->row0;8 int x0 = source->peak->xf - source->psfImage->col0; 9 int y0 = source->peak->yf - source->psfImage->row0; 10 10 11 11 // need to decide on the size: dynamically? statically? … … 17 17 // if the realized PSF for this object does not cover the full kernel, give up for now 18 18 if (x0 + psf->xMin < 0) goto escape; 19 if (x0 + psf->xMax >= source->psf Flux->numCols) goto escape;19 if (x0 + psf->xMax >= source->psfImage->numCols) goto escape; 20 20 if (y0 + psf->yMin < 0) goto escape; 21 if (y0 + psf->yMax >= source->psf Flux->numRows) goto escape;21 if (y0 + psf->yMax >= source->psfImage->numRows) goto escape; 22 22 23 23 double sum = 0.0; 24 24 for (int j = psf->yMin; j <= psf->yMax; j++) { 25 25 for (int i = psf->xMin; i <= psf->xMax; i++) { 26 double value = source->psf Flux->data.F32[y0 + j][x0 + i];26 double value = source->psfImage->data.F32[y0 + j][x0 + i]; 27 27 psf->kernel[j][i] = value; 28 28 sum += value; -
branches/tap_branches/psphot/src/psphotLoadPSF.c
r18002 r27838 1 1 # include "psphotInternal.h" 2 2 3 // NOTE : pmPSF_IO.c functions must load the psf model onto the chip->analysis metadata because 4 // the I/O operation likely occurs before the readout exists. This implementation assumes that 5 // a single psf model is valid for the entire set of readouts (not valid for a time series of readouts) 6 7 // XXX for now (2010.01.27), the supporting programs do not define multiple PSPHOT.PSF.LOAD 8 // files to go with multiple PSPHOT.INPUT files. as a result, the implementation below is 9 // currently going to work for the case of a single input file, but will fail if we try with a 10 // stack of images. 11 3 12 // load an externally supplied psf model 4 pmPSF *psphotLoadPSF (pmConfig *config, const pmFPAview *view, psMetadata *recipe) { 13 bool psphotLoadPSFReadout (pmConfig *config, const pmFPAview *view, const char *outFilename, const char *inFilename, int index) { 14 15 bool status; 16 17 // find the currently selected readout 18 pmFPAfile *inFile = pmFPAfileSelectSingle(config->files, inFilename, index); // File of interest 19 if (inFile == NULL) { 20 psLogMsg ("psphot", 3, "no psf supplied for this chip"); 21 return true; 22 } 23 24 // find the currently selected readout 25 pmFPAfile *outFile = pmFPAfileSelectSingle(config->files, outFilename, index); // File of interest 26 if (outFile == NULL) { 27 psLogMsg ("psphot", 3, "no psf supplied for this chip"); 28 return true; 29 } 5 30 6 31 // find the currently selected chip 7 pmChip *chip = pmFPA fileThisChip (config->files, view, "PSPHOT.PSF.LOAD");8 if (!chip) return NULL;32 pmChip *chip = pmFPAviewThisChip (view, inFile->fpa); 33 if (!chip) return false; 9 34 10 35 // find the currently selected readout 11 pmReadout *readout = pmFPA fileThisReadout (config->files, view, "PSPHOT.PSF.LOAD");12 if (!readout) return NULL;36 pmReadout *readout = pmFPAviewThisReadout (view, outFile->fpa); 37 if (!readout) return false; 13 38 14 39 // check if a PSF model is supplied by the user 15 pmPSF *psf = psMetadataLookupPtr ( NULL, chip->analysis, "PSPHOT.PSF");40 pmPSF *psf = psMetadataLookupPtr (&status, chip->analysis, "PSPHOT.PSF"); 16 41 if (psf == NULL) { 17 42 psLogMsg ("psphot", 3, "no psf supplied for this chip"); 18 return NULL;43 return true; 19 44 } 20 45 21 if (!psphotPSFstats (readout, recipe, psf)) psAbort("cannot measure PSF shape terms"); 46 if (!psphotPSFstats (readout, psf)) { 47 psAbort("cannot measure PSF shape terms"); 48 } 22 49 23 50 psLogMsg ("psphot", 3, "using externally supplied PSF model for this readout"); 24 51 25 // we return a psf which can be free (and which may be removed from the metadata) 26 psMemIncrRefCounter (psf); 27 return psf; 52 // save PSF on readout->analysis 53 if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot psf model", psf)) { 54 psError (PSPHOT_ERR_UNKNOWN, false, "problem saving sources on readout"); 55 return false; 56 } 57 58 return true; 28 59 } 60 61 bool psphotLoadPSF (pmConfig *config, const pmFPAview *view) { 62 63 bool status = false; 64 65 // XXX PSPHOT.PSF.LOAD vs PSPHOT.INPUT -- see note at top 66 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 67 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 68 69 // loop over the available readouts 70 for (int i = 0; i < num; i++) { 71 72 // Generate the mask and weight images, including the user-defined analysis region of interest 73 if (!psphotLoadPSFReadout (config, view, "PSPHOT.INPUT", "PSPHOT.PSF.LOAD", i)) { 74 psError (PSPHOT_ERR_CONFIG, false, "failed to load PSF model for PSPHOT.PSF.LOAD entry %d", i); 75 return false; 76 } 77 } 78 return true; 79 } -
branches/tap_branches/psphot/src/psphotMagnitudes.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 bool psphotMagnitudes(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources, const pmPSF *psf) { 3 bool psphotMagnitudes (pmConfig *config, const pmFPAview *view) 4 { 5 bool status = true; 6 7 // select the appropriate recipe information 8 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 9 psAssert (recipe, "missing recipe?"); 10 11 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 12 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 13 14 // skip the chisq image (optionally?) 15 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 16 if (!status) chisqNum = -1; 17 18 // loop over the available readouts 19 for (int i = 0; i < num; i++) { 20 if (i == chisqNum) continue; // skip chisq image 21 22 // find the currently selected readout 23 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", i); // File of interest 24 psAssert (file, "missing file?"); 25 26 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 27 psAssert (readout, "missing readout?"); 28 29 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 30 psAssert (detections, "missing detections?"); 31 32 psArray *sources = detections->allSources; 33 psAssert (sources, "missing sources?"); 34 35 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 36 psAssert (psf, "missing psf?"); 37 38 if (!psphotMagnitudesReadout (config, recipe, view, readout, sources, psf)) { 39 psError (PSPHOT_ERR_CONFIG, false, "failed to measure magnitudes for PSPHOT.INPUT entry %d", i); 40 return false; 41 } 42 } 43 return true; 44 } 45 46 bool psphotMagnitudesReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf) { 4 47 5 48 bool status = false; 6 49 int Nap = 0; 7 50 51 if (!sources->n) { 52 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source magnitudes"); 53 return true; 54 } 55 8 56 psTimerStart ("psphot.mags"); 9 10 // select the appropriate recipe information11 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);12 assert (recipe);13 57 14 58 // determine the number of allowed threads … … 41 85 } 42 86 43 bool IGNORE_GROWTH = psMetadataLookupBool (&status, recipe, "IGNORE_GROWTH");87 bool IGNORE_GROWTH = psMetadataLookupBool (&status, recipe, "IGNORE_GROWTH"); 44 88 bool INTERPOLATE_AP = psMetadataLookupBool (&status, recipe, "INTERPOLATE_AP"); 89 bool DIFF_STATS = psMetadataLookupBool (&status, recipe, "INTERPOLATE_AP"); 45 90 46 91 pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_APCORR | PM_SOURCE_PHOT_WEIGHT; 47 92 if (!IGNORE_GROWTH) photMode |= PM_SOURCE_PHOT_GROWTH; 48 93 if (INTERPOLATE_AP) photMode |= PM_SOURCE_PHOT_INTERP; 94 if (DIFF_STATS) photMode |= PM_SOURCE_PHOT_DIFFSTATS; 49 95 50 96 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) … … 64 110 65 111 psArrayAdd(job->args, 1, cells->data[j]); // sources 66 psArrayAdd(job->args, 1, (pmPSF*)psf); // Casting away const112 psArrayAdd(job->args, 1, psf); 67 113 psArrayAdd(job->args, 1, binning); 68 114 psArrayAdd(job->args, 1, backModel); … … 179 225 } 180 226 181 # if (0)182 bool psphotMagnitudes_Unthreaded (int *nap, psArray *sources, pmPSF *psf, psImageBinning *binning, pmReadout *backModel, pmReadout *backStdev, pmSourcePhotometryMode photMode, psImageMaskType maskVal) {183 184 bool status;185 int Nap = 0;186 187 for (int i = 0; i < sources->n; i++) {188 pmSource *source = (pmSource *) sources->data[i];189 status = pmSourceMagnitudes (source, psf, photMode, maskVal);190 if (status && isfinite(source->apMag)) Nap ++;191 192 if (backModel) {193 psAssert (binning, "if backModel is defined, so should binning be");194 source->sky = psImageUnbinPixel(source->peak->x, source->peak->y, backModel->image, binning);195 if (isnan(source->sky) && false) {196 psLogMsg ("psphot.magnitudes", PS_LOG_DETAIL, "error setting pmSource.sky");197 }198 } else {199 source->sky = NAN;200 }201 202 if (backStdev) {203 psAssert (binning, "if backStdev is defined, so should binning be");204 source->skyErr = psImageUnbinPixel(source->peak->x, source->peak->y, backStdev->image, binning);205 if (isnan(source->skyErr) && false) {206 psLogMsg ("psphot.magnitudes", PS_LOG_DETAIL, "error setting pmSource.skyErr");207 }208 } else {209 source->skyErr = NAN;210 }211 }212 213 // change the value of a scalar on the array (wrap this and put it in psArray.h)214 *nap = Nap;215 216 return true;217 }218 # endif219 220 227 bool psphotPSFWeights(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources) { 221 228 -
branches/tap_branches/psphot/src/psphotMakeResiduals.c
r25755 r27838 305 305 if (fabs(resid->Ro->data.F32[oy][ox]) < pixelSN*dRo/sqrt(nKeep)) { 306 306 resid->mask->data.PM_TYPE_RESID_MASK_DATA[oy][ox] = 1; 307 resid->Ro->data.F32[oy][ox] = 0.0; 308 resid->Rx->data.F32[oy][ox] = 0.0; 309 resid->Ry->data.F32[oy][ox] = 0.0; 307 310 } 308 311 } -
branches/tap_branches/psphot/src/psphotMaskReadout.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 bool psphotSetMaskAndVariance (pmConfig *config, const pmFPAview *view) { 4 5 bool status = false; 6 7 // select the appropriate recipe information 8 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 9 psAssert (recipe, "missing recipe?"); 10 11 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 12 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 13 14 // loop over the available readouts 15 for (int i = 0; i < num; i++) { 16 17 // Generate the mask and weight images, including the user-defined analysis region of interest 18 if (!psphotSetMaskAndVarianceReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 19 psError (PSPHOT_ERR_CONFIG, false, "failed to generate mask for PSPHOT.INPUT entry %d", i); 20 return false; 21 } 22 } 23 return true; 24 } 25 3 26 // generate mask and variance if not defined, additional mask for restricted subregion 4 bool psphotSetMaskAndVariance (pmConfig *config, pmReadout *readout, psMetadata *recipe) {27 bool psphotSetMaskAndVarianceReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 5 28 6 29 bool status; 7 30 8 // ** Interpret the mask values: 9 // XXX drop the write to recipe and move config into psphotRoughClass? 10 // XXX alternatively, define a function to set the psphot recipe masks 31 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", index); // File of interest 32 psAssert (file, "missing file?"); 33 34 // find the currently selected readout 35 pmReadout *readout = pmFPAviewThisReadout (view, file->fpa); 36 psAssert (readout, "missing readout?"); 37 38 // save maskSat and maskBad on the psphot recipe (mostly for psphotRoughClass) 11 39 psImageMaskType maskSat = pmConfigMaskGet("SAT", config); // Mask value for saturated pixels 12 40 psMetadataAddImageMask (recipe, PS_LIST_TAIL, "MASK.SAT", PS_META_REPLACE, "user-defined mask", maskSat); … … 14 42 psImageMaskType maskBad = pmConfigMaskGet("LOW", config); // Mask value for low pixels 15 43 if (!maskBad) { 16 // XXX:for backward compatability look up old name44 // for backward compatability look up old name 17 45 maskBad = pmConfigMaskGet("BAD", config); 18 46 } … … 73 101 } 74 102 103 // display the image, weight, mask (ch 1,2,3) 104 psphotVisualShowImage (readout); 105 75 106 return true; 76 107 } -
branches/tap_branches/psphot/src/psphotMergeSources.c
r21519 r27838 5 5 PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_EXT_LIMIT) // Mask to apply for PSF sources 6 6 7 // for now, let's store the detections on the readout->analysis for each readout 8 bool psphotMergeSources (pmConfig *config, const pmFPAview *view) 9 { 10 bool status = true; 11 12 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 13 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 14 15 // loop over the available readouts 16 for (int i = 0; i < num; i++) { 17 if (!psphotMergeSourcesReadout (config, view, "PSPHOT.INPUT", i)) { 18 psError (PSPHOT_ERR_CONFIG, false, "failed to merge sources for PSPHOT.INPUT entry %d", i); 19 return false; 20 } 21 } 22 return true; 23 } 24 7 25 // add newly selected sources to the existing list of sources 8 bool psphotMergeSources (psArray *oldSources, psArray *newSources) { 26 bool psphotMergeSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index) { 27 28 bool status; 29 30 // find the currently selected readout 31 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 32 psAssert (file, "missing file?"); 33 34 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 35 psAssert (readout, "missing readout?"); 36 37 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 38 psAssert (detections, "missing detections?"); 39 40 psArray *newSources = detections->newSources; 41 psAssert (newSources, "missing sources?"); 42 43 // XXX TEST: 44 if (detections->allSources) { 45 psphotMaskCosmicRayFootprintCheck(detections->allSources); 46 } 47 if (detections->newSources) { 48 psphotMaskCosmicRayFootprintCheck(detections->newSources); 49 } 50 51 if (!detections->allSources) { 52 detections->allSources = psArrayAllocEmpty(newSources->n); 53 } 54 psArray *allSources = detections->allSources; 9 55 10 56 for (int i = 0; i < newSources->n; i++) { 11 57 pmSource *source = newSources->data[i]; 12 psArrayAdd (oldSources, 100, source); 13 } 14 return true; 15 } 16 17 // merge the externally supplied sources with the existing sources. mark them as having 18 // mode PM_SOURCE_MODE_EXTERNAL 19 bool psphotLoadExtSources (pmConfig *config, const pmFPAview *view, psArray *sources) { 20 21 // find the currently selected readout 22 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT.CMF"); 23 if (!readout) { 24 psLogMsg ("psphot", 3, "no external sources supplied"); 25 return true; 26 } 27 28 psArray *extSources = psMetadataLookupPtr (NULL, readout->analysis, "PSPHOT.SOURCES"); 29 if (!extSources) { 58 psArrayAdd (allSources, 100, source); 59 } 60 61 psFree (detections->newSources); 62 detections->newSources = NULL; 63 64 return true; 65 } 66 67 // Merge the externally supplied sources with the existing sources. Mark them as having mode 68 // PM_SOURCE_MODE_EXTERNAL. 69 70 // XXX This function needs to be updated to loop over set of input files. At the moment, we 71 // only expect a single entry for PSPHOT.INPUT.CMF and PSPHOT.SOURCES.TEXT, so we can only 72 // associate input sources with a single entry for PSPHOT.INPUT 73 bool psphotLoadExtSources (pmConfig *config, const pmFPAview *view) { 74 75 bool status; 76 pmDetections *extCMF = NULL; 77 psArray *extSourcesTXT = NULL; 78 int index = 0; 79 80 // find the currently selected readout 81 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", index); // File of interest 82 psAssert (file, "missing file?"); 83 84 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 85 psAssert (readout, "missing readout?"); 86 87 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 88 if (!detections) { 89 detections = pmDetectionsAlloc(); 90 detections->newSources = psArrayAllocEmpty (100); 91 // save detections on the readout->analysis 92 if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot detections", detections)) { 93 psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout"); 94 return false; 95 } 96 } else { 97 psMemIncrRefCounter(detections); // so we can free the detections below 98 } 99 100 psArray *sources = detections->newSources; 101 psAssert (sources, "missing sources?"); 102 103 // load data from input CMF file: 104 { 105 pmReadout *readoutCMF = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT.CMF"); 106 if (!readoutCMF) goto loadTXT; 107 108 extCMF = psMetadataLookupPtr (NULL, readoutCMF->analysis, "PSPHOT.DETECTIONS"); 109 if (extCMF) { 110 for (int i = 0; i < extCMF->allSources->n; i++) { 111 pmSource *source = extCMF->allSources->data[i]; 112 source->mode |= PM_SOURCE_MODE_EXTERNAL; 113 114 // the supplied peak flux needs to be re-normalized 115 source->peak->flux = 1.0; 116 source->peak->value = 1.0; 117 118 // drop the loaded source modelPSF 119 psFree (source->modelPSF); 120 source->modelPSF = NULL; 121 source->imageID = index; 122 123 psArrayAdd (detections->newSources, 100, source); 124 } 125 } 126 } 127 128 loadTXT: 129 130 // load data from input TXT file: 131 { 132 pmChip *chipTXT = pmFPAfileThisChip (config->files, view, "PSPHOT.INPUT"); 133 if (!chipTXT) goto finish; 134 135 extSourcesTXT = psMetadataLookupPtr (NULL, chipTXT->analysis, "PSPHOT.SOURCES.TEXT"); 136 if (extSourcesTXT) { 137 for (int i = 0; i < extSourcesTXT->n; i++) { 138 pmSource *source = extSourcesTXT->data[i]; 139 source->mode |= PM_SOURCE_MODE_EXTERNAL; 140 141 // drop the loaded source modelPSF 142 psFree (source->modelPSF); 143 source->modelPSF = NULL; 144 source->imageID = index; 145 146 psArrayAdd (detections->newSources, 100, source); 147 } 148 } 149 } 150 151 finish: 152 153 psFree (detections); 154 155 if (!extCMF && !extSourcesTXT) { 30 156 psLogMsg ("psphot", 3, "no external sources for this readout"); 31 157 return true; 32 158 } 33 159 34 for (int i = 0; i < extSources->n; i++) { 35 pmSource *source = extSources->data[i]; 36 source->mode |= PM_SOURCE_MODE_EXTERNAL; 37 pmModel *model = source->modelPSF; 38 39 float xpos = model->params->data.F32[PM_PAR_XPOS]; 40 float ypos = model->params->data.F32[PM_PAR_YPOS]; 41 42 source->peak = pmPeakAlloc(xpos, ypos, 1.0, PM_PEAK_LONE); 43 source->peak->xf = xpos; 44 source->peak->yf = ypos; 45 source->peak->flux = 1.0; 46 47 // drop the loaded source modelPSF 48 psFree (source->modelPSF); 49 source->modelPSF = NULL; 50 } 51 52 psphotMergeSources (sources, extSources); 53 psLogMsg ("psphot", 3, "%ld external sources merged to yield %ld total sources", extSources->n, sources->n); 54 160 int nCMF = extCMF ? extCMF->allSources->n : 0; 161 int nTXT = extSourcesTXT ? extSourcesTXT->n : 0; 162 163 psLogMsg ("psphot", 3, "%d external sources (%d cmf, %d text) merged to yield %ld total sources", 164 nCMF + nTXT, nCMF, nTXT, sources->n); 55 165 return true; 56 166 } 57 167 58 168 // extract the input sources corresponding to this readout 169 // XXX this function needs to be updated to work with the new context of pshot inputs 59 170 psArray *psphotLoadPSFSources (pmConfig *config, const pmFPAview *view) { 171 172 bool status; 60 173 61 174 // find the currently selected readout … … 66 179 } 67 180 68 psArray *sources = psMetadataLookupPtr (NULL, readout->analysis, "PSPHOT.SOURCES"); 181 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 182 if (!detections) { 183 psLogMsg ("psphot", 3, "no psf sources for this readout"); 184 return NULL; 185 } 186 187 psArray *sources = detections->allSources; 69 188 if (!sources) { 70 189 psLogMsg ("psphot", 3, "no psf sources for this readout"); 190 return NULL; 71 191 } 72 192 … … 74 194 } 75 195 196 // this function is used to fix sources which were loaded externally, but have passed from 197 // psphotDetectionsFromSources to psphotSourceStats and are now stored on 198 // detections->newSources. 199 bool psphotRepairLoadedSources (pmConfig *config, const pmFPAview *view) { 200 201 // find the currently selected readout 202 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", 0); // File of interest 203 psAssert (file, "missing file?"); 204 205 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 206 psAssert (readout, "missing readout?"); 207 208 pmDetections *detections = psMetadataLookupPtr (NULL, readout->analysis, "PSPHOT.DETECTIONS"); 209 if (!detections) { 210 psError(PSPHOT_ERR_CONFIG, false, "missing detections"); 211 return false; 212 } 213 214 psArray *sources = detections->newSources; 215 psAssert (sources, "missing sources?"); 216 217 // peak flux is wrong : set based on previous image 218 // use the peak measured in the moments analysis: 219 for (int i = 0; i < sources->n; i++) { 220 pmSource *source = sources->data[i]; 221 source->peak->flux = source->moments->Peak; 222 } 223 224 return true; 225 } 226 76 227 // generate the detection structure for the supplied array of sources 77 pmDetections *psphotDetectionsFromSources (pmConfig *config, psArray *sources) { 228 // XXX this currently assumes there is a single input file 229 bool psphotDetectionsFromSources (pmConfig *config, const pmFPAview *view, psArray *sources) { 230 231 // find the currently selected readout 232 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", 0); // File of interest 233 psAssert (file, "missing file?"); 234 235 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 236 psAssert (readout, "missing readout?"); 78 237 79 238 pmDetections *detections = pmDetectionsAlloc(); … … 88 247 float snMin = psMetadataLookupF32(NULL, recipe, "MOMENTS_SN_MIN"); 89 248 if (!isfinite(snMin)) { 90 return NULL;249 return false; 91 250 } 92 251 … … 96 255 97 256 if (source->mode & PSF_SOURCE_MASK || !isfinite(source->psfMag)) { 257 continue; 258 } 259 260 // use the existing peak information, otherwise generate a new peak 261 if (source->peak) { 262 source->peak->assigned = false; // So the moments will be measured 263 psArrayAdd (detections->peaks, 100, source->peak); 98 264 continue; 99 265 } … … 108 274 peak->flux = flux; // this are being set wrong, but does it matter? 109 275 110 if (isfinite (source->errMag) && (source->errMag > 0.0)) {111 peak->SN = 1.0 / source->errMag; 112 } else {113 peak->SN = 0.0;114 }276 if (isfinite (source->errMag) && (source->errMag > 0.0)) { 277 peak->SN = 1.0 / source->errMag; 278 } else { 279 peak->SN = 0.0; 280 } 115 281 116 282 psArrayAdd (detections->peaks, 100, peak); … … 120 286 psLogMsg ("psphot", 3, "%ld PSF sources loaded", detections->peaks->n); 121 287 122 return detections; 288 // save detections on the readout->analysis 289 if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot detectinos", detections)) { 290 psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout"); 291 return false; 292 } 293 psFree (detections); 294 return true; 123 295 } 124 296 … … 149 321 peak->flux = flux; // this are being set wrong, but does it matter? 150 322 151 if (isfinite (source->errMag) && (source->errMag > 0.0)) {152 peak->SN = 1.0 / source->errMag; 153 } else {154 peak->SN = 0.0;155 }323 if (isfinite (source->errMag) && (source->errMag > 0.0)) { 324 peak->SN = 1.0 / source->errMag; 325 } else { 326 peak->SN = 0.0; 327 } 156 328 157 329 source->peak = peak; … … 162 334 return true; 163 335 } 336 337 bool psphotCheckExtSources (pmConfig *config, const pmFPAview *view) { 338 339 bool status; 340 341 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE); 342 psAssert (recipe, "missing recipe"); 343 344 // find the currently selected readout 345 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", 0); // File of interest 346 psAssert (file, "missing file?"); 347 348 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 349 psAssert (readout, "missing readout?"); 350 351 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 352 psAssert (detections, "missing detections?"); 353 354 // XXX allSources of newSources? 355 psArray *sources = detections->allSources; 356 psAssert (sources, "missing sources?"); 357 358 if (sources->n) { 359 // the user wants to make the psf from these stars; define them as psf stars: 360 for (int i = 0; i < sources->n; i++) { 361 pmSource *source = sources->data[i]; 362 source->mode |= PM_SOURCE_MODE_PSFSTAR; 363 } 364 // force psphotChoosePSF to use all loaded sources 365 psMetadataAddS32 (recipe, PS_LIST_TAIL, "PSF_MAX_NSTARS", PS_META_REPLACE, "max number of sources for PSF model", sources->n); 366 367 // measure stats of externally specified sources 368 if (!psphotSourceStatsUpdate (sources, config, readout)) { 369 psError(PSPHOT_ERR_CONFIG, false, "failure to measure stats of existing sources"); 370 return false; 371 } 372 } else { 373 374 // find the detections (by peak and/or footprint) in the image. 375 if (!psphotFindDetections (config, view, true)) { 376 psError(PSPHOT_ERR_CONFIG, false, "unable to find detections in this image"); 377 return psphotReadoutCleanup (config, view); 378 } 379 380 // construct sources and measure basic stats 381 psphotSourceStats (config, view, true); 382 383 // find blended neighbors of very saturated stars 384 psphotDeblendSatstars (config, view); 385 386 // mark blended peaks PS_SOURCE_BLEND 387 if (!psphotBasicDeblend (config, view)) { 388 psLogMsg ("psphot", 3, "failed on deblend analysis"); 389 return psphotReadoutCleanup (config, view); 390 } 391 392 // classify sources based on moments, brightness 393 if (!psphotRoughClass (config, view)) { 394 psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image"); 395 return psphotReadoutCleanup (config, view); 396 } 397 } 398 399 return true; 400 } -
branches/tap_branches/psphot/src/psphotModelBackground.c
r24188 r27838 5 5 // Determine the binning characteristics for the background model 6 6 // Sets the ruff image size and skip based on recipe values for the binning 7 static psImageBinning *backgroundBinning(const psImage *image, // Image for which to generate a bg model7 psImageBinning *psphotBackgroundBinning(const psImage *image, // Image for which to generate a bg model 8 8 const pmConfig *config // Configuration 9 9 ) … … 28 28 } 29 29 30 30 31 // Generate the background model 31 static bool backgroundModel(psImage *model, // Model image 32 psImage *modelStdev, // Model stdev image 33 psMetadata *analysis, // Analysis metadata for outputs 34 pmReadout *readout, // Readout for which to generate a background model 35 psImageBinning *binning, // Binning parameters 36 const pmConfig *config // Configuration 37 ) 32 // generate the median in NxN boxes, clipping heavily 33 // linear interpolation to generate full-scale model 34 // 35 // NOTE that the 'analysis' metedata pass in here is used to store the binning information. 36 // This may be the analysis for this readout, but it may be the analysis for the pmFPAfile 37 // corresponding to the model. Other information about the background model is saved on the 38 // readout->analysis 39 static bool psphotModelBackgroundReadout(psImage *model, // Model image 40 psImage *modelStdev, // Model stdev image 41 psMetadata *analysis, // Analysis metadata for outputs 42 pmReadout *readout, // Readout for which to generate a background model 43 psImageBinning *binning, // Binning parameters 44 const pmConfig *config // Configuration 45 ) 38 46 { 39 47 psTimerStart ("psphot.background"); … … 137 145 138 146 // we save the binning structure for use in psphotMagnitudes 139 psMetadataAddPtr(analysis, PS_LIST_TAIL, "PSPHOT.BACKGROUND.BINNING", 140 PS_DATA_UNKNOWN | PS_META_REPLACE, "Background binning", binning); 147 psMetadataAddPtr(analysis, PS_LIST_TAIL, "PSPHOT.BACKGROUND.BINNING", PS_DATA_UNKNOWN | PS_META_REPLACE, "Background binning", binning); 141 148 142 149 psF32 **modelData = model->data.F32; … … 144 151 145 152 // XXXX we can thread this here by running blocks in parallel 153 154 int nFailures = 0; 155 psImageBackgroundInit(); 146 156 147 157 // measure clipped median for subimages … … 211 221 stats->options = PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV; 212 222 if (!psImageBackground(stats, &sample, subset, submask, maskVal, rng)) { 213 psLogMsg ("psphot", PS_LOG_WARN, "Failed to estimate background using ROBUST_MEDIAN for " 214 "(%dx%d, (row0,col0) = (%d,%d)", 215 subset->numRows, subset->numCols, subset->row0, subset->col0); 223 if ((nFailures < 3) || (nFailures % 100 == 0)) { 224 psLogMsg ("psphot", PS_LOG_WARN, "Failed to estimate background using ROBUST_MEDIAN for " 225 "(%dx%d, (row0,col0) = (%d,%d)", 226 subset->numRows, subset->numCols, subset->row0, subset->col0); 227 } 228 nFailures ++; 216 229 modelData[iy][ix] = modelStdevData[iy][ix] = NAN; 217 230 } else { … … 232 245 psFree (submask); 233 246 } 247 } 248 249 if (nFailures) { 250 psLogMsg ("psphot", PS_LOG_WARN, "Failed to estimate background for %d of %d subimages", nFailures, (model->numRows*model->numCols)); 234 251 } 235 252 … … 293 310 psLogMsg ("psphot", PS_LOG_INFO, "built background image: %f sec\n", psTimerMark ("psphot.background")); 294 311 295 psMetadataAddF32(re cipe, PS_LIST_TAIL, "SKY_MEAN", PS_META_REPLACE, "sky mean", Value);296 psMetadataAddF32(re cipe, PS_LIST_TAIL, "SKY_STDEV", PS_META_REPLACE, "sky stdev", ValueStdev);312 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_MEAN", PS_META_REPLACE, "sky mean", Value); 313 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_STDEV", PS_META_REPLACE, "sky stdev", ValueStdev); 297 314 psLogMsg ("psphot", PS_LOG_INFO, "image sky : mean %f stdev %f", Value, ValueStdev); 298 315 … … 303 320 PS_STAT_MAX); 304 321 psImageStats (statsBck, model, NULL, 0); 305 psMetadataAddF32 (recipe, PS_LIST_TAIL, "MSKY_MN", 306 PS_META_REPLACE, "sky model mean", statsBck->sampleMean); 307 psMetadataAddF32 (recipe, PS_LIST_TAIL, "MSKY_SIG", 308 PS_META_REPLACE, "sky model stdev", statsBck->sampleStdev); 309 psMetadataAddF32 (recipe, PS_LIST_TAIL, "MSKY_MAX", 310 PS_META_REPLACE, "sky model maximum value", statsBck->max); 311 psMetadataAddF32 (recipe, PS_LIST_TAIL, "MSKY_MIN", 312 PS_META_REPLACE, "sky model minimum value", statsBck->min); 313 psMetadataAddS32 (recipe, PS_LIST_TAIL, "MSKY_NX", 314 PS_META_REPLACE, "sky model size (x)", model->numCols); 315 psMetadataAddS32 (recipe, PS_LIST_TAIL, "MSKY_NY", 316 PS_META_REPLACE, "sky model size (y)", model->numRows); 322 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MN", PS_META_REPLACE, "sky model mean", statsBck->sampleMean); 323 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_SIG", PS_META_REPLACE, "sky model stdev", statsBck->sampleStdev); 324 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MAX", PS_META_REPLACE, "sky model maximum value", statsBck->max); 325 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MIN", PS_META_REPLACE, "sky model minimum value", statsBck->min); 326 psMetadataAddS32 (readout->analysis, PS_LIST_TAIL, "MSKY_NX", PS_META_REPLACE, "sky model size (x)", model->numCols); 327 psMetadataAddS32 (readout->analysis, PS_LIST_TAIL, "MSKY_NY", PS_META_REPLACE, "sky model size (y)", model->numRows); 317 328 psLogMsg ("psphot", PS_LOG_INFO, "background sky : min %f mean %f max %f stdev %f", 318 329 statsBck->min, statsBck->sampleMean, statsBck->max, statsBck->sampleStdev); … … 327 338 } 328 339 329 330 331 psImage *psphotBackgroundModel(pmReadout *ro, const pmConfig *config) 340 // generate a background model for a single readout. do not save an associated pmFPAfile for possible output 341 psImage *psphotModelBackgroundReadoutNoFile(pmReadout *readout, const pmConfig *config) 332 342 { 333 PM_ASSERT_READOUT_NON_NULL(r o, NULL);334 PM_ASSERT_READOUT_IMAGE(r o, NULL);343 PM_ASSERT_READOUT_NON_NULL(readout, NULL); 344 PM_ASSERT_READOUT_IMAGE(readout, NULL); 335 345 PS_ASSERT_PTR_NON_NULL(config, NULL); 336 346 337 psImageBinning *binning = backgroundBinning(ro->image, config); // Image binning parameters347 psImageBinning *binning = psphotBackgroundBinning(readout->image, config); // Image binning parameters 338 348 psImage *model = psImageAlloc(binning->nXruff, binning->nYruff, PS_TYPE_F32); // Background model 339 349 psImage *modelStdev = psImageAlloc(binning->nXruff, binning->nYruff, PS_TYPE_F32); // Standard deviation 340 350 341 if (! backgroundModel(model, modelStdev, ro->analysis, ro, binning, config)) {351 if (!psphotModelBackgroundReadout(model, modelStdev, readout->analysis, readout, binning, config)) { 342 352 psFree(model); 343 353 psFree(modelStdev); … … 345 355 return NULL; 346 356 } 347 348 357 psFree(modelStdev); 349 350 358 return model; 351 359 } 352 360 353 354 // generate the median in NxN boxes, clipping heavily 355 // linear interpolation to generate full-scale model 356 bool psphotModelBackground (pmConfig *config, const pmFPAview *view, const char *filename) 361 // generate a background model for readout number index; save an associated pmFPAfile for possible output 362 bool psphotModelBackgroundReadoutFileIndex (pmConfig *config, const pmFPAview *view, const char *filename, int index) 357 363 { 358 bool status = true;359 360 364 // find the currently selected readout 361 pmFPAfile *file = psMetadataLookupPtr (&status, config->files, filename); 365 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 366 psAssert (file, "missing file?"); 367 362 368 pmFPA *inFPA = file->fpa; 363 369 pmReadout *readout = pmFPAviewThisReadout(view, inFPA); 364 365 psImageBinning *binning = backgroundBinning(readout->image, config); // Image binning parameters 366 pmReadout *model = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL", inFPA, binning); 367 pmReadout *modelStdev = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL.STDEV", inFPA, binning); 368 369 if (!backgroundModel(model->image, modelStdev->image, model->analysis, readout, binning, config)) { 370 psAssert (readout, "missing readout?"); 371 372 psImageBinning *binning = psphotBackgroundBinning(readout->image, config); // Image binning parameters 373 pmReadout *model = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL", inFPA, binning, index); 374 pmReadout *modelStdev = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL.STDEV", inFPA, binning, index); 375 376 if (!psphotModelBackgroundReadout(model->image, modelStdev->image, model->analysis, readout, binning, config)) { 370 377 psError(PS_ERR_UNKNOWN, false, "Unable to generate background model"); 371 378 return false; … … 375 382 return true; 376 383 } 384 385 // XXX supply filename or keep PSPHOT.INPUT fixed? 386 bool psphotModelBackground (pmConfig *config, const pmFPAview *view) 387 { 388 bool status = false; 389 390 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 391 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 392 393 // loop over the available readouts 394 for (int i = 0; i < num; i++) { 395 if (!psphotModelBackgroundReadoutFileIndex(config, view, "PSPHOT.INPUT", i)) { 396 psError (PSPHOT_ERR_CONFIG, false, "failed to model background for PSPHOT.INPUT entry %d", i); 397 return false; 398 } 399 } 400 return true; 401 } -
branches/tap_branches/psphot/src/psphotModelTest.c
r24588 r27838 139 139 140 140 // get the source moments 141 status = pmSourceMoments (source, mRADIUS, 0.0, 1.0 );141 status = pmSourceMoments (source, mRADIUS, 0.0, 1.0, maskVal); 142 142 if (!status) psAbort("psSourceMoments error"); 143 143 source->peak->value = source->moments->Peak; -
branches/tap_branches/psphot/src/psphotMomentsStudy.c
r24585 r27838 148 148 pmSourceAdd(source, PM_MODEL_OP_FUNC, 0); 149 149 150 pmSourceMoments (source, 32.0, sigWindow, 0.0 );150 pmSourceMoments (source, 32.0, sigWindow, 0.0, 0xffff); 151 151 // fprintf (stderr, "sigOut : %f\n", sqrt(source->moments->Mxx)); 152 152 -
branches/tap_branches/psphot/src/psphotOutput.c
r25755 r27838 126 126 } 127 127 128 bool psphotAddPhotcode (psMetadata *recipe, pmConfig *config, const pmFPAview *view, const char *filerule) { 129 130 bool status; 131 132 pmFPAfile *input = psMetadataLookupPtr (&status, config->files, filerule); 133 PS_ASSERT (status, false); 134 135 // determine PHOTCODE from fpa & view, overwrite in recipe 136 char *photcode = pmConceptsPhotcodeForView (input, view); 128 bool psphotAddPhotcode (pmConfig *config, const pmFPAview *view) { 129 130 bool status = false; 131 132 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 133 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 134 135 // loop over the available readouts 136 for (int i = 0; i < num; i++) { 137 if (!psphotAddPhotcodeReadout (config, view, "PSPHOT.INPUT", i)) { 138 psError (PSPHOT_ERR_CONFIG, false, "failed to add photcode to PSPHOT.INPUT entry %d", i); 139 return false; 140 } 141 } 142 return true; 143 } 144 145 bool psphotAddPhotcodeReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index) { 146 147 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, index); // File of interest 148 PS_ASSERT (file, false); 149 150 pmReadout *readout = pmFPAviewThisReadout (view, file->fpa); 151 152 // determine PHOTCODE from fpa & view, overwrite in readout->analysis 153 char *photcode = pmConceptsPhotcodeForView (file, view); 137 154 PS_ASSERT (photcode, false); 138 155 139 psMetadataAddStr (re cipe, PS_LIST_TAIL, "PHOTCODE", PS_META_REPLACE, "photcode from FPA concepts", photcode);156 psMetadataAddStr (readout->analysis, PS_LIST_TAIL, "PHOTCODE", PS_META_REPLACE, "photcode from FPA concepts", photcode); 140 157 psLogMsg ("psphot", 3, "PHOTCODE is %s", photcode); 141 158 … … 144 161 } 145 162 146 bool psphotSetHeaderNstars (psMetadata * recipe, psArray *sources) {163 bool psphotSetHeaderNstars (psMetadata *header, psArray *sources) { 147 164 148 165 int nSrc = 0; … … 173 190 } 174 191 175 psMetadataAddS32 (recipe, PS_LIST_TAIL, "NSTARS", PS_META_REPLACE, "Number of sources", nSrc); 176 psMetadataAddS32 (recipe, PS_LIST_TAIL, "NDET_EXT", PS_META_REPLACE, "Number of extended sources", nEXT); 177 psMetadataAddS32 (recipe, PS_LIST_TAIL, "NDET_CR", PS_META_REPLACE, "Number of cosmic rays", nCR); 178 return true; 179 } 180 181 // these values are saved in an output header stub - they are added to either the 182 // PHU header (CMP) or the MEF table header (CMF) 183 psMetadata *psphotDefineHeader (psMetadata *recipe) { 192 psMetadataAddS32 (header, PS_LIST_TAIL, "NSTARS", PS_META_REPLACE, "Number of sources", nSrc); 193 psMetadataAddS32 (header, PS_LIST_TAIL, "NDET_EXT", PS_META_REPLACE, "Number of extended sources", nEXT); 194 psMetadataAddS32 (header, PS_LIST_TAIL, "NDET_CR", PS_META_REPLACE, "Number of cosmic rays", nCR); 195 return true; 196 } 197 198 // these values are saved in an output header stub - they are added to either the PHU header 199 // (CMP) or the MEF table header (CMF). before the header is created, each readout has these 200 // values stored on readout->analysis 201 psMetadata *psphotDefineHeader (psMetadata *analysis) { 202 203 bool status = true; 184 204 185 205 psMetadata *header = psMetadataAlloc (); 186 206 187 207 // write necessary information to output header 188 psMetadataItemSupplement ( header, recipe, "ZERO_PT");189 psMetadataItemSupplement ( header, recipe, "PHOTCODE");190 191 psMetadataItemSupplement ( header, recipe, "APMIFIT");192 psMetadataItemSupplement ( header, recipe, "DAPMIFIT");193 psMetadataItemSupplement ( header, recipe, "NAPMIFIT");208 psMetadataItemSupplement (&status, header, analysis, "ZERO_PT"); 209 psMetadataItemSupplement (&status, header, analysis, "PHOTCODE"); 210 211 psMetadataItemSupplement (&status, header, analysis, "APMIFIT"); 212 psMetadataItemSupplement (&status, header, analysis, "DAPMIFIT"); 213 psMetadataItemSupplement (&status, header, analysis, "NAPMIFIT"); 194 214 195 215 // PSF model parameters (shape values for image center) 196 psMetadataItemSupplement ( header, recipe, "NPSFSTAR");197 psMetadataItemSupplement ( header, recipe, "APLOSS");198 199 psMetadataItemSupplement ( header, recipe, "FWHM_MAJ");200 psMetadataItemSupplement ( header, recipe, "FW_MJ_SG");201 psMetadataItemSupplement ( header, recipe, "FW_MJ_LQ");202 psMetadataItemSupplement ( header, recipe, "FW_MJ_UQ");203 204 psMetadataItemSupplement ( header, recipe, "FWHM_MIN");205 psMetadataItemSupplement ( header, recipe, "FW_MN_SG");206 psMetadataItemSupplement ( header, recipe, "FW_MN_LQ");207 psMetadataItemSupplement ( header, recipe, "FW_MN_UQ");208 209 psMetadataItemSupplement ( header, recipe, "ANGLE");216 psMetadataItemSupplement (&status, header, analysis, "NPSFSTAR"); 217 psMetadataItemSupplement (&status, header, analysis, "APLOSS"); 218 219 psMetadataItemSupplement (&status, header, analysis, "FWHM_MAJ"); 220 psMetadataItemSupplement (&status, header, analysis, "FW_MJ_SG"); 221 psMetadataItemSupplement (&status, header, analysis, "FW_MJ_LQ"); 222 psMetadataItemSupplement (&status, header, analysis, "FW_MJ_UQ"); 223 224 psMetadataItemSupplement (&status, header, analysis, "FWHM_MIN"); 225 psMetadataItemSupplement (&status, header, analysis, "FW_MN_SG"); 226 psMetadataItemSupplement (&status, header, analysis, "FW_MN_LQ"); 227 psMetadataItemSupplement (&status, header, analysis, "FW_MN_UQ"); 228 229 psMetadataItemSupplement (&status, header, analysis, "ANGLE"); 210 230 211 231 // Image Quality measurements 212 psMetadataItemSupplement ( header, recipe, "IQ_NSTAR");213 214 psMetadataItemSupplement ( header, recipe, "IQ_FW1");215 psMetadataItemSupplement ( header, recipe, "IQ_FW1_E");216 psMetadataItemSupplement ( header, recipe, "IQ_FW2");217 psMetadataItemSupplement ( header, recipe, "IQ_FW2_E");218 219 psMetadataItemSupplement ( header, recipe, "IQ_M2");220 psMetadataItemSupplement ( header, recipe, "IQ_M2_ER");221 psMetadataItemSupplement ( header, recipe, "IQ_M2_LQ");222 psMetadataItemSupplement ( header, recipe, "IQ_M2_UQ");223 224 psMetadataItemSupplement ( header, recipe, "IQ_M2C");225 psMetadataItemSupplement ( header, recipe, "IQ_M2C_E");226 psMetadataItemSupplement ( header, recipe, "IQ_M2C_L");227 psMetadataItemSupplement ( header, recipe, "IQ_M2C_U");228 229 psMetadataItemSupplement ( header, recipe, "IQ_M2S");230 psMetadataItemSupplement ( header, recipe, "IQ_M2S_E");231 psMetadataItemSupplement ( header, recipe, "IQ_M2S_L");232 psMetadataItemSupplement ( header, recipe, "IQ_M2S_U");233 234 psMetadataItemSupplement ( header, recipe, "IQ_M3");235 psMetadataItemSupplement ( header, recipe, "IQ_M3_ER");236 psMetadataItemSupplement ( header, recipe, "IQ_M3_LQ");237 psMetadataItemSupplement ( header, recipe, "IQ_M3_UQ");238 239 psMetadataItemSupplement ( header, recipe, "IQ_M4");240 psMetadataItemSupplement ( header, recipe, "IQ_M4_ER");241 psMetadataItemSupplement ( header, recipe, "IQ_M4_LQ");242 psMetadataItemSupplement ( header, recipe, "IQ_M4_UQ");232 psMetadataItemSupplement (&status, header, analysis, "IQ_NSTAR"); 233 234 psMetadataItemSupplement (&status, header, analysis, "IQ_FW1"); 235 psMetadataItemSupplement (&status, header, analysis, "IQ_FW1_E"); 236 psMetadataItemSupplement (&status, header, analysis, "IQ_FW2"); 237 psMetadataItemSupplement (&status, header, analysis, "IQ_FW2_E"); 238 239 psMetadataItemSupplement (&status, header, analysis, "IQ_M2"); 240 psMetadataItemSupplement (&status, header, analysis, "IQ_M2_ER"); 241 psMetadataItemSupplement (&status, header, analysis, "IQ_M2_LQ"); 242 psMetadataItemSupplement (&status, header, analysis, "IQ_M2_UQ"); 243 244 psMetadataItemSupplement (&status, header, analysis, "IQ_M2C"); 245 psMetadataItemSupplement (&status, header, analysis, "IQ_M2C_E"); 246 psMetadataItemSupplement (&status, header, analysis, "IQ_M2C_L"); 247 psMetadataItemSupplement (&status, header, analysis, "IQ_M2C_U"); 248 249 psMetadataItemSupplement (&status, header, analysis, "IQ_M2S"); 250 psMetadataItemSupplement (&status, header, analysis, "IQ_M2S_E"); 251 psMetadataItemSupplement (&status, header, analysis, "IQ_M2S_L"); 252 psMetadataItemSupplement (&status, header, analysis, "IQ_M2S_U"); 253 254 psMetadataItemSupplement (&status, header, analysis, "IQ_M3"); 255 psMetadataItemSupplement (&status, header, analysis, "IQ_M3_ER"); 256 psMetadataItemSupplement (&status, header, analysis, "IQ_M3_LQ"); 257 psMetadataItemSupplement (&status, header, analysis, "IQ_M3_UQ"); 258 259 psMetadataItemSupplement (&status, header, analysis, "IQ_M4"); 260 psMetadataItemSupplement (&status, header, analysis, "IQ_M4_ER"); 261 psMetadataItemSupplement (&status, header, analysis, "IQ_M4_LQ"); 262 psMetadataItemSupplement (&status, header, analysis, "IQ_M4_UQ"); 243 263 244 264 // XXX these need to be defined from elsewhere 245 265 psMetadataAdd (header, PS_LIST_TAIL, "FSATUR", PS_DATA_F32 | PS_META_REPLACE, "SATURATION MAG", 0.0); 246 266 psMetadataAdd (header, PS_LIST_TAIL, "FLIMIT", PS_DATA_F32 | PS_META_REPLACE, "COMPLETENESS MAG", 0.0); 247 psMetadataItemSupplement ( header, recipe, "NSTARS");248 249 psMetadataItemSupplement ( header, recipe, "NDET_EXT");250 psMetadataItemSupplement ( header, recipe, "NDET_CR");267 psMetadataItemSupplement (&status, header, analysis, "NSTARS"); 268 269 psMetadataItemSupplement (&status, header, analysis, "NDET_EXT"); 270 psMetadataItemSupplement (&status, header, analysis, "NDET_CR"); 251 271 252 272 // sky background model statistics 253 psMetadataItemSupplement ( header, recipe, "MSKY_MN");254 psMetadataItemSupplement ( header, recipe, "MSKY_SIG");255 psMetadataItemSupplement ( header, recipe, "MSKY_MIN");256 psMetadataItemSupplement ( header, recipe, "MSKY_MAX");257 psMetadataItemSupplement ( header, recipe, "MSKY_NX");258 psMetadataItemSupplement ( header, recipe, "MSKY_NY");273 psMetadataItemSupplement (&status, header, analysis, "MSKY_MN"); 274 psMetadataItemSupplement (&status, header, analysis, "MSKY_SIG"); 275 psMetadataItemSupplement (&status, header, analysis, "MSKY_MIN"); 276 psMetadataItemSupplement (&status, header, analysis, "MSKY_MAX"); 277 psMetadataItemSupplement (&status, header, analysis, "MSKY_NX"); 278 psMetadataItemSupplement (&status, header, analysis, "MSKY_NY"); 259 279 260 280 psMetadataAddF32 (header, PS_LIST_TAIL, "DT_PHOT", PS_META_REPLACE, "elapsed psphot time", psTimerMark ("psphotReadout")); 261 262 // XXX : don't require any of these about values to exist263 psErrorClear ();264 281 265 282 return header; -
branches/tap_branches/psphot/src/psphotPSFConvModel.c
r25755 r27838 39 39 // adjust the pixels based on the footprint 40 40 float radius = psphotSetRadiusEXT (readout, source, markVal); 41 if (!pmSourceMoments (source, radius, 0.0, 0.0 )) return false;41 if (!pmSourceMoments (source, radius, 0.0, 0.0, maskVal)) return false; 42 42 43 43 // XXX test : modify the Io, SXX, SYY terms based on the psf SXX, SYY terms: -
branches/tap_branches/psphot/src/psphotParseCamera.c
r21458 r27838 39 39 return NULL; 40 40 } 41 // specify the number of psphot input images 42 psMetadataAddS32 (config->arguments, PS_LIST_TAIL, "PSPHOT.INPUT.NUM", PS_META_REPLACE, "number of inputs", 1); 41 43 42 44 // define the additional input/output files associated with psphot -
branches/tap_branches/psphot/src/psphotPetrosian.c
r25755 r27838 7 7 8 8 psAssert (source->extpars, "need to run psphotRadialProfile first"); 9 psAssert (source->extpars-> profile, "need to run psphotRadialProfile first");9 psAssert (source->extpars->ellipticalFlux, "need to run psphotRadialProfile first"); 10 10 11 11 // integrate the radial profile for radial bins defined for the petrosian measurement: … … 24 24 psTrace ("psphot", 3, "source at %f,%f: petrosian radius: %f, flux: %f, axis ratio: %f, angle: %f", 25 25 source->peak->xf, source->peak->yf, 26 source->extpars->petrosian _80->radius,27 source->extpars->petrosian _80->flux,28 source->extpars-> profile->axes.minor/source->extpars->profile->axes.major,29 source->extpars-> profile->axes.theta*PS_DEG_RAD);26 source->extpars->petrosianRadius, 27 source->extpars->petrosianFlux, 28 source->extpars->axes.minor/source->extpars->axes.major, 29 source->extpars->axes.theta*PS_DEG_RAD); 30 30 31 31 return true; -
branches/tap_branches/psphot/src/psphotPetrosianRadialBins.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 float InterpolateValues (float X0, float Y0, float X1, float Y1, float X); 2 3 3 4 // convert the flux vs elliptical radius to annular bins … … 5 6 // we are guaranteed to be limited by either the seeing (1 - few pixels) or by the pixels 6 7 // themselves. this function does not attempt to measure the radial profiles accurately 7 // for radii that are smaller than a minimum (currently 1.0 pixels).8 // for radii that are smaller than ~2 pixels 8 9 9 10 // for small radii, we are measuring the mean surface brightness in non-overlapping radial … … 13 14 // track the non-overlapping radius values. 14 15 16 // Photo interpolates the image of interest to place the peak on the center of the central 17 // pixel, and then uses the exact fractions of the pixels in each of the first few annuli. 18 // Seems like a reasonable thing, but is there any significance to the difference? 19 15 20 // XXX move the resulting elements from profile to extpars->petrosian? 16 21 bool psphotPetrosianRadialBins (pmSource *source, float radiusMax, float skynoise) { 17 22 18 p mSourceRadialProfile *profile = source->extpars->profile;19 20 float skyModelErrorSQ = PS_SQR(skynoise);21 22 psVector *radius = profile->radiusElliptical;23 psVector *flux = profile->fluxElliptical;23 psAssert (source, "missing source"); 24 psAssert (source->extpars, "missing extpars"); 25 psAssert (source->extpars->ellipticalFlux, "missing ellipticalFlux"); 26 27 psVector *radius = source->extpars->ellipticalFlux->radiusElliptical; 28 psVector *flux = source->extpars->ellipticalFlux->fluxElliptical; 24 29 25 30 // sort incoming vectors by radius 26 31 pmSourceRadialProfileSortPair (radius, flux); 32 33 if (!source->extpars->petProfile) { 34 source->extpars->petProfile = pmSourceRadialProfileAlloc(); 35 } 36 pmSourceRadialProfile *profile = source->extpars->petProfile; 37 38 float skyModelErrorSQ = PS_SQR(skynoise); 27 39 28 40 int nMax = radiusMax; … … 107 119 psVector *values = psVectorAllocEmpty (flux->n, PS_TYPE_F32); 108 120 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 109 // psStats *stats = psStatsAlloc(PS_STAT_FITTED_MEAN_V4 | PS_STAT_FITTED_STDEV_V4);110 111 // integrate flux, radius for each of these bins. since flux is sorted by radius,112 // we can do this fairly quickly113 121 114 122 bool done = false; … … 133 141 dvalue = NAN; 134 142 } 135 // binSB->data.F32[nOut] = stats->sampleMedian; 143 136 144 binSB->data.F32[nOut] = value; 137 145 binSBstdev->data.F32[nOut] = sqrt(PS_SQR(dvalue) / values->n + skyModelErrorSQ); 138 // binSB->data.F32[nOut] = stats->fittedMean;139 // binSBstdev->data.F32[nOut] = sqrt(PS_SQR(stats->fittedStdev) / values->n + skyModelErrorSQ);140 146 141 147 // error in the SB is the stdev per bin / sqrt (number of pixels) … … 143 149 // residual flux, but the sky from the sky model) 144 150 145 psTrace ("psphot", 5, "%3d %5.1f %5.1f : %5.1f %5.2f\n", 146 nOut, radAlp->data.F32[nOut], radBet->data.F32[nOut], binSB->data.F32[nOut], binSBstdev->data.F32[nOut]); 151 psTrace ("psphot", 5, "%3d %5.1f %5.1f : %5.1f %5.2f\n", nOut, radAlp->data.F32[nOut], radBet->data.F32[nOut], binSB->data.F32[nOut], binSBstdev->data.F32[nOut]); 147 152 148 153 nOut ++; … … 163 168 // XXX I think this misses the last radial bin -- do we care? 164 169 170 // interpolate any bins that were empty (extrapolate to center if needed) 171 if (!isfinite(binSB->data.F32[0]) && !isfinite(binSB->data.F32[1])) { 172 psWarning ("center 2 bins of source at %f, %f are NAN, skipping this source", source->peak->xf, source->peak->yf); 173 // XXX raise a flag 174 psFree(binSB); 175 psFree(binSBstdev); 176 psFree(binRad); 177 psFree(binArea); 178 psFree(radMin); 179 psFree(radMax); 180 psFree(radAlp); 181 psFree(radBet); 182 psFree(values); 183 psFree(stats); 184 return false; 185 } 186 187 // if center bin is empty assume same SB as next radius (probably true due to PSF) 188 if (!isfinite(binSB->data.F32[0])) { 189 binSB->data.F32[0] = binSB->data.F32[1]; 190 binSBstdev->data.F32[0] = binSBstdev->data.F32[1]; 191 } 192 193 // interpolate any bins that were empty (if center if needed) 194 for (int i = 1; i < binSB->n - 1; i++) { 195 if (isfinite(binSB->data.F32[i])) continue; 196 binSB->data.F32[i] = InterpolateValues (binRad->data.F32[i-1], binSB->data.F32[i-1], binRad->data.F32[i+1], binSB->data.F32[i+1], binRad->data.F32[i]); 197 binSBstdev->data.F32[i] = InterpolateValues (binRad->data.F32[i-1], binSBstdev->data.F32[i-1], binRad->data.F32[i+1], binSBstdev->data.F32[i+1], binRad->data.F32[i]); 198 } 199 200 psFree(profile->binSB); 201 psFree(profile->binSBstdev); 202 psFree(profile->radialBins); 203 psFree(profile->area); 204 165 205 // save the vectors 166 206 profile->radialBins = binRad; -
branches/tap_branches/psphot/src/psphotPetrosianStats.c
r25755 r27838 10 10 bool psphotPetrosianStats (pmSource *source) { 11 11 12 pmSourceRadialProfile *profile = source->extpars->profile; 13 14 float petRadius = NAN; 15 float petFlux = NAN; 12 psAssert (source, "missing source"); 13 psAssert (source->extpars, "missing extpars"); 14 psAssert (source->extpars->petProfile, "missing petProfile"); 15 16 pmSourceRadialProfile *profile = source->extpars->petProfile; 16 17 17 18 psVector *binSB = profile->binSB; … … 28 29 psVector *areaSum = psVectorAllocEmpty(binSB->n, PS_TYPE_F32); 29 30 31 float petRadius = NAN; 32 float petFlux = NAN; 33 30 34 bool anyPetro = false; 31 35 bool manyPetro = false; … … 38 42 int lowestSignificantRadius = 0; 39 43 float lowestSignificantRatio = 1.0; 44 45 // find the Petrosian Radius and Petrosian Flux 40 46 41 47 int nOut = 0; … … 142 148 } 143 149 144 if (!source->extpars->petrosian_80) { 145 source->extpars->petrosian_80 = pmSourceExtendedFluxAlloc (); 146 } 147 pmSourceExtendedFlux *petrosian = source->extpars->petrosian_80; 150 // now measure the radii R90 and R50 where flux = 0.9 (or 0.5) * petFlux; 151 float flux90 = 0.9 * petFlux; 152 float flux50 = 0.5 * petFlux; 153 float R50 = NAN; 154 float R90 = NAN; 155 bool found50 = false; 156 bool found90 = false; 157 // XXX use bisection to do this faster: 158 for (int i = 0; !(found50 && found90) && i < refRadius->n; i++) { 159 if (!found50 && (fluxSum->data.F32[i] > flux50)) { 160 if (i == 0) { 161 psWarning ("does this case make any sense? (fluxSum[0] > flux50)"); 162 continue; 163 } else { 164 R50 = InterpolateValues (fluxSum->data.F32[i-1], refRadius->data.F32[i-1], fluxSum->data.F32[i], refRadius->data.F32[i], flux50); 165 found50 = true; 166 } 167 } 168 if (!found90 && (fluxSum->data.F32[i] > flux90)) { 169 if (i == 0) { 170 psWarning ("does this case make any sense? (fluxSum[0] > flux90)"); 171 continue; 172 } else { 173 R90 = InterpolateValues (fluxSum->data.F32[i-1], refRadius->data.F32[i-1], fluxSum->data.F32[i], refRadius->data.F32[i], flux90); 174 found90 = true; 175 } 176 } 177 } 178 148 179 149 180 // XXX save flags (anyPetro, manyPetro) 150 petrosian->radius = petRadius; 151 petrosian->flux = petFlux; 152 153 // psphotPetrosianVisualStats (binRad, binSB, refRadius, meanSB, petRatio, petRatioErr, fluxSum, petRadius, PETROSIAN_RATIO, petFlux, apRadius); 181 source->extpars->petrosianRadius = petRadius; 182 source->extpars->petrosianFlux = petFlux; 183 source->extpars->petrosianR50 = R50; 184 source->extpars->petrosianR90 = R90; 185 186 // XXX add the errors 187 source->extpars->petrosianRadiusErr = NAN; 188 source->extpars->petrosianFluxErr = NAN; 189 source->extpars->petrosianR50Err = NAN; 190 source->extpars->petrosianR90Err = NAN; 191 192 fprintf (stderr, "source @ %f,%f\n", source->peak->xf, source->peak->yf); 193 psphotPetrosianVisualStats (binRad, binSB, refRadius, meanSB, petRatio, petRatioErr, fluxSum, petRadius, PETROSIAN_RATIO, petFlux, apRadius); 154 194 155 195 psFree(fluxSum); -
branches/tap_branches/psphot/src/psphotPetrosianVisual.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 # define FORCE_VISUAL 0 2 3 3 4 // this function displays representative images as the psphot analysis progresses: … … 54 55 55 56 // return true; 56 if (! pmVisualIsVisual()) return true;57 if (!FORCE_VISUAL && !pmVisualIsVisual()) return true; 57 58 58 59 if (kapa2 == -1) { … … 101 102 102 103 // return true; 103 if (! pmVisualIsVisual()) return true;104 if (!FORCE_VISUAL && !pmVisualIsVisual()) return true; 104 105 105 106 if (kapa == -1) { … … 172 173 KapaSection section; 173 174 174 if (!pmVisualIsVisual()) return true; 175 if (!FORCE_VISUAL && !pmVisualIsVisual()) return true; 176 177 if (kapa2 == -1) { 178 kapa2 = KapaOpenNamedSocket ("kapa", "psphot:stats"); 179 if (kapa2 == -1) { 180 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 181 pmVisualSetVisual(false); 182 return false; 183 } 184 } 185 186 KapaClearPlots (kapa2); 187 KapaInitGraph (&graphdata); 188 KapaSetFont (kapa2, "courier", 14); 189 190 // radius vs flux 191 // radius vs mean SB 192 // radius vs petRatio 193 194 // *** section 1: radius vs mean SB 195 section.dx = 1.00; 196 section.dy = 0.33; 197 section.x = 0.00; 198 section.y = 0.00; 199 section.name = psStringCopy ("meanSB"); 200 KapaSetSection (kapa2, §ion); 201 psFree (section.name); 202 203 graphdata.color = KapaColorByName ("black"); 204 pmVisualLimitsFromVectors (&graphdata, radBin, fluxBin); 205 KapaSetLimits (kapa2, &graphdata); 206 207 KapaBox (kapa2, &graphdata); 208 KapaSendLabel (kapa2, "radius", KAPA_LABEL_XM); 209 KapaSendLabel (kapa2, "mean SB", KAPA_LABEL_YM); 210 211 graphdata.color = KapaColorByName ("black"); 212 graphdata.style = 2; 213 graphdata.ptype = 0; 214 graphdata.size = 1.0; 215 KapaPrepPlot (kapa2, radBin->n, &graphdata); 216 KapaPlotVector (kapa2, radBin->n, radBin->data.F32, "x"); 217 KapaPlotVector (kapa2, radBin->n, fluxBin->data.F32, "y"); 218 219 graphdata.color = KapaColorByName ("red"); 220 graphdata.style = 2; 221 graphdata.ptype = 1; 222 graphdata.size = 2.0; 223 KapaPrepPlot (kapa2, refRadius->n, &graphdata); 224 KapaPlotVector (kapa2, refRadius->n, refRadius->data.F32, "x"); 225 KapaPlotVector (kapa2, refRadius->n, meanSB->data.F32, "y"); 226 227 // *** section 2: radius vs petrosian ratio 228 section.dx = 1.00; 229 section.dy = 0.33; 230 section.x = 0.00; 231 section.y = 0.33; 232 section.name = psStringCopy ("ratio"); 233 KapaSetSection (kapa2, §ion); 234 psFree (section.name); 235 236 graphdata.color = KapaColorByName ("black"); 237 graphdata.ymax = +1.05; 238 graphdata.ymin = -0.05; 239 pmVisualLimitsFromVectors (&graphdata, radBin, NULL); 240 KapaSetLimits (kapa2, &graphdata); 241 242 KapaBox (kapa2, &graphdata); 243 KapaSendLabel (kapa2, "radius", KAPA_LABEL_XM); 244 KapaSendLabel (kapa2, "ratio", KAPA_LABEL_YM); 245 246 graphdata.color = KapaColorByName ("black"); 247 graphdata.style = 2; 248 graphdata.ptype = 0; 249 graphdata.size = 1.0; 250 graphdata.etype = 0x01; 251 KapaPrepPlot (kapa2, refRadius->n, &graphdata); 252 KapaPlotVector (kapa2, refRadius->n, refRadius->data.F32, "x"); 253 KapaPlotVector (kapa2, refRadius->n, petRatio->data.F32, "y"); 254 KapaPlotVector (kapa2, refRadius->n, petRatioErr->data.F32, "dym"); 255 KapaPlotVector (kapa2, refRadius->n, petRatioErr->data.F32, "dyp"); 256 graphdata.etype = 0; 257 258 graphdata.color = KapaColorByName ("red"); 259 graphdata.style = 2; 260 graphdata.ptype = 2; 261 graphdata.size = 2.0; 262 KapaPrepPlot (kapa2, 1, &graphdata); 263 KapaPlotVector (kapa2, 1, &petRadius, "x"); 264 KapaPlotVector (kapa2, 1, &ratioForRadius, "y"); 265 266 // *** section 3: radius vs integrated flux 267 section.dx = 1.00; 268 section.dy = 0.33; 269 section.x = 0.00; 270 section.y = 0.66; 271 section.name = psStringCopy ("flux"); 272 KapaSetSection (kapa2, §ion); 273 psFree (section.name); 274 275 graphdata.color = KapaColorByName ("black"); 276 pmVisualLimitsFromVectors (&graphdata, radBin, fluxSum); 277 KapaSetLimits (kapa2, &graphdata); 278 279 KapaBox (kapa2, &graphdata); 280 KapaSendLabel (kapa2, "radius", KAPA_LABEL_XM); 281 KapaSendLabel (kapa2, "integrated flux", KAPA_LABEL_YM); 282 283 graphdata.color = KapaColorByName ("black"); 284 graphdata.style = 2; 285 graphdata.ptype = 0; 286 graphdata.size = 1.0; 287 KapaPrepPlot (kapa2, refRadius->n, &graphdata); 288 KapaPlotVector (kapa2, refRadius->n, refRadius->data.F32, "x"); 289 KapaPlotVector (kapa2, refRadius->n, fluxSum->data.F32, "y"); 290 291 graphdata.color = KapaColorByName ("red"); 292 graphdata.ptype = 2; 293 graphdata.style = 2; 294 graphdata.size = 2.0; 295 KapaPrepPlot (kapa2, 1, &graphdata); 296 KapaPlotVector (kapa2, 1, &radiusForFlux, "x"); 297 KapaPlotVector (kapa2, 1, &petFlux, "y"); 298 299 // pause and wait for user input: 300 // continue, save (provide name), ?? 301 char key[10]; 302 fprintf (stdout, "[c]ontinue? "); 303 if (!fgets(key, 8, stdin)) { 304 psWarning("Unable to read option"); 305 } 306 return true; 307 } 308 309 bool psphotPetrosianVisualEllipticalContour (pmSourceRadialFlux *radFlux, pmSourceExtendedPars *extpars) { 310 311 Graphdata graphdata; 312 313 if (!FORCE_VISUAL && !pmVisualIsVisual()) return true; 175 314 176 315 if (kapa == -1) { … … 187 326 KapaSetFont (kapa, "courier", 14); 188 327 189 // radius vs flux 190 // radius vs mean SB 191 // radius vs petRatio 192 193 // *** section 1: radius vs mean SB 194 section.dx = 1.00; 195 section.dy = 0.33; 196 section.x = 0.00; 197 section.y = 0.00; 198 section.name = psStringCopy ("meanSB"); 199 KapaSetSection (kapa, §ion); 200 psFree (section.name); 201 202 graphdata.color = KapaColorByName ("black"); 203 pmVisualLimitsFromVectors (&graphdata, radBin, fluxBin); 328 psVector *theta = radFlux->theta; 329 psVector *radius = radFlux->isophotalRadii; 330 331 // find Rmin and Rmax for the initial guess 332 float Rmin = radius->data.F32[0]; 333 float Rmax = radius->data.F32[0]; 334 335 psVector *Rx = psVectorAlloc(radius->n, PS_TYPE_F32); 336 psVector *Ry = psVectorAlloc(radius->n, PS_TYPE_F32); 337 338 for (int i = 0; i < theta->n; i++) { 339 Rx->data.F32[i] = radius->data.F32[i]*cos(theta->data.F32[i]); 340 Ry->data.F32[i] = radius->data.F32[i]*sin(theta->data.F32[i]); 341 342 // check the radius range 343 Rmin = MIN (Rmin, radius->data.F32[i]); 344 Rmax = MAX (Rmax, radius->data.F32[i]); 345 } 346 347 psVector *rx = psVectorAlloc(361, PS_TYPE_F32); 348 psVector *ry = psVectorAlloc(361, PS_TYPE_F32); 349 350 float epsilon = extpars->axes.minor / extpars->axes.major; 351 352 for (int i = 0; i < 361; i++) { 353 354 float alpha = PS_RAD_DEG * i; 355 356 float cs_alpha = cos(alpha); 357 float sn_alpha = sin(alpha); 358 359 float cs_phi = cos(alpha - extpars->axes.theta); 360 float sn_phi = sin(alpha - extpars->axes.theta); 361 362 float r = 1.0 / sqrt(SQ(sn_phi) + SQ(epsilon*cs_phi)); 363 364 // generate the model fit here 365 rx->data.F32[i] = extpars->axes.minor * cs_alpha * r; 366 ry->data.F32[i] = extpars->axes.minor * sn_alpha * r; 367 } 368 369 graphdata.color = KapaColorByName ("black"); 370 graphdata.xmin = -1.1*Rmax; 371 graphdata.ymin = -1.1*Rmax; 372 graphdata.xmax = +1.1*Rmax; 373 graphdata.ymax = +1.1*Rmax; 204 374 KapaSetLimits (kapa, &graphdata); 205 375 206 376 KapaBox (kapa, &graphdata); 207 KapaSendLabel (kapa, "radius", KAPA_LABEL_XM); 208 KapaSendLabel (kapa, "mean SB", KAPA_LABEL_YM); 209 210 graphdata.color = KapaColorByName ("black"); 211 graphdata.style = 2; 212 graphdata.ptype = 0; 213 graphdata.size = 1.0; 214 KapaPrepPlot (kapa, radBin->n, &graphdata); 215 KapaPlotVector (kapa, radBin->n, radBin->data.F32, "x"); 216 KapaPlotVector (kapa, radBin->n, fluxBin->data.F32, "y"); 377 KapaSendLabel (kapa, "R_x", KAPA_LABEL_XM); 378 KapaSendLabel (kapa, "R_y", KAPA_LABEL_YM); 217 379 218 380 graphdata.color = KapaColorByName ("red"); 219 381 graphdata.style = 2; 220 graphdata.ptype = 1;221 graphdata.size = 2.0;222 KapaPrepPlot (kapa, refRadius->n, &graphdata);223 KapaPlotVector (kapa, refRadius->n, refRadius->data.F32, "x");224 KapaPlotVector (kapa, refRadius->n, meanSB->data.F32, "y");225 226 // *** section 2: radius vs petrosian ratio227 section.dx = 1.00;228 section.dy = 0.33;229 section.x = 0.00;230 section.y = 0.33;231 section.name = psStringCopy ("ratio");232 KapaSetSection (kapa, §ion);233 psFree (section.name);234 235 graphdata.color = KapaColorByName ("black");236 graphdata.ymax = +1.05;237 graphdata.ymin = -0.05;238 pmVisualLimitsFromVectors (&graphdata, radBin, NULL);239 KapaSetLimits (kapa, &graphdata);240 241 KapaBox (kapa, &graphdata);242 KapaSendLabel (kapa, "radius", KAPA_LABEL_XM);243 KapaSendLabel (kapa, "ratio", KAPA_LABEL_YM);244 245 graphdata.color = KapaColorByName ("black");246 graphdata.style = 2;247 graphdata.ptype = 0;248 graphdata.size = 1.0;249 graphdata.etype = 0x01;250 KapaPrepPlot (kapa, refRadius->n, &graphdata);251 KapaPlotVector (kapa, refRadius->n, refRadius->data.F32, "x");252 KapaPlotVector (kapa, refRadius->n, petRatio->data.F32, "y");253 KapaPlotVector (kapa, refRadius->n, petRatioErr->data.F32, "dym");254 KapaPlotVector (kapa, refRadius->n, petRatioErr->data.F32, "dyp");255 graphdata.etype = 0;256 257 graphdata.color = KapaColorByName ("red");258 graphdata.style = 2;259 382 graphdata.ptype = 2; 260 graphdata.size = 2.0; 261 KapaPrepPlot (kapa, 1, &graphdata); 262 KapaPlotVector (kapa, 1, &petRadius, "x"); 263 KapaPlotVector (kapa, 1, &ratioForRadius, "y"); 264 265 // *** section 3: radius vs integrated flux 266 section.dx = 1.00; 267 section.dy = 0.33; 268 section.x = 0.00; 269 section.y = 0.66; 270 section.name = psStringCopy ("flux"); 271 KapaSetSection (kapa, §ion); 272 psFree (section.name); 273 274 graphdata.color = KapaColorByName ("black"); 275 pmVisualLimitsFromVectors (&graphdata, radBin, fluxSum); 276 KapaSetLimits (kapa, &graphdata); 277 278 KapaBox (kapa, &graphdata); 279 KapaSendLabel (kapa, "radius", KAPA_LABEL_XM); 280 KapaSendLabel (kapa, "integrated flux", KAPA_LABEL_YM); 281 282 graphdata.color = KapaColorByName ("black"); 283 graphdata.style = 2; 284 graphdata.ptype = 0; 285 graphdata.size = 1.0; 286 KapaPrepPlot (kapa, refRadius->n, &graphdata); 287 KapaPlotVector (kapa, refRadius->n, refRadius->data.F32, "x"); 288 KapaPlotVector (kapa, refRadius->n, fluxSum->data.F32, "y"); 289 290 graphdata.color = KapaColorByName ("red"); 291 graphdata.ptype = 2; 292 graphdata.style = 2; 293 graphdata.size = 2.0; 294 KapaPrepPlot (kapa, 1, &graphdata); 295 KapaPlotVector (kapa, 1, &radiusForFlux, "x"); 296 KapaPlotVector (kapa, 1, &petFlux, "y"); 383 graphdata.size = 1.0; 384 KapaPrepPlot (kapa, Rx->n, &graphdata); 385 KapaPlotVector (kapa, Rx->n, Rx->data.F32, "x"); 386 KapaPlotVector (kapa, Rx->n, Ry->data.F32, "y"); 387 388 graphdata.color = KapaColorByName ("black"); 389 graphdata.style = 0; 390 graphdata.ptype = 0; 391 graphdata.size = 1.0; 392 KapaPrepPlot (kapa, rx->n, &graphdata); 393 KapaPlotVector (kapa, rx->n, rx->data.F32, "x"); 394 KapaPlotVector (kapa, rx->n, ry->data.F32, "y"); 297 395 298 396 // pause and wait for user input: … … 306 404 } 307 405 308 bool psphotPetrosianVisualEllipticalContour (pmPetrosian *petrosian) {309 310 Graphdata graphdata;311 312 if (!pmVisualIsVisual()) return true;313 314 if (kapa == -1) {315 kapa = KapaOpenNamedSocket ("kapa", "psphot:plots");316 if (kapa == -1) {317 fprintf (stderr, "failure to open kapa; visual mode disabled\n");318 pmVisualSetVisual(false);319 return false;320 }321 }322 323 KapaClearPlots (kapa);324 KapaInitGraph (&graphdata);325 KapaSetFont (kapa, "courier", 14);326 327 psVector *theta = petrosian->theta;328 psVector *radius = petrosian->isophotalRadii;329 330 // find Rmin and Rmax for the initial guess331 float Rmin = radius->data.F32[0];332 float Rmax = radius->data.F32[0];333 334 psVector *Rx = psVectorAlloc(radius->n, PS_TYPE_F32);335 psVector *Ry = psVectorAlloc(radius->n, PS_TYPE_F32);336 337 for (int i = 0; i < theta->n; i++) {338 Rx->data.F32[i] = radius->data.F32[i]*cos(theta->data.F32[i]);339 Ry->data.F32[i] = radius->data.F32[i]*sin(theta->data.F32[i]);340 341 // check the radius range342 Rmin = MIN (Rmin, radius->data.F32[i]);343 Rmax = MAX (Rmax, radius->data.F32[i]);344 }345 346 psVector *rx = psVectorAlloc(361, PS_TYPE_F32);347 psVector *ry = psVectorAlloc(361, PS_TYPE_F32);348 349 float epsilon = petrosian->axes.minor / petrosian->axes.major;350 351 for (int i = 0; i < 361; i++) {352 353 float alpha = PS_RAD_DEG * i;354 355 float cs_alpha = cos(alpha);356 float sn_alpha = sin(alpha);357 358 float cs_phi = cos(alpha - petrosian->axes.theta);359 float sn_phi = sin(alpha - petrosian->axes.theta);360 361 float r = 1.0 / sqrt(SQ(sn_phi) + SQ(epsilon*cs_phi));362 363 // generate the model fit here364 rx->data.F32[i] = petrosian->axes.minor * cs_alpha * r;365 ry->data.F32[i] = petrosian->axes.minor * sn_alpha * r;366 }367 368 graphdata.color = KapaColorByName ("black");369 graphdata.xmin = -1.1*Rmax;370 graphdata.ymin = -1.1*Rmax;371 graphdata.xmax = +1.1*Rmax;372 graphdata.ymax = +1.1*Rmax;373 KapaSetLimits (kapa, &graphdata);374 375 KapaBox (kapa, &graphdata);376 KapaSendLabel (kapa, "R_x", KAPA_LABEL_XM);377 KapaSendLabel (kapa, "R_y", KAPA_LABEL_YM);378 379 graphdata.color = KapaColorByName ("red");380 graphdata.style = 2;381 graphdata.ptype = 2;382 graphdata.size = 1.0;383 KapaPrepPlot (kapa, Rx->n, &graphdata);384 KapaPlotVector (kapa, Rx->n, Rx->data.F32, "x");385 KapaPlotVector (kapa, Rx->n, Ry->data.F32, "y");386 387 graphdata.color = KapaColorByName ("black");388 graphdata.style = 0;389 graphdata.ptype = 0;390 graphdata.size = 1.0;391 KapaPrepPlot (kapa, rx->n, &graphdata);392 KapaPlotVector (kapa, rx->n, rx->data.F32, "x");393 KapaPlotVector (kapa, rx->n, ry->data.F32, "y");394 395 // pause and wait for user input:396 // continue, save (provide name), ??397 char key[10];398 fprintf (stdout, "[c]ontinue? ");399 if (!fgets(key, 8, stdin)) {400 psWarning("Unable to read option");401 }402 return true;403 }404 405 406 # endif -
branches/tap_branches/psphot/src/psphotRadialProfile.c
r25755 r27838 3 3 bool psphotRadialProfile (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal) { 4 4 5 bool status; 6 5 7 // allocate pmSourceExtendedParameters, if not already defined 6 8 if (!source->extpars) { 7 9 source->extpars = pmSourceExtendedParsAlloc (); 8 }9 10 if (!source->extpars->profile) {11 source->extpars->profile = pmSourceRadialProfileAlloc ();12 10 } 13 11 … … 17 15 float fluxMin = 0.0; 18 16 float fluxMax = source->peak->flux; 17 18 bool RAW_RADIUS = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_RAW_RADIUS"); 19 19 20 20 // generate a series of radial profiles at Nsec evenly spaced angles. the profile flux … … 28 28 // use the radial profiles to determine the radius of a given isophote. this isophote 29 29 // is used to determine the elliptical shape of the object, so it has a relatively high 30 // value (nominally 50% of the peak)30 // value (nominally 25% of the peak) 31 31 if (!psphotRadiiFromProfiles (source, fluxMin, fluxMax)) { 32 32 psError (PS_ERR_UNKNOWN, false, "failed to measure isophotal radii from profiles"); … … 42 42 // generate a single, normalized radial profile following the elliptical contours. 43 43 // the radius is normalized by the axis ratio so that on the major axis, 1 pixel = 1 pixel 44 if (!psphotEllipticalProfile (source )) {44 if (!psphotEllipticalProfile (source, RAW_RADIUS)) { 45 45 psError (PS_ERR_UNKNOWN, false, "failed to generate elliptical profile"); 46 return false; 47 } 48 49 // generated profile in averaged bins 50 if (!psphotRadialBins (recipe, source, Rmax, skynoise)) { 51 psError (PS_ERR_UNKNOWN, false, "failed to generate radial bins"); 46 52 return false; 47 53 } -
branches/tap_branches/psphot/src/psphotRadialProfileByAngles.c
r25755 r27838 12 12 bool psphotRadialProfilesByAngles (pmSource *source, int Nsec, float Rmax) { 13 13 14 psAssert (source->extpars, "define extpars"); 15 14 16 // we want to have an even number of sectors so we can do 180 deg symmetrizing 15 17 Nsec = (Nsec % 2) ? Nsec + 1 : Nsec; 16 18 float dtheta = 2.0*M_PI / Nsec; 17 19 18 pmSourceRadialProfile *profile = source->extpars->profile; 20 if (!source->extpars->radFlux) { 21 source->extpars->radFlux = pmSourceRadialFluxAlloc(); 22 } 23 pmSourceRadialFlux *profile = source->extpars->radFlux; 19 24 psFree(profile->radii); 20 25 psFree(profile->fluxes); … … 24 29 profile->fluxes = psArrayAllocEmpty(Nsec); 25 30 profile->theta = psVectorAllocEmpty(Nsec, PS_TYPE_F32); 26 27 31 28 32 for (int i = 0; i < Nsec; i++) { -
branches/tap_branches/psphot/src/psphotRadiiFromProfiles.c
r25755 r27838 5 5 bool psphotRadiiFromProfiles (pmSource *source, float fluxMin, float fluxMax) { 6 6 7 pmSourceRadialProfile *profile = source->extpars->profile; 7 psAssert (source, "missing source"); 8 psAssert (source->extpars, "missing extpars"); 9 psAssert (source->extpars->radFlux, "missing radFlux"); 10 11 pmSourceRadialFlux *profile = source->extpars->radFlux; 8 12 9 13 psFree(profile->isophotalRadii); … … 146 150 147 151 // show the results 148 // psphotPetrosianVisualProfileRadii (radius, flux, radiusBinned, fluxBinned, Ro);152 // psphotPetrosianVisualProfileRadii (radius, flux, radiusBinned, fluxBinned, fluxMax, Ro); 149 153 150 154 psFree(fluxBinned); … … 152 156 return Ro; 153 157 } 158 159 160 -
branches/tap_branches/psphot/src/psphotRadiusChecks.c
r25755 r27838 4 4 static float PSF_FIT_NSIGMA; 5 5 static float PSF_FIT_PADDING; 6 static float PSF_APERTURE = 0; // radius to use in PSF aperture mags 6 7 static float PSF_FIT_RADIUS = 0; // radius to use in fitting (ignored if <= 0, 7 8 // and a per-object radius is calculated) 8 9 9 static float PSF_APERTURE = 0; // radius to use in PSF aperture mags 10 11 12 bool psphotInitRadiusPSF(const psMetadata *recipe, const pmModelType type) { 10 bool psphotInitRadiusPSF(const psMetadata *recipe, const psMetadata *analysis, const pmModelType type) { 13 11 14 12 bool status = true; 15 13 16 PSF_FIT_NSIGMA = psMetadataLookupF32(&status, recipe, "PSF_FIT_NSIGMA");14 PSF_FIT_NSIGMA = psMetadataLookupF32(&status, recipe, "PSF_FIT_NSIGMA"); 17 15 PSF_FIT_PADDING = psMetadataLookupF32(&status, recipe, "PSF_FIT_PADDING"); 18 PSF_FIT_RADIUS = psMetadataLookupF32(&status, recipe, "PSF_FIT_RADIUS"); 19 PSF_APERTURE = psMetadataLookupF32(&status, recipe, "PSF_APERTURE"); 16 17 PSF_FIT_RADIUS = psMetadataLookupF32(&status, analysis, "PSF_FIT_RADIUS"); 18 if (!status) { 19 PSF_FIT_RADIUS = psMetadataLookupF32(&status, recipe, "PSF_FIT_RADIUS"); 20 } 21 22 PSF_APERTURE = psMetadataLookupF32(&status, analysis, "PSF_APERTURE"); 23 if (!status) { 24 PSF_APERTURE = psMetadataLookupF32(&status, recipe, "PSF_APERTURE"); 25 } 20 26 21 27 return true; -
branches/tap_branches/psphot/src/psphotReadout.c
r25755 r27838 3 3 // this should be called by every program that links against libpsphot 4 4 bool psphotInit (void) { 5 6 5 psphotErrorRegister(); // register our error codes/messages 7 6 psphotModelClassInit (); // load implementation-specific models … … 12 11 bool psphotReadout(pmConfig *config, const pmFPAview *view) { 13 12 14 // measure the total elapsed time in psphotReadout. XXX the current threading plan 15 // for psphot envisions threading within psphotReadout, not multiple threads calling 16 // the same psphotReadout. In the current plan, this dtime is the elapsed time used 17 // jointly by the multiple threads, not the total time used by all threads. 13 // measure the total elapsed time in psphotReadout. dtime is the elapsed time used jointly 14 // by the multiple threads, not the total time used by all threads. 18 15 psTimerStart ("psphotReadout"); 19 16 … … 26 23 return false; 27 24 } 25 // optional break-point for processing 26 char *breakPt = psMetadataLookupStr (NULL, recipe, "BREAK_POINT"); 27 psAssert (breakPt, "configuration error: set BREAK_POINT"); 28 28 29 29 // set the photcode for this image 30 if (!psphotAddPhotcode ( recipe, config, view, "PSPHOT.INPUT")) {30 if (!psphotAddPhotcode (config, view)) { 31 31 psError (PSPHOT_ERR_CONFIG, false, "trouble defining the photcode"); 32 32 return false; 33 33 } 34 34 35 // find the currently selected readout36 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");37 PS_ASSERT_PTR_NON_NULL (readout, false);38 39 // optional break-point for processing40 char *breakPt = psMetadataLookupStr (NULL, recipe, "BREAK_POINT");41 PS_ASSERT_PTR_NON_NULL (breakPt, false);42 43 35 // Generate the mask and weight images, including the user-defined analysis region of interest 44 psphotSetMaskAndVariance (config, readout, recipe); 36 if (!psphotSetMaskAndVariance (config, view)) { 37 return psphotReadoutCleanup(config, view); 38 } 45 39 if (!strcasecmp (breakPt, "NOTHING")) { 46 return psphotReadoutCleanup(config, readout, recipe, NULL, NULL, NULL); 47 } 48 49 // display the image, weight, mask (ch 1,2,3) 50 psphotVisualShowImage (readout); 40 return psphotReadoutCleanup(config, view); 41 } 51 42 52 43 // generate a background model (median, smoothed image) 53 if (!psphotModelBackground (config, view , "PSPHOT.INPUT")) {54 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);55 } 56 if (!psphotSubtractBackground (config, view , "PSPHOT.INPUT")) {57 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);44 if (!psphotModelBackground (config, view)) { 45 return psphotReadoutCleanup (config, view); 46 } 47 if (!psphotSubtractBackground (config, view)) { 48 return psphotReadoutCleanup (config, view); 58 49 } 59 50 if (!strcasecmp (breakPt, "BACKMDL")) { 60 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL); 61 } 62 63 // display the backsub and backgnd images 64 psphotVisualShowBackground (config, view, readout); 65 66 // run a single-model test if desired (exits from here if test is run) 67 psphotModelTest (config, view, recipe); 68 69 // load the psf model, if suppled. FWHM_X,FWHM_Y,etc are saved in the recipe 70 pmPSF *psf = psphotLoadPSF (config, view, recipe); 71 72 // several functions below behave differently if we have a PSF model already 73 bool havePSF = (psf != NULL); 51 return psphotReadoutCleanup (config, view); 52 } 53 54 // load the psf model, if suppled. FWHM_X,FWHM_Y,etc are determined and saved on 55 // readout->analysis XXX this function currently only works with a single PSPHOT.INPUT 56 if (!psphotLoadPSF (config, view)) { 57 psError (PSPHOT_ERR_UNKNOWN, false, "error loading psf model"); 58 return psphotReadoutCleanup (config, view); 59 } 74 60 75 61 // find the detections (by peak and/or footprint) in the image. 76 pmDetections *detections = psphotFindDetections (NULL, readout, recipe); 77 if (!detections) { 78 psLogMsg ("psphot", 3, "unable to find detections in this image"); 79 return psphotReadoutCleanup (config, readout, recipe, detections, psf, NULL); 80 } 81 82 // construct sources and measure basic stats 83 psArray *sources = psphotSourceStats (config, readout, detections, true); 84 if (!sources) return false; 62 if (!psphotFindDetections (config, view, true)) { // pass 1 63 // this only happens if we had an error in psphotFindDetections 64 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis"); 65 return psphotReadoutCleanup (config, view); 66 } 67 68 // construct sources and measure basic stats (saved on detections->newSources) 69 if (!psphotSourceStats (config, view, true)) { // pass 1 70 psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources"); 71 return psphotReadoutCleanup (config, view); 72 } 85 73 if (!strcasecmp (breakPt, "PEAKS")) { 86 return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources); 87 } 88 89 // find blended neighbors of very saturated stars 90 // XXX merge this with Basic Deblend? 91 psphotDeblendSatstars (readout, sources, recipe); 92 93 // mark blended peaks PS_SOURCE_BLEND 94 if (!psphotBasicDeblend (sources, recipe)) { 95 psLogMsg ("psphot", 3, "failed on deblend analysis"); 96 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources); 97 } 98 99 // classify sources based on moments, brightness 100 if (!psphotRoughClass (readout, sources, recipe, havePSF)) { 101 psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image"); 102 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources); 74 return psphotReadoutCleanup(config, view); 75 } 76 77 // find blended neighbors of very saturated stars (detections->newSources) 78 if (!psphotDeblendSatstars (config, view)) { 79 psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis"); 80 return psphotReadoutCleanup (config, view); 81 } 82 83 // mark blended peaks PS_SOURCE_BLEND (detections->newSources) 84 if (!psphotBasicDeblend (config, view)) { 85 psError (PSPHOT_ERR_UNKNOWN, false, "failed on deblend analysis"); 86 return psphotReadoutCleanup (config, view); 87 } 88 89 // classify sources based on moments, brightness. if a PSF model has been loaded, the PSF 90 // clump defined for it is used not measured (detections->newSources) 91 if (!psphotRoughClass (config, view)) { // pass 1 92 psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough classifications"); 93 return psphotReadoutCleanup (config, view); 94 } 95 // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources) 96 if (!psphotImageQuality (config, view)) { // pass 1 97 psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality"); 98 return psphotReadoutCleanup(config, view); 103 99 } 104 100 if (!strcasecmp (breakPt, "MOMENTS")) { 105 return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources); 106 } 107 108 if (!havePSF && !psphotImageQuality (recipe, sources)) { 109 psLogMsg("psphot", 3, "failed to measure image quality"); 110 return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources); 111 } 112 113 // if we were not supplied a PSF, choose one here 114 if (psf == NULL) { 115 // use bright stellar objects to measure PSF 116 // XXX if we do not have enough stars to generate the PSF, build one 117 // from the SEEING guess and model class 118 psf = psphotChoosePSF (readout, sources, recipe); 119 if (psf == NULL) { 120 psLogMsg ("psphot", 3, "failure to construct a psf model"); 121 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources); 122 } 123 havePSF = true; 101 return psphotReadoutCleanup(config, view); 102 } 103 104 // use bright stellar objects to measure PSF if we were supplied a PSF for any input file, 105 // this step is skipped 106 if (!psphotChoosePSF (config, view)) { // pass 1 107 psLogMsg ("psphot", 3, "failure to construct a psf model"); 108 return psphotReadoutCleanup (config, view); 124 109 } 125 110 if (!strcasecmp (breakPt, "PSFMODEL")) { 126 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources); 127 } 128 psphotVisualShowPSFModel (readout, psf); 111 return psphotReadoutCleanup (config, view); 112 } 129 113 130 114 // include externally-supplied sources 131 psphotLoadExtSources (config, view, sources); 132 133 // construct an initial model for each object, set the radius to fitRadius, set circular fit mask 134 psphotGuessModels (config, readout, sources, psf); 115 // XXX fix this in the new multi-input context 116 // psphotLoadExtSources (config, view); // pass 1 117 118 // construct an initial model for each object, set the radius to fitRadius, set circular 119 // fit mask (detections->newSources) 120 psphotGuessModels (config, view); // pass 1 121 122 // merge the newly selected sources into the existing list 123 // NOTE: merge OLD and NEW 124 psphotMergeSources (config, view); 135 125 136 126 // linear PSF fit to source peaks, subtract the models from the image (in PSF mask) 137 psphotFitSourcesLinear (readout, sources, recipe, psf, FALSE); 138 139 // We have to place these visualizations here because the models are not realized until 140 // psphotGuessModels or fitted until psphotFitSourcesLinear. 141 psphotVisualShowPSFStars (recipe, psf, sources); 142 143 // identify CRs and extended sources 144 psphotSourceSize (config, readout, sources, recipe, psf, 0); 127 psphotFitSourcesLinear (config, view, false); // pass 1 (detections->allSources) 128 129 // identify CRs and extended sources (only unmeasured sources are measured) 130 psphotSourceSize (config, view, true); // pass 1 (detections->allSources) 145 131 if (!strcasecmp (breakPt, "ENSEMBLE")) { 146 132 goto finish; 147 133 } 148 psphotVisualShowSatStars (recipe, psf, sources);149 134 150 135 // non-linear PSF and EXT fit to brighter sources 151 136 // replace model flux, adjust mask as needed, fit, subtract the models (full stamp) 152 psphotBlendFit (config, readout, sources, psf);137 psphotBlendFit (config, view); // pass 1 (detections->allSources) 153 138 154 139 // replace all sources 155 psphotReplaceAllSources ( sources, recipe);140 psphotReplaceAllSources (config, view); // pass 1 (detections->allSources) 156 141 157 142 // linear fit to include all sources (subtract again) 158 psphotFitSourcesLinear (readout, sources, recipe, psf, TRUE); 143 // NOTE : apply to ALL sources (extended + psf) 144 psphotFitSourcesLinear (config, view, true); // pass 2 (detections->allSources) 159 145 160 146 // if we only do one pass, skip to extended source analysis 161 if (!strcasecmp (breakPt, "PASS1")) { 162 goto pass1finish; 163 } 164 // NOTE: possibly re-measure background model here with objects subtracted 147 if (!strcasecmp (breakPt, "PASS1")) goto pass1finish; 148 149 // NOTE: possibly re-measure background model here with objects subtracted / or masked 165 150 166 151 // add noise for subtracted objects 167 psphotAddNoise (readout, sources, recipe); 168 169 // find fainter sources (pass 2) 170 detections = psphotFindDetections (detections, readout, recipe); 152 psphotAddNoise (config, view); // pass 1 (detections->allSources) 153 154 // find fainter sources 155 // NOTE: finds new peaks and new footprints, OLD and FULL set are saved on detections 156 psphotFindDetections (config, view, false); // pass 2 (detections->peaks, detections->footprints) 171 157 172 158 // remove noise for subtracted objects (ie, return to normal noise level) 173 psphotSubNoise (readout, sources, recipe); 159 // NOTE: this needs to operate only on the OLD sources 160 psphotSubNoise (config, view); // pass 1 (detections->allSources) 174 161 175 162 // define new sources based on only the new peaks 176 psArray *newSources = psphotSourceStats (config, readout, detections, false); 163 // NOTE: new sources are saved on detections->newSources 164 psphotSourceStats (config, view, false); // pass 2 (detections->newSources) 177 165 178 166 // set source type 179 if (!psphotRoughClass (readout, newSources, recipe, havePSF)) { 167 // NOTE: apply only to detections->newSources 168 if (!psphotRoughClass (config, view)) { // pass 2 (detections->newSources) 180 169 psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image"); 181 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);170 return psphotReadoutCleanup (config, view); 182 171 } 183 172 184 173 // create full input models, set the radius to fitRadius, set circular fit mask 185 psphotGuessModels (config, readout, newSources, psf); 174 // NOTE: apply only to detections->newSources 175 psphotGuessModels (config, view); // pass 2 (detections->newSources) 186 176 187 177 // replace all sources so fit below applies to all at once 188 psphotReplaceAllSources (sources, recipe); 178 // NOTE: apply only to OLD sources (which have been subtracted) 179 psphotReplaceAllSources (config, view); // pass 2 189 180 190 181 // merge the newly selected sources into the existing list 191 psphotMergeSources (sources, newSources); 192 psFree (newSources); 193 194 // linear fit to all sources 195 psphotFitSourcesLinear (readout, sources, recipe, psf, TRUE); 182 // NOTE: merge OLD and NEW 183 // XXX check on free of sources... 184 psphotMergeSources (config, view); // (detections->newSources + detections->allSources -> detections->allSources) 185 186 // NOTE: apply to ALL sources 187 psphotFitSourcesLinear (config, view, true); // pass 3 (detections->allSources) 196 188 197 189 pass1finish: 198 190 199 191 // measure source size for the remaining sources 200 psphotSourceSize (config, readout, sources, recipe, psf, 0);201 202 psphotExtendedSourceAnalysis (readout, sources, recipe); 203 204 psphotExtendedSourceFits ( readout, sources, recipe);192 // NOTE: applies only to NEW (unmeasured) sources 193 psphotSourceSize (config, view, false); // pass 2 (detections->allSources) 194 195 psphotExtendedSourceAnalysis (config, view); // pass 1 (detections->allSources) 196 psphotExtendedSourceFits (config, view); // pass 1 (detections->allSources) 205 197 206 198 finish: … … 210 202 211 203 // measure aperture photometry corrections 212 if (!psphotApResid (config, readout, sources, psf)) {204 if (!psphotApResid (config, view)) { // pass 1 (detections->allSources) 213 205 psLogMsg ("psphot", 3, "failed on psphotApResid"); 214 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);206 return psphotReadoutCleanup (config, view); 215 207 } 216 208 217 209 // calculate source magnitudes 218 psphotMagnitudes(config, readout, view, sources, psf);219 220 if (!psphotEfficiency(config, readout, view, psf, recipe, sources)) {210 psphotMagnitudes(config, view); // pass 1 (detections->allSources) 211 212 if (!psphotEfficiency(config, view)) { // pass 1 221 213 psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources"); 222 214 psErrorClear(); … … 227 219 228 220 // replace background in residual image 229 psphotSkyReplace (config, view); 221 psphotSkyReplace (config, view); // pass 1 230 222 231 223 // drop the references to the image pixels held by each source 232 psphotSourceFreePixels ( sources);224 psphotSourceFreePixels (config, view); // pass 1 233 225 234 226 // create the exported-metadata and free local data 235 return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);227 return psphotReadoutCleanup(config, view); 236 228 } 237 -
branches/tap_branches/psphot/src/psphotReadoutCleanup.c
r24203 r27838 1 1 # include "psphotInternal.h" 2 2 3 // psphotReadoutCleanup is called on exit from psphotReadout. If the last raised error is4 // not a DATA error, then there was a serious problem. Only in this case, or if the fail 5 // on the stats measurement, do we return false 6 bool psphotReadoutCleanup (pmConfig *config, pmReadout *readout, psMetadata *recipe, pmDetections *detections, pmPSF *psf, psArray *sources) { 3 // for now, let's store the detections on the readout->analysis for each readout 4 bool psphotReadoutCleanup (pmConfig *config, const pmFPAview *view) 5 { 6 bool status = true; 7 7 8 8 // remove internal pmFPAfiles, if created … … 12 12 } 13 13 if (psErrorCodeLast() != PS_ERR_NONE) { 14 psFree (psf);15 psFree (sources);16 psFree (detections);17 14 return false; 18 15 } 19 16 17 // select the appropriate recipe information 18 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 19 psAssert (recipe, "missing recipe?"); 20 21 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 22 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 23 24 // loop over the available readouts 25 for (int i = 0; i < num; i++) { 26 if (!psphotReadoutCleanupReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 27 psError (PSPHOT_ERR_CONFIG, false, "failed on psphotReadoutCleanup for PSPHOT.INPUT entry %d", i); 28 return false; 29 } 30 } 31 32 // XXX move this to top of loop? 33 pmKapaClose (); 34 35 return true; 36 } 37 38 // psphotReadoutCleanup is called on exit from psphotReadout. If the last raised error is 39 // not a DATA error, then there was a serious problem. Only in this case, or if the fail 40 // on the stats measurement, do we return false 41 bool psphotReadoutCleanupReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 42 43 bool status = true; 44 45 // find the currently selected readout 46 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 47 psAssert (file, "missing file?"); 48 49 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 50 psAssert (readout, "missing readout?"); 51 52 // when psphotReadoutCleanup is called, these are not necessarily defined 53 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 54 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 55 psArray *sources = detections ? detections->allSources : NULL; 56 // XXX where do we free these, in here (psMetadataRemove?) 57 20 58 // use the psf-model to measure FWHM stats 21 59 if (psf) { 22 if (!psphotPSFstats (readout, recipe,psf)) {60 if (!psphotPSFstats (readout, psf)) { 23 61 psError(PSPHOT_ERR_PROG, false, "Failed to measure PSF shape parameters"); 24 psFree (psf);25 psFree (sources);26 psFree (detections);27 62 return false; 28 63 } … … 30 65 // otherwise, use the source moments to measure FWHM stats 31 66 if (!psf && sources) { 32 if (!psphotMomentsStats (readout, recipe,sources)) {67 if (!psphotMomentsStats (readout, sources)) { 33 68 psError(PSPHOT_ERR_PROG, false, "Failed to measure Moment shape parameters"); 34 psFree (psf);35 psFree (sources);36 psFree (detections);37 69 return false; 38 70 } … … 40 72 41 73 // Check to see if the image quality was measured 42 if (!psf) { 74 // XXX not sure we want / need this test 75 if (0 && !psf) { 43 76 bool mdok; // Status of MD lookup 44 77 int nIQ = psMetadataLookupS32(&mdok, recipe, "IQ_NSTAR"); // Number of stars for IQ measurement 45 78 if (!mdok || nIQ <= 0) { 46 79 psError(PSPHOT_ERR_DATA, false, "Unable to measure image quality"); 47 psFree (psf);48 psFree (sources);49 psFree (detections);50 80 return false; 51 81 } 52 82 } 53 83 84 // create an output header with stats results currently saved on readout->analysis 85 psMetadata *header = psphotDefineHeader (readout->analysis); 54 86 55 87 // write NSTARS to the image header 56 psphotSetHeaderNstars (recipe, sources); 57 58 // create an output header with stats results 59 psMetadata *header = psphotDefineHeader (recipe); 88 psphotSetHeaderNstars (header, sources); 60 89 61 90 // save the results of the analysis 91 // this should happen way up stream (when needed?) 62 92 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.HEADER", PS_DATA_METADATA, "header stats", header); 63 if (sources) { 64 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_DATA_ARRAY, "psphot sources", sources); 65 } 93 66 94 if (psf) { 95 // XXX this seems a little silly : we saved the psf on readout->analysis above, but now 96 // we are moving it to chip->analysis. 67 97 // save the psf for possible output. if there was already an entry, it was loaded from external sources 68 98 // the new one may have been updated or modified, so replace the existing entry. We … … 79 109 } 80 110 81 // XXX move this to top of loop?82 pmKapaClose ();83 84 psFree (detections);85 psFree (psf);86 111 psFree (header); 87 psFree (sources);88 89 112 return true; 90 113 } -
branches/tap_branches/psphot/src/psphotReadoutFindPSF.c
r25755 r27838 7 7 psTimerStart ("psphotReadout"); 8 8 9 // select the current recipe 10 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE); 11 if (!recipe) { 12 psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE); 13 return false; 14 } 15 16 // set the photcode for this image 17 if (!psphotAddPhotcode(recipe, config, view, "PSPHOT.INPUT")) { 9 // set the photcode for the PSPHOT.INPUT 10 if (!psphotAddPhotcode(config, view)) { 18 11 psError(PSPHOT_ERR_CONFIG, false, "trouble defining the photcode"); 19 12 return false; 20 13 } 21 14 22 // find the currently selected readout23 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");24 PS_ASSERT_PTR_NON_NULL (readout, false);25 26 15 // Generate the mask and variance images, including the user-defined analysis region of interest 27 psphotSetMaskAndVariance (config, readout, recipe); 28 29 // display the image, weight, mask (ch 1,2,3) 30 psphotVisualShowImage (readout); 16 psphotSetMaskAndVariance (config, view); 31 17 32 18 // Note that in this implementation, we do NOT model the background and we do not … … 34 20 35 21 // include externally-supplied sources (supplied as PSPHOT.INPUT.CMF) 36 pmDetections *detections = psphotDetectionsFromSources (config, inSources);37 if (! detections || !detections->peaks) {22 // XXX we assume a single set of input sources is supplied 23 if (!psphotDetectionsFromSources (config, view, inSources)) { 38 24 psError(PSPHOT_ERR_ARGUMENTS, true, "Can't find PSF stars"); 39 return psphotReadoutCleanup(config, readout, recipe, detections, NULL, NULL);25 return psphotReadoutCleanup(config, view); 40 26 } 41 27 42 // construct sources and measure basic stats (moments, local sky) 43 psArray *sources = psphotSourceStats(config, readout, detections, true); 44 if (!sources) return false; 28 // construct detections->newSources and measure basic stats (moments, local sky) 29 if (!psphotSourceStats(config, view, true)) { 30 psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources"); 31 return false; 32 } 45 33 46 // peak flux is wrong : set based on previous image 47 // use the peak measured in the moments analysis: 48 for (int i = 0; i < sources->n; i++) { 49 pmSource *source = sources->data[i]; 50 source->peak->flux = source->moments->Peak; 34 // peak flux is wrong : use the peak measured in the moments analysis: 35 if (!psphotRepairLoadedSources(config, view)) { 36 psError(PSPHOT_ERR_UNKNOWN, false, "failure to repair sources"); 37 return false; 51 38 } 52 39 53 40 // classify sources based on moments, brightness (psf is not known) 54 if (!psphotRoughClass ( readout, sources, recipe, false)) {55 ps LogMsg ("psphot", 3, "failed to find a valid PSF clump for image");56 return psphotReadoutCleanup (config, readout, recipe, detections, NULL, sources);41 if (!psphotRoughClass (config, view)) { 42 psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough source class"); 43 return psphotReadoutCleanup (config, view); 57 44 } 58 45 59 pmPSF *psf = psphotChoosePSF(readout, sources, recipe); 60 if (!psf) { 46 if (!psphotImageQuality (config, view)) { 47 psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality"); 48 return psphotReadoutCleanup(config, view); 49 } 50 51 if (!psphotChoosePSF(config, view)) { 61 52 psError(PSPHOT_ERR_PSF, false, "Failed to construct a psf model"); 62 psFree(sources); 63 return psphotReadoutCleanup(config, readout, recipe, detections, NULL, NULL); 53 return psphotReadoutCleanup(config, view); 64 54 } 65 psphotVisualShowPSFModel(readout, psf); 55 56 # if 0 57 // XXX if we want to determine the aperture residual correction here, we either 58 // need to carry it out of the PSF determination analysis above, or save the model 59 // fits from that analysis, or run the linear PSF fit for all objects currently in hand 60 // construct an initial model for each object, set the radius to fitRadius, set circular fit mask 61 psphotGuessModels (config, view); 62 # endif 63 64 // merge the newly selected sources into the existing list 65 // NOTE: merge OLD and NEW 66 psphotMergeSources (config, view); 67 68 # if 0 69 // measure aperture photometry corrections 70 if (!psphotApResid (config, view)) { 71 psLogMsg ("psphot", 3, "failed on psphotApResid"); 72 return psphotReadoutCleanup (config, view); 73 } 74 # endif 66 75 67 76 // drop the references to the image pixels held by each source 68 psphotSourceFreePixels(sources); 69 psFree(sources); 77 psphotSourceFreePixels(config, view); 70 78 71 79 // create the exported-metadata and free local data 72 return psphotReadoutCleanup(config, readout, recipe, detections, psf, NULL);80 return psphotReadoutCleanup(config, view); 73 81 } -
branches/tap_branches/psphot/src/psphotReadoutKnownSources.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 // in this psphotReadout-variant, we are only measuring the photometry for known sources, 4 // using a PSF generated from this observationthose sources3 // in this psphotReadout-variant, we are only measuring the photometry for known sources, using 4 // a PSF generated for this observation from those sources 5 5 bool psphotReadoutKnownSources(pmConfig *config, const pmFPAview *view, psArray *inSources) { 6 6 7 7 psTimerStart ("psphotReadout"); 8 8 9 // select the current recipe10 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);11 if (!recipe) {12 psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE);13 return false;14 }15 16 9 // set the photcode for this image 17 if (!psphotAddPhotcode( recipe, config, view, "PSPHOT.INPUT")) {10 if (!psphotAddPhotcode(config, view)) { 18 11 psError(PSPHOT_ERR_CONFIG, false, "trouble defining the photcode"); 19 12 return false; 20 13 } 21 14 22 // find the currently selected readout23 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");24 PS_ASSERT_PTR_NON_NULL (readout, false);25 26 15 // Generate the mask and weight images, including the user-defined analysis region of interest 27 psphotSetMaskAndVariance (config, readout, recipe); 28 29 // display the image, weight, mask (ch 1,2,3) 30 psphotVisualShowImage (readout); 16 psphotSetMaskAndVariance (config, view); 31 17 32 18 // Note that in this implementation, we do NOT model the background and we do not … … 34 20 35 21 // include externally-supplied sources (supplied as PSPHOT.INPUT.CMF) 36 pmDetections *detections = psphotDetectionsFromSources (config, inSources); 37 if (!detections || !detections->peaks) { 22 if (!psphotDetectionsFromSources (config, view, inSources)) { 38 23 psError(PSPHOT_ERR_ARGUMENTS, true, "Can't find PSF stars"); 39 return psphotReadoutCleanup(config, readout, recipe, detections, NULL, NULL);24 return psphotReadoutCleanup(config, view); 40 25 } 41 26 42 27 // construct sources and measure basic stats 43 psArray *sources = psphotSourceStats (config, readout, detections, true); 44 if (!sources) return false; 28 if (!psphotSourceStats (config, view, true)) { 29 psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources"); 30 return false; 31 } 45 32 46 // peak flux is wrong : set based on previous image 47 // use the peak measured in the moments analysis: 48 for (int i = 0; i < sources->n; i++) { 49 pmSource *source = sources->data[i]; 50 source->peak->flux = source->moments->Peak; 33 // peak flux is wrong : use the peak measured in the moments analysis: 34 if (!psphotRepairLoadedSources(config, view)) { 35 psError(PSPHOT_ERR_UNKNOWN, false, "failure to repair sources"); 36 return false; 51 37 } 52 38 53 39 // classify sources based on moments, brightness (psf is not known) 54 if (!psphotRoughClass ( readout, sources, recipe, false)) {55 ps LogMsg ("psphot", 3, "failed to find a valid PSF clump for image");56 return psphotReadoutCleanup (config, readout, recipe, detections, NULL, sources);40 if (!psphotRoughClass (config, view)) { 41 psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough source class"); 42 return psphotReadoutCleanup(config, view); 57 43 } 58 44 59 pmPSF *psf = psphotChoosePSF (readout, sources, recipe); 60 if (!psf) { 61 psLogMsg ("psphot", 3, "failure to construct a psf model"); 62 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources); 45 if (!psphotChoosePSF (config, view)) { 46 psError(PSPHOT_ERR_PSF, false, "Failed to construct a psf model"); 47 return psphotReadoutCleanup(config, view); 63 48 } 64 psphotVisualShowPSFModel (readout, psf);65 49 66 50 // construct an initial model for each object 67 psphotGuessModels (config, readout, sources, psf); 51 psphotGuessModels (config, view); 52 53 // merge the newly selected sources into the existing list 54 // NOTE: merge OLD and NEW 55 psphotMergeSources (config, view); 68 56 69 57 // linear PSF fit to source peaks 70 psphotFitSourcesLinear (readout, sources, recipe, psf, FALSE); 71 72 // We have to place these visualizations here because the models are not realized until 73 // psphotGuessModels or fitted until psphotFitSourcesLinear. 74 psphotVisualShowPSFStars (recipe, psf, sources); 75 psphotVisualShowSatStars (recipe, psf, sources); 58 psphotFitSourcesLinear (config, view, false); 76 59 77 60 // measure aperture photometry corrections 78 if (!psphotApResid (config, readout, sources, psf)) {61 if (!psphotApResid (config, view)) { 79 62 psLogMsg ("psphot", 3, "failed on psphotApResid"); 80 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);63 return psphotReadoutCleanup(config, view); 81 64 } 82 65 83 66 // calculate source magnitudes 84 psphotMagnitudes(config, readout, view, sources, psf);67 psphotMagnitudes(config, view); 85 68 86 69 // drop the references to the image pixels held by each source 87 psphotSourceFreePixels ( sources);70 psphotSourceFreePixels (config, view); 88 71 89 72 // create the exported-metadata and free local data 90 return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);73 return psphotReadoutCleanup(config, view); 91 74 } -
branches/tap_branches/psphot/src/psphotReadoutMinimal.c
r25755 r27838 1 1 # include "psphotInternal.h" 2 2 3 // this badly-named function performs photometry assuming (a) a supplied PSF, (b) 4 // background subtraction, (c) linear psf-model fits only. it is currently only being5 // used by ppSub.3 // this badly-named function performs photometry assuming (a) a supplied PSF, (b) background 4 // subtraction, (c) linear psf-model fits only, (d) a prior analysis has supplied the moments 5 // window parameters. It is currently only being used by ppSub. 6 6 7 7 // NOTE: ppSub needs to perform extended source analysis for comets and trails. … … 17 17 pmModelClassSetLimits(PM_MODEL_LIMITS_LAX); 18 18 19 // select the current recipe20 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);21 if (!recipe) {22 psError(PSPHOT_ERR_CONFIG, false, "missing recipe %s", PSPHOT_RECIPE);23 return false;24 }25 26 19 // set the photcode for this image 27 if (!psphotAddPhotcode( recipe, config, view, "PSPHOT.INPUT")) {20 if (!psphotAddPhotcode(config, view)) { 28 21 psError(PSPHOT_ERR_CONFIG, false, "trouble defining the photcode"); 29 22 return false; 30 23 } 31 24 32 // find the currently selected readout 33 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT"); 34 PS_ASSERT_PTR_NON_NULL (readout, false); 25 // Generate the mask and weight images, including the user-defined analysis region of interest 26 psphotSetMaskAndVariance (config, view); 35 27 36 // Generate the mask and weight images, including the user-defined analysis region of interest 37 psphotSetMaskAndVariance (config, readout, recipe); 38 39 // display the image, weight, mask (ch 1,2,3) 40 psphotVisualShowImage (readout); 41 42 // load the psf model, if suppled. FWHM_X,FWHM_Y,etc are saved in the recipe 43 pmPSF *psf = psphotLoadPSF (config, view, recipe); 44 if (!psf) { 28 // load the psf model, if suppled. FWHM_X,FWHM_Y,etc are saved on readout->analysis 29 if (!psphotLoadPSF (config, view)) { 45 30 psError (PSPHOT_ERR_CONFIG, false, "missing psf model"); 46 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);31 return psphotReadoutCleanup (config, view); 47 32 } 48 33 49 // find the detections (by peak and/or footprint) in the image. 50 pmDetections *detections = pmDetectionsAlloc(); // New detections; allocated to ensure pass=2 51 detections = psphotFindDetections(detections, readout, recipe); 52 if (!detections) { 53 psLogMsg ("psphot", 3, "unable to find detections in this image"); 54 return psphotReadoutCleanup (config, readout, recipe, detections, psf, NULL); 34 // find the detections (by peak and/or footprint) in the image. (final pass) 35 if (!psphotFindDetections(config, view, false)) { 36 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis"); 37 return psphotReadoutCleanup (config, view); 55 38 } 56 39 57 // construct sources and measure basic stats 58 psArray *sources = psphotSourceStats (config, readout, detections, true); 59 if (!sources) return false; 40 // construct sources and measure basic stats (saved on detections->newSources) 41 if (!psphotSourceStats (config, view, false)) { // pass 1 42 psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources"); 43 return psphotReadoutCleanup (config, view); 44 } 60 45 61 46 // find blended neighbors of very saturated stars 62 // XXX merge this with Basic Deblend? 63 psphotDeblendSatstars (readout, sources, recipe); 47 psphotDeblendSatstars (config, view); 64 48 65 49 // mark blended peaks PS_SOURCE_BLEND 66 if (!psphotBasicDeblend ( sources, recipe)) {50 if (!psphotBasicDeblend (config, view)) { 67 51 psLogMsg ("psphot", 3, "failed on deblend analysis"); 68 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);52 return psphotReadoutCleanup (config, view); 69 53 } 70 54 71 55 // classify sources based on moments, brightness (use supplied psf shape parameters) 72 if (!psphotRoughClass ( readout, sources, recipe, true)) {56 if (!psphotRoughClass (config, view)) { 73 57 psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image"); 74 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);58 return psphotReadoutCleanup (config, view); 75 59 } 76 60 77 61 // construct an initial model for each object 78 psphotGuessModels (config, readout, sources, psf); 62 psphotGuessModels (config, view); 63 64 // merge the newly selected sources into the existing list 65 psphotMergeSources (config, view); 79 66 80 67 // linear PSF fit to source peaks 81 psphotFitSourcesLinear (readout, sources, recipe, psf, FALSE); 82 83 // We have to place these visualizations here because the models are not realized until 84 // psphotGuessModels or fitted until psphotFitSourcesLinear. 85 psphotVisualShowPSFStars (recipe, psf, sources); 86 psphotVisualShowSatStars (recipe, psf, sources); 68 psphotFitSourcesLinear (config, view, false); 87 69 88 70 // XXX eventually, add the extended source fits here 89 71 # if (0) 90 72 // measure source size for the remaining sources 91 psphotSourceSize (config, readout, sources, recipe, 0);73 psphotSourceSize (config, view); 92 74 93 psphotExtendedSourceAnalysis ( readout, sources, recipe);75 psphotExtendedSourceAnalysis (config, view); 94 76 95 psphotExtendedSourceFits ( readout, sources, recipe);77 psphotExtendedSourceFits (config, view); 96 78 # endif 97 79 98 80 // calculate source magnitudes 99 psphotMagnitudes(config, readout, view, sources, psf);81 psphotMagnitudes(config, view); 100 82 101 if (!psphotEfficiency(config, readout, view, psf, recipe, sources)) { 83 // XXX ensure this is measured if the analysis succeeds (even if quality is low) 84 if (!psphotEfficiency(config, view)) { 102 85 psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources"); 103 86 psErrorClear(); … … 105 88 106 89 // drop the references to the image pixels held by each source 107 psphotSourceFreePixels ( sources);90 psphotSourceFreePixels (config, view); 108 91 109 92 // create the exported-metadata and free local data 110 return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);93 return psphotReadoutCleanup(config, view); 111 94 } -
branches/tap_branches/psphot/src/psphotReplaceUnfit.c
r25755 r27838 22 22 } 23 23 24 bool psphotReplaceAllSources (psArray *sources, psMetadata *recipe) { 24 // for now, let's store the detections on the readout->analysis for each readout 25 bool psphotReplaceAllSources (pmConfig *config, const pmFPAview *view) 26 { 27 bool status = true; 28 29 // select the appropriate recipe information 30 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 31 psAssert (recipe, "missing recipe?"); 32 33 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 34 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 35 36 // loop over the available readouts 37 for (int i = 0; i < num; i++) { 38 if (!psphotReplaceAllSourcesReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 39 psError (PSPHOT_ERR_CONFIG, false, "failed to replace all sources for PSPHOT.INPUT entry %d", i); 40 return false; 41 } 42 } 43 return true; 44 } 45 46 bool psphotReplaceAllSourcesReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 25 47 26 48 bool status; … … 29 51 psTimerStart ("psphot.replace"); 30 52 53 // find the currently selected readout 54 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 55 psAssert (file, "missing file?"); 56 57 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 58 psAssert (readout, "missing readout?"); 59 60 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 61 psAssert (detections, "missing detections?"); 62 63 psArray *sources = detections->allSources; 64 psAssert (sources, "missing sources?"); 65 31 66 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 32 67 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 33 assert (maskVal);68 psAssert (maskVal, "missing mask value?"); 34 69 35 70 for (int i = 0; i < sources->n; i++) { … … 67 102 return true; 68 103 } 69 70 # if (0)71 // add source, if the source has been subtracted; do not modify state72 bool psphotAddWithTest (pmSource *source, bool useState, psImageMaskType maskVal) {73 74 // what is current state? (true : add; false : sub)75 bool state = !(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);76 if (state && useState) return true;77 78 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);79 return true;80 }81 82 // sub source, if the source has been added; do not modify state83 bool psphotSubWithTest (pmSource *source, bool useState, psImageMaskType maskVal) {84 85 // what is current state? (true : sub; false : add)86 bool state = (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);87 if (state && useState) return true;88 89 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);90 return true;91 }92 93 // add or sub source to match recorded state: supply current state as true (add) or false (sub)94 bool psphotSetState (pmSource *source, bool curState, psImageMaskType maskVal) {95 96 // what is desired state? (true : add; false : sub)97 bool newState = !(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED);98 if (curState == newState) return true;99 100 if (curState && !newState) {101 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal);102 }103 if (newState && !curState) {104 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);105 }106 return true;107 }108 # endif -
branches/tap_branches/psphot/src/psphotRoughClass.c
r25852 r27838 7 7 } } 8 8 9 bool psphotRoughClassRegion (int nRegion, psRegion *region, psArray *sources, psMetadata *target, psMetadata *recipe, const bool havePSF); 9 // for now, let's store the detections on the readout->analysis for each readout 10 bool psphotRoughClass (pmConfig *config, const pmFPAview *view) 11 { 12 bool status = true; 10 13 11 // 2006.02.02 : no leaks 12 bool psphotRoughClass (pmReadout *readout, psArray *sources, psMetadata *recipe, const bool havePSF) { 14 // select the appropriate recipe information 15 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 16 psAssert (recipe, "missing recipe?"); 17 18 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 19 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 20 21 // skip the chisq image (optionally?) 22 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 23 if (!status) chisqNum = -1; 24 25 // loop over the available readouts 26 for (int i = 0; i < num; i++) { 27 if (i == chisqNum) continue; // skip chisq image 28 if (!psphotRoughClassReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 29 psError (PSPHOT_ERR_CONFIG, false, "failed on rough classification for PSPHOT.INPUT entry %d", i); 30 return false; 31 } 32 } 33 return true; 34 } 35 36 bool psphotRoughClassReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 13 37 14 38 bool status; 15 39 16 40 psTimerStart ("psphot.rough"); 41 42 // find the currently selected readout 43 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 44 psAssert (file, "missing file?"); 45 46 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 47 psAssert (readout, "missing readout?"); 48 49 // if we have a PSF, use the existing PSF clump region below 50 bool havePSF = false; 51 if (psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF")) { 52 havePSF = true; 53 } 54 55 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 56 psAssert (detections, "missing detections?"); 57 58 psArray *sources = detections->newSources; 59 psAssert (sources, "missing sources?"); 60 61 if (!sources->n) { 62 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping rough classification"); 63 return true; 64 } 17 65 18 66 // we make this measurement on a NxM grid of regions across the readout … … 37 85 } 38 86 } 39 psMetadataAddS32 (re cipe, PS_LIST_TAIL, "PSF.CLUMP.NREGIONS", PS_META_REPLACE, "psf clump regions", nRegion);87 psMetadataAddS32 (readout->analysis, PS_LIST_TAIL, "PSF.CLUMP.NREGIONS", PS_META_REPLACE, "psf clump regions", nRegion); 40 88 41 89 // optional printout of source moments only … … 51 99 } 52 100 53 bool psphotRoughClassRegion (int nRegion, psRegion *region, psArray *sources, psMetadata * target, psMetadata *recipe, const bool havePSF) {101 bool psphotRoughClassRegion (int nRegion, psRegion *region, psArray *sources, psMetadata *analysis, psMetadata *recipe, const bool havePSF) { 54 102 55 103 bool status; … … 61 109 assert (maskSat); 62 110 111 // the regions are saved on the readout->analysis metadata folder (passed to us as analysis) 63 112 snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", nRegion); 64 psMetadata *regionMD = psMetadataLookupPtr (&status, target, regionName);113 psMetadata *regionMD = psMetadataLookupPtr (&status, analysis, regionName); 65 114 if (!regionMD) { 66 115 // allocate the region metadata folder and add this region to it. 67 116 regionMD = psMetadataAlloc(); 68 psMetadataAddMetadata ( target, PS_LIST_TAIL, regionName, PS_META_REPLACE, "psf clump region", regionMD);117 psMetadataAddMetadata (analysis, PS_LIST_TAIL, regionName, PS_META_REPLACE, "psf clump region", regionMD); 69 118 psFree (regionMD); 70 119 } … … 74 123 // determine the PSF parameters from the source moment values 75 124 // XXX why not save the psfClump as a PTR? 76 psfClump = pmSourcePSFClump (region, sources, target); 125 126 float PSF_SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM"); 127 float MOMENTS_AR_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_AR_MAX"); psAssert (status, "missing MOMENTS_AR_MAX"); 128 129 float PSF_CLUMP_GRID_SCALE = psMetadataLookupF32(&status, analysis, "PSF_CLUMP_GRID_SCALE"); 130 if (!status) { 131 PSF_CLUMP_GRID_SCALE = psMetadataLookupF32(&status, recipe, "PSF_CLUMP_GRID_SCALE"); 132 psAssert (status, "missing PSF_CLUMP_GRID_SCALE"); 133 } 134 float MOMENTS_SX_MAX = psMetadataLookupF32(&status, analysis, "MOMENTS_SX_MAX"); 135 if (!status) { 136 MOMENTS_SX_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_SX_MAX"); 137 psAssert (status, "missing MOMENTS_SX_MAX"); 138 } 139 float MOMENTS_SY_MAX = psMetadataLookupF32(&status, analysis, "MOMENTS_SY_MAX"); 140 if (!status) { 141 MOMENTS_SY_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_SY_MAX"); 142 psAssert (status, "missing MOMENTS_SY_MAX"); 143 } 144 145 psfClump = pmSourcePSFClump (NULL, region, sources, PSF_SN_LIM, PSF_CLUMP_GRID_SCALE, MOMENTS_SX_MAX, MOMENTS_SY_MAX, MOMENTS_AR_MAX); 146 77 147 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.X", PS_META_REPLACE, "psf clump center", psfClump.X); 78 148 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.Y", PS_META_REPLACE, "psf clump center", psfClump.Y); … … 102 172 psLogMsg ("psphot", 3, "psf clump DX, DY: %f, %f\n", psfClump.dX, psfClump.dY); 103 173 174 // get basic parameters, or set defaults 175 float PSF_SN_LIM = psMetadataLookupF32 (&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM"); 176 float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA"); psAssert (status, "missing PSF_CLUMP_NSIGMA"); 177 104 178 // group into STAR, COSMIC, EXTENDED, SATURATED, etc. 105 if (!pmSourceRoughClass (region, sources, recipe, psfClump, maskSat)) {179 if (!pmSourceRoughClass (region, sources, PSF_SN_LIM, PSF_CLUMP_NSIGMA, psfClump, maskSat)) { 106 180 psError(PSPHOT_ERR_PROG, false, "programming error calling pmSourceRoughClass"); 107 181 return false; -
branches/tap_branches/psphot/src/psphotSetThreads.c
r25755 r27838 25 25 psFree(task); 26 26 27 task = psThreadTaskAlloc("PSPHOT_SOURCE_STATS", 5);27 task = psThreadTaskAlloc("PSPHOT_SOURCE_STATS", 10); 28 28 task->function = &psphotSourceStats_Threaded; 29 29 psThreadTaskAdd(task); -
branches/tap_branches/psphot/src/psphotSignificanceImage.c
r25383 r27838 22 22 } 23 23 24 // if we have already determined the PSF model, then we have a better idea how to smooth this image 24 25 bool statusMajor, statusMinor; 25 float fwhmMajor = psMetadataLookupF32(&statusMajor, re cipe, "FWHM_MAJ");26 float fwhmMinor = psMetadataLookupF32(&statusMinor, re cipe, "FWHM_MIN");26 float fwhmMajor = psMetadataLookupF32(&statusMajor, readout->analysis, "FWHM_MAJ"); 27 float fwhmMinor = psMetadataLookupF32(&statusMinor, readout->analysis, "FWHM_MIN"); 27 28 if (statusMajor && statusMinor) { 28 29 // if we know the FHWM, use that to set the smoothing kernel (XXX allow an optional override?) … … 43 44 } 44 45 // record the actual smoothing sigma 45 psMetadataAddF32(recipe, PS_LIST_TAIL, "SIGMA_SMOOTH", PS_META_REPLACE, "Smoothing sigma for detections", 46 SIGMA_SMTH); 46 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SIGMA_SMOOTH", PS_META_REPLACE, "Smoothing sigma for detections", SIGMA_SMTH); 47 47 48 48 // smooth the image, applying the mask as we go … … 59 59 // effective per-pixel variance is maintained. 60 60 psImage *smooth_wt = psImageCopy(NULL, readout->variance, PS_TYPE_F32); 61 psImageSmoothMask_Threaded(smooth_wt, smooth_wt, readout->mask, maskVal, SIGMA_SMTH * M_SQRT1_2, 62 NSIGMA_SMTH, minGauss); 61 psImageSmoothMask_Threaded(smooth_wt, smooth_wt, readout->mask, maskVal, SIGMA_SMTH * M_SQRT1_2, NSIGMA_SMTH, minGauss); 63 62 psLogMsg("psphot", PS_LOG_MINUTIA, "smooth variance: %f sec\n", psTimerMark("psphot.smooth")); 64 63 … … 77 76 // Calculate correction factor for the covariance produced by the (potentially multiple) smoothing 78 77 psKernel *kernel = psImageSmoothKernel(SIGMA_SMTH, NSIGMA_SMTH); // Kernel used for smoothing 79 psKernel *covar = psImageCovarianceCalculate(kernel, readout->covariance); // Covariance matrix78 float factor = 1.0 / psImageCovarianceCalculateFactor(kernel, readout->covariance); 80 79 psFree(kernel); 81 float factor = 1.0 / psImageCovarianceFactor(covar);82 psFree(covar);83 80 84 81 // record the effective area and significance scaling factor 85 82 float effArea = 8.0 * M_PI * PS_SQR(SIGMA_SMTH); 86 psMetadataAddF32(recipe, PS_LIST_TAIL, "EFFECTIVE_AREA", PS_META_REPLACE, "Effective Area", effArea); 87 psMetadataAddF32(recipe, PS_LIST_TAIL, "SIGNIFICANCE_SCALE_FACTOR", PS_META_REPLACE, 88 "Signicance scale factor", factor); 83 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "EFFECTIVE_AREA", PS_META_REPLACE, "Effective Area", effArea); 84 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SIGNIFICANCE_SCALE_FACTOR", PS_META_REPLACE, "Signicance scale factor", factor); 89 85 90 86 // XXX multithread this if needed -
branches/tap_branches/psphot/src/psphotSkyReplace.c
r21183 r27838 1 1 # include "psphotInternal.h" 2 3 bool psphotSkyReplace (pmConfig *config, const pmFPAview *view) 4 { 5 bool status = true; 6 7 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 8 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 9 10 // skip the chisq image (optionally?) 11 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 12 if (!status) chisqNum = -1; 13 14 // loop over the available readouts 15 for (int i = 0; i < num; i++) { 16 if (i == chisqNum) continue; // skip chisq image 17 if (!psphotSkyReplaceReadout (config, view, "PSPHOT.INPUT", i)) { 18 psError (PSPHOT_ERR_CONFIG, false, "failed to replace sky for PSPHOT.INPUT entry %d", i); 19 return false; 20 } 21 } 22 return true; 23 } 2 24 3 25 // XXX make this an option? 4 26 // in order to successfully replace the sky, we must define a corresponding file... 5 bool psphotSkyReplace (pmConfig *config, const pmFPAview *view) {27 bool psphotSkyReplaceReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index) { 6 28 7 29 psTimerStart ("psphot.skyreplace"); 8 30 9 31 // find the currently selected readout 10 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT"); 11 if (readout == NULL) psAbort("input not defined"); 32 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 33 psAssert (file, "missing file?"); 34 35 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 36 psAssert (readout, "missing readout?"); 12 37 13 38 // select background pixels, from output background file, or create -
branches/tap_branches/psphot/src/psphotSourceFits.c
r25755 r27838 219 219 double chiTrend; 220 220 pmModel *ONE = NULL; 221 pmSource *tmpSrc = NULL; 222 pmModel *EXT = NULL; 223 psArray *DBL = NULL; 221 224 222 225 // skip the source if we don't think it is extended … … 232 235 // at this stage, skip Gaussian windowing, and do not clip pixels by S/N 233 236 // this uses the footprint to judge both radius and aperture? 234 if (!pmSourceMoments (source, radius, 0.0, 0.0 )) return false;237 if (!pmSourceMoments (source, radius, 0.0, 0.0, maskVal)) return false; 235 238 236 239 psTrace ("psphot", 5, "trying blob...\n"); … … 240 243 241 244 // this temporary source is used as a place-holder by the psphotEval functions below 242 pmSource *tmpSrc = pmSourceAlloc ();245 tmpSrc = pmSourceAlloc (); 243 246 244 247 // XXX need to handle failures better here 245 pmModel *EXT = psphotFitEXT (readout, source, modelTypeEXT, maskVal, markVal); 246 if (!isfinite(EXT->params->data.F32[PM_PAR_I0])) psAbort("nan in fit"); 248 EXT = psphotFitEXT (readout, source, modelTypeEXT, maskVal, markVal); 249 if (!EXT) goto escape; 250 if (!isfinite(EXT->params->data.F32[PM_PAR_I0])) goto escape; 247 251 248 252 okEXT = psphotEvalEXT (tmpSrc, EXT); … … 250 254 251 255 // DBL will always be defined, but DBL->data[n] might not 252 psArray *DBL = psphotFitDBL (readout, source, maskVal, markVal); 256 DBL = psphotFitDBL (readout, source, maskVal, markVal); 257 if (!DBL) goto escape; 258 if (!DBL->n) goto escape; 259 253 260 okDBL = psphotEvalDBL (tmpSrc, DBL->data[0]); 254 261 okDBL &= psphotEvalDBL (tmpSrc, DBL->data[1]); … … 362 369 psFree (DBL); 363 370 return true; 371 372 escape: 373 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); 374 psFree (tmpSrc); 375 psFree (EXT); 376 psFree (DBL); 377 return false; 364 378 } 365 379 … … 425 439 // use the source moments, etc to guess basic model parameters 426 440 pmModel *EXT = pmSourceModelGuess (source, modelType); 427 PS_ASSERT (EXT, NULL); 441 if (!EXT) { 442 psTrace ("psphot", 5, "failed to generate a model for source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy); 443 return NULL; 444 } 428 445 429 446 if ((source->moments->Mxx < 1e-3) || (source->moments->Myy < 1e-3)) { -
branches/tap_branches/psphot/src/psphotSourceFreePixels.c
r12792 r27838 1 1 # include "psphotInternal.h" 2 2 3 void psphotSourceFreePixels (psArray *sources) { 3 bool psphotSourceFreePixels (pmConfig *config, const pmFPAview *view) 4 { 5 bool status = true; 4 6 5 if (!sources) return; 7 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 8 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 9 10 // loop over the available readouts 11 for (int i = 0; i < num; i++) { 12 if (!psphotSourceFreePixelsReadout (config, view, "PSPHOT.INPUT", i)) { 13 psError (PSPHOT_ERR_CONFIG, false, "failed to free source pixels for PSPHOT.INPUT entry %d", i); 14 return false; 15 } 16 } 17 return true; 18 } 19 20 bool psphotSourceFreePixelsReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index) { 21 22 bool status; 23 24 // find the currently selected readout 25 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 26 psAssert (file, "missing file?"); 27 28 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 29 psAssert (readout, "missing readout?"); 30 31 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 32 psAssert (detections, "missing detections?"); 33 34 psArray *sources = detections->allSources; 35 psAssert (sources, "missing sources?"); 6 36 7 37 for (int i = 0; i < sources->n; i++) { … … 9 39 pmSourceFreePixels (source); 10 40 } 11 return ;41 return true; 12 42 } -
branches/tap_branches/psphot/src/psphotSourceSize.c
r25852 r27838 13 13 float soft; 14 14 int grow; 15 int xtest, ytest; 16 bool apply; // apply CR mask? 15 17 } psphotSourceSizeOptions; 16 18 19 // local functions: 17 20 bool psphotSourceSizePSF (psphotSourceSizeOptions *options, psArray *sources, pmPSF *psf); 18 21 bool psphotSourceClass (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options); 19 22 bool psphotSourceClassRegion (psRegion *region, pmPSFClump *psfClump, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options); 20 23 bool psphotSourceSizeCR (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options); 21 bool psphotMaskCosmicRay (psImage *mask, pmSource *source, psImageMaskType maskVal, psImageMaskType crMask); 22 bool psphotMaskCosmicRayIsophot (pmSource *source, psImageMaskType maskVal, psImageMaskType crMask); 24 bool psphotMaskCosmicRay (pmReadout *readout, pmSource *source, psImageMaskType maskVal); 25 bool psphotMaskCosmicRayFootprintCheck (psArray *sources); 26 int psphotMaskCosmicRayConnected (int xPeak, int yPeak, psImage *mymask, psImage *myvar, psImage *edges, int binning, float sigma_thresh); 23 27 24 28 // we need to call this function after sources have been fitted to the PSF model and … … 28 32 // deviation from the psf model at the r = FWHM/2 position 29 33 30 // XXX use an internal flag to mark sources which have already been measured 31 bool psphotSourceSize(pmConfig *config, pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, long first) 34 // for now, let's store the detections on the readout->analysis for each readout 35 bool psphotSourceSize (pmConfig *config, const pmFPAview *view, bool getPSFsize) 36 { 37 bool status = true; 38 39 // select the appropriate recipe information 40 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 41 psAssert (recipe, "missing recipe?"); 42 43 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 44 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 45 46 // skip the chisq image (optionally?) 47 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 48 if (!status) chisqNum = -1; 49 50 // loop over the available readouts 51 for (int i = 0; i < num; i++) { 52 if (i == chisqNum) continue; // skip chisq image 53 if (!psphotSourceSizeReadout (config, view, "PSPHOT.INPUT", i, recipe, getPSFsize)) { 54 psError (PSPHOT_ERR_CONFIG, false, "failed on source size analysis for PSPHOT.INPUT entry %d", i); 55 return false; 56 } 57 } 58 return true; 59 } 60 61 // this function use an internal flag to mark sources which have already been measured 62 bool psphotSourceSizeReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool getPSFsize) 32 63 { 33 64 bool status; … … 36 67 psTimerStart ("psphot.size"); 37 68 69 // find the currently selected readout 70 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 71 psAssert (file, "missing file?"); 72 73 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 74 psAssert (readout, "missing readout?"); 75 76 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 77 psAssert (detections, "missing detections?"); 78 79 psArray *sources = detections->allSources; 80 psAssert (sources, "missing sources?"); 81 82 if (!sources->n) { 83 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size"); 84 return true; 85 } 86 87 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 88 psAssert (psf, "missing psf?"); 89 38 90 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 39 91 options.maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels … … 55 107 // XXX recipe name is not great 56 108 options.nSigmaMoments = psMetadataLookupF32 (&status, recipe, "PSPHOT.EXT.NSIGMA.MOMENTS"); 109 assert (status); 110 111 // XXX recipe name is not great 112 options.xtest = psMetadataLookupS32 (&status, recipe, "PSPHOT.CRMASK.XTEST"); 113 options.ytest = psMetadataLookupS32 (&status, recipe, "PSPHOT.CRMASK.YTEST"); 57 114 assert (status); 58 115 … … 69 126 } 70 127 128 options.apply = psMetadataLookupBool(&status, recipe, "PSPHOT.CRMASK.APPLY"); // Growth size for CRs 129 if (!status) { 130 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "PSPHOT.CRMASK.APPLY is not defined."); 131 return false; 132 } 133 71 134 // We are using the value psfMag - 2.5*log10(moment.Sum) as a measure of the extendedness 72 // of an dobject. We need to model this distribution for the PSF stars before we can test135 // of an object. We need to model this distribution for the PSF stars before we can test 73 136 // the significance for a specific object 74 137 // XXX move this to the code that generates the PSF? 75 138 // XXX store the results on pmPSF? 76 psphotSourceSizePSF (&options, sources, psf); 139 140 // XXX this should only be done on the first pass (ie, if we have newSources or allSources?) 141 if (getPSFsize) { 142 psphotSourceSizePSF (&options, sources, psf); 143 } 77 144 78 145 // classify the sources based on ApResid and Moments (extended sources) 146 // NOTE: only sources not already measured !(source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) 79 147 psphotSourceClass(readout, sources, recipe, psf, &options); 80 148 149 // NOTE: only sources not already measured !(source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) 81 150 psphotSourceSizeCR (readout, sources, &options); 82 151 83 psLogMsg ("psphot.size", PS_LOG_INFO, "measure source sizes for %ld sources: %f sec\n", sources->n - first, psTimerMark ("psphot.size")); 152 // XXX fix this (was source->n - first) 153 psLogMsg ("psphot.size", PS_LOG_INFO, "measure source sizes for %ld sources: %f sec\n", sources->n, psTimerMark ("psphot.size")); 84 154 85 155 psphotVisualPlotSourceSize (recipe, readout->analysis, sources); 86 156 psphotVisualShowSourceSize (readout, sources); 87 157 psphotVisualPlotApResid (sources, options.ApResid, options.ApSysErr); 158 psphotVisualShowSatStars (recipe, psf, sources); 88 159 89 160 return true; 90 161 } 91 162 92 bool psphotMaskCosmicRay (psImage *mask, pmSource *source, psImageMaskType maskVal, psImageMaskType crMask) { 163 // model the apmifit distribution for the psf stars: 164 bool psphotSourceSizePSF (psphotSourceSizeOptions *options, psArray *sources, pmPSF *psf) { 165 166 // select stats from the psf stars 167 psVector *Ap = psVectorAllocEmpty (100, PS_TYPE_F32); 168 psVector *ApErr = psVectorAllocEmpty (100, PS_TYPE_F32); 169 170 psImageMaskType maskVal = options->maskVal | options->markVal; 171 172 // XXX why PHOT_WEIGHT?? 173 pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_WEIGHT; 174 175 int num = 0; // Number of sources measured 176 for (int i = 0; i < sources->n; i++) { 177 pmSource *source = sources->data[i]; 178 if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue; 179 num++; 180 181 // replace object in image 182 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) { 183 pmSourceAdd (source, PM_MODEL_OP_FULL, options->maskVal); 184 } 185 186 // clear the mask bit and set the circular mask pixels 187 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal)); 188 psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, source->apRadius, "OR", options->markVal); 189 190 // XXX can we test if psfMag is set and calculate only if needed? 191 pmSourceMagnitudes (source, psf, photMode, maskVal); // maskVal includes markVal 192 193 // clear the mask bit 194 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal)); 195 196 // re-subtract the object, leave local sky 197 pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal); 198 199 float apMag = -2.5*log10(source->moments->Sum); 200 float dMag = source->psfMag - apMag; 201 202 psVectorAppend (Ap, dMag); 203 psVectorAppend (ApErr, source->errMag); 204 } 205 if (num == 0) { 206 // Not raising an error, because errors aren't being checked elsewhere in this function 207 psFree(Ap); 208 psFree(ApErr); 209 return false; 210 } 211 212 // model the distribution as a mean or median value and a systematic error from that value: 213 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); 214 psVectorStats (stats, Ap, NULL, NULL, 0); 215 216 psVector *dAp = psVectorAlloc (Ap->n, PS_TYPE_F32); 217 for (int i = 0; i < Ap->n; i++) { 218 dAp->data.F32[i] = Ap->data.F32[i] - stats->robustMedian; 219 } 220 221 options->ApResid = stats->robustMedian; 222 options->ApSysErr = psVectorSystematicError(dAp, ApErr, 0.05); 223 // XXX this is quite arbitrary... 224 if (!isfinite(options->ApSysErr)) options->ApSysErr = 0.01; 225 psLogMsg ("psphot", PS_LOG_DETAIL, "psf - Sum: %f +/- %f\n", options->ApResid, options->ApSysErr); 226 227 psFree (Ap); 228 psFree (ApErr); 229 psFree (stats); 230 psFree (dAp); 231 232 return true; 233 } 234 235 // classify sources based on the combination of psf-mag, Mxx, Myy 236 bool psphotSourceClass (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options) { 237 238 bool status; 239 pmPSFClump psfClump; 240 char regionName[64]; 241 242 psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4s %4s %4s %4s %4s %4s", "Npsf", "Next", "Nsat", "Ncr", "Nmiss", "Nskip"); 243 244 int nRegions = psMetadataLookupS32 (&status, readout->analysis, "PSF.CLUMP.NREGIONS"); 245 for (int i = 0; i < nRegions; i ++) { 246 snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", i); 247 psMetadata *regionMD = psMetadataLookupPtr (&status, readout->analysis, regionName); 248 psAssert (regionMD, "regions must be defined by earlier call to psphotRoughClassRegion"); 249 250 psRegion *region = psMetadataLookupPtr (&status, regionMD, "REGION"); 251 psAssert (region, "regions must be defined by earlier call to psphotRoughClassRegion"); 252 253 // pull FWHM_X,Y from the recipe, use to define psfClump.X,Y 254 psfClump.X = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X"); psAssert (status, "missing PSF.CLUMP.X"); 255 psfClump.Y = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y"); psAssert (status, "missing PSF.CLUMP.Y"); 256 psfClump.dX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX"); psAssert (status, "missing PSF.CLUMP.DX"); 257 psfClump.dY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY"); psAssert (status, "missing PSF.CLUMP.DY"); 258 259 if ((psfClump.X < 0) || (psfClump.Y < 0) || !psfClump.X || !psfClump.Y || isnan(psfClump.X) || isnan(psfClump.Y)) { 260 psLogMsg ("psphot", 4, "Failed to find a valid PSF clump for region %f,%f - %f,%f\n", region->x0, region->y0, region->x1, region->y1); 261 continue; 262 } 263 264 if (!psphotSourceClassRegion (region, &psfClump, sources, recipe, psf, options)) { 265 psLogMsg ("psphot", 4, "Failed to determine source classification for region %f,%f - %f,%f\n", region->x0, region->y0, region->x1, region->y1); 266 continue; 267 } 268 // psphotVisualPlotSourceSize (recipe, readout->analysis, sources); 269 } 270 271 return true; 272 } 273 274 # define SIZE_SN_LIM 10 275 bool psphotSourceClassRegion (psRegion *region, pmPSFClump *psfClump, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options) { 276 277 PS_ASSERT_PTR_NON_NULL(sources, false); 278 PS_ASSERT_PTR_NON_NULL(recipe, false); 279 280 int Nsat = 0; 281 int Next = 0; 282 int Npsf = 0; 283 int Ncr = 0; 284 int Nmiss = 0; 285 int Nskip = 0; 286 287 pmSourceMode noMoments = PM_SOURCE_MODE_MOMENTS_FAILURE | PM_SOURCE_MODE_SKYVAR_FAILURE | PM_SOURCE_MODE_SKY_FAILURE | PM_SOURCE_MODE_BELOW_MOMENTS_SN; 288 pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_WEIGHT; 289 290 psImageMaskType maskVal = options->maskVal | options->markVal; 291 292 for (psS32 i = 0 ; i < sources->n ; i++) { 293 294 pmSource *source = (pmSource *) sources->data[i]; 295 296 // psfClumps are found for image subregions: 297 // skip sources not in this region 298 if (source->peak->x < region->x0) continue; 299 if (source->peak->x >= region->x1) continue; 300 if (source->peak->y < region->y0) continue; 301 if (source->peak->y >= region->y1) continue; 302 303 // skip source if it was already measured 304 if (source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) { 305 psTrace("psphot", 7, "Not calculating source size since it has already been measured\n"); 306 continue; 307 } 308 309 // source must have been subtracted 310 if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) { 311 source->mode |= PM_SOURCE_MODE_SIZE_SKIPPED; 312 psTrace("psphot", 7, "Not calculating source size since source is not subtracted\n"); 313 continue; 314 } 315 316 // we are basically classifying by moments 317 psAssert (source->moments, "why is this source missing moments?"); 318 if (source->mode & noMoments) { 319 Nskip ++; 320 continue; 321 } 322 323 // convert to Mmaj, Mmin: 324 psF32 Mxx = source->moments->Mxx; 325 psF32 Myy = source->moments->Myy; 326 327 // replace object in image 328 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) { 329 pmSourceAdd (source, PM_MODEL_OP_FULL, options->maskVal); 330 } 331 332 // clear the mask bit and set the circular mask pixels 333 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal)); 334 psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, source->apRadius, "OR", options->markVal); 335 336 // XXX can we test if psfMag is set and calculate only if needed? 337 pmSourceMagnitudes (source, psf, photMode, maskVal); // maskVal includes markVal 338 339 // clear the mask bit 340 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal)); 341 342 // re-subtract the object, leave local sky 343 pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal); 344 345 float apMag = -2.5*log10(source->moments->Sum); 346 float dMag = source->psfMag - apMag; 347 348 // set nSigma to include both systematic and poisson error terms 349 // XXX the 'poisson error' contribution for size is probably wrong... 350 float nSigmaMAG = (dMag - options->ApResid) / hypot(source->errMag, options->ApSysErr); 351 float nSigmaMXX = (Mxx - psfClump->X) / hypot(psfClump->dX, psfClump->X*psfClump->X*source->errMag); 352 float nSigmaMYY = (Myy - psfClump->Y) / hypot(psfClump->dY, psfClump->Y*psfClump->Y*source->errMag); 353 354 // partially-masked sources are more likely to be mis-measured PSFs 355 float sizeBias = 1.0; 356 if (source->pixWeight < 0.9) { 357 sizeBias = 3.0; 358 } 359 360 float minMxx = psfClump->X - sizeBias*options->nSigmaMoments*psfClump->dX; 361 float minMyy = psfClump->Y - sizeBias*options->nSigmaMoments*psfClump->dY; 362 363 // include MAG, MXX, and MYY? 364 source->extNsigma = nSigmaMAG; 365 366 // notes to clarify the source size classification rules: 367 // * a defect should be functionally equivalent to a cosmic ray 368 // * CR & defect should have a faintess limit (min S/N) 369 // * SAT stars should not be faint, but defects may? 370 371 // Anything within this region is a probably PSF-like object. Saturated stars may land 372 // in this region, but are detected elsewhere on the basis of their peak value. 373 bool isPSF = (fabs(nSigmaMAG) < options->nSigmaApResid) && (fabs(nSigmaMXX) < sizeBias*options->nSigmaMoments) && (fabs(nSigmaMYY) < sizeBias*options->nSigmaMoments); 374 if (isPSF) { 375 psTrace("psphotSourceClassRegion.PSF",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g PSF\t%g %g\n", 376 source->peak->xf,source->peak->yf,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigmaMAG, 377 options->nSigmaApResid,sizeBias*options->nSigmaMoments); 378 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED; 379 Npsf ++; 380 continue; 381 } 382 383 // Defects may not always match CRs from peak curvature analysis 384 // Defects may also be marked as SATSTAR -- XXX deactivate this flag? 385 // XXX this rule is not great 386 // XXX only accept brightish detections as CRs 387 // (nSigmaMAG < -options->nSigmaApResid) || 388 bool isCR = isCR = (source->errMag < 1.0 / SIZE_SN_LIM) && ((Mxx < minMxx) || (Myy < minMyy)); 389 if (isCR) { 390 psTrace("psphotSourceClassRegion.CR",4,"CLASS: %g %g %f\t%g %g %g %g %g %g\t%g %g\t%g CR\t%g %g\n", 391 source->peak->xf,source->peak->yf,source->pixWeight,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigmaMAG, 392 options->nSigmaApResid,sizeBias*options->nSigmaMoments); 393 source->mode |= PM_SOURCE_MODE_DEFECT; 394 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_CR_CANDIDATE; 395 Ncr ++; 396 continue; 397 } 398 399 // saturated star (determined in PSF fit). These may also be saturated galaxies, or 400 // just large saturated regions. 401 if (source->mode & PM_SOURCE_MODE_SATSTAR) { 402 psTrace("psphotSourceClassRegion.SAT",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g SAT\t%g %g\n", 403 source->peak->xf,source->peak->yf,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigmaMAG, 404 options->nSigmaApResid,sizeBias*options->nSigmaMoments); 405 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED; 406 Nsat ++; 407 continue; 408 } 409 410 // XXX allow the Mxx, Myy to be less than psfClump->X,Y (by some nSigma)? 411 bool isEXT = (nSigmaMAG > options->nSigmaApResid) || (Mxx > minMxx) || (Myy > minMyy); 412 if (isEXT) { 413 psTrace("psphotSourceClassRegion.EXT",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g Ext\t%g %g\n", 414 source->peak->xf,source->peak->yf,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigmaMAG, 415 options->nSigmaApResid,sizeBias*options->nSigmaMoments); 416 417 source->mode |= PM_SOURCE_MODE_EXT_LIMIT; 418 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED; 419 Next ++; 420 continue; 421 } 422 psTrace("psphotSourceClassRegion.MISS",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g Unk\t%g %g\n", 423 source->peak->xf,source->peak->yf,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigmaMAG, 424 options->nSigmaApResid,sizeBias*options->nSigmaMoments); 425 426 // sources that reach here are probably too faint for a reasonable source size measurement 427 // psWarning ("sourse size was missed for %f,%f : %f %f -- %f\n", source->peak->xf, source->peak->yf, Mxx, Myy, nSigmaMAG); 428 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED; 429 Nmiss ++; 430 } 431 432 psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4d %4d %4d %4d %4d %4d", Npsf, Next, Nsat, Ncr, Nmiss, Nskip); 433 434 return true; 435 } 436 437 // given an object suspected to be a defect, generate a pixel mask using the Lapacian transform 438 // if enough of the object is detected as 'sharp', consider the object a cosmic ray 439 bool psphotSourceSizeCR (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options) { 440 441 psTimerStart ("psphot.cr"); 442 443 int nMasked = 0; 444 for (int i = 0; i < sources->n; i++) { 445 pmSource *source = sources->data[i]; 446 447 // skip source if it was already measured 448 if (source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) { 449 psTrace("psphot", 7, "Not calculating source size since it has already been measured\n"); 450 continue; 451 } 452 453 // only check candidates marked above 454 if (!(source->tmpFlags & PM_SOURCE_TMPF_SIZE_CR_CANDIDATE)) { 455 psTrace("psphot", 7, "Not calculating source size since it has already been measured\n"); 456 continue; 457 } 458 459 // skip unless this source is thought to be a cosmic ray. flag the detection and mask the pixels 460 // XXX this may be degenerate with the above test 461 if (!(source->mode & PM_SOURCE_MODE_DEFECT)) continue; 462 463 // Integer position of peak 464 int xPeak = source->peak->xf - source->pixels->col0 + 0.5; 465 int yPeak = source->peak->yf - source->pixels->row0 + 0.5; 466 467 // Skip sources which are too close to a boundary. These are mostly caught as DEFECT 468 if (xPeak < 1 || xPeak > source->pixels->numCols - 2 || 469 yPeak < 1 || yPeak > source->pixels->numRows - 2) { 470 psTrace("psphot", 7, "Not calculating crNsigma due to edge\n"); 471 continue; 472 } 473 474 // XXX for testing, only CRMASK a single source: 475 if (options->xtest && (fabs(source->peak->xf - options->xtest) > 5)) continue; 476 if (options->ytest && (fabs(source->peak->yf - options->ytest) > 5)) continue; 477 478 // replace object in image 479 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) { 480 pmSourceAdd (source, PM_MODEL_OP_FULL, options->maskVal); 481 } 482 483 // XXX this is running slowly and is too agressive, but it more-or-less works 484 psTrace("psphot", 6, "mask cosmic ray at %f, %f\n", source->peak->xf, source->peak->yf); 485 if (options->apply) { 486 psphotMaskCosmicRay(readout, source, options->crMask); 487 } else { 488 source->mode |= PM_SOURCE_MODE_CR_LIMIT; 489 } 490 nMasked ++; 491 492 // re-subtract the object, leave local sky 493 pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal); 494 } 495 496 // now that we have masked pixels associated with CRs, we can grow the mask 497 if (options->grow > 0) { 498 bool oldThreads = psImageConvolveSetThreads(true); // Old value of threading for psImageConvolveMask 499 psImage *newMask = psImageConvolveMask(NULL, readout->mask, options->crMask, options->crMask, -options->grow, options->grow, -options->grow, options->grow); 500 psImageConvolveSetThreads(oldThreads); 501 if (!newMask) { 502 psError(PS_ERR_UNKNOWN, false, "Unable to grow CR mask"); 503 return false; 504 } 505 psFree(readout->mask); 506 readout->mask = newMask; 507 } 508 509 psLogMsg ("psphot.cr", PS_LOG_INFO, "mask CR: %d masked in %f sec\n", nMasked, psTimerMark ("psphot.cr")); 510 511 // XXX test : save the mask image 512 if (0) { 513 psphotSaveImage (NULL, readout->mask, "mask.fits"); 514 } 515 516 return true; 517 } 518 519 # define DUMPPICS 0 520 # define LIMIT_XRANGE(X, IMAGE) { X = PS_MIN(PS_MAX(0, X), IMAGE->numCols); } 521 # define LIMIT_YRANGE(Y, IMAGE) { Y = PS_MIN(PS_MAX(0, Y), IMAGE->numRows); } 522 523 // Comments by CZW 20091209 : Mechanics of how to identify CR pixels taken from "Cosmic-Ray 524 // Rejection by Laplacian Edge Detection" by Pieter van Dokkum, arXiv:astro-ph/0108003. This 525 // does no repair or recovery of the CR pixels, it only masks them out. My test code can be 526 // found at /data/ipp031.0/watersc1/psphot.20091209/algo_check.c 527 bool psphotMaskCosmicRay (pmReadout *readout, pmSource *source, psImageMaskType maskVal) { 528 529 // Get the actual images and information about the peak. 530 psImage *mask = readout->mask; 531 pmPeak *peak = source->peak; 532 pmFootprint *footprint = peak->footprint; 533 534 // Bounding boxes are inclusive of final pixel 535 int xs = footprint->bbox.x0; 536 int xe = footprint->bbox.x1 + 1; 537 int ys = footprint->bbox.y0; 538 int ye = footprint->bbox.y1 + 1; 539 540 LIMIT_XRANGE(xs, mask); 541 LIMIT_XRANGE(xe, mask); 542 LIMIT_YRANGE(ys, mask); 543 LIMIT_YRANGE(ye, mask); 544 545 int dx = xe - xs; 546 int dy = ye - ys; 547 548 psImage *image= readout->image; 549 psImage *variance = readout->variance; 550 551 int binning = 2; 552 float sigma_thresh = 3.0; 553 int max_iter = 1; // XXX with isophot masking, we only want to do a single pass 554 555 // Temporary images. 556 psImage *mypix = psImageAlloc(dx,dy,image->type.type); 557 psImage *myfix = psImageAlloc(dx,dy,image->type.type); 558 psImage *myvar = psImageAlloc(dx,dy,image->type.type); 559 psImage *binned = psImageAlloc(dx * binning,dy * binning,image->type.type); 560 psImage *conved = psImageAlloc(dx * binning,dy * binning,image->type.type); 561 psImage *edges = psImageAlloc(dx,dy,image->type.type); 562 psImage *mymask = psImageAlloc(dx,dy,PS_TYPE_IMAGE_MASK); 563 564 // Load my copy of things. 565 for (int y = 0; y < dy; y++) { 566 for (int x = 0; x < dx; x++) { 567 mypix->data.F32[y][x] = image->data.F32[y+ys][x+xs]; 568 myvar->data.F32[y][x] = variance->data.F32[y+ys][x+xs]; 569 mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = 0x00; 570 } 571 } 572 // Mask so I can see on the output image where the footprint is. 573 for (int i = 0; i < footprint->spans->n; i++) { 574 pmSpan *sp = footprint->spans->data[i]; 575 for (int j = sp->x0; j <= sp->x1; j++) { 576 int y = sp->y - ys; 577 int x = j - xs; 578 mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= 0x01; 579 } 580 } 581 582 int nCRpix = 1; // force at least one pass... 583 for (int iteration = 0; (iteration < max_iter) && (nCRpix > 0); iteration++) { 584 nCRpix = 0; 585 psImageInit (binned, 0.0); 586 psImageInit (conved, 0.0); 587 psImageInit (edges, 0.0); 588 589 // Make subsampled image. Maybe this should be called "unbinned" or something 590 for (int y = 0; y < binning * dy; y++) { 591 int yraw = y / binning; 592 for (int x = 0; x < binning * dx; x++) { 593 int xraw = x / binning; 594 binned->data.F32[y][x] = mypix->data.F32[yraw][xraw]; 595 } 596 } 597 598 // Apply Laplace transform (kernel = [[0 -0.25 0][-0.25 1 -0.25][0 -0.25 0]]), clipping at zero 599 for (int y = 1; y < binning * dy - 1; y++) { 600 for (int x = 1; x < binning * dx - 1; x++) { 601 float value = binned->data.F32[y][x] - 0.25 * 602 (binned->data.F32[y+0][x-1] + binned->data.F32[y+0][x+1] + 603 binned->data.F32[y-1][x+0] + binned->data.F32[y+1][x+0]); 604 value = PS_MAX(0.0, value); 605 606 conved->data.F32[y][x] = value; 607 } 608 } 609 610 // Create an edge map by rebinning 611 for (int y = 0; y < binning * dy; y++) { 612 int yraw = y / binning; 613 for (int x = 0; x < binning * dx; x++) { 614 int xraw = x / binning; 615 edges->data.F32[yraw][xraw] += conved->data.F32[y][x]; 616 } 617 } 618 619 // coordinate of peak in subimage pixels: 620 int xPeak = peak->x - xs; 621 int yPeak = peak->y - ys; 622 623 // Modify my mask if we're above the significance threshold, but only for connected pixels 624 nCRpix = psphotMaskCosmicRayConnected (xPeak, yPeak, mymask, myvar, edges, binning, sigma_thresh); 625 626 # if DUMPPICS 627 psphotSaveImage (NULL, mypix, "crmask.pix.fits"); 628 # endif 629 630 // XXX do not repair the pixels in isophot version 631 # if 0 632 // "Repair" Masked pixels for the next round. 633 for (int y = 1; y < dy - 1; y++) { 634 for (int x = 1; x < dx - 1; x++) { 635 if (!(mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & 0x40)) { 636 myfix->data.F32[y][x] = mypix->data.F32[y][x]; 637 continue; 638 } 639 myfix->data.F32[y][x] = 0.25 * 640 (mypix->data.F32[y+0][x-1] + mypix->data.F32[y+0][x+1] + 641 mypix->data.F32[y-1][x+0] + mypix->data.F32[y+1][x+0]); 642 } 643 } 644 645 // "Repair" Masked pixels for the next round. 646 for (int y = 1; y < dy - 1; y++) { 647 for (int x = 1; x < dx - 1; x++) { 648 mypix->data.F32[y][x] = myfix->data.F32[y][x]; 649 } 650 } 651 # endif 652 653 # if DUMPPICS 654 fprintf (stderr, "CRMASK %d %d %d %d %d\n", xs, ys, dx, dy, iteration); 655 psphotSaveImage (NULL, mypix, "crmask.fix.fits"); 656 psphotSaveImage (NULL, myvar, "crmask.var.fits"); 657 psphotSaveImage (NULL, binned, "crmask.binn.fits"); 658 psphotSaveImage (NULL, conved, "crmask.conv.fits"); 659 psphotSaveImage (NULL, edges, "crmask.edge.fits"); 660 psphotSaveImage (NULL, mymask, "crmask.mask.fits"); 661 # endif 662 psTrace("psphot.czw",2,"Iter: %d Count: %d",iteration, nCRpix); 663 } 664 665 # if 0 666 // A solitary masked pixel is likely a lie. Remove those 667 // XXX can't we use nCRpix == 1 to test for these? 668 for (int x = 0; x < dx; x++) { 669 for (int y = 0; y < dy; y++) { 670 if (!(mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & 0x40)) continue; 671 if ((x-1 >= 0) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x-1] & 0x40)) { 672 continue; 673 } 674 if ((y-1 >= 0) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[y-1][x] & 0x40)) { 675 continue; 676 } 677 if ((x+1 < dx) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x+1] & 0x40)) { 678 continue; 679 } 680 if ((y+1 < dy) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[y+1][x] & 0x40)) { 681 continue; 682 } 683 mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] ^= 0x40; 684 } 685 } 686 # endif 687 688 // transfer temporary mask to real mask & count masked pixels 689 nCRpix = 0; 690 for (int x = 0; x < dx; x++) { 691 for (int y = 0; y < dy; y++) { 692 if (mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & 0x40) { 693 mask->data.PS_TYPE_IMAGE_MASK_DATA[y+ys+mask->row0][x+xs+mask->col0] |= maskVal; 694 nCRpix ++; 695 } 696 } 697 } 698 699 // XXX if we decide this REALLY is a cosmic ray, set the CR_LIMIT bit 700 if (nCRpix > 1) { 701 source->mode |= PM_SOURCE_MODE_CR_LIMIT; 702 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED; 703 } 704 // fprintf (stderr, "CRMASK %d %d %d %d %d\n", peak->x, peak->y, dx, dy, nCRpix); 705 706 psFree(mypix); 707 psFree(myfix); 708 psFree(myvar); 709 psFree(binned); 710 psFree(conved); 711 psFree(edges); 712 psFree(mymask); 713 714 return true; 715 } 716 717 bool psphotMaskCosmicRayFootprintCheck (psArray *sources) { 718 719 for (int i = 0; i < sources->n; i++) { 720 pmSource *source = sources->data[i]; 721 pmPeak *peak = source->peak; 722 pmFootprint *footprint = peak->footprint; 723 if (!footprint) continue; 724 for (int j = 0; j < footprint->spans->n; j++) { 725 pmSpan *sp = footprint->spans->data[j]; 726 psAssert (sp, "missing span"); 727 } 728 } 729 return true; 730 } 731 732 /**** ------ old versions of cosmic ray masking ----- ****/ 733 734 bool psphotMaskCosmicRayIsophot (pmSource *source, psImageMaskType maskVal, psImageMaskType crMask); 735 736 // This attempt to mask the cosmic rays used the isophotal boundary 737 bool psphotMaskCosmicRay_V1 (psImage *mask, pmSource *source, psImageMaskType maskVal, psImageMaskType crMask) { 93 738 94 739 // replace the source flux … … 103 748 pmFootprint *footprint = peak->footprint; 104 749 if (!footprint) { 750 psTrace("psphot.czw",2,"Using isophot CR mask code."); 751 105 752 // if we have not footprint, use the old code to mask by isophot 106 753 psphotMaskCosmicRayIsophot (source, maskVal, crMask); … … 109 756 110 757 if (!footprint->spans) { 758 psTrace("psphot.czw",2,"Using isophot CR mask code."); 759 111 760 // if we have no footprint, use the old code to mask by isophot 112 761 psphotMaskCosmicRayIsophot (source, maskVal, crMask); 113 762 return true; 114 763 } 115 764 psphotMaskCosmicRayIsophot (source, maskVal, crMask); 116 765 // mask all of the pixels covered by the spans of the footprint 117 766 for (int j = 1; j < footprint->spans->n; j++) { … … 127 776 } 128 777 return true; 778 } 779 780 # define VERBOSE 0 781 int psphotMaskCosmicRayConnected (int xPeak, int yPeak, psImage *mymask, psImage *myvar, psImage *edges, int binning, float sigma_thresh) { 782 783 int xLo, xRo; 784 int nCRpix = 0; 785 786 float noise_factor = 5.0 / 4.0; // Intrinsic to the Laplacian making noise spikes spikier. 787 788 // mark the pixels in this row to the left, then the right. stay within footprint 789 int xL = xPeak; // find the range of valid pixels in this row 790 int xR = xPeak; 791 for (int ix = xPeak; (ix >= 0) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[yPeak][ix] & 0x01); ix--) { 792 float noise = binning * sqrt(noise_factor * myvar->data.F32[yPeak][ix]); 793 float value = edges->data.F32[yPeak][ix] / noise; 794 if (value < sigma_thresh ) break; 795 mymask->data.PS_TYPE_IMAGE_MASK_DATA[yPeak][ix] |= 0x40; 796 xL = ix; 797 nCRpix ++; 798 if (VERBOSE) fprintf (stderr, "mark %d,%d (%d) : %d - %d\n", ix, yPeak, nCRpix, xL, xR); 799 } 800 for (int ix = xPeak; (ix < mymask->numCols) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[yPeak][ix] & 0x01); ix++) { 801 float noise = binning * sqrt(noise_factor * myvar->data.F32[yPeak][ix]); 802 float value = edges->data.F32[yPeak][ix] / noise; 803 if (value < sigma_thresh ) break; 804 mymask->data.PS_TYPE_IMAGE_MASK_DATA[yPeak][ix] |= 0x40; 805 xR = ix; 806 nCRpix ++; 807 if (VERBOSE) fprintf (stderr, "mark %d,%d (%d) : %d - %d\n", ix, yPeak, nCRpix, xL, xR); 808 } 809 // xL and xR mark the first and last valid pixel in the row 810 811 // for each of the neighboring rows, mark the high pixels if they touch the range xL to xR 812 xLo = PS_MAX(xL - 1, 0); 813 xRo = PS_MIN(xR + 1, mymask->numCols); 814 815 // first go down: 816 for (int iy = yPeak - 1; iy >= 0; iy--) { 817 818 int xLn = -1; 819 int xRn = -1; 820 int newPix = 0; 821 822 // mark the pixels in the good range 823 for (int ix = xLo; ix < xRo; ix++) { 824 if (!(mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & 0x01)) continue; // only use pixels in the footprint 825 float noise = binning * sqrt(noise_factor * myvar->data.F32[iy][ix]); 826 float value = edges->data.F32[iy][ix] / noise; 827 if (value < sigma_thresh ) continue; 828 mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= 0x40; 829 if (xLn == -1) xLn = ix; // first valid pixel in this row 830 xRn = ix; // last valid pixel in this row 831 nCRpix ++; 832 newPix ++; 833 if (VERBOSE) fprintf (stderr, "mark C %d,%d (%d) : %d - %d | %d - %d | %d - %d \n", ix, iy, nCRpix, xL, xR, xLo, xRo, xLn, xRn); 834 } 835 836 // mark the pixels to the left of the good range 837 for (int ix = xLo; (ix >= 0) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & 0x01); ix--) { 838 float noise = binning * sqrt(noise_factor * myvar->data.F32[iy][ix]); 839 float value = edges->data.F32[iy][ix] / noise; 840 if (value < sigma_thresh ) break; 841 mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= 0x40; 842 if (xRn == -1) xRn = ix; // last valid pixel in this row 843 xLn = ix; 844 nCRpix ++; 845 newPix ++; 846 if (VERBOSE) fprintf (stderr, "mark L %d,%d (%d) : %d - %d | %d - %d | %d - %d \n", ix, iy, nCRpix, xL, xR, xLo, xRo, xLn, xRn); 847 } 848 849 // mark the pixels to the right of the good range 850 for (int ix = xRo; (ix < mymask->numCols) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & 0x01); ix++) { 851 float noise = binning * sqrt(noise_factor * myvar->data.F32[iy][ix]); 852 float value = edges->data.F32[iy][ix] / noise; 853 if (value < sigma_thresh ) break; 854 mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= 0x40; 855 if (xLn == -1) xLn = ix; // first valid pixel in this row 856 xRn = ix; 857 nCRpix ++; 858 newPix ++; 859 if (VERBOSE) fprintf (stderr, "mark R %d,%d (%d) : %d - %d | %d - %d | %d - %d \n", ix, iy, nCRpix, xL, xR, xLo, xRo, xLn, xRn); 860 } 861 if (newPix == 0) break; 862 xLo = PS_MAX(xLn - 1, 0); 863 xRo = PS_MIN(xRn + 1, mymask->numCols); 864 } 865 866 xLo = PS_MAX(xL - 1, 0); 867 xRo = PS_MIN(xR + 1, mymask->numCols); 868 869 // next go up: 870 for (int iy = yPeak + 1; iy < mymask->numRows; iy++) { 871 872 int xLn = -1; 873 int xRn = -1; 874 int newPix = 0; 875 876 // mark the pixels in the good range 877 for (int ix = xLo; ix < xRo; ix++) { 878 if (!(mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & 0x01)) continue; // only use pixels in the footprint 879 float noise = binning * sqrt(noise_factor * myvar->data.F32[iy][ix]); 880 float value = edges->data.F32[iy][ix] / noise; 881 if (value < sigma_thresh ) continue; 882 mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= 0x40; 883 if (xLn == -1) xLn = ix; // first valid pixel in this row 884 xRn = ix; // last valid pixel in this row 885 nCRpix ++; 886 newPix ++; 887 if (VERBOSE) fprintf (stderr, "mark C %d,%d (%d) : %d - %d | %d - %d | %d - %d \n", ix, iy, nCRpix, xL, xR, xLo, xRo, xLn, xRn); 888 } 889 890 // mark the pixels to the left of the good range 891 for (int ix = xLo; (ix >= 0) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & 0x01); ix--) { 892 float noise = binning * sqrt(noise_factor * myvar->data.F32[iy][ix]); 893 float value = edges->data.F32[iy][ix] / noise; 894 if (value < sigma_thresh ) break; 895 mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= 0x40; 896 if (xRn == -1) xRn = ix; // last valid pixel in this row 897 xLn = ix; 898 nCRpix ++; 899 newPix ++; 900 if (VERBOSE) fprintf (stderr, "mark L %d,%d (%d) : %d - %d | %d - %d | %d - %d \n", ix, iy, nCRpix, xL, xR, xLo, xRo, xLn, xRn); 901 } 902 903 // mark the pixels to the right of the good range 904 for (int ix = xRo; (ix < mymask->numCols) && (mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] & 0x01); ix++) { 905 float noise = binning * sqrt(noise_factor * myvar->data.F32[iy][ix]); 906 float value = edges->data.F32[iy][ix] / noise; 907 if (value < sigma_thresh ) break; 908 mymask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= 0x40; 909 if (xLn == -1) xLn = ix; // first valid pixel in this row 910 xRn = ix; 911 nCRpix ++; 912 newPix ++; 913 if (VERBOSE) fprintf (stderr, "mark R %d,%d (%d) : %d - %d | %d - %d | %d - %d \n", ix, iy, nCRpix, xL, xR, xLo, xRo, xLn, xRn); 914 } 915 if (newPix == 0) break; 916 xLo = PS_MAX(xLn - 1, 0); 917 xRo = PS_MIN(xRn + 1, mymask->numCols); 918 } 919 920 return nCRpix; 129 921 } 130 922 … … 192 984 } 193 985 } 194 return true;195 }196 197 // model the apmifit distribution for the psf stars:198 bool psphotSourceSizePSF (psphotSourceSizeOptions *options, psArray *sources, pmPSF *psf) {199 200 // select stats from the psf stars201 psVector *Ap = psVectorAllocEmpty (100, PS_TYPE_F32);202 psVector *ApErr = psVectorAllocEmpty (100, PS_TYPE_F32);203 204 psImageMaskType maskVal = options->maskVal | options->markVal;205 206 // XXX why PHOT_WEIGHT??207 pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_WEIGHT;208 209 for (int i = 0; i < sources->n; i++) {210 pmSource *source = sources->data[i];211 if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;212 213 // replace object in image214 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {215 pmSourceAdd (source, PM_MODEL_OP_FULL, options->maskVal);216 }217 218 // clear the mask bit and set the circular mask pixels219 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal));220 psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, source->apRadius, "OR", options->markVal);221 222 // XXX can we test if psfMag is set and calculate only if needed?223 pmSourceMagnitudes (source, psf, photMode, maskVal); // maskVal includes markVal224 225 // clear the mask bit226 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal));227 228 // re-subtract the object, leave local sky229 pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal);230 231 float apMag = -2.5*log10(source->moments->Sum);232 float dMag = source->psfMag - apMag;233 234 psVectorAppend (Ap, 100, dMag);235 psVectorAppend (ApErr, 100, source->errMag);236 }237 238 // model the distribution as a mean or median value and a systematic error from that value:239 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN);240 psVectorStats (stats, Ap, NULL, NULL, 0);241 242 psVector *dAp = psVectorAlloc (Ap->n, PS_TYPE_F32);243 for (int i = 0; i < Ap->n; i++) {244 dAp->data.F32[i] = Ap->data.F32[i] - stats->robustMedian;245 }246 247 options->ApResid = stats->robustMedian;248 options->ApSysErr = psVectorSystematicError(dAp, ApErr, 0.05);249 psLogMsg ("psphot", PS_LOG_DETAIL, "psf - Sum: %f +/- %f\n", options->ApResid, options->ApSysErr);250 251 psFree (Ap);252 psFree (ApErr);253 psFree (stats);254 psFree (dAp);255 256 return true;257 }258 259 // classify sources based on the combination of psf-mag, Mxx, Myy260 bool psphotSourceClass (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options) {261 262 bool status;263 pmPSFClump psfClump;264 char regionName[64];265 266 psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4s %4s %4s %4s %4s %4s", "Npsf", "Next", "Nsat", "Ncr", "Nmiss", "Nskip");267 268 int nRegions = psMetadataLookupS32 (&status, readout->analysis, "PSF.CLUMP.NREGIONS");269 for (int i = 0; i < nRegions; i ++) {270 snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", i);271 psMetadata *regionMD = psMetadataLookupPtr (&status, readout->analysis, regionName);272 psAssert (regionMD, "regions must be defined by earlier call to psphotRoughClassRegion");273 274 psRegion *region = psMetadataLookupPtr (&status, regionMD, "REGION");275 psAssert (region, "regions must be defined by earlier call to psphotRoughClassRegion");276 277 // pull FWHM_X,Y from the recipe, use to define psfClump.X,Y278 psfClump.X = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X"); psAssert (status, "missing PSF.CLUMP.X");279 psfClump.Y = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y"); psAssert (status, "missing PSF.CLUMP.Y");280 psfClump.dX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX"); psAssert (status, "missing PSF.CLUMP.DX");281 psfClump.dY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY"); psAssert (status, "missing PSF.CLUMP.DY");282 283 if ((psfClump.X < 0) || (psfClump.Y < 0) || !psfClump.X || !psfClump.Y || isnan(psfClump.X) || isnan(psfClump.Y)) {284 psLogMsg ("psphot", 4, "Failed to find a valid PSF clump for region %f,%f - %f,%f\n", region->x0, region->y0, region->x1, region->y1);285 continue;286 }287 288 if (!psphotSourceClassRegion (region, &psfClump, sources, recipe, psf, options)) {289 psLogMsg ("psphot", 4, "Failed to determine source classification for region %f,%f - %f,%f\n", region->x0, region->y0, region->x1, region->y1);290 continue;291 }292 }293 294 return true;295 }296 297 bool psphotSourceClassRegion (psRegion *region, pmPSFClump *psfClump, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options) {298 299 PS_ASSERT_PTR_NON_NULL(sources, false);300 PS_ASSERT_PTR_NON_NULL(recipe, false);301 302 int Nsat = 0;303 int Next = 0;304 int Npsf = 0;305 int Ncr = 0;306 int Nmiss = 0;307 int Nskip = 0;308 309 pmSourceMode noMoments = PM_SOURCE_MODE_MOMENTS_FAILURE | PM_SOURCE_MODE_SKYVAR_FAILURE | PM_SOURCE_MODE_SKY_FAILURE | PM_SOURCE_MODE_BELOW_MOMENTS_SN;310 pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_WEIGHT;311 312 psImageMaskType maskVal = options->maskVal | options->markVal;313 314 for (psS32 i = 0 ; i < sources->n ; i++) {315 316 pmSource *source = (pmSource *) sources->data[i];317 318 // psfClumps are found for image subregions:319 // skip sources not in this region320 if (source->peak->x < region->x0) continue;321 if (source->peak->x >= region->x1) continue;322 if (source->peak->y < region->y0) continue;323 if (source->peak->y >= region->y1) continue;324 325 // skip source if it was already measured326 if (source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) {327 psTrace("psphot", 7, "Not calculating source size since it has already been measured\n");328 continue;329 }330 331 // source must have been subtracted332 if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) {333 source->mode |= PM_SOURCE_MODE_SIZE_SKIPPED;334 psTrace("psphot", 7, "Not calculating source size since source is not subtracted\n");335 continue;336 }337 338 // we are basically classifying by moments; use the default if not found339 psAssert (source->moments, "why is this source missing moments?");340 if (source->mode & noMoments) {341 Nskip ++;342 continue;343 }344 345 psF32 Mxx = source->moments->Mxx;346 psF32 Myy = source->moments->Myy;347 348 // replace object in image349 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {350 pmSourceAdd (source, PM_MODEL_OP_FULL, options->maskVal);351 }352 353 // clear the mask bit and set the circular mask pixels354 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal));355 psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, source->apRadius, "OR", options->markVal);356 357 // XXX can we test if psfMag is set and calculate only if needed?358 pmSourceMagnitudes (source, psf, photMode, maskVal); // maskVal includes markVal359 360 // clear the mask bit361 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal));362 363 // re-subtract the object, leave local sky364 pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal);365 366 float apMag = -2.5*log10(source->moments->Sum);367 float dMag = source->psfMag - apMag;368 float nSigma = (dMag - options->ApResid) / hypot(source->errMag, options->ApSysErr);369 370 source->extNsigma = nSigma;371 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED;372 373 // Anything within this region is a probably PSF-like object. Saturated stars may land374 // in this region, but are detected elsewhere on the basis of their peak value.375 bool isPSF = (fabs(nSigma) < options->nSigmaApResid) && (fabs(Mxx - psfClump->X) < options->nSigmaMoments*psfClump->dX) && (fabs(Myy - psfClump->Y) < options->nSigmaMoments*psfClump->dY);376 if (isPSF) {377 Npsf ++;378 continue;379 }380 381 // Defects may not always match CRs from peak curvature analysis382 // Defects may also be marked as SATSTAR -- XXX deactivate this flag?383 // XXX this rule is not great384 if ((Mxx < psfClump->X) || (Myy < psfClump->Y)) {385 source->mode |= PM_SOURCE_MODE_DEFECT;386 Ncr ++;387 continue;388 }389 390 // saturated star (determined in PSF fit). These may also be saturated galaxies, or391 // just large saturated regions.392 if (source->mode & PM_SOURCE_MODE_SATSTAR) {393 Nsat ++;394 continue;395 }396 397 // XXX allow the Mxx, Myy to be less than psfClump->X,Y (by some nSigma)?398 bool isEXT = (nSigma > options->nSigmaApResid) || ((Mxx > psfClump->X) && (Myy > psfClump->Y));399 if (isEXT) {400 source->mode |= PM_SOURCE_MODE_EXT_LIMIT;401 Next ++;402 continue;403 }404 405 psWarning ("sourse size was missed for %f,%f : %f %f -- %f\n", source->peak->xf, source->peak->yf, Mxx, Myy, nSigma);406 Nmiss ++;407 }408 409 psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4d %4d %4d %4d %4d %4d", Npsf, Next, Nsat, Ncr, Nmiss, Nskip);410 411 986 return true; 412 987 } … … 486 1061 } 487 1062 488 bool psphotSourceSizeCR (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options) { 1063 // this was an old attempt to identify cosmic rays based on the peak curvature 1064 bool psphotSourcePeakCurvature (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options) { 489 1065 490 1066 // classify the sources based on the CR test (place this in a function?) … … 618 1194 return true; 619 1195 } 1196 -
branches/tap_branches/psphot/src/psphotSourceStats.c
r25852 r27838 1 1 # include "psphotInternal.h" 2 2 3 bool psphotSetMomentsWindow (psMetadata *recipe, psMetadata *analysis, psArray *sources); 4 5 psArray *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections, bool setWindow) { 3 // convert detections to sources and measure their basic properties (moments, local sky, sky 4 // variance) Note: this function only generates sources for the new peaks (peak->assigned). 5 // The new sources are added to any existing sources on detections->newSources. The sources 6 // on detections->allSources are ignored. 7 bool psphotSourceStats (pmConfig *config, const pmFPAview *view, bool setWindow) 8 { 9 bool status = true; 10 11 // select the appropriate recipe information 12 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 13 psAssert (recipe, "missing recipe?"); 14 15 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 16 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 17 18 // loop over the available readouts 19 for (int i = 0; i < num; i++) { 20 if (!psphotSourceStatsReadout (config, view, "PSPHOT.INPUT", i, recipe, setWindow)) { 21 psError (PSPHOT_ERR_CONFIG, false, "failed to find initial detections for PSPHOT.INPUT entry %d", i); 22 return false; 23 } 24 } 25 return true; 26 } 27 28 bool psphotSourceStatsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool setWindow) { 6 29 7 30 bool status = false; … … 10 33 psTimerStart ("psphot.stats"); 11 34 12 // select the appropriate recipe information 13 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 14 assert (recipe); 35 // find the currently selected readout 36 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 37 psAssert (file, "missing file?"); 38 39 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 40 psAssert (readout, "missing readout?"); 41 42 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 43 psAssert (detections, "missing detections?"); 44 45 // XXX TEST: 46 if (detections->allSources) { 47 psphotMaskCosmicRayFootprintCheck(detections->allSources); 48 } 49 if (detections->newSources) { 50 psphotMaskCosmicRayFootprintCheck(detections->newSources); 51 } 15 52 16 53 // determine the number of allowed threads … … 21 58 22 59 // determine properties (sky, moments) of initial sources 23 float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 24 if (!status) return NULL; 25 60 float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 61 psAssert (status, "missing SKY_OUTER_RADIUS in recipe?"); 62 63 // XXX this seems like an arbitrary number... 26 64 OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius 27 65 28 66 char *breakPt = psMetadataLookupStr (&status, recipe, "BREAK_POINT"); 29 if (!status) return NULL; 67 psAssert (status, "missing BREAK_POINT?"); 68 69 float INNER = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS"); psAssert (status, "missing SKY_INNER_RADIUS"); 70 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); psAssert (status, "missing MOMENTS_SN_MIN"); 71 72 // bit-masks to test for good/bad pixels 73 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); 74 psAssert (maskVal, "missing MASK.PSPHOT"); 75 76 // bit-mask to mark pixels not used in analysis 77 psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); 78 psAssert (markVal, "missing MARK.PSPHOT"); 30 79 31 80 psArray *peaks = detections->peaks; 32 81 if (!peaks) { 33 82 psError(PS_ERR_UNEXPECTED_NULL, false, "No peaks found!"); 34 return NULL;83 return false; 35 84 } 36 85 37 86 // generate the array of sources, define the associated pixel 38 sources = psArrayAllocEmpty (peaks->n); 87 if (!detections->newSources) { 88 detections->newSources = psArrayAllocEmpty (peaks->n); 89 } 90 sources = detections->newSources; 91 92 // if there are no peaks, we save the empty source array and return 93 if (!peaks->n) { 94 return true; 95 } 39 96 40 97 for (int i = 0; i < peaks->n; i++) { … … 45 102 // create a new source 46 103 pmSource *source = pmSourceAlloc(); 104 source->imageID = index; 47 105 48 106 // add the peak … … 58 116 psArrayAdd (sources, 100, source); 59 117 psFree (source); 118 } 119 120 if (!strcasecmp (breakPt, "PEAKS")) { 121 psLogMsg ("psphot", PS_LOG_INFO, "%ld sources : %f sec\n", sources->n, psTimerMark ("psphot.stats")); 122 psLogMsg ("psphot", PS_LOG_INFO, "break point PEAKS, skipping MOMENTS\n"); 123 psphotVisualShowMoments (sources); 124 return true; 125 } 126 127 if (setWindow) { 128 if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) { 129 psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!"); 130 psFree(detections->newSources); 131 return false; 132 } 133 } 134 135 // if we have measured the window, we will be saving the modified version of these recipe values on readout->analysis 136 float SIGMA = psMetadataLookupF32 (&status, readout->analysis, "MOMENTS_GAUSS_SIGMA"); 137 if (!status) { 138 SIGMA = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA"); 139 } 140 float RADIUS = psMetadataLookupF32 (&status, readout->analysis, "PSF_MOMENTS_RADIUS"); 141 if (!status) { 142 RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS"); 143 } 144 145 // threaded measurement of the source magnitudes 146 int Nfail = 0; 147 int Nmoments = 0; 148 int Nfaint = 0; 149 150 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) 151 int Cx = 1, Cy = 1; 152 psphotChooseCellSizes (&Cx, &Cy, readout, nThreads); 153 154 psArray *cellGroups = psphotAssignSources (Cx, Cy, sources); 155 156 for (int i = 0; i < cellGroups->n; i++) { 157 158 psArray *cells = cellGroups->data[i]; 159 160 for (int j = 0; j < cells->n; j++) { 161 162 // allocate a job -- if threads are not defined, this just runs the job 163 psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS"); 164 165 psArrayAdd(job->args, 1, cells->data[j]); // sources 166 167 PS_ARRAY_ADD_SCALAR(job->args, INNER, PS_TYPE_F32); 168 PS_ARRAY_ADD_SCALAR(job->args, MIN_SN, PS_TYPE_F32); 169 PS_ARRAY_ADD_SCALAR(job->args, RADIUS, PS_TYPE_F32); 170 PS_ARRAY_ADD_SCALAR(job->args, SIGMA, PS_TYPE_F32); 171 172 PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK); 173 PS_ARRAY_ADD_SCALAR(job->args, markVal, PS_TYPE_IMAGE_MASK); 174 175 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nmoments 176 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail 177 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfaint 178 179 if (!psThreadJobAddPending(job)) { 180 psError(PS_ERR_UNKNOWN, false, "Unable to launch thread job PSPHOT_SOURCE_STATS"); 181 psFree (job); 182 psFree(detections->newSources); 183 return false; 184 } 185 psFree(job); 186 } 187 188 // wait for the threads to finish and manage results 189 if (!psThreadPoolWait (false)) { 190 psError(PS_ERR_UNKNOWN, false, "Failure in thread job PSPHOT_SOURCE_STATS"); 191 psFree(detections->newSources); 192 return false; 193 } 194 195 // we have only supplied one type of job, so we can assume the types here 196 psThreadJob *job = NULL; 197 while ((job = psThreadJobGetDone()) != NULL) { 198 if (job->args->n < 1) { 199 fprintf (stderr, "error with job\n"); 200 } else { 201 psScalar *scalar = NULL; 202 scalar = job->args->data[7]; 203 Nmoments += scalar->data.S32; 204 scalar = job->args->data[8]; 205 Nfail += scalar->data.S32; 206 scalar = job->args->data[9]; 207 Nfaint += scalar->data.S32; 208 } 209 psFree(job); 210 } 211 } 212 213 psFree (cellGroups); 214 215 psLogMsg ("psphot", PS_LOG_INFO, "%ld sources, %d moments, %d faint, %d failed: %f sec\n", sources->n, Nmoments, Nfaint, Nfail, psTimerMark ("psphot.stats")); 216 217 psphotVisualShowMoments (sources); 218 219 if (detections->allSources) { 220 psphotMaskCosmicRayFootprintCheck(detections->allSources); 221 } 222 if (detections->newSources) { 223 psphotMaskCosmicRayFootprintCheck(detections->newSources); 224 } 225 226 return true; 227 } 228 229 // this function is currently only called by psphotCheckExtSources 230 bool psphotSourceStatsUpdate (psArray *sources, pmConfig *config, pmReadout *readout) { 231 232 bool status = false; 233 234 psTimerStart ("psphot.stats"); 235 236 // select the appropriate recipe information 237 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 238 assert (recipe); 239 240 // determine the number of allowed threads 241 int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads 242 if (!status) { 243 nThreads = 0; 244 } 245 246 // determine properties (sky, moments) of initial sources 247 float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 248 if (!status) return false; 249 250 OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius 251 252 char *breakPt = psMetadataLookupStr (&status, recipe, "BREAK_POINT"); 253 if (!status) return false; 254 255 for (int i = 0; i < sources->n; i++) { 256 257 pmSource *source = sources->data[i]; 258 if (!source->peak) continue; // XXX how can we have a peak-less source? 259 260 // allocate space for moments 261 if (!source->moments) { 262 source->moments = pmMomentsAlloc(); 263 } 264 265 // allocate image, weight, mask arrays for each peak (square of radius OUTER) 266 pmSourceDefinePixels (source, readout, source->peak->x, source->peak->y, OUTER); 267 source->peak->assigned = true; 60 268 } 61 269 … … 67 275 } 68 276 69 if (setWindow) { 70 if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) { 71 psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!"); 72 return NULL; 73 } 277 // XXX how else could we get the window size in? 278 if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) { 279 psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!"); 280 return NULL; 74 281 } 75 282 … … 94 301 psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS"); 95 302 303 // XXX: this must match the above 96 304 psArrayAdd(job->args, 1, cells->data[j]); // sources 97 305 psArrayAdd(job->args, 1, recipe); … … 148 356 149 357 psArray *sources = job->args->data[0]; 150 psMetadata *recipe = job->args->data[1]; 151 152 float INNER = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS"); 153 if (!status) return false; 154 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); 155 if (!status) return false; 156 float RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS"); 157 if (!status) return false; 158 float SIGMA = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA"); 159 if (!status) return false; 160 161 // bit-masks to test for good/bad pixels 162 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); 163 assert (maskVal); 164 165 // bit-mask to mark pixels not used in analysis 166 psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); 167 assert (markVal); 358 359 float INNER = PS_SCALAR_VALUE(job->args->data[1],F32); 360 float MIN_SN = PS_SCALAR_VALUE(job->args->data[2],F32); 361 float RADIUS = PS_SCALAR_VALUE(job->args->data[3],F32); 362 float SIGMA = PS_SCALAR_VALUE(job->args->data[4],F32); 363 364 psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA); 365 psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[6],PS_TYPE_IMAGE_MASK_DATA); 168 366 169 367 // maskVal is used to test for rejected pixels, and must include markVal … … 176 374 for (int i = 0; i < sources->n; i++) { 177 375 pmSource *source = sources->data[i]; 376 377 if (source->tmpFlags & PM_SOURCE_TMPF_MOMENTS_MEASURED) continue; 378 source->tmpFlags |= PM_SOURCE_TMPF_MOMENTS_MEASURED; 178 379 179 380 // skip faint sources for moments measurement … … 205 406 206 407 // measure basic source moments (no S/N clipping on input pixels) 207 status = pmSourceMoments (source, RADIUS, SIGMA, 0.0 );408 status = pmSourceMoments (source, RADIUS, SIGMA, 0.0, maskVal); 208 409 if (status) { 209 410 Nmoments ++; … … 215 416 BIG_RADIUS = PS_MIN (INNER, 3*RADIUS); 216 417 psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y); 217 status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, 0.0 );418 status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, 0.0, maskVal); 218 419 if (status) { 219 420 source->mode |= PM_SOURCE_MODE_BIG_RADIUS; … … 229 430 230 431 // change the value of a scalar on the array (wrap this and put it in psArray.h) 231 scalar = job->args->data[ 2];432 scalar = job->args->data[7]; 232 433 scalar->data.S32 = Nmoments; 233 434 234 scalar = job->args->data[ 3];435 scalar = job->args->data[8]; 235 436 scalar->data.S32 = Nfail; 236 437 237 scalar = job->args->data[ 4];438 scalar = job->args->data[9]; 238 439 scalar->data.S32 = Nfaint; 239 440 … … 242 443 243 444 // this function attempts to iteratively determine the best value for sigma of the moments weighting Gaussian 445 // this function modifies the recipe values MOMENTS_SX_MAX, MOMENTS_SY_MAX, and PSF_CLUMP_GRID_SCALE, used by pmSourcePSFClump 244 446 bool psphotSetMomentsWindow (psMetadata *recipe, psMetadata *analysis, psArray *sources) { 245 447 246 448 bool status; 247 449 248 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); 249 if (!status) return false; 450 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); psAssert (status, "missing MOMENTS_SN_MIN"); 451 float PSF_SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM"); 452 psF32 MOMENTS_AR_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_AR_MAX"); psAssert (status, "missing MOMENTS_AR_MAX"); 250 453 251 454 // XXX move this to a config file? 252 float sigma[4] = {1.0, 2.0, 3.0, 4.5}; 253 float Sout[4]; 455 # define NSIGMA 8 456 float sigma[NSIGMA] = {1.0, 2.0, 3.0, 4.5, 6.0, 9.0, 12.0, 18.0}; 457 float Sout[NSIGMA]; 254 458 255 459 // this sorts by peak->SN … … 257 461 258 462 // loop over radii: 259 for (int i = 0; i < 4; i++) {463 for (int i = 0; i < NSIGMA; i++) { 260 464 261 465 // XXX move max source number to config … … 272 476 273 477 // measure basic source moments (no S/N clipping on input pixels) 274 status = pmSourceMoments (source, 4*sigma[i], sigma[i], 0.0 );478 status = pmSourceMoments (source, 4*sigma[i], sigma[i], 0.0, 0xffff); 275 479 } 276 480 277 481 // choose a grid scale that is a fixed fraction of the psf sigma^2 278 psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(sigma[i]));279 psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i]));280 psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i]));482 float PSF_CLUMP_GRID_SCALE = 0.1*PS_SQR(sigma[i]); 483 float MOMENTS_SX_MAX = 2.0*PS_SQR(sigma[i]); 484 float MOMENTS_SY_MAX = 2.0*PS_SQR(sigma[i]); 281 485 282 486 // determine the PSF parameters from the source moment values 283 pmPSFClump psfClump = pmSourcePSFClump (NULL, sources, recipe);487 pmPSFClump psfClump = pmSourcePSFClump (NULL, NULL, sources, PSF_SN_LIM, PSF_CLUMP_GRID_SCALE, MOMENTS_SX_MAX, MOMENTS_SY_MAX, MOMENTS_AR_MAX); 284 488 psLogMsg ("psphot", 3, "radius %.1f, nStars: %d, nSigma: %5.2f, X, Y: %f, %f (%f, %f)\n", sigma[i], psfClump.nStars, psfClump.nSigma, psfClump.X, psfClump.Y, sqrt(psfClump.X) / sigma[i], sqrt(psfClump.Y) / sigma[i]); 285 489 … … 296 500 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.DY", PS_META_REPLACE, "psf clump center", psfClump.dY); 297 501 298 // psphotVisualPlotMoments (recipe, sources);502 psphotVisualPlotMoments (recipe, analysis, sources); 299 503 300 504 Sout[i] = sqrt(0.5*(psfClump.X + psfClump.Y)) / sigma[i]; … … 302 506 303 507 // we are looking for sigma for which Sout = 0.65 (or some other value) 304 305 508 float Sigma = NAN; 306 509 float minS = Sout[0]; 307 510 float maxS = Sout[0]; 308 for (int i = 0; i < 4; i++) {511 for (int i = 0; i < NSIGMA; i++) { 309 512 minS = PS_MIN(Sout[i], minS); 310 513 maxS = PS_MAX(Sout[i], maxS); 311 514 } 312 if (minS > 0.65) Sigma = sigma[ 3];515 if (minS > 0.65) Sigma = sigma[NSIGMA-1]; 313 516 if (maxS < 0.65) Sigma = sigma[0]; 314 517 315 for (int i = 0; i < 3; i++) { 518 for (int i = 0; i < NSIGMA - 1 && isnan(Sigma); i++) { 519 if (!isfinite(Sout[i]) || !isfinite(Sout[i+1])) continue; 316 520 if ((Sout[i] > 0.65) && (Sout[i+1] > 0.65)) continue; 317 521 if ((Sout[i] < 0.65) && (Sout[i+1] < 0.65)) continue; … … 321 525 322 526 // choose a grid scale that is a fixed fraction of the psf sigma^2 323 psMetadataAddF32( recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(Sigma));324 psMetadataAddF32( recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));325 psMetadataAddF32( recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));326 psMetadataAddF32( recipe, PS_LIST_TAIL, "MOMENTS_GAUSS_SIGMA", PS_META_REPLACE, "moments limit", Sigma);327 psMetadataAddF32( recipe, PS_LIST_TAIL, "PSF_MOMENTS_RADIUS", PS_META_REPLACE, "moments limit", 4.0*Sigma);527 psMetadataAddF32(analysis, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(Sigma)); 528 psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma)); 529 psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma)); 530 psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_GAUSS_SIGMA", PS_META_REPLACE, "moments limit", Sigma); 531 psMetadataAddF32(analysis, PS_LIST_TAIL, "PSF_MOMENTS_RADIUS", PS_META_REPLACE, "moments limit", 4.0*Sigma); 328 532 329 533 psLogMsg ("psphot", 3, "using window function with sigma = %f\n", Sigma); 330 534 return true; 331 535 } 536 537 // if we use the footprints, the output peaks list contains both old and new peaks, 538 // otherwise it only contains the new peaks. 539 -
branches/tap_branches/psphot/src/psphotSubtractBackground.c
r23287 r27838 4 4 // generate the median in NxN boxes, clipping heavily 5 5 // linear interpolation to generate full-scale model 6 bool psphotSubtractBackground (pmConfig *config, const pmFPAview *view, const char *filename)6 bool psphotSubtractBackgroundReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) 7 7 { 8 8 bool status = true; … … 13 13 14 14 // find the currently selected readout 15 pmFPAfile *file = psMetadataLookupPtr (&status, config->files, filename); 15 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 16 16 17 pmFPA *inFPA = file->fpa; 17 18 pmReadout *readout = pmFPAviewThisReadout (view, inFPA); … … 19 20 psImage *mask = readout->mask; 20 21 21 // find the currently selected readout 22 pmReadout *model = pmFPAfileThisReadout (config->files, view, "PSPHOT.BACKMDL"); 22 // find the currently selected readout (XXX note that the model is saved on PSPHOT.BACKMDL regardless of 'filename' 23 pmFPAfile *modelFile = pmFPAfileSelectSingle(config->files, "PSPHOT.BACKMDL", index); // File of interest 24 assert (modelFile); 25 26 pmReadout *model = NULL; 27 if (modelFile->mode == PM_FPA_MODE_INTERNAL) { 28 model = modelFile->readout; 29 } else { 30 model = pmFPAviewThisReadout (view, modelFile->fpa); 31 } 23 32 assert (model); 24 25 // select the appropriate recipe information26 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);27 assert (recipe);28 33 29 34 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) … … 35 40 36 41 // select background pixels, from output background file, or create 42 // XXX for now, we will only allow a single background image to be generated 37 43 file = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKGND"); 38 44 if (file) { … … 66 72 67 73 // back-sub image pixels, from output background file (don't create if not requested) 74 // XXX for now, we will only allow a single background-subtracted image to be generated 68 75 file = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKSUB"); 69 76 if (file) { … … 109 116 // the pmReadout selected in this function are all view on entries in config->files 110 117 118 // display the backsub and backgnd images 119 // move this inthe the subtract background loop 120 psphotVisualShowBackground (config, view, readout); 121 111 122 npass ++; 112 123 return true; 113 124 } 125 126 bool psphotSubtractBackground (pmConfig *config, const pmFPAview *view) 127 { 128 bool status = false; 129 130 // select the appropriate recipe information 131 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 132 psAssert (recipe, "missing recipe?"); 133 134 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 135 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 136 137 // loop over the available readouts 138 for (int i = 0; i < num; i++) { 139 if (!psphotSubtractBackgroundReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 140 psError (PSPHOT_ERR_CONFIG, false, "failed to subtract background for PSPHOT.INPUT entry %d", i); 141 return false; 142 } 143 } 144 return true; 145 } -
branches/tap_branches/psphot/src/psphotVisual.c
r25852 r27838 60 60 } 61 61 62 bool psphotVisualEraseOverlays (int channel, char *overlay) { 63 64 int myKapa = psphotKapaChannel (channel); 65 if (!(strcasecmp (overlay, "all"))) { 66 KiiEraseOverlay (myKapa, "red"); 67 KiiEraseOverlay (myKapa, "green"); 68 KiiEraseOverlay (myKapa, "blue"); 69 KiiEraseOverlay (myKapa, "yellow"); 70 return true; 71 } 72 KiiEraseOverlay (myKapa, overlay); 73 return true; 74 } 75 62 76 bool psphotVisualShowMask (int kapaFD, psImage *inImage, const char *name, int channel) { 63 77 … … 106 120 } 107 121 108 bool psphotVisualScaleImage (int kapaFD, psImage *inImage, const char *name, int channel) {122 bool psphotVisualScaleImage (int kapaFD, psImage *inImage, psImage *inMask, const char *name, int channel) { 109 123 110 124 KiiImage image; … … 116 130 psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 117 131 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); 118 if (!psImageBackground(stats, NULL, inImage, NULL, 0, rng)) {132 if (!psImageBackground(stats, NULL, inImage, inMask, 0xffff, rng)) { 119 133 fprintf (stderr, "failed to get background values\n"); 120 134 return false; … … 171 185 if (kapa == -1) return false; 172 186 173 //psphotVisualShowMask (kapa, readout->mask, "mask", 2);174 psphotVisualScaleImage (kapa, readout->variance, "variance", 1);175 psphotVisualScaleImage (kapa, readout->image, "image", 0);187 psphotVisualShowMask (kapa, readout->mask, "mask", 2); 188 psphotVisualScaleImage (kapa, readout->variance, readout->mask, "variance", 1); 189 psphotVisualScaleImage (kapa, readout->image, readout->mask, "image", 0); 176 190 177 191 pmVisualAskUser(NULL); … … 197 211 } 198 212 199 psphotVisualScaleImage (kapa, backgnd->image, "backgnd", 2);200 psphotVisualScaleImage (kapa, readout->image, "backsub", 0);213 psphotVisualScaleImage (kapa, backgnd->image, readout->mask, "backgnd", 2); 214 psphotVisualScaleImage (kapa, readout->image, readout->mask, "backsub", 0); 201 215 202 216 pmVisualAskUser(NULL); … … 204 218 } 205 219 206 bool psphotVisualShowSignificance (psImage *image ) {220 bool psphotVisualShowSignificance (psImage *image, float min, float max) { 207 221 208 222 if (!pmVisualIsVisual()) return true; … … 211 225 if (kapa == -1) return false; 212 226 213 psphotVisualRangeImage (kapa, image, "signif", 2, -1.0, 25.0*25.0);227 psphotVisualRangeImage (kapa, image, "signif", 2, min, max); 214 228 215 229 pmVisualAskUser(NULL); … … 247 261 overlay[Noverlay].text = NULL; 248 262 Noverlay ++; 249 250 # if (0) 251 overlay[Noverlay].type = KII_OVERLAY_BOX; 252 overlay[Noverlay].x = peak->x; 253 overlay[Noverlay].y = peak->y; 254 overlay[Noverlay].dx = 1.0; 255 overlay[Noverlay].dy = 1.0; 256 overlay[Noverlay].angle = 0.0; 257 overlay[Noverlay].text = NULL; 258 Noverlay ++; 259 260 overlay[Noverlay].type = KII_OVERLAY_CIRCLE; 261 overlay[Noverlay].x = peak->xf; 262 overlay[Noverlay].y = peak->yf; 263 overlay[Noverlay].dx = 2.0; 264 overlay[Noverlay].dy = 2.0; 265 overlay[Noverlay].angle = 0.0; 266 overlay[Noverlay].text = NULL; 267 Noverlay ++; 268 # endif 269 } 270 271 # if (1) 272 overlay[Noverlay].type = KII_OVERLAY_BOX; 273 overlay[Noverlay].x = 10.0; 274 overlay[Noverlay].y = 10.0; 275 overlay[Noverlay].dx = 1.0; 276 overlay[Noverlay].dy = 1.0; 277 overlay[Noverlay].angle = 0.0; 278 overlay[Noverlay].text = NULL; 279 Noverlay ++; 280 # endif 263 } 281 264 282 265 KiiLoadOverlay (kapa, overlay, Noverlay, "red"); … … 463 446 KapaSetFont (myKapa, "courier", 14); 464 447 448 section.bg = KapaColorByName ("none"); // XXX probably should be 'none' 449 465 450 float SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); 466 451 … … 494 479 Xmin = PS_MAX(Xmin, -0.1); 495 480 Ymin = PS_MAX(Ymin, -0.1); 481 482 // XXX test: hardwire plot limits 483 // Xmin = -0.1; Ymin = -0.1; 484 // Xmax = 20.1; Ymax = 20.1; 496 485 497 486 // storage vectors for data to be plotted … … 551 540 KapaSetLimits (myKapa, &graphdata); 552 541 542 graphdata.padXm = NAN; 543 graphdata.padYm = NAN; 544 graphdata.padXp = 0.5; 545 graphdata.padYp = 0.5; 553 546 KapaBox (myKapa, &graphdata); 547 554 548 KapaSendLabel (myKapa, "M_xx| (pixels)", KAPA_LABEL_XM); 555 549 KapaSendLabel (myKapa, "M_yy| (pixels)", KAPA_LABEL_YM); … … 560 554 graphdata.style = 2; 561 555 KapaPrepPlot (myKapa, nF, &graphdata); 556 562 557 KapaPlotVector (myKapa, nF, xFaint->data.F32, "x"); 563 558 KapaPlotVector (myKapa, nF, yFaint->data.F32, "y"); … … 575 570 section.dy = 0.25; 576 571 section.x = 0.00; 577 section.y = 0. 80;572 section.y = 0.75; 578 573 section.name = psStringCopy ("MagMyy"); 579 574 KapaSetSection (myKapa, §ion); … … 587 582 KapaSetLimits (myKapa, &graphdata); 588 583 584 graphdata.padXm = 0.5; 585 graphdata.padYm = NAN; 586 graphdata.padXp = NAN; 587 graphdata.padYp = 0.5; 589 588 strcpy (graphdata.labels, "0210"); 590 589 KapaBox (myKapa, &graphdata); … … 611 610 section.dx = 0.25; 612 611 section.dy = 0.75; 613 section.x = 0. 80;612 section.x = 0.75; 614 613 section.y = 0.00; 615 614 section.name = psStringCopy ("MagMxx"); … … 624 623 KapaSetLimits (myKapa, &graphdata); 625 624 625 graphdata.padXm = NAN; 626 graphdata.padYm = 0.5; 627 graphdata.padXp = 0.5; 628 graphdata.padYp = NAN; 626 629 strcpy (graphdata.labels, "2001"); 627 630 KapaBox (myKapa, &graphdata); … … 654 657 655 658 int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS"); 656 float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, analysis, "PSF_CLUMP_NSIGMA");659 float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA"); 657 660 658 661 graphdata.color = KapaColorByName ("blue"); … … 1107 1110 } 1108 1111 1109 psphotVisualScaleImage (myKapa, outsat, "satstar", 2);1112 psphotVisualScaleImage (myKapa, outsat, NULL, "satstar", 2); 1110 1113 1111 1114 pmVisualAskUser(NULL); 1112 1115 psFree (outsat); 1113 1116 return true; 1117 } 1118 1119 static void plotline (int myKapa, Graphdata *graphdata, float x0, float y0, float x1, float y1) 1120 { 1121 float x[2], y[2]; 1122 x[0] = x0; 1123 x[1] = x1; 1124 y[0] = y0; 1125 y[1] = y1; 1126 KapaPrepPlot (myKapa, 2, graphdata); 1127 KapaPlotVector (myKapa, 2, x, "x"); 1128 KapaPlotVector (myKapa, 2, y, "y"); 1114 1129 } 1115 1130 … … 1151 1166 } 1152 1167 1168 // generate model profiles (major and minor axis): 1169 // create a model with theta = 0.0 so major and minor axes are equiv to x and y: 1170 psEllipseShape rawShape, rotShape; 1171 1172 rawShape.sx = source->modelPSF->params->data.F32[PM_PAR_SXX] / M_SQRT2; 1173 rawShape.sy = source->modelPSF->params->data.F32[PM_PAR_SYY] / M_SQRT2; 1174 rawShape.sxy = source->modelPSF->params->data.F32[PM_PAR_SXY]; 1175 1176 psEllipseAxes axes = psEllipseShapeToAxes (rawShape, 20.0); 1177 1178 axes.theta = 0.0; 1179 1180 rotShape = psEllipseAxesToShape (axes); 1181 1182 psVector *params = psVectorAlloc(source->modelPSF->params->n, PS_TYPE_F32); 1183 for (int i = 0; i < source->modelPSF->params->n; i++) { 1184 params->data.F32[i] = source->modelPSF->params->data.F32[i]; 1185 } 1186 params->data.F32[PM_PAR_SXX] = rotShape.sx * M_SQRT2; 1187 params->data.F32[PM_PAR_SYY] = rotShape.sy * M_SQRT2; 1188 params->data.F32[PM_PAR_SXY] = rotShape.sxy; 1189 params->data.F32[PM_PAR_XPOS] = 0.0; 1190 params->data.F32[PM_PAR_YPOS] = 0.0; 1191 1192 psVector *rmod = psVectorAlloc(300, PS_TYPE_F32); 1193 psVector *fmaj = psVectorAlloc(300, PS_TYPE_F32); 1194 psVector *fmin = psVectorAlloc(300, PS_TYPE_F32); 1195 1196 psVector *coord = psVectorAlloc(2, PS_TYPE_F32); 1197 1198 float r = 0.0; 1199 for (int i = 0; i < rmod->n; i++) { 1200 r = i*0.1; 1201 rmod->data.F32[i] = r; 1202 1203 coord->data.F32[1] = r; 1204 coord->data.F32[0] = 0.0; 1205 fmaj->data.F32[i] = log10(source->modelPSF->modelFunc (NULL, params, coord)); 1206 1207 coord->data.F32[0] = r; 1208 coord->data.F32[1] = 0.0; 1209 fmin->data.F32[i] = log10(source->modelPSF->modelFunc (NULL, params, coord)); 1210 } 1211 psFree (coord); 1212 psFree (params); 1213 1214 float FWHM_MAJOR = 2.0*source->modelPSF->modelRadius (source->modelPSF->params, 0.5*source->modelPSF->params->data.F32[PM_PAR_I0]); 1215 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major); 1216 if (FWHM_MAJOR < FWHM_MINOR) PS_SWAP (FWHM_MAJOR, FWHM_MINOR); 1217 1218 psEllipseMoments emoments; 1219 emoments.x2 = source->moments->Mxx; 1220 emoments.xy = source->moments->Mxy; 1221 emoments.y2 = source->moments->Myy; 1222 axes = psEllipseMomentsToAxes (emoments, 20.0); 1223 float MOMENTS_MAJOR = 2.355*axes.major; 1224 float MOMENTS_MINOR = 2.355*axes.minor; 1225 1226 float logHM = log10(0.5*source->modelPSF->params->data.F32[PM_PAR_I0]); 1227 1153 1228 // reset source Add/Sub state to recorded 1154 1229 if (subtracted) pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); … … 1187 1262 KapaPlotVector (myKapa, nb, fb->data.F32, "y"); 1188 1263 1264 graphdata.color = KapaColorByName ("blue"); 1265 graphdata.ptype = 0; 1266 graphdata.size = 0.0; 1267 graphdata.style = 0; 1268 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1269 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1270 KapaPlotVector (myKapa, rmod->n, fmin->data.F32, "y"); 1271 plotline (myKapa, &graphdata, 0.0, logHM, 30.0, logHM); 1272 plotline (myKapa, &graphdata, 0.5*FWHM_MINOR, 0.0, 0.5*FWHM_MINOR, 5.0); 1273 graphdata.ltype = 1; 1274 plotline (myKapa, &graphdata, 0.5*MOMENTS_MINOR, 0.0, 0.5*MOMENTS_MINOR, 5.0); 1275 graphdata.ltype = 0; 1276 1277 graphdata.color = KapaColorByName ("green"); 1278 graphdata.ptype = 0; 1279 graphdata.size = 0.0; 1280 graphdata.style = 0; 1281 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1282 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1283 KapaPlotVector (myKapa, rmod->n, fmaj->data.F32, "y"); 1284 plotline (myKapa, &graphdata, 0.5*FWHM_MAJOR, 0.0, 0.5*FWHM_MAJOR, 5.0); 1285 graphdata.ltype = 1; 1286 plotline (myKapa, &graphdata, 0.5*MOMENTS_MAJOR, 0.0, 0.5*MOMENTS_MAJOR, 5.0); 1287 graphdata.ltype = 0; 1288 1289 for (int i = 0; i < rmod->n; i++) { 1290 rmod->data.F32[i] = log10(rmod->data.F32[i]); 1291 } 1292 1189 1293 // ** loglog ** 1190 1294 KapaSelectSection (myKapa, "loglog"); … … 1195 1299 graphdata.ymin = -0.05; 1196 1300 graphdata.ymax = +5.05; 1301 graphdata.color = KapaColorByName ("black"); 1197 1302 KapaSetLimits (myKapa, &graphdata); 1198 1303 … … 1217 1322 KapaPlotVector (myKapa, nb, Rb->data.F32, "x"); 1218 1323 KapaPlotVector (myKapa, nb, fb->data.F32, "y"); 1324 1325 graphdata.color = KapaColorByName ("blue"); 1326 graphdata.ptype = 0; 1327 graphdata.size = 0.0; 1328 graphdata.style = 0; 1329 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1330 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1331 KapaPlotVector (myKapa, rmod->n, fmin->data.F32, "y"); 1332 1333 graphdata.color = KapaColorByName ("green"); 1334 graphdata.ptype = 0; 1335 graphdata.size = 0.0; 1336 graphdata.style = 0; 1337 KapaPrepPlot (myKapa, rmod->n, &graphdata); 1338 KapaPlotVector (myKapa, rmod->n, rmod->data.F32, "x"); 1339 KapaPlotVector (myKapa, rmod->n, fmaj->data.F32, "y"); 1340 1341 psFree (rmod); 1342 psFree (fmin); 1343 psFree (fmaj); 1219 1344 1220 1345 psFree (rg); … … 1240 1365 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 1241 1366 assert (maskVal); 1367 1368 section.bg = KapaColorByName ("none"); // XXX probably should be 'none' 1242 1369 1243 1370 KapaClearPlots (myKapa); … … 1405 1532 if (source == NULL) continue; 1406 1533 1407 // if (source->type != type) continue;1408 1534 if (mode) { 1409 1535 if (keep) { … … 1478 1604 KapaSetFont (myKapa, "courier", 14); 1479 1605 1606 section.bg = KapaColorByName ("none"); // XXX probably should be 'none' 1607 1480 1608 // select the max psfX,Y values for the plot limits 1481 1609 float Xmin = 1000.0, Xmax = 0.0; … … 1529 1657 psVector *sDEF = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 1530 1658 1659 psVector *xLOW = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 1660 psVector *yLOW = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 1661 psVector *mLOW = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 1662 psVector *sLOW = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 1663 1531 1664 psVector *xCR = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 1532 1665 psVector *yCR = psVectorAllocEmpty (sources->n, PS_TYPE_F32); … … 1539 1672 int nPSF = 0; 1540 1673 int nDEF = 0; 1674 int nLOW = 0; 1541 1675 int nCR = 0; 1542 1676 for (int i = 0; i < sources->n; i++) { 1543 1677 pmSource *source = sources->data[i]; 1544 1678 if (source->moments == NULL) continue; 1679 1680 // only plot the measured sources... 1681 if (!(source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED)) continue; 1545 1682 1546 1683 if (source->mode & PM_SOURCE_MODE_CR_LIMIT) { … … 1574 1711 continue; 1575 1712 } 1576 if ((source->mode & PM_SOURCE_MODE_CR_LIMIT) || (source->mode & PM_SOURCE_MODE_SATSTAR)) { 1713 if (source->errMag > 0.1) { 1714 xLOW->data.F32[nLOW] = source->moments->Mxx; 1715 yLOW->data.F32[nLOW] = source->moments->Myy; 1716 mLOW->data.F32[nLOW] = -2.5*log10(source->moments->Sum); 1717 sLOW->data.F32[nLOW] = source->extNsigma; 1718 nLOW++; 1577 1719 continue; 1578 1720 } … … 1583 1725 nPSF++; 1584 1726 } 1727 1585 1728 xSAT->n = nSAT; 1586 1729 ySAT->n = nSAT; … … 1607 1750 mDEF->n = nDEF; 1608 1751 sDEF->n = nDEF; 1752 1753 xLOW->n = nLOW; 1754 yLOW->n = nLOW; 1755 mLOW->n = nLOW; 1756 sLOW->n = nLOW; 1609 1757 1610 1758 // four sections: MxxMyy, MagMxx, MagMyy, MagSigma … … 1626 1774 KapaSetLimits (myKapa, &graphdata); 1627 1775 1776 graphdata.padXm = NAN; 1777 graphdata.padYm = NAN; 1778 graphdata.padXp = 0.5; 1779 graphdata.padYp = 0.5; 1628 1780 KapaBox (myKapa, &graphdata); 1629 1781 KapaSendLabel (myKapa, "M_xx| (pixels)", KAPA_LABEL_XM); … … 1669 1821 KapaPlotVector (myKapa, nSAT, xSAT->data.F32, "x"); 1670 1822 KapaPlotVector (myKapa, nSAT, ySAT->data.F32, "y"); 1823 1824 graphdata.color = KapaColorByName ("black"); 1825 graphdata.ptype = 7; 1826 graphdata.size = 1.0; 1827 graphdata.style = 2; 1828 KapaPrepPlot (myKapa, nLOW, &graphdata); 1829 KapaPlotVector (myKapa, nLOW, xLOW->data.F32, "x"); 1830 KapaPlotVector (myKapa, nLOW, yLOW->data.F32, "y"); 1671 1831 1672 1832 // second section: MagMyy … … 1681 1841 graphdata.color = KapaColorByName ("black"); 1682 1842 graphdata.xmin = -17.1; 1683 graphdata.xmax = - 7.9;1843 graphdata.xmax = -6.9; 1684 1844 graphdata.ymin = Ymin; 1685 1845 graphdata.ymax = Ymax; 1686 1846 KapaSetLimits (myKapa, &graphdata); 1687 1847 1848 graphdata.padXm = 0.5; 1849 graphdata.padYm = NAN; 1850 graphdata.padXp = NAN; 1851 graphdata.padYp = 0.5; 1688 1852 strcpy (graphdata.labels, "0210"); 1689 1853 KapaBox (myKapa, &graphdata); … … 1734 1898 section.dx = 0.25; 1735 1899 section.dy = 0.60; 1736 section.x = 0. 80;1900 section.x = 0.75; 1737 1901 section.y = 0.00; 1738 1902 section.name = psStringCopy ("MagMxx"); … … 1743 1907 graphdata.xmin = Xmin; 1744 1908 graphdata.xmax = Xmax; 1745 graphdata.ymin = - 7.9;1909 graphdata.ymin = -6.9; 1746 1910 graphdata.ymax = -17.1; 1747 1911 KapaSetLimits (myKapa, &graphdata); 1748 1912 1913 graphdata.padXm = NAN; 1914 graphdata.padYm = 0.5; 1915 graphdata.padXp = 0.5; 1916 graphdata.padYp = NAN; 1749 1917 strcpy (graphdata.labels, "2001"); 1750 1918 KapaBox (myKapa, &graphdata); … … 1794 1962 // fourth section: MagSigma 1795 1963 section.dx = 0.75; 1796 section.dy = 0. 15;1964 section.dy = 0.20; 1797 1965 section.x = 0.00; 1798 section.y = 0.6 5;1966 section.y = 0.60; 1799 1967 section.name = psStringCopy ("MagSigma"); 1800 1968 KapaSetSection (myKapa, §ion); … … 1802 1970 1803 1971 graphdata.color = KapaColorByName ("black"); 1804 graphdata.xmax = - 7.9;1972 graphdata.xmax = -6.9; 1805 1973 graphdata.xmin = -17.1; 1806 1974 graphdata.ymin = -20.1; … … 1808 1976 KapaSetLimits (myKapa, &graphdata); 1809 1977 1978 graphdata.padXm = 0.5; 1979 graphdata.padYm = NAN; 1980 graphdata.padXp = 0.5; 1981 graphdata.padYp = 0.5; 1810 1982 strcpy (graphdata.labels, "0100"); 1811 1983 KapaBox (myKapa, &graphdata); … … 1862 2034 1863 2035 int nRegions = psMetadataLookupS32 (&status, analysis, "PSF.CLUMP.NREGIONS"); 1864 float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, analysis, "PSF_CLUMP_NSIGMA");2036 float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA"); 1865 2037 1866 2038 graphdata.color = KapaColorByName ("blue"); … … 1901 2073 psFree (ySAT); 1902 2074 psFree (mSAT); 2075 psFree (sSAT); 1903 2076 1904 2077 psFree (xEXT); 1905 2078 psFree (yEXT); 1906 2079 psFree (mEXT); 2080 psFree (sEXT); 1907 2081 1908 2082 psFree (xPSF); 1909 2083 psFree (yPSF); 1910 2084 psFree (mPSF); 2085 psFree (sPSF); 1911 2086 1912 2087 psFree (xDEF); 1913 2088 psFree (yDEF); 1914 2089 psFree (mDEF); 2090 psFree (sDEF); 2091 2092 psFree (xLOW); 2093 psFree (yLOW); 2094 psFree (mLOW); 2095 psFree (sLOW); 1915 2096 1916 2097 psFree (xCR); 1917 2098 psFree (yCR); 1918 2099 psFree (mCR); 2100 psFree (sCR); 1919 2101 1920 2102 pmVisualAskUser(NULL); … … 1929 2111 if (myKapa == -1) return false; 1930 2112 1931 psphotVisualScaleImage (myKapa, readout->image, "resid", 1);2113 psphotVisualScaleImage (myKapa, readout->image, readout->mask, "resid", 1); 1932 2114 1933 2115 pmVisualAskUser(NULL); … … 2054 2236 } 2055 2237 2238 bool psphotVisualPlotChisq (psArray *sources) { 2239 2240 Graphdata graphdata; 2241 2242 if (!pmVisualIsVisual()) return true; 2243 2244 int myKapa = psphotKapaChannel (2); 2245 if (myKapa == -1) return false; 2246 2247 KapaClearPlots (myKapa); 2248 KapaInitGraph (&graphdata); 2249 2250 psVector *x = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 2251 psVector *y = psVectorAllocEmpty (sources->n, PS_TYPE_F32); 2252 2253 graphdata.xmin = +32.0; 2254 graphdata.xmax = -32.0; 2255 graphdata.ymin = +32.0; 2256 graphdata.ymax = -32.0; 2257 2258 FILE *f = fopen ("chisq.dat", "w"); 2259 2260 // construct the plot vectors 2261 int n = 0; 2262 for (int i = 0; i < sources->n; i++) { 2263 pmSource *source = sources->data[i]; 2264 if (!source) continue; 2265 if (source->type != PM_SOURCE_TYPE_STAR) continue; 2266 if (!source->moments) continue; 2267 if (!isfinite(source->moments->Sum)) continue; 2268 if (!source->modelPSF) continue; 2269 if (!isfinite(source->modelPSF->chisq)) continue; 2270 2271 x->data.F32[n] = -2.5*log10(source->moments->Sum); 2272 y->data.F32[n] = source->modelPSF->chisq / source->modelPSF->nDOF; 2273 graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]); 2274 graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]); 2275 graphdata.ymin = PS_MIN(graphdata.ymin, y->data.F32[n]); 2276 graphdata.ymax = PS_MAX(graphdata.ymax, y->data.F32[n]); 2277 2278 fprintf (f, "%d %d %f %f\n", i, n, x->data.F32[n], y->data.F32[n]); 2279 2280 n++; 2281 } 2282 x->n = y->n = n; 2283 fclose (f); 2284 2285 float range; 2286 range = graphdata.xmax - graphdata.xmin; 2287 graphdata.xmax += 0.05*range; 2288 graphdata.xmin -= 0.05*range; 2289 range = graphdata.ymax - graphdata.ymin; 2290 graphdata.ymax += 0.05*range; 2291 graphdata.ymin -= 0.05*range; 2292 2293 // XXX test 2294 graphdata.xmin = -17.0; 2295 graphdata.xmax = -3.0; 2296 graphdata.ymin = -0.1; 2297 graphdata.ymax = +10.1; 2298 2299 KapaSetLimits (myKapa, &graphdata); 2300 2301 KapaSetFont (myKapa, "helvetica", 14); 2302 KapaBox (myKapa, &graphdata); 2303 KapaSendLabel (myKapa, "PSF Mag", KAPA_LABEL_XM); 2304 KapaSendLabel (myKapa, "ChiSq", KAPA_LABEL_YM); 2305 2306 graphdata.color = KapaColorByName ("black"); 2307 graphdata.ptype = 2; 2308 graphdata.size = 0.5; 2309 graphdata.style = 2; 2310 KapaPrepPlot (myKapa, n, &graphdata); 2311 KapaPlotVector (myKapa, n, x->data.F32, "x"); 2312 KapaPlotVector (myKapa, n, y->data.F32, "y"); 2313 2314 psFree (x); 2315 psFree (y); 2316 2317 pmVisualAskUser(NULL); 2318 return true; 2319 } 2320 2056 2321 bool psphotVisualShowPetrosians (psArray *sources) { 2057 2322 … … 2073 2338 if (!source) continue; 2074 2339 if (!source->extpars) continue; 2075 if (!source->extpars->profile) continue; 2076 if (!source->extpars->petrosian_80) continue; 2077 2078 pmSourceRadialProfile *profile = source->extpars->profile; 2079 pmSourceExtendedFlux *petrosian = source->extpars->petrosian_80; 2340 if (!source->extpars->petProfile) continue; 2341 2342 float petrosianRadius = source->extpars->petrosianRadius; 2343 psEllipseAxes *axes = &source->extpars->axes; 2080 2344 2081 2345 overlay[Noverlay].type = KII_OVERLAY_CIRCLE; 2082 2346 overlay[Noverlay].x = source->peak->xf; 2083 2347 overlay[Noverlay].y = source->peak->yf; 2084 overlay[Noverlay].dx = 2.0*petrosian->radius;2085 overlay[Noverlay].dy = 2.0*petrosian->radius*profile->axes.minor/profile->axes.major;2086 overlay[Noverlay].angle = profile->axes.theta * PS_DEG_RAD;2348 overlay[Noverlay].dx = 1.0*petrosianRadius; 2349 overlay[Noverlay].dy = 1.0*petrosianRadius*axes->minor/axes->major; 2350 overlay[Noverlay].angle = axes->theta * PS_DEG_RAD; 2087 2351 overlay[Noverlay].text = NULL; 2088 2352 Noverlay ++; 2089 2353 CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100); 2090 2354 2091 overlay[Noverlay].type = KII_OVERLAY_CIRCLE;2092 overlay[Noverlay].x = source->peak->xf;2093 overlay[Noverlay].y = source->peak->yf;2094 overlay[Noverlay].dx = 4.0*petrosian->radius;2095 overlay[Noverlay].dy = 4.0*petrosian->radius*profile->axes.minor/profile->axes.major;2096 overlay[Noverlay].angle = profile->axes.theta * PS_DEG_RAD;2097 overlay[Noverlay].text = NULL;2098 Noverlay ++;2099 CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100);2355 // overlay[Noverlay].type = KII_OVERLAY_CIRCLE; 2356 // overlay[Noverlay].x = source->peak->xf; 2357 // overlay[Noverlay].y = source->peak->yf; 2358 // overlay[Noverlay].dx = 2.0*petrosianRadius; 2359 // overlay[Noverlay].dy = 2.0*petrosianRadius*axes->minor/axes->major; 2360 // overlay[Noverlay].angle = axes->theta * PS_DEG_RAD; 2361 // overlay[Noverlay].text = NULL; 2362 // Noverlay ++; 2363 // CHECK_REALLOCATE (overlay, KiiOverlay, NOVERLAY, Noverlay, 100); 2100 2364 } 2101 2365
Note:
See TracChangeset
for help on using the changeset viewer.
