Changeset 26894
- Timestamp:
- Feb 10, 2010, 7:36:29 PM (16 years ago)
- Location:
- trunk/psphot
- Files:
-
- 49 edited
- 6 copied
-
doc/footprints.txt (modified) (1 diff)
-
doc/notes.20100131.txt (copied) (copied from branches/eam_branches/20091201/psphot/doc/notes.20100131.txt )
-
doc/stack.txt (modified) (1 diff)
-
src/Makefile.am (modified) (5 diffs)
-
src/psphot.h (modified) (11 diffs)
-
src/psphotAddNoise.c (modified) (3 diffs)
-
src/psphotApResid.c (modified) (6 diffs)
-
src/psphotBasicDeblend.c (modified) (2 diffs)
-
src/psphotBlendFit.c (modified) (5 diffs)
-
src/psphotChoosePSF.c (modified) (13 diffs)
-
src/psphotDeblendSatstars.c (modified) (2 diffs)
-
src/psphotEfficiency.c (modified) (5 diffs)
-
src/psphotExtendedSourceAnalysis.c (modified) (2 diffs)
-
src/psphotExtendedSourceFits.c (modified) (3 diffs)
-
src/psphotFake.c (modified) (2 diffs)
-
src/psphotFindDetections.c (modified) (5 diffs)
-
src/psphotFindFootprints.c (modified) (3 diffs)
-
src/psphotFindPeaks.c (modified) (1 diff)
-
src/psphotFitSourcesLinear.c (modified) (3 diffs)
-
src/psphotForcedReadout.c (modified) (4 diffs)
-
src/psphotGuessModels.c (modified) (7 diffs)
-
src/psphotImageQuality.c (modified) (16 diffs)
-
src/psphotLoadPSF.c (modified) (1 diff)
-
src/psphotMagnitudes.c (modified) (4 diffs)
-
src/psphotMakePSFReadout.c (modified) (2 diffs)
-
src/psphotMaskReadout.c (modified) (3 diffs)
-
src/psphotMergeSources.c (modified) (10 diffs)
-
src/psphotModelBackground.c (modified) (8 diffs)
-
src/psphotModelTest.c (modified) (1 diff)
-
src/psphotMomentsStudy.c (modified) (1 diff)
-
src/psphotOutput.c (modified) (3 diffs)
-
src/psphotPSFConvModel.c (modified) (1 diff)
-
src/psphotParseCamera.c (modified) (1 diff)
-
src/psphotRadiusChecks.c (modified) (1 diff)
-
src/psphotReadout.c (modified) (5 diffs)
-
src/psphotReadoutCleanup.c (modified) (6 diffs)
-
src/psphotReadoutFindPSF.c (modified) (2 diffs)
-
src/psphotReadoutKnownSources.c (modified) (2 diffs)
-
src/psphotReadoutMinimal.c (modified) (3 diffs)
-
src/psphotReplaceUnfit.c (modified) (3 diffs)
-
src/psphotRoughClass.c (modified) (3 diffs)
-
src/psphotSetThreads.c (modified) (1 diff)
-
src/psphotSignificanceImage.c (modified) (4 diffs)
-
src/psphotSkyReplace.c (modified) (1 diff)
-
src/psphotSourceFits.c (modified) (6 diffs)
-
src/psphotSourceFreePixels.c (modified) (2 diffs)
-
src/psphotSourceSize.c (modified) (9 diffs)
-
src/psphotSourceStats.c (modified) (15 diffs)
-
src/psphotStack.c (copied) (copied from branches/eam_branches/20091201/psphot/src/psphotStack.c )
-
src/psphotStackArguments.c (copied) (copied from branches/eam_branches/20091201/psphot/src/psphotStackArguments.c )
-
src/psphotStackImageLoop.c (copied) (copied from branches/eam_branches/20091201/psphot/src/psphotStackImageLoop.c )
-
src/psphotStackParseCamera.c (copied) (copied from branches/eam_branches/20091201/psphot/src/psphotStackParseCamera.c )
-
src/psphotStackReadout.c (copied) (copied from branches/eam_branches/20091201/psphot/src/psphotStackReadout.c )
-
src/psphotSubtractBackground.c (modified) (6 diffs)
-
src/psphotVisual.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/doc/footprints.txt
r17710 r26894 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 -
trunk/psphot/doc/stack.txt
r24583 r26894 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 -
trunk/psphot/src/Makefile.am
r25984 r26894 25 25 libpsphot_la_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 26 26 27 bin_PROGRAMS = psphot psphotForced psphotMakePSF psphotTest psphotMomentsStudy 28 # bin_PROGRAMS = psphotPetrosianStudy 29 # bin_PROGRAMS = psphot 27 bin_PROGRAMS = psphot psphotForced psphotMakePSF 28 # bin_PROGRAMS = psphotPetrosianStudy psphotTest psphotMomentsStudy 30 29 31 30 psphot_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) … … 41 40 psphotMakePSF_LDADD = libpsphot.la 42 41 43 psphotTest_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 44 psphotTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 45 psphotTest_LDADD = libpsphot.la 46 47 psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 48 psphotMomentsStudy_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 49 psphotMomentsStudy_LDADD = libpsphot.la 42 # psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 43 # psphotMomentsStudy_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 44 # psphotMomentsStudy_LDADD = libpsphot.la 50 45 51 46 # psphotPetrosianStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 52 47 # psphotPetrosianStudy_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 53 48 # psphotPetrosianStudy_LDADD = libpsphot.la 49 50 # psphotTest_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 51 # psphotTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 52 # psphotTest_LDADD = libpsphot.la 54 53 55 54 # standard psphot for generic photometry … … 82 81 psphotCleanup.c 83 82 84 85 # psphot analysis of the detectability of specified positions 86 psphotDetect_SOURCES = \ 87 psphotDetect.c \ 88 psphotDetectArguments.c \ 89 psphotDetectParseCamera.c \ 90 psphotDetectImageLoop.c \ 91 psphotDetectReadout.c \ 92 psphotMosaicChip.c \ 93 psphotCleanup.c 94 95 psphotTest_SOURCES = \ 96 psphotTest.c 97 98 psphotMomentsStudy_SOURCES = \ 99 psphotMomentsStudy.c 100 83 # # psphot analysis of the detectability of specified positions 84 # psphotDetect_SOURCES = \ 85 # psphotDetect.c \ 86 # psphotDetectArguments.c \ 87 # psphotDetectParseCamera.c \ 88 # psphotDetectImageLoop.c \ 89 # psphotDetectReadout.c \ 90 # psphotMosaicChip.c \ 91 # psphotCleanup.c 92 93 # psphotTest_SOURCES = \ 94 # psphotTest.c 95 # 96 # psphotMomentsStudy_SOURCES = \ 97 # psphotMomentsStudy.c 98 # 101 99 # psphotPetrosianStudy_SOURCES = \ 102 100 # psphotPetrosianStudy.c … … 146 144 psphotKernelFromPSF.c \ 147 145 psphotPSFConvModel.c \ 148 psphotModelTest.c \149 146 psphotFitSet.c \ 150 147 psphotSourceFreePixels.c \ … … 175 172 psphotEfficiency.c 176 173 174 # XXX need to fix this for the new apis 175 # psphotModelTest.c 176 177 177 # re-instate these 178 178 # psphotIsophotal.c \ -
trunk/psphot/src/psphot.h
r25987 r26894 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 45 psImageBinning *psphotBackgroundBinning(const psImage *, const pmConfig *); 46 47 pmDetections *psphotFindDetections (pmDetections *detections, pmReadout *readout, psMetadata *recipe); 48 49 bool psphotRoughClass (pmReadout *readout, psArray *sources, psMetadata *recipe, const bool findPsfClump); 50 bool psphotBasicDeblend (psArray *sources, psMetadata *recipe); 51 pmPSF *psphotChoosePSF (pmReadout *readout, psArray *sources, psMetadata *recipe); 52 bool psphotPSFstats (pmReadout *readout, psMetadata *recipe, pmPSF *psf); 53 bool psphotMomentsStats (pmReadout *readout, psMetadata *recipe, psArray *sources); 54 bool psphotFitSourcesLinear (pmReadout *readout, psArray *sources, const psMetadata *recipe, const pmPSF *psf, bool final); 55 bool psphotReplaceUnfitSources (psArray *sources, psImageMaskType maskVal); 56 57 bool psphotReplaceAllSources (psArray *sources, psMetadata *recipe); 58 bool psphotRemoveAllSources (const psArray *sources, const psMetadata *recipe); 59 60 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 (pmConfig *config, const pmFPAview *view, const char *filename, int index, 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); 61 101 bool psphotBlendFit_Threaded (psThreadJob *job); 62 102 63 bool psphotSourceStatsUpdate (psArray *sources, pmConfig *config, pmReadout *readout); 64 psArray *psphotSourceStats (pmConfig *config, pmReadout *readout, pmDetections *detections, bool setWindow); 65 bool psphotSourceStats_Threaded (psThreadJob *job); 66 67 bool psphotGuessModels (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf); 68 bool psphotGuessModel_Threaded (psThreadJob *job); 69 70 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, const pmFPAview *view, const char *filename, int index, psMetadata *recipe); 71 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); 72 126 73 127 bool psphotPSFWeights(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources); 74 128 bool psphotPSFWeights_Threaded (psThreadJob *job); 75 129 76 bool psphotApResid (pmConfig *config, pmReadout *readout, psArray *sources, pmPSF *psf);77 78 130 bool psphotSkyReplace (pmConfig *config, const pmFPAview *view); 79 bool psphotExtendedSourceAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe); 80 bool psphotExtendedSourceFits (pmReadout *readout, psArray *sources, psMetadata *recipe); 81 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); 82 168 83 169 // thread-related: … … 93 179 psErrorCode psphotCullPeaks(const psImage *img, const psImage *weight, const psMetadata *recipe, psArray *footprints); 94 180 95 // generate the detection structure for the supplied array of sources 96 pmDetections *psphotDetectionsFromSources (pmConfig *config, psArray *sources); 97 98 // used by ApResid 181 // in psphotApResid.c: 99 182 pmTrend2D *psphotApResidTrend (float *apResidSysErr, pmReadout *readout, int Nx, int Ny, psVector *xPos, psVector *yPos, psVector *apResid, psVector *dMag); 100 183 bool psphotApResidMags_Threaded (psThreadJob *job); … … 103 186 void psphotModelClassInit (void); 104 187 bool psphotGrowthCurve (pmReadout *readout, pmPSF *psf, bool ignore, psImageMaskType maskVal); 105 bool psphotSetMaskAndVariance (pmConfig *config, pmReadout *readout, psMetadata *recipe);106 void psphotSourceFreePixels (psArray *sources);107 188 108 189 // functions to set the correct source pixels 109 bool psphotInitRadiusPSF (const psMetadata *recipe, const pmModelType type); 190 bool psphotInitRadiusPSF(const psMetadata *recipe, const psMetadata *analysis, const pmModelType type); 191 110 192 bool psphotCheckRadiusPSF (pmReadout *readout, pmSource *source, pmModel *model, psImageMaskType markVal); 111 193 bool psphotCheckRadiusPSFBlend (pmReadout *readout, pmSource *source, pmModel *model, psImageMaskType markVal, float dR); … … 114 196 float psphotSetRadiusEXT (pmReadout *readout, pmSource *source, psImageMaskType markVal); 115 197 116 // output functions117 bool psphotAddPhotcode (psMetadata *recipe, pmConfig *config, const pmFPAview *view, const char *filerule);118 198 bool psphotDumpMoments (psMetadata *recipe, psArray *sources); 119 199 psMetadata *psphotDefineHeader (psMetadata *recipe); … … 146 226 bool psphotFitSummary (void); 147 227 148 bool psphotMergeSources (psArray *oldSources, psArray *newSources); 149 bool psphotLoadExtSources (pmConfig *config, const pmFPAview *view, psArray *sources); 150 psArray *psphotLoadPSFSources (pmConfig *config, const pmFPAview *view); 151 152 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 153 231 bool psphotSetHeaderNstars (psMetadata *recipe, psArray *sources); 154 bool psphotAddNoise (pmReadout *readout, const psArray *sources, const psMetadata *recipe);155 bool psphotSubNoise (pmReadout *readout, const psArray *sources, const psMetadata *recipe);156 bool psphotAddOrSubNoise (pmReadout *readout, const psArray *sources, const psMetadata *recipe, bool add);157 232 bool psphotRadialPlot (int *kapa, const char *filename, pmSource *source); 158 233 bool psphotSourcePlots (pmReadout *readout, psArray *sources, psMetadata *recipe); 159 234 bool psphotMosaicSubimage (psImage *outImage, pmSource *source, int Xo, int Yo, int DX, int DY, bool normalize); 160 235 161 bool psphotAddWithTest (pmSource *source, bool useState, psImageMaskType maskVal);162 bool psphotSubWithTest (pmSource *source, bool useState, psImageMaskType maskVal);163 bool psphotSetState (pmSource *source, bool curState, psImageMaskType maskVal);164 bool psphotDeblendSatstars (pmReadout *readout, psArray *sources, psMetadata *recipe);165 bool psphotSourceSize (pmConfig *config, pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, long first);166 167 236 bool psphotMakeResiduals (psArray *sources, psMetadata *recipe, pmPSF *psf, psImageMaskType maskVal); 168 237 … … 172 241 173 242 // functions related to extended source analysis 174 bool psphotRadialProfile (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal);175 bool psphotRadialProfilesByAngles (pmSource *source, int Nsec, float Rmax);176 float psphotRadiusFromProfile (pmSource *source, psVector *radius, psVector *flux, float fluxMin, float fluxMax);177 bool psphotRadiiFromProfiles (pmSource *source, float fluxMin, float fluxMax);178 bool psphotEllipticalProfile (pmSource *source);179 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); 248 bool psphotEllipticalContour (pmSource *source); 180 249 181 250 // psphotVisual functions 182 bool psphotVisualShowImage (pmReadout *readout); 183 bool psphotVisualShowBackground (pmConfig *config, const pmFPAview *view, pmReadout *readout); 184 bool psphotVisualShowSignificance (psImage *image); 185 bool psphotVisualShowPeaks (pmDetections *detections); 186 bool psphotVisualShowFootprints (pmDetections *detections); 187 bool psphotVisualShowMoments (psArray *sources); 188 bool psphotVisualPlotMoments (psMetadata *recipe, psMetadata *analysis, psArray *sources); 189 bool psphotVisualShowRoughClass (psArray *sources); 190 bool psphotVisualShowPSFStars (psMetadata *recipe, pmPSF *psf, psArray *sources); 191 bool psphotVisualShowSatStars (psMetadata *recipe, pmPSF *psf, psArray *sources); 192 bool psphotVisualShowPSFModel (pmReadout *readout, pmPSF *psf); 193 bool psphotVisualPlotRadialProfile (int myKapa, pmSource *source, psImageMaskType maskVal); 194 bool psphotVisualPlotRadialProfiles (psMetadata *recipe, psArray *sources); 195 bool psphotVisualShowFlags (psArray *sources); 196 bool psphotVisualShowSourceSize (pmReadout *readout, psArray *sources); 197 bool psphotVisualShowResidualImage (pmReadout *readout); 198 bool psphotVisualPlotApResid (psArray *sources, float mean, float error); 199 bool psphotVisualPlotChisq (psArray *sources); 200 bool psphotVisualPlotSourceSize (psMetadata *recipe, psMetadata *analysis, psArray *sources); 201 bool psphotVisualShowPetrosians (psArray *sources); 202 203 // bool psphotPetrosianAnalysis (pmReadout *readout, psArray *sources, psMetadata *recipe); 204 // 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); 205 272 206 273 bool psphotPetrosian (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal); … … 208 275 bool psphotPetrosianStats (pmSource *source); 209 276 210 // XXX old versions, currently disabled277 // currently disabled: 211 278 // bool psphotIsophotal (pmSource *source, psMetadata *recipe, psImageMaskType maskVal); 212 279 // bool psphotAnnuli (pmSource *source, psMetadata *recipe, psImageMaskType maskVal); … … 223 290 // float petFlux, float radiusForFlux); 224 291 225 bool psphotImageQuality (psMetadata *recipe, psArray *sources);226 227 292 // structures & functions to support psf-convolved model fitting 228 229 // pmPCMData : PSF Convolved Model data storage structure230 typedef struct {231 psImage *model;232 psArray *dmodels;233 psImage *modelConv;234 psArray *dmodelsConv;235 } pmPCMData;236 237 293 238 294 // psf-convolved model fitting … … 277 333 int psphotSupplementStars (psArray *stars, psArray *sources, psImageBinning *binning, int ix, int iy); 278 334 279 280 // Create a background model for a readout281 // Essentially identical to psphotModelBackground, but with a more convenient API for outsiders.282 psImage *psphotBackgroundModel(pmReadout *ro, // Readout for which to generate background model283 const pmConfig *config // Configuration284 );285 286 335 pmConfig *psphotForcedArguments(int argc, char **argv); 287 336 bool psphotForcedImageLoop (pmConfig *config); -
trunk/psphot/src/psphotAddNoise.c
r25755 r26894 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): -
trunk/psphot/src/psphotApResid.c
r26261 r26894 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 // loop over the available readouts 19 for (int i = 0; i < num; i++) { 20 if (!psphotApResidReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 21 psError (PSPHOT_ERR_CONFIG, false, "failed to measure aperture residual for PSPHOT.INPUT entry %d", i); 22 return false; 23 } 24 } 25 return true; 26 } 27 28 bool psphotApResidReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) 7 29 { 8 30 int Nfail = 0; … … 13 35 pmSource *source; 14 36 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 37 psTimerStart ("psphot.apresid"); 21 38 22 // select the appropriate recipe information 23 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 24 assert (recipe); 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->allSources; 50 psAssert (sources, "missing sources?"); 51 52 if (!sources->n) { 53 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping ap resid"); 54 return true; 55 } 56 57 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 58 psAssert (psf, "missing psf?"); 25 59 26 60 // determine the number of allowed threads … … 33 67 if (!measureAptrend) { 34 68 // 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);69 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", NAN); 70 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", NAN); 71 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", 0); 72 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", NAN); 39 73 return true; 40 74 } … … 288 322 289 323 // save results for later output 290 psMetadataAdd (re cipe, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", psf->ApResid);291 psMetadataAdd (re cipe, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", psf->dApResid);292 psMetadataAdd (re cipe, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", psf->nApResid);293 psMetadataAdd (re cipe, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", psf->growth->apLoss);324 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", psf->ApResid); 325 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", psf->dApResid); 326 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", psf->nApResid); 327 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", psf->growth->apLoss); 294 328 295 329 psLogMsg ("psphot.apresid", PS_LOG_DETAIL, "aperture residual: %f +/- %f\n", psf->ApResid, psf->dApResid); … … 308 342 escape: 309 343 // save nan values since these were not calculated 310 psMetadataAdd (re cipe, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", NAN);311 psMetadataAdd (re cipe, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", NAN);312 psMetadataAdd (re cipe, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", 0);313 psMetadataAdd (re cipe, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", NAN);344 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APMIFIT", PS_DATA_F32 | PS_META_REPLACE, "aperture residual", NAN); 345 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "DAPMIFIT", PS_DATA_F32 | PS_META_REPLACE, "ap residual scatter", NAN); 346 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "NAPMIFIT", PS_DATA_S32 | PS_META_REPLACE, "number of apresid stars", 0); 347 psMetadataAdd (readout->analysis, PS_LIST_TAIL, "APLOSS", PS_DATA_F32 | PS_META_REPLACE, "aperture loss (mag)", NAN); 314 348 315 349 psFree (xPos); … … 318 352 psFree (mag); 319 353 psFree (dMag); 320 return false; 354 return true; 355 // this is a quality error, not a programming error 321 356 } 322 357 -
trunk/psphot/src/psphotBasicDeblend.c
r20453 r26894 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"); -
trunk/psphot/src/psphotBlendFit.c
r25755 r26894 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 -
trunk/psphot/src/psphotChoosePSF.c
r26262 r26894 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 // loop over the available readouts 16 for (int i = 0; i < num; i++) { 17 if (!psphotChoosePSFReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 18 psError (PSPHOT_ERR_CONFIG, false, "failed to choose a psf model for PSPHOT.INPUT entry %d", i); 19 return false; 20 } 21 } 22 return true; 23 } 24 3 25 // try PSF models and select best option 4 pmPSF *psphotChoosePSF (pmReadout *readout, psArray *sources, psMetadata *recipe) {26 bool psphotChoosePSFReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 5 27 6 28 bool status; 7 29 8 30 psTimerStart ("psphot.choose.psf"); 31 32 // find the currently selected readout 33 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 34 psAssert (file, "missing file?"); 35 36 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 37 psAssert (readout, "missing readout?"); 38 39 // do not generate a PSF if we already were supplied one 40 if (psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF")) { 41 psLogMsg ("psphot", PS_LOG_DETAIL, "psf model supplied for input file %d", index); 42 return true; 43 } 44 45 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 46 psAssert (detections, "missing detections?"); 47 48 psArray *sources = detections->newSources; 49 psAssert (sources, "missing sources?"); 50 51 if (!sources->n) { 52 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping PSF model"); 53 return true; 54 } 9 55 10 56 // bit-masks to test for good/bad pixels 11 57 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); 12 assert (maskVal);58 psAssert (maskVal, "missing mask value?"); 13 59 14 60 // bit-mask to mark pixels not used in analysis 15 61 psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); 16 assert (markVal);62 psAssert (markVal, "missing mark value?"); 17 63 18 64 // maskVal is used to test for rejected pixels, and must include markVal … … 61 107 // assert (status); 62 108 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"); 109 // values on readout->analysis if we have calculated a Gaussian window function, use that 110 // for both the PSF fit radius and the aperture radius (scaling SIGMA), otherwise base the value on the recipe value for MOMENTS_GAUSS_SIGMA 111 float gaussSigma = psMetadataLookupF32 (&status, readout->analysis, "MOMENTS_GAUSS_SIGMA"); 112 if (!status) { 113 gaussSigma = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA"); 114 } 66 115 float fitScale = psMetadataLookupF32(&status, recipe, "PSF_FIT_RADIUS_SCALE"); 67 116 float apScale = psMetadataLookupF32(&status, recipe, "PSF_APERTURE_SCALE"); … … 70 119 71 120 // XXX use the same radii for standard analysis as for the PSF creation 72 psMetadataAddF32(re cipe, PS_LIST_TAIL, "PSF_FIT_RADIUS", PS_META_REPLACE, "fit radius", options->fitRadius);73 psMetadataAddF32(re cipe, PS_LIST_TAIL, "PSF_APERTURE", PS_META_REPLACE, "psf aperture", options->apRadius);121 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PSF_FIT_RADIUS", PS_META_REPLACE, "fit radius", options->fitRadius); 122 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "PSF_APERTURE", PS_META_REPLACE, "psf aperture", options->apRadius); 74 123 75 124 // dimensions of the field for which the PSF is defined … … 158 207 bool status = true; 159 208 status &= psphotMakeFluxScale (readout->image, recipe, psf); 160 status &= psphotPSFstats (readout, recipe,psf);209 status &= psphotPSFstats (readout, psf); 161 210 if (!status) { 162 211 psError(PSPHOT_ERR_PSF, false, "Failed to fit any models when choosing PSF"); … … 233 282 bool status = true; 234 283 status &= psphotMakeFluxScale (readout->image, recipe, psf); 235 status &= psphotPSFstats (readout, recipe,psf);284 status &= psphotPSFstats (readout, psf); 236 285 if (!status) { 237 286 psError(PSPHOT_ERR_PSF, false, "Failed to fit any models when choosing PSF"); … … 290 339 psFree (models); 291 340 292 if (!psphotPSFstats (readout, recipe,psf)) {341 if (!psphotPSFstats (readout, psf)) { 293 342 psError(PSPHOT_ERR_PSF, false, "cannot measure PSF shape terms"); 294 343 psFree(options); … … 302 351 303 352 psFree (options); 304 return (psf); 353 354 // save PSF on readout->analysis 355 if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot psf model", psf)) { 356 psError (PSPHOT_ERR_UNKNOWN, false, "problem saving sources on readout"); 357 return false; 358 } 359 psFree (psf); // XXX double-check 360 361 // move into psphotChoosePSF 362 psphotVisualShowPSFModel (readout, psf); 363 364 return true; 305 365 } 306 366 307 367 // measure average parameters of the PSF model 308 bool psphotPSFstats (pmReadout *readout, p sMetadata *recipe, pmPSF *psf) {368 bool psphotPSFstats (pmReadout *readout, pmPSF *psf) { 309 369 310 370 psEllipseShape shape; … … 312 372 313 373 PS_ASSERT_PTR_NON_NULL(readout, false); 314 PS_ASSERT_PTR_NON_NULL(recipe, false);315 374 PS_ASSERT_PTR_NON_NULL(psf, false); 316 375 … … 362 421 } 363 422 364 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "FWHM_MAJ", PS_META_REPLACE, "PSF FWHM Major axis (mean)", stats->sampleMean);365 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "FW_MJ_SG", PS_META_REPLACE, "PSF FWHM Major axis (sigma)", stats->sampleStdev);366 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "FW_MJ_LQ", PS_META_REPLACE, "PSF FWHM Major axis (lower quartile)", stats->sampleLQ);367 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "FW_MJ_UQ", PS_META_REPLACE, "PSF FWHM Major axis (upper quartile)", stats->sampleUQ);423 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FWHM_MAJ", PS_META_REPLACE, "PSF FWHM Major axis (mean)", stats->sampleMean); 424 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_SG", PS_META_REPLACE, "PSF FWHM Major axis (sigma)", stats->sampleStdev); 425 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_LQ", PS_META_REPLACE, "PSF FWHM Major axis (lower quartile)", stats->sampleLQ); 426 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_UQ", PS_META_REPLACE, "PSF FWHM Major axis (upper quartile)", stats->sampleUQ); 368 427 369 428 if (!psVectorStats (stats, fwhmMinor, NULL, NULL, 0)) { … … 371 430 return false; 372 431 } 373 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "FWHM_MIN", PS_META_REPLACE, "PSF FWHM Minor axis (mean)", stats->sampleMean);374 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "FW_MN_SG", PS_META_REPLACE, "PSF FWHM Minor axis (sigma)", stats->sampleStdev);375 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "FW_MN_LQ", PS_META_REPLACE, "PSF FWHM Minor axis (lower quartile)", stats->sampleLQ);376 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "FW_MN_UQ", PS_META_REPLACE, "PSF FWHM Minor axis (upper quartile)", stats->sampleUQ);377 378 psMetadataAddF32 (re cipe, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", axes.theta);379 psMetadataAddS32 (re cipe, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", psf->nPSFstars);380 psMetadataAddBool(re cipe, PS_LIST_TAIL, "PSFMODEL", PS_META_REPLACE, "Valid PSF Model?", true);432 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FWHM_MIN", PS_META_REPLACE, "PSF FWHM Minor axis (mean)", stats->sampleMean); 433 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_SG", PS_META_REPLACE, "PSF FWHM Minor axis (sigma)", stats->sampleStdev); 434 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_LQ", PS_META_REPLACE, "PSF FWHM Minor axis (lower quartile)", stats->sampleLQ); 435 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_UQ", PS_META_REPLACE, "PSF FWHM Minor axis (upper quartile)", stats->sampleUQ); 436 437 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", axes.theta); 438 psMetadataAddS32 (readout->analysis, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", psf->nPSFstars); 439 psMetadataAddBool(readout->analysis, PS_LIST_TAIL, "PSFMODEL", PS_META_REPLACE, "Valid PSF Model?", true); 381 440 382 441 psFree (fwhmMajor); … … 387 446 388 447 // determine approximate PSF shape parameters based on the moments 389 bool psphotMomentsStats (pmReadout *readout, ps Metadata *recipe, psArray *sources) {448 bool psphotMomentsStats (pmReadout *readout, psArray *sources) { 390 449 391 450 // without the PSF model, we can only rely on the source->moments … … 401 460 402 461 PS_ASSERT_PTR_NON_NULL(readout, false); 403 PS_ASSERT_PTR_NON_NULL(recipe, false);404 462 PS_ASSERT_PTR_NON_NULL(sources, false); 405 463 … … 429 487 FWHM_T /= FWHM_N; 430 488 431 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FWHM_MAJ", PS_META_REPLACE, "PSF FWHM Major axis (mean)", FWHM_X); 432 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MJ_SG", PS_META_REPLACE, "PSF FWHM Major axis (sigma)", 0); 433 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MJ_LQ", PS_META_REPLACE, "PSF FWHM Major axis (lower quartile)", 0); 434 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MJ_UQ", PS_META_REPLACE, "PSF FWHM Major axis (upper quartile)", 0); 435 436 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FWHM_MIN", PS_META_REPLACE, "PSF FWHM Minor axis (mean)", FWHM_Y); 437 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MN_SG", PS_META_REPLACE, "PSF FWHM Minor axis (sigma)", 0); 438 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MN_LQ", PS_META_REPLACE, "PSF FWHM Minor axis (lower quartile)", 0); 439 psMetadataAddF32 (recipe, PS_LIST_TAIL, "FW_MN_UQ", PS_META_REPLACE, "PSF FWHM Minor axis (upper quartile)", 0); 440 441 psMetadataAddF32 (recipe, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", FWHM_T); 442 psMetadataAddS32 (recipe, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", 0); 443 psMetadataAddBool(recipe, PS_LIST_TAIL, "PSFMODEL", PS_META_REPLACE, "Valid PSF Model?", false); 489 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FWHM_MAJ", PS_META_REPLACE, "PSF FWHM Major axis (mean)", FWHM_X); 490 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_SG", PS_META_REPLACE, "PSF FWHM Major axis (sigma)", 0); 491 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_LQ", PS_META_REPLACE, "PSF FWHM Major axis (lower quartile)", 0); 492 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MJ_UQ", PS_META_REPLACE, "PSF FWHM Major axis (upper quartile)", 0); 493 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FWHM_MIN", PS_META_REPLACE, "PSF FWHM Minor axis (mean)", FWHM_Y); 494 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_SG", PS_META_REPLACE, "PSF FWHM Minor axis (sigma)", 0); 495 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_LQ", PS_META_REPLACE, "PSF FWHM Minor axis (lower quartile)", 0); 496 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "FW_MN_UQ", PS_META_REPLACE, "PSF FWHM Minor axis (upper quartile)", 0); 497 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", FWHM_T); 498 psMetadataAddS32 (readout->analysis, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", 0); 499 psMetadataAddBool(readout->analysis, PS_LIST_TAIL, "PSFMODEL", PS_META_REPLACE, "Valid PSF Model?", false); 444 500 445 501 return true; -
trunk/psphot/src/psphotDeblendSatstars.c
r25885 r26894 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"); -
trunk/psphot/src/psphotEfficiency.c
r26453 r26894 6 6 //#define TESTING 7 7 8 9 # if 0 8 10 9 11 // Calculate the limiting magnitude for an image … … 33 35 34 36 psKernel *kernel = psImageSmoothKernel(smoothSigma, smoothNsigma); // Kernel used for smoothing 35 psKernel *newCovar = psImageCovarianceCalculate(kernel, ro->covariance); // Covariance matrix37 *covarFactor = psImageCovarianceCalculateFactor(kernel, ro->covariance); 36 38 psFree(kernel); 37 *covarFactor = psImageCovarianceFactor(newCovar); // Variance factor38 psFree(newCovar);39 39 40 40 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); // Statistics for variance … … 152 152 } 153 153 154 # endif 155 156 bool psphotEfficiency (pmConfig *config, const pmFPAview *view) 157 { 158 bool status = true; 159 160 // select the appropriate recipe information 161 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 162 psAssert (recipe, "missing recipe?"); 163 164 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 165 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 166 167 // loop over the available readouts 168 for (int i = 0; i < num; i++) { 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 } 154 176 155 177 // Determine detection efficiency 156 bool psphotEfficiency(pmConfig *config, pmReadout *readout, const pmFPAview *view, const pmPSF *psf, 157 psMetadata *recipe, const psArray *realSources) 178 bool psphotEfficiencyReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) 158 179 { 180 # if 0 181 bool status = true; 182 183 psTimerStart("psphot.fake"); 184 185 // find the currently selected readout 186 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 187 psAssert (file, "missing file?"); 188 189 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 190 psAssert (readout, "missing readout?"); 191 192 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 193 psAssert (detections, "missing detections?"); 194 195 psArray *realSources = detections->allSources; 196 psAssert (realSources, "missing sources?"); 197 198 // XXX do we need to skip this step if we do not have a psf? 199 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 200 psAssert (psf, "missing psf?"); 201 159 202 PM_ASSERT_READOUT_NON_NULL(readout, false); 160 203 PM_ASSERT_READOUT_IMAGE(readout, false); 161 204 PS_ASSERT_PTR_NON_NULL(psf, false); 162 205 PS_ASSERT_METADATA_NON_NULL(recipe, false); 163 PS_ASSERT_ARRAY_NON_NULL(realSources, false);164 165 psTimerStart("psphot.fake");166 206 167 207 // Collect recipe information … … 206 246 // remove all sources, adding noise for subtracted sources 207 247 psphotRemoveAllSources(realSources, recipe); 208 // psphotAddNoise(readout, realSources, recipe);248 // psphotAddNoise(readout, realSources, recipe); 209 249 210 250 … … 480 520 psLogMsg("psphot", PS_LOG_INFO, "Detection efficiency: %lf sec\n", psTimerClear("psphot.fake")); 481 521 522 # endif 482 523 483 524 return true; -
trunk/psphot/src/psphotExtendedSourceAnalysis.c
r25755 r26894 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 // find the currently selected readout 42 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 43 psAssert (file, "missing file?"); 44 45 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 46 psAssert (readout, "missing readout?"); 47 48 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 49 psAssert (detections, "missing detections?"); 50 51 psArray *sources = detections->allSources; 52 psAssert (sources, "missing sources?"); 53 54 if (!sources->n) { 55 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size"); 56 return true; 57 } 58 13 59 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 14 60 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 15 61 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 62 23 63 // XXX require petrosian analysis for non-linear fits? -
trunk/psphot/src/psphotExtendedSourceFits.c
r25755 r26894 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 -
trunk/psphot/src/psphotFake.c
r26266 r26894 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); -
trunk/psphot/src/psphotFindDetections.c
r25755 r26894 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 -
trunk/psphot/src/psphotFindFootprints.c
r25755 r26894 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 { … … 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 } -
trunk/psphot/src/psphotFindPeaks.c
r25755 r26894 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 -
trunk/psphot/src/psphotFitSourcesLinear.c
r25990 r26894 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 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 20 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 21 22 // loop over the available readouts 23 for (int i = 0; i < num; i++) { 24 if (!psphotFitSourcesLinearReadout (config, view, "PSPHOT.INPUT", i, final)) { 25 psError (PSPHOT_ERR_CONFIG, false, "failed to fit sources (linear) for PSPHOT.INPUT entry %d", i); 26 return false; 27 } 28 } 29 return true; 30 } 31 32 bool psphotFitSourcesLinearReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, bool final) { 15 33 16 34 bool status; … … 19 37 float f; 20 38 // float r; 39 40 // select the appropriate recipe information 41 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 42 assert (recipe); 43 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 linear fit"); 59 return true; 60 } 61 62 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 63 psAssert (sources, "missing psf?"); 21 64 22 65 psTimerStart ("psphot.linear"); … … 248 291 psphotVisualPlotChisq (sources); 249 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); 250 297 251 298 return true; -
trunk/psphot/src/psphotForcedReadout.c
r25981 r26894 20 20 21 21 // set the photcode for this image 22 if (!psphotAddPhotcode ( recipe, config, view, "PSPHOT.INPUT")) {22 if (!psphotAddPhotcode (config, view)) { 23 23 psError (PSPHOT_ERR_CONFIG, false, "trouble defining the photcode"); 24 24 return false; 25 25 } 26 27 // find the currently selected readout28 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");29 PS_ASSERT_PTR_NON_NULL (readout, false);30 26 31 27 // optional break-point for processing … … 34 30 35 31 // Generate the mask and weight images, including the user-defined analysis region of interest 36 psphotSetMaskAndVariance (config, readout, recipe);32 psphotSetMaskAndVariance (config, view); 37 33 if (!strcasecmp (breakPt, "NOTHING")) { 38 return psphotReadoutCleanup(config, readout, recipe, NULL, NULL, NULL);34 return psphotReadoutCleanup(config, view); 39 35 } 40 36 41 // display the image, weight, mask (ch 1,2,3)42 psphotVisualShowImage (readout);43 44 37 // generate a background model (median, smoothed image) 45 if (!psphotModelBackground (config, view , "PSPHOT.INPUT")) {46 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);38 if (!psphotModelBackground (config, view)) { 39 return psphotReadoutCleanup (config, view); 47 40 } 48 if (!psphotSubtractBackground (config, view , "PSPHOT.INPUT")) {49 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);41 if (!psphotSubtractBackground (config, view)) { 42 return psphotReadoutCleanup (config, view); 50 43 } 51 44 if (!strcasecmp (breakPt, "BACKMDL")) { 52 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);45 return psphotReadoutCleanup (config, view); 53 46 } 54 47 55 // display the backsub and backgnd images 56 psphotVisualShowBackground (config, view, readout); 57 58 // load the psf model, if suppled. FWHM_X,FWHM_Y,etc are saved in the recipe 59 pmPSF *psf = psphotLoadPSF (config, view, recipe); 60 if (!psf) { 61 psError(PSPHOT_ERR_CONFIG, false, "unable to load psf model"); 62 return false; 48 if (!psphotLoadPSF (config, view)) { 49 // this only happens if we had a programming error in psphotLoadPSF 50 psError (PSPHOT_ERR_UNKNOWN, false, "error loading psf model"); 51 return psphotReadoutCleanup (config, view); 63 52 } 64 53 65 54 // include externally-supplied sources 66 psArray *sources = psArrayAllocEmpty(100); 67 psphotLoadExtSources (config, view, sources); 55 psphotLoadExtSources (config, view); 68 56 69 57 // construct an initial model for each object, set the radius to fitRadius, set circular fit mask 70 psphotGuessModels (config, readout, sources, psf);58 psphotGuessModels (config, view); 71 59 72 60 // linear PSF fit to source peaks, subtract the models from the image (in PSF mask) 73 psphotFitSourcesLinear ( readout, sources, recipe, psf, FALSE);61 psphotFitSourcesLinear (config, view, false); 74 62 75 63 // identify CRs and extended sources … … 79 67 80 68 // calculate source magnitudes 81 psphotMagnitudes(config, readout, view, sources, psf);69 psphotMagnitudes(config, view); 82 70 83 71 // XXX do I want to do this? … … 91 79 92 80 // drop the references to the image pixels held by each source 93 psphotSourceFreePixels ( sources);81 psphotSourceFreePixels (config, view); 94 82 95 83 // create the exported-metadata and free local data 96 return psphotReadoutCleanup(config, readout, recipe, NULL, psf, sources);84 return psphotReadoutCleanup(config, view); 97 85 } -
trunk/psphot/src/psphotGuessModels.c
r25755 r26894 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 // loop over the available readouts 18 for (int i = 0; i < num; i++) { 19 if (!psphotGuessModelsReadout (config, view, "PSPHOT.INPUT", i)) { 20 psError (PSPHOT_ERR_CONFIG, false, "failed on to guess models for PSPHOT.INPUT entry %d", i); 21 return false; 22 } 23 } 24 return true; 25 } 26 27 // construct an initial PSF model for each object (new sources only) 28 bool psphotGuessModelsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index) { 11 29 12 30 bool status; 13 31 14 32 psTimerStart ("psphot.models"); 33 34 // find the currently selected readout 35 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 36 psAssert (file, "missing file?"); 37 38 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 39 psAssert (readout, "missing readout?"); 40 41 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 42 psAssert (detections, "missing detections?"); 43 44 psArray *sources = detections->newSources; 45 psAssert (sources, "missing sources?"); 46 47 if (!sources->n) { 48 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping model guess"); 49 return true; 50 } 51 52 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 53 psAssert (psf, "missing psf?"); 15 54 16 55 // select the appropriate recipe information … … 21 60 int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads 22 61 if (!status) { 23 nThreads = 0;62 nThreads = 0; 24 63 } 25 64 … … 36 75 37 76 // setup the PSF fit radius details 38 psphotInitRadiusPSF (recipe, psf->type);77 psphotInitRadiusPSF (recipe, readout->analysis, psf->type); 39 78 40 79 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) … … 46 85 for (int i = 0; i < cellGroups->n; i++) { 47 86 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 }87 psArray *cells = cellGroups->data[i]; 88 89 for (int j = 0; j < cells->n; j++) { 90 91 // allocate a job -- if threads are not defined, this just runs the job 92 psThreadJob *job = psThreadJobAlloc ("PSPHOT_GUESS_MODEL"); 93 psArrayAdd(job->args, 1, readout); 94 psArrayAdd(job->args, 1, cells->data[j]); // sources 95 psArrayAdd(job->args, 1, psf); 96 97 // XXX change these to use abstract mask type info 98 PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK); 99 PS_ARRAY_ADD_SCALAR(job->args, markVal, PS_TYPE_IMAGE_MASK); 100 101 if (!psThreadJobAddPending(job)) { 102 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 103 psFree (job); 104 return false; 105 } 106 psFree(job); 107 } 108 109 // wait for the threads to finish and manage results 110 // wait here for the threaded jobs to finish 111 // fprintf (stderr, "wait for threads (%d, %d)\n", jx, jy); 112 if (!psThreadPoolWait (false)) { 113 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 114 return false; 115 } 116 117 // we have only supplied one type of job, so we can assume the types here 118 psThreadJob *job = NULL; 119 while ((job = psThreadJobGetDone()) != NULL) { 120 // we have no returned data from this operation 121 if (job->args->n < 1) { 122 fprintf (stderr, "error with job\n"); 123 } 124 psFree(job); 125 } 87 126 } 88 127 … … 90 129 int nMiss = 0; 91 130 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 ++;131 pmSource *source = sources->data[i]; 132 if (source->tmpFlags & PM_SOURCE_TMPF_MODEL_GUESS) { 133 continue; 134 } 135 nMiss ++; 97 136 } 98 137 psAssert (nMiss == 0, "failed to attempt to build models for %d objects\n", nMiss); … … 110 149 psArray *sources = job->args->data[1]; 111 150 pmPSF *psf = job->args->data[2]; 112 151 113 152 psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[3],PS_TYPE_IMAGE_MASK_DATA); 114 153 psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA); … … 117 156 118 157 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 (!)158 pmSource *source = sources->data[i]; 159 160 // this is used to mark sources for which the model is measured. We check later that 161 // all are used. 162 source->tmpFlags |= PM_SOURCE_TMPF_MODEL_GUESS; 163 164 // skip non-astronomical objects (very likely defects) 165 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 166 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 167 if (!source->peak) continue; 168 169 nSrc ++; 170 171 // the guess central intensity comes from the peak: 172 float Io = source->peak->flux; 173 174 // We have two options to get a guess for the object position: the position from the 175 // peak and the position from the moments. Use the peak position if (a) there are no 176 // moments and (b) the sources is not saturated 177 178 bool useMoments = false; 179 useMoments = (source->mode & PM_SOURCE_MODE_SATSTAR); // we only want to try if SATSTAR is set, but.. 180 useMoments = (useMoments && source->moments); // can't if there are no moments 181 useMoments = (useMoments && source->moments->nPixels); // can't if the moments were not measured 182 useMoments = (useMoments && !(source->mode && PM_SOURCE_MODE_MOMENTS_FAILURE)); // can't if the moments failed... 183 184 float Xo, Yo; 185 if (useMoments) { 186 Xo = source->moments->Mx; 187 Yo = source->moments->My; 188 } else { 189 Xo = source->peak->xf; 190 Yo = source->peak->yf; 191 } 192 193 // set PSF parameters for this model (apply 2D shape model to coordinates Xo, Yo) 194 pmModel *modelPSF = pmModelFromPSFforXY(psf, Xo, Yo, Io); 195 196 if (modelPSF == NULL) { 197 psWarning ("Failed to determine PSF model at (%f,%f); trying image center", Xo, Yo); 198 199 float Xc = 0.5*readout->image->numCols; 200 float Yc = 0.5*readout->image->numRows; 201 pmModel *modelPSF = pmModelFromPSFforXY(psf, Xc, Yc, Io); 202 if (modelPSF == NULL) { 203 psError(PSPHOT_ERR_PSF, false, "Failed to determine PSF model at center of image"); 204 return false; 205 } 206 207 // Now set the object position at the expected location: 208 modelPSF->params->data.F32[PM_PAR_XPOS] = Xo; 209 modelPSF->params->data.F32[PM_PAR_YPOS] = Yo; 210 source->mode |= PM_SOURCE_MODE_BADPSF; 211 } 212 213 // set the fit radius based on the object flux limit and the model 214 // this function affects the mask pixels 215 psphotCheckRadiusPSF (readout, source, modelPSF, markVal); 216 217 // set the source PSF model 218 psAssert (source->modelPSF == NULL, "failed to free one of the models?"); 219 source->modelPSF = modelPSF; 220 source->modelPSF->residuals = psf->residuals; 221 222 pmSourceCacheModel (source, maskVal); // ALLOC x14 (!) 184 223 } 185 224 -
trunk/psphot/src/psphotImageQuality.c
r25755 r26894 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 // loop over the available readouts 19 for (int i = 0; i < num; i++) { 20 if (!psphotImageQualityReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 21 psError (PSPHOT_ERR_CONFIG, false, "failed on to measure image quality for PSPHOT.INPUT entry %d", i); 22 return false; 23 } 24 } 25 return true; 26 } 27 6 28 // 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)29 bool psphotImageQualityReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) 8 30 { 31 bool status = true; 32 33 // find the currently selected readout 34 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 35 psAssert (file, "missing file?"); 36 37 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 38 psAssert (readout, "missing readout?"); 39 40 // if we have a PSF, skip this analysis 41 if (psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF")) { 42 return true; 43 } 44 45 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 46 psAssert (detections, "missing detections?"); 47 48 psArray *sources = detections->newSources; 49 psAssert (sources, "missing sources?"); 50 51 if (!sources->n) { 52 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping image quality"); 53 return true; 54 } 55 9 56 psVector *FWHM_MAJOR = psVectorAllocEmpty(100, PS_TYPE_F32); 10 57 psVector *FWHM_MINOR = psVectorAllocEmpty(100, PS_TYPE_F32); … … 81 128 82 129 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); 130 psLogMsg ("psphot", PS_LOG_INFO, "no valid sources for image quality, skipping"); 131 return true; 132 } 133 134 psMetadataAddS32(readout->analysis, PS_LIST_TAIL, "IQ_NSTAR", PS_META_REPLACE, "Number of stars used for IQ measurements", M2->n); 89 135 90 136 // XXX make this a recipe option … … 98 144 99 145 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); 146 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW1", PS_META_REPLACE, "FWHM of Major Axis from moments", stats->sampleMean); 147 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW1_E", PS_META_REPLACE, "FWHM scatter (Major) from moments", stats->sampleStdev); 104 148 105 149 if (!psVectorStats(stats, FWHM_MINOR, NULL, NULL, 0)) { … … 108 152 } 109 153 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); 154 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW2", PS_META_REPLACE, "FWHM of Minor Axis from moments", stats->sampleMean); 155 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW2_E", PS_META_REPLACE, "FWHM scatter (Minor) from moments", stats->sampleStdev); 114 156 115 157 if (!psVectorStats(stats, M2, NULL, NULL, 0)) { … … 119 161 float vM2 = stats->sampleMean; 120 162 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); 163 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2", PS_META_REPLACE, "M_2 = sqrt (M_c2^2 + M_s2^2)", vM2); 164 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_ER", PS_META_REPLACE, "Stdev of M_2", dM2); 165 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_LQ", PS_META_REPLACE, "Lower Quartile of M_2", stats->sampleLQ); 166 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_UQ", PS_META_REPLACE, "Upper Quartile of M_2", stats->sampleUQ); 129 167 130 168 if (!psVectorStats(stats, M2c, NULL, NULL, 0)) { … … 132 170 goto FAIL; 133 171 } 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); 172 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C", PS_META_REPLACE, "M_2c = sum f r^2 cos(2phi) / sum f", stats->sampleMean); 173 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_E", PS_META_REPLACE, "Stdev of M_2c", stats->sampleStdev); 174 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_L", PS_META_REPLACE, "Lower Quartile of M_2c", stats->sampleLQ); 175 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_U", PS_META_REPLACE, "Upper Quartile of M_2c", stats->sampleUQ); 142 176 143 177 if (!psVectorStats(stats, M2s, NULL, NULL, 0)) { … … 145 179 goto FAIL; 146 180 } 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); 181 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S", PS_META_REPLACE, "M_2s = sum f r^2 cos(2phi) / sum f", stats->sampleMean); 182 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_E", PS_META_REPLACE, "Stdev of M_2s", stats->sampleStdev); 183 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_L", PS_META_REPLACE, "Lower Quartile of M_2s", stats->sampleLQ); 184 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_U", PS_META_REPLACE, "Upper Quartile of M_2s", stats->sampleUQ); 155 185 156 186 if (!psVectorStats(stats, M3, NULL, NULL, 0)) { … … 160 190 float vM3 = stats->sampleMean; 161 191 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); 192 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3", PS_META_REPLACE, "M_3 = sqrt (M_c3^2 + M_s3^2)", vM3); 193 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_ER", PS_META_REPLACE, "Stdev of M_3", dM3); 194 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_LQ", PS_META_REPLACE, "Lower Quartile of M_3", stats->sampleLQ); 195 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_UQ", PS_META_REPLACE, "Upper Quartile of M_3", stats->sampleUQ); 170 196 171 197 if (!psVectorStats(stats, M4, NULL, NULL, 0)) { … … 175 201 float vM4 = stats->sampleMean; 176 202 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); 203 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4", PS_META_REPLACE, "M_4 = sqrt (M_c4^2 + M_s4^2)", vM4); 204 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_ER", PS_META_REPLACE, "Stdev of M_4", dM4); 205 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_LQ", PS_META_REPLACE, "Lower Quartile of M_4", stats->sampleLQ); 206 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_UQ", PS_META_REPLACE, "Upper Quartile of M_4", stats->sampleUQ); 185 207 186 208 #else … … 192 214 } 193 215 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); 216 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW1", PS_META_REPLACE, "FWHM of Major Axis from moments", stats->robustMedian); 217 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW1_E", PS_META_REPLACE, "FWHM scatter (Major) from moments", stats->robustStdev); 198 218 199 219 if (!psVectorStats(stats, FWHM_MINOR, NULL, NULL, 0)) { … … 202 222 } 203 223 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); 224 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW2", PS_META_REPLACE, "FWHM of Minor Axis from moments", stats->robustMedian); 225 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_FW2_E", PS_META_REPLACE, "FWHM scatter (Minor) from moments", stats->robustStdev); 208 226 209 227 if (!psVectorStats(stats, M2, NULL, NULL, 0)) { … … 213 231 float vM2 = stats->robustMedian; 214 232 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); 233 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2", PS_META_REPLACE, "M_2 = sqrt (M_c2^2 + M_s2^2)", vM2); 234 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_ER", PS_META_REPLACE, "Stdev of M_2", dM2); 235 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_LQ", PS_META_REPLACE, "Lower Quartile of M_2", stats->robustLQ); 236 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2_UQ", PS_META_REPLACE, "Upper Quartile of M_2", stats->robustUQ); 223 237 224 238 if (!psVectorStats(stats, M2c, NULL, NULL, 0)) { … … 226 240 goto FAIL; 227 241 } 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); 242 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C", PS_META_REPLACE, "M_2c = sum f r^2 cos(2phi) / sum f", stats->robustMedian); 243 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_E", PS_META_REPLACE, "Stdev of M_2c", stats->robustStdev); 244 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_L", PS_META_REPLACE, "Lower Quartile of M_2c", stats->robustLQ); 245 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2C_U", PS_META_REPLACE, "Upper Quartile of M_2c", stats->robustUQ); 236 246 237 247 if (!psVectorStats(stats, M2s, NULL, NULL, 0)) { … … 239 249 goto FAIL; 240 250 } 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); 251 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S", PS_META_REPLACE, "M_2s = sum f r^2 cos(2phi) / sum f", stats->robustMedian); 252 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_E", PS_META_REPLACE, "Stdev of M_2s", stats->robustStdev); 253 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_L", PS_META_REPLACE, "Lower Quartile of M_2s", stats->robustLQ); 254 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M2S_U", PS_META_REPLACE, "Upper Quartile of M_2s", stats->robustUQ); 249 255 250 256 if (!psVectorStats(stats, M3, NULL, NULL, 0)) { … … 254 260 float vM3 = stats->robustMedian; 255 261 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); 262 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3", PS_META_REPLACE, "M_3 = sqrt (M_c3^2 + M_s3^2)", vM3); 263 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_ER", PS_META_REPLACE, "Stdev of M_3", dM3); 264 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_LQ", PS_META_REPLACE, "Lower Quartile of M_3", stats->robustLQ); 265 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M3_UQ", PS_META_REPLACE, "Upper Quartile of M_3", stats->robustUQ); 264 266 265 267 if (!psVectorStats(stats, M4, NULL, NULL, 0)) { … … 269 271 float vM4 = stats->robustMedian; 270 272 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); 273 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4", PS_META_REPLACE, "M_4 = sqrt (M_c4^2 + M_s4^2)", vM4); 274 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_ER", PS_META_REPLACE, "Stdev of M_4", dM4); 275 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_LQ", PS_META_REPLACE, "Lower Quartile of M_4", stats->robustLQ); 276 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "IQ_M4_UQ", PS_META_REPLACE, "Upper Quartile of M_4", stats->robustUQ); 279 277 #endif 280 278 -
trunk/psphot/src/psphotLoadPSF.c
r18002 r26894 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 } -
trunk/psphot/src/psphotMagnitudes.c
r25755 r26894 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 // loop over the available readouts 15 for (int i = 0; i < num; i++) { 16 if (!psphotMagnitudesReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 17 psError (PSPHOT_ERR_CONFIG, false, "failed to measure magnitudes for PSPHOT.INPUT entry %d", i); 18 return false; 19 } 20 } 21 return true; 22 } 23 24 bool psphotMagnitudesReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 4 25 5 26 bool status = false; … … 8 29 psTimerStart ("psphot.mags"); 9 30 10 // select the appropriate recipe information 11 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 12 assert (recipe); 31 // find the currently selected readout 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?"); 37 38 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 39 psAssert (detections, "missing detections?"); 40 41 psArray *sources = detections->allSources; 42 psAssert (sources, "missing sources?"); 43 44 if (!sources->n) { 45 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size"); 46 return true; 47 } 48 49 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 50 psAssert (psf, "missing psf?"); 13 51 14 52 // determine the number of allowed threads … … 64 102 65 103 psArrayAdd(job->args, 1, cells->data[j]); // sources 66 psArrayAdd(job->args, 1, (pmPSF*)psf); // Casting away const104 psArrayAdd(job->args, 1, psf); 67 105 psArrayAdd(job->args, 1, binning); 68 106 psArrayAdd(job->args, 1, backModel); … … 179 217 } 180 218 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 219 bool psphotPSFWeights(pmConfig *config, pmReadout *readout, const pmFPAview *view, psArray *sources) { 221 220 -
trunk/psphot/src/psphotMakePSFReadout.c
r25982 r26894 19 19 20 20 // set the photcode for this image 21 if (!psphotAddPhotcode ( recipe, config, view, "PSPHOT.INPUT")) {21 if (!psphotAddPhotcode (config, view)) { 22 22 psError (PSPHOT_ERR_CONFIG, false, "trouble defining the photcode"); 23 23 return false; 24 24 } 25 26 // find the currently selected readout27 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT");28 PS_ASSERT_PTR_NON_NULL (readout, false);29 25 30 26 // optional break-point for processing … … 33 29 34 30 // Generate the mask and weight images, including the user-defined analysis region of interest 35 psphotSetMaskAndVariance (config, readout, recipe);31 psphotSetMaskAndVariance (config, view); 36 32 if (!strcasecmp (breakPt, "NOTHING")) { 37 return psphotReadoutCleanup(config, readout, recipe, NULL, NULL, NULL);33 return psphotReadoutCleanup(config, view); 38 34 } 39 35 40 // display the image, weight, mask (ch 1,2,3)41 psphotVisualShowImage (readout);42 43 36 // generate a background model (median, smoothed image) 44 if (!psphotModelBackground (config, view , "PSPHOT.INPUT")) {45 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);37 if (!psphotModelBackground (config, view)) { 38 return psphotReadoutCleanup (config, view); 46 39 } 47 if (!psphotSubtractBackground (config, view , "PSPHOT.INPUT")) {48 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);40 if (!psphotSubtractBackground (config, view)) { 41 return psphotReadoutCleanup (config, view); 49 42 } 50 43 if (!strcasecmp (breakPt, "BACKMDL")) { 51 return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);44 return psphotReadoutCleanup (config, view); 52 45 } 53 46 54 // display the backsub and backgnd images 55 psphotVisualShowBackground (config, view, readout); 47 psphotLoadExtSources (config, view); 56 48 57 pmDetections *detections = NULL; 58 59 // If sources have been supplied, then these should be used to measure the PSF 60 // include externally-supplied sources 61 62 // XXX sources loaded from a text file have no valid SN values, but psphotChoosePSF 63 // selected the top PSF_MAX_NSTARS to generate the PSF, excluding an arbitrary subset. 64 psArray *sources = psArrayAllocEmpty(100); 65 psphotLoadExtSources (config, view, sources); 66 if (sources->n) { 67 // the user wants to make the psf from these stars; define them as psf stars: 68 for (int i = 0; i < sources->n; i++) { 69 pmSource *source = sources->data[i]; 70 source->mode |= PM_SOURCE_MODE_PSFSTAR; 71 } 72 // force psphotChoosePSF to use all loaded sources 73 psMetadataAddS32 (recipe, PS_LIST_TAIL, "PSF_MAX_NSTARS", PS_META_REPLACE, "fit radius", sources->n); 74 75 // measure stats of externally specified sources 76 if (!psphotSourceStatsUpdate (sources, config, readout)) { 77 psError(PSPHOT_ERR_CONFIG, false, "failure to measure stats of existing sources"); 78 return false; 79 } 80 81 } else { 82 // find the detections (by peak and/or footprint) in the image. 83 detections = psphotFindDetections (NULL, readout, recipe); 84 if (!detections) { 85 psLogMsg ("psphot", 3, "unable to find detections in this image"); 86 return psphotReadoutCleanup (config, readout, recipe, detections, NULL, sources); 87 } 88 89 // construct sources and measure basic stats 90 psFree (sources); 91 sources = psphotSourceStats (config, readout, detections, true); 92 if (!sources) return false; 93 94 // find blended neighbors of very saturated stars 95 // XXX merge this with Basic Deblend? 96 psphotDeblendSatstars (readout, sources, recipe); 97 98 // mark blended peaks PS_SOURCE_BLEND 99 if (!psphotBasicDeblend (sources, recipe)) { 100 psLogMsg ("psphot", 3, "failed on deblend analysis"); 101 return psphotReadoutCleanup (config, readout, recipe, detections, NULL, sources); 102 } 103 104 // classify sources based on moments, brightness 105 if (!psphotRoughClass (readout, sources, recipe, false)) { 106 psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image"); 107 return psphotReadoutCleanup (config, readout, recipe, detections, NULL, sources); 108 } 49 // If sources have been supplied, then these should be used to measure the PSF include 50 // externally-supplied sources; if not, we need to generate a set of possible PSF sources. 51 // This function updates the SN entries for the loaded sources or generates a set of 52 // detections from the image, if no external ones have been supplied. Sources loaded from 53 // a text file have no valid SN values, but psphotChoosePSF needs to select the top 54 // PSF_MAX_NSTARS to generate the PSF. 55 if (!psphotCheckExtSources (config, view)) { 56 psLogMsg ("psphot", 3, "failure to select possible PSF sources (external or internal)"); 57 return psphotReadoutCleanup (config, view); 109 58 } 110 59 111 // use bright stellar objects to measure PSF 112 // XXX if we do not have enough stars to generate the PSF, build one 113 // from the SEEING guess and model class 114 pmPSF *psf = psphotChoosePSF (readout, sources, recipe); 115 if (psf == NULL) { 60 // Use bright stellar objects to measure PSF. If we do not have enough stars to generate 61 // the PSF, build one from the SEEING guess and model class 62 if (!psphotChoosePSF (config, view)) { 116 63 psLogMsg ("psphot", 3, "failure to construct a psf model"); 117 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);64 return psphotReadoutCleanup (config, view); 118 65 } 119 psphotVisualShowPSFModel (readout, psf);120 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);121 }122 66 123 67 // measure aperture photometry corrections 124 // XXX isn't this part of the PSF?? 125 // if (!psphotApResid (config, readout, sources, psf)) { 126 // psLogMsg ("psphot", 3, "failed on psphotApResid"); 127 // return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources); 128 // } 68 # if 0 69 if (!psphotApResid (config, view)) { 70 psLogMsg ("psphot", 3, "failed on psphotApResid"); 71 return psphotReadoutCleanup (config, view); 72 } 73 # endif 74 75 return psphotReadoutCleanup (config, view); 76 } -
trunk/psphot/src/psphotMaskReadout.c
r25755 r26894 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 } -
trunk/psphot/src/psphotMergeSources.c
r25983 r26894 5 5 PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_EXT_LIMIT) // Mask to apply for PSF sources 6 6 7 // merge the externally supplied sources with the existing sources. mark them as having 8 // mode PM_SOURCE_MODE_EXTERNAL 9 bool psphotLoadExtSources (pmConfig *config, const pmFPAview *view, psArray *sources) { 10 11 psArray *extSourcesCMF = NULL; 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 25 // add newly selected sources to the existing list of sources 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; 55 56 for (int i = 0; i < newSources->n; i++) { 57 pmSource *source = newSources->data[i]; 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; 12 77 psArray *extSourcesTXT = NULL; 13 78 79 // find the currently selected readout 80 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", 0); // File of interest 81 psAssert (file, "missing file?"); 82 83 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 84 psAssert (readout, "missing readout?"); 85 86 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 87 psAssert (detections, "missing detections?"); 88 89 // XXX allSources or newSources? 90 psArray *sources = detections->allSources; 91 psAssert (sources, "missing sources?"); 92 14 93 // load data from input CMF file: 15 { 16 pmReadout *readoutCMF = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT.CMF"); 17 if (!readoutCMF) goto loadTXT; 18 19 extSourcesCMF = psMetadataLookupPtr (NULL, readoutCMF->analysis, "PSPHOT.SOURCES"); 20 if (extSourcesCMF) { 21 for (int i = 0; i < extSourcesCMF->n; i++) { 22 pmSource *source = extSourcesCMF->data[i]; 23 source->mode |= PM_SOURCE_MODE_EXTERNAL; 24 25 // the supplied peak flux needs to be re-normalized 26 source->peak->flux = 1.0; 27 source->peak->value = 1.0; 28 29 // drop the loaded source modelPSF 30 psFree (source->modelPSF); 31 source->modelPSF = NULL; 32 } 33 psphotMergeSources (sources, extSourcesCMF); 34 } 94 { 95 pmReadout *readoutCMF = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT.CMF"); 96 if (!readoutCMF) goto loadTXT; 97 98 extCMF = psMetadataLookupPtr (NULL, readoutCMF->analysis, "PSPHOT.DETECTIONS"); 99 if (extCMF) { 100 for (int i = 0; i < extCMF->allSources->n; i++) { 101 pmSource *source = extCMF->allSources->data[i]; 102 source->mode |= PM_SOURCE_MODE_EXTERNAL; 103 104 // the supplied peak flux needs to be re-normalized 105 source->peak->flux = 1.0; 106 source->peak->value = 1.0; 107 108 // drop the loaded source modelPSF 109 psFree (source->modelPSF); 110 source->modelPSF = NULL; 111 112 psArrayAdd (detections->allSources, 100, source); 113 } 114 } 35 115 } 36 116 … … 38 118 39 119 // load data from input TXT file: 40 { 41 pmChip *chipTXT = pmFPAfileThisChip (config->files, view, "PSPHOT.INPUT"); 42 if (!chipTXT) goto finish; 43 44 extSourcesTXT = psMetadataLookupPtr (NULL, chipTXT->analysis, "PSPHOT.SOURCES.TEXT"); 45 if (extSourcesTXT) { 46 for (int i = 0; i < extSourcesTXT->n; i++) { 47 pmSource *source = extSourcesTXT->data[i]; 48 source->mode |= PM_SOURCE_MODE_EXTERNAL; 49 50 // drop the loaded source modelPSF 51 psFree (source->modelPSF); 52 source->modelPSF = NULL; 53 } 54 psphotMergeSources (sources, extSourcesTXT); 55 } 120 { 121 pmChip *chipTXT = pmFPAfileThisChip (config->files, view, "PSPHOT.INPUT"); 122 if (!chipTXT) goto finish; 123 124 extSourcesTXT = psMetadataLookupPtr (NULL, chipTXT->analysis, "PSPHOT.SOURCES.TEXT"); 125 if (extSourcesTXT) { 126 for (int i = 0; i < extSourcesTXT->n; i++) { 127 pmSource *source = extSourcesTXT->data[i]; 128 source->mode |= PM_SOURCE_MODE_EXTERNAL; 129 130 // drop the loaded source modelPSF 131 psFree (source->modelPSF); 132 source->modelPSF = NULL; 133 134 psArrayAdd (detections->allSources, 100, source); 135 } 136 } 56 137 } 57 138 58 139 finish: 59 140 60 if (!ext SourcesTXT&& !extSourcesTXT) {141 if (!extCMF && !extSourcesTXT) { 61 142 psLogMsg ("psphot", 3, "no external sources for this readout"); 62 143 return true; 63 144 } 64 145 65 int nCMF = ext SourcesCMF ? extSourcesCMF->n: 0;146 int nCMF = extCMF ? extCMF->allSources->n : 0; 66 147 int nTXT = extSourcesTXT ? extSourcesTXT->n : 0; 67 148 68 psLogMsg ("psphot", 3, "%d external sources (%d cmf, %d text) merged to yield %ld total sources", 69 nCMF + nTXT, nCMF, nTXT, sources->n); 70 return true; 71 } 72 73 // add newly selected sources to the existing list of sources 74 bool psphotMergeSources (psArray *oldSources, psArray *newSources) { 75 76 for (int i = 0; i < newSources->n; i++) { 77 pmSource *source = newSources->data[i]; 78 psArrayAdd (oldSources, 100, source); 79 } 149 psLogMsg ("psphot", 3, "%d external sources (%d cmf, %d text) merged to yield %ld total sources", 150 nCMF + nTXT, nCMF, nTXT, sources->n); 80 151 return true; 81 152 } 82 153 83 154 // extract the input sources corresponding to this readout 155 // XXX this function needs to be updated to work with the new context of pshot inputs 84 156 psArray *psphotLoadPSFSources (pmConfig *config, const pmFPAview *view) { 157 158 bool status; 85 159 86 160 // find the currently selected readout … … 91 165 } 92 166 93 psArray *sources = psMetadataLookupPtr (NULL, readout->analysis, "PSPHOT.SOURCES"); 167 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 168 if (!detections) { 169 psLogMsg ("psphot", 3, "no psf sources for this readout"); 170 return NULL; 171 } 172 173 psArray *sources = detections->allSources; 94 174 if (!sources) { 95 175 psLogMsg ("psphot", 3, "no psf sources for this readout"); 176 return NULL; 96 177 } 97 178 … … 99 180 } 100 181 182 // this function is used to fix sources which were loaded externally, but have passed from 183 // psphotDetectionsFromSources to psphotSourceStats and are now stored on 184 // detections->newSources. 185 bool psphotRepairLoadedSources (pmConfig *config, const pmFPAview *view) { 186 187 // find the currently selected readout 188 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", 0); // File of interest 189 psAssert (file, "missing file?"); 190 191 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 192 psAssert (readout, "missing readout?"); 193 194 pmDetections *detections = psMetadataLookupPtr (NULL, readout->analysis, "PSPHOT.DETECTIONS"); 195 if (!detections) { 196 psError(PSPHOT_ERR_CONFIG, false, "missing detections"); 197 return false; 198 } 199 200 psArray *sources = detections->newSources; 201 psAssert (sources, "missing sources?"); 202 203 // peak flux is wrong : set based on previous image 204 // use the peak measured in the moments analysis: 205 for (int i = 0; i < sources->n; i++) { 206 pmSource *source = sources->data[i]; 207 source->peak->flux = source->moments->Peak; 208 } 209 210 return true; 211 } 212 101 213 // generate the detection structure for the supplied array of sources 102 pmDetections *psphotDetectionsFromSources (pmConfig *config, psArray *sources) { 214 // XXX this currently assumes there is a single input file 215 bool psphotDetectionsFromSources (pmConfig *config, const pmFPAview *view, psArray *sources) { 216 217 // find the currently selected readout 218 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", 0); // File of interest 219 psAssert (file, "missing file?"); 220 221 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 222 psAssert (readout, "missing readout?"); 103 223 104 224 pmDetections *detections = pmDetectionsAlloc(); … … 113 233 float snMin = psMetadataLookupF32(NULL, recipe, "MOMENTS_SN_MIN"); 114 234 if (!isfinite(snMin)) { 115 return NULL;235 return false; 116 236 } 117 237 … … 121 241 122 242 if (source->mode & PSF_SOURCE_MASK || !isfinite(source->psfMag)) { 243 continue; 244 } 245 246 // use the existing peak information, otherwise generate a new peak 247 if (source->peak) { 248 source->peak->assigned = false; // So the moments will be measured 249 psArrayAdd (detections->peaks, 100, source->peak); 123 250 continue; 124 251 } … … 133 260 peak->flux = flux; // this are being set wrong, but does it matter? 134 261 135 if (isfinite (source->errMag) && (source->errMag > 0.0)) {136 peak->SN = 1.0 / source->errMag; 137 } else {138 peak->SN = 0.0;139 }262 if (isfinite (source->errMag) && (source->errMag > 0.0)) { 263 peak->SN = 1.0 / source->errMag; 264 } else { 265 peak->SN = 0.0; 266 } 140 267 141 268 psArrayAdd (detections->peaks, 100, peak); … … 145 272 psLogMsg ("psphot", 3, "%ld PSF sources loaded", detections->peaks->n); 146 273 147 return detections; 274 // save detections on the readout->analysis 275 if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "psphot detectinos", detections)) { 276 psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout"); 277 return false; 278 } 279 psFree (detections); 280 return true; 148 281 } 149 282 … … 174 307 peak->flux = flux; // this are being set wrong, but does it matter? 175 308 176 if (isfinite (source->errMag) && (source->errMag > 0.0)) {177 peak->SN = 1.0 / source->errMag; 178 } else {179 peak->SN = 0.0;180 }309 if (isfinite (source->errMag) && (source->errMag > 0.0)) { 310 peak->SN = 1.0 / source->errMag; 311 } else { 312 peak->SN = 0.0; 313 } 181 314 182 315 source->peak = peak; … … 187 320 return true; 188 321 } 322 323 bool psphotCheckExtSources (pmConfig *config, const pmFPAview *view) { 324 325 bool status; 326 327 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE); 328 psAssert (recipe, "missing recipe"); 329 330 // find the currently selected readout 331 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", 0); // File of interest 332 psAssert (file, "missing file?"); 333 334 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 335 psAssert (readout, "missing readout?"); 336 337 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 338 psAssert (detections, "missing detections?"); 339 340 // XXX allSources of newSources? 341 psArray *sources = detections->allSources; 342 psAssert (sources, "missing sources?"); 343 344 if (sources->n) { 345 // the user wants to make the psf from these stars; define them as psf stars: 346 for (int i = 0; i < sources->n; i++) { 347 pmSource *source = sources->data[i]; 348 source->mode |= PM_SOURCE_MODE_PSFSTAR; 349 } 350 // force psphotChoosePSF to use all loaded sources 351 psMetadataAddS32 (recipe, PS_LIST_TAIL, "PSF_MAX_NSTARS", PS_META_REPLACE, "max number of sources for PSF model", sources->n); 352 353 // measure stats of externally specified sources 354 if (!psphotSourceStatsUpdate (sources, config, readout)) { 355 psError(PSPHOT_ERR_CONFIG, false, "failure to measure stats of existing sources"); 356 return false; 357 } 358 } else { 359 360 // find the detections (by peak and/or footprint) in the image. 361 if (!psphotFindDetections (config, view, true)) { 362 psError(PSPHOT_ERR_CONFIG, false, "unable to find detections in this image"); 363 return psphotReadoutCleanup (config, view); 364 } 365 366 // construct sources and measure basic stats 367 psphotSourceStats (config, view, true); 368 369 // find blended neighbors of very saturated stars 370 psphotDeblendSatstars (config, view); 371 372 // mark blended peaks PS_SOURCE_BLEND 373 if (!psphotBasicDeblend (config, view)) { 374 psLogMsg ("psphot", 3, "failed on deblend analysis"); 375 return psphotReadoutCleanup (config, view); 376 } 377 378 // classify sources based on moments, brightness 379 if (!psphotRoughClass (config, view)) { 380 psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image"); 381 return psphotReadoutCleanup (config, view); 382 } 383 } 384 385 return true; 386 } -
trunk/psphot/src/psphotModelBackground.c
r26452 r26894 30 30 31 31 // Generate the background model 32 static bool backgroundModel(psImage *model, // Model image 33 psImage *modelStdev, // Model stdev image 34 psMetadata *analysis, // Analysis metadata for outputs 35 pmReadout *readout, // Readout for which to generate a background model 36 psImageBinning *binning, // Binning parameters 37 const pmConfig *config // Configuration 38 ) 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 ) 39 46 { 40 47 psTimerStart ("psphot.background"); … … 138 145 139 146 // we save the binning structure for use in psphotMagnitudes 140 psMetadataAddPtr(analysis, PS_LIST_TAIL, "PSPHOT.BACKGROUND.BINNING", 141 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); 142 148 143 149 psF32 **modelData = model->data.F32; … … 304 310 psLogMsg ("psphot", PS_LOG_INFO, "built background image: %f sec\n", psTimerMark ("psphot.background")); 305 311 306 psMetadataAddF32(re cipe, PS_LIST_TAIL, "SKY_MEAN", PS_META_REPLACE, "sky mean", Value);307 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); 308 314 psLogMsg ("psphot", PS_LOG_INFO, "image sky : mean %f stdev %f", Value, ValueStdev); 309 315 … … 314 320 PS_STAT_MAX); 315 321 psImageStats (statsBck, model, NULL, 0); 316 psMetadataAddF32 (recipe, PS_LIST_TAIL, "MSKY_MN", 317 PS_META_REPLACE, "sky model mean", statsBck->sampleMean); 318 psMetadataAddF32 (recipe, PS_LIST_TAIL, "MSKY_SIG", 319 PS_META_REPLACE, "sky model stdev", statsBck->sampleStdev); 320 psMetadataAddF32 (recipe, PS_LIST_TAIL, "MSKY_MAX", 321 PS_META_REPLACE, "sky model maximum value", statsBck->max); 322 psMetadataAddF32 (recipe, PS_LIST_TAIL, "MSKY_MIN", 323 PS_META_REPLACE, "sky model minimum value", statsBck->min); 324 psMetadataAddS32 (recipe, PS_LIST_TAIL, "MSKY_NX", 325 PS_META_REPLACE, "sky model size (x)", model->numCols); 326 psMetadataAddS32 (recipe, PS_LIST_TAIL, "MSKY_NY", 327 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); 328 328 psLogMsg ("psphot", PS_LOG_INFO, "background sky : min %f mean %f max %f stdev %f", 329 329 statsBck->min, statsBck->sampleMean, statsBck->max, statsBck->sampleStdev); … … 338 338 } 339 339 340 341 342 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) 343 342 { 344 PM_ASSERT_READOUT_NON_NULL(r o, NULL);345 PM_ASSERT_READOUT_IMAGE(r o, NULL);343 PM_ASSERT_READOUT_NON_NULL(readout, NULL); 344 PM_ASSERT_READOUT_IMAGE(readout, NULL); 346 345 PS_ASSERT_PTR_NON_NULL(config, NULL); 347 346 348 psImageBinning *binning = psphotBackgroundBinning(r o->image, config); // Image binning parameters347 psImageBinning *binning = psphotBackgroundBinning(readout->image, config); // Image binning parameters 349 348 psImage *model = psImageAlloc(binning->nXruff, binning->nYruff, PS_TYPE_F32); // Background model 350 349 psImage *modelStdev = psImageAlloc(binning->nXruff, binning->nYruff, PS_TYPE_F32); // Standard deviation 351 350 352 if (! backgroundModel(model, modelStdev, ro->analysis, ro, binning, config)) {351 if (!psphotModelBackgroundReadout(model, modelStdev, readout->analysis, readout, binning, config)) { 353 352 psFree(model); 354 353 psFree(modelStdev); … … 356 355 return NULL; 357 356 } 358 359 357 psFree(modelStdev); 360 361 358 return model; 362 359 } 363 360 364 365 // generate the median in NxN boxes, clipping heavily 366 // linear interpolation to generate full-scale model 367 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) 368 363 { 369 bool status = true;370 371 364 // find the currently selected readout 372 pmFPAfile *file = psMetadataLookupPtr (&status, config->files, filename); 365 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 366 psAssert (file, "missing file?"); 367 373 368 pmFPA *inFPA = file->fpa; 374 369 pmReadout *readout = pmFPAviewThisReadout(view, inFPA); 370 psAssert (readout, "missing readout?"); 375 371 376 372 psImageBinning *binning = psphotBackgroundBinning(readout->image, config); // Image binning parameters … … 378 374 pmReadout *modelStdev = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL.STDEV", inFPA, binning); 379 375 380 if (! backgroundModel(model->image, modelStdev->image, model->analysis, readout, binning, config)) {376 if (!psphotModelBackgroundReadout(model->image, modelStdev->image, model->analysis, readout, binning, config)) { 381 377 psError(PS_ERR_UNKNOWN, false, "Unable to generate background model"); 382 378 return false; … … 386 382 return true; 387 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 } -
trunk/psphot/src/psphotModelTest.c
r24588 r26894 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; -
trunk/psphot/src/psphotMomentsStudy.c
r24585 r26894 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 -
trunk/psphot/src/psphotOutput.c
r25755 r26894 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; -
trunk/psphot/src/psphotPSFConvModel.c
r25755 r26894 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: -
trunk/psphot/src/psphotParseCamera.c
r21458 r26894 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 -
trunk/psphot/src/psphotRadiusChecks.c
r25755 r26894 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; -
trunk/psphot/src/psphotReadout.c
r25755 r26894 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 psphotSetMaskAndVariance (config, view); 45 37 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); 38 return psphotReadoutCleanup(config, view); 39 } 51 40 52 41 // 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);42 if (!psphotModelBackground (config, view)) { 43 return psphotReadoutCleanup (config, view); 44 } 45 if (!psphotSubtractBackground (config, view)) { 46 return psphotReadoutCleanup (config, view); 58 47 } 59 48 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); 49 return psphotReadoutCleanup (config, view); 50 } 51 52 // load the psf model, if suppled. FWHM_X,FWHM_Y,etc are determined and saved on 53 // readout->analysis XXX this function currently only works with a single PSPHOT.INPUT 54 if (!psphotLoadPSF (config, view)) { 55 psError (PSPHOT_ERR_UNKNOWN, false, "error loading psf model"); 56 return psphotReadoutCleanup (config, view); 57 } 74 58 75 59 // 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; 60 if (!psphotFindDetections (config, view, true)) { // pass 1 61 // this only happens if we had an error in psphotFindDetections 62 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis"); 63 return psphotReadoutCleanup (config, view); 64 } 65 66 // construct sources and measure basic stats (saved on detections->newSources) 67 if (!psphotSourceStats (config, view, true)) { // pass 1 68 psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources"); 69 return psphotReadoutCleanup (config, view); 70 } 85 71 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); 72 return psphotReadoutCleanup(config, view); 73 } 74 75 // find blended neighbors of very saturated stars (detections->newSources) 76 if (!psphotDeblendSatstars (config, view)) { 77 psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis"); 78 return psphotReadoutCleanup (config, view); 79 } 80 81 // mark blended peaks PS_SOURCE_BLEND (detections->newSources) 82 if (!psphotBasicDeblend (config, view)) { 83 psError (PSPHOT_ERR_UNKNOWN, false, "failed on deblend analysis"); 84 return psphotReadoutCleanup (config, view); 85 } 86 87 // classify sources based on moments, brightness. if a PSF model has been loaded, the PSF 88 // clump defined for it is used not measured (detections->newSources) 89 if (!psphotRoughClass (config, view)) { // pass 1 90 psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough classifications"); 91 return psphotReadoutCleanup (config, view); 103 92 } 104 93 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; 94 return psphotReadoutCleanup(config, view); 95 } 96 97 // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources) 98 if (!psphotImageQuality (config, view)) { // pass 1 99 psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality"); 100 return psphotReadoutCleanup(config, view); 101 } 102 103 // use bright stellar objects to measure PSF if we were supplied a PSF for any input file, 104 // this step is skipped 105 if (!psphotChoosePSF (config, view)) { // pass 1 106 psLogMsg ("psphot", 3, "failure to construct a psf model"); 107 return psphotReadoutCleanup (config, view); 124 108 } 125 109 if (!strcasecmp (breakPt, "PSFMODEL")) { 126 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources); 127 } 128 psphotVisualShowPSFModel (readout, psf); 110 return psphotReadoutCleanup (config, view); 111 } 129 112 130 113 // 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); 114 // XXX fix this in the new multi-input context 115 // psphotLoadExtSources (config, view); // pass 1 116 117 // construct an initial model for each object, set the radius to fitRadius, set circular 118 // fit mask (detections->newSources) 119 psphotGuessModels (config, view); // pass 1 120 121 // merge the newly selected sources into the existing list 122 // NOTE: merge OLD and NEW 123 psphotMergeSources (config, view); 135 124 136 125 // 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); 126 psphotFitSourcesLinear (config, view, false); // pass 1 (detections->allSources) 127 128 // identify CRs and extended sources (only unmeasured sources are measured) 129 psphotSourceSize (config, view, true); // pass 1 (detections->allSources) 145 130 if (!strcasecmp (breakPt, "ENSEMBLE")) { 146 131 goto finish; 147 132 } 148 psphotVisualShowSatStars (recipe, psf, sources);149 133 150 134 // non-linear PSF and EXT fit to brighter sources 151 135 // replace model flux, adjust mask as needed, fit, subtract the models (full stamp) 152 psphotBlendFit (config, readout, sources, psf);136 psphotBlendFit (config, view); // pass 1 (detections->allSources) 153 137 154 138 // replace all sources 155 psphotReplaceAllSources ( sources, recipe);139 psphotReplaceAllSources (config, view); // pass 1 (detections->allSources) 156 140 157 141 // linear fit to include all sources (subtract again) 158 psphotFitSourcesLinear (readout, sources, recipe, psf, TRUE); 142 // NOTE : apply to ALL sources (extended + psf) 143 psphotFitSourcesLinear (config, view, true); // pass 2 (detections->allSources) 159 144 160 145 // 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 146 if (!strcasecmp (breakPt, "PASS1")) goto pass1finish; 147 148 // NOTE: possibly re-measure background model here with objects subtracted / or masked 165 149 166 150 // add noise for subtracted objects 167 psphotAddNoise (readout, sources, recipe); 168 169 // find fainter sources (pass 2) 170 detections = psphotFindDetections (detections, readout, recipe); 151 psphotAddNoise (config, view); // pass 1 (detections->allSources) 152 153 // find fainter sources 154 // NOTE: finds new peaks and new footprints, OLD and FULL set are saved on detections 155 psphotFindDetections (config, view, false); // pass 2 (detections->peaks, detections->footprints) 171 156 172 157 // remove noise for subtracted objects (ie, return to normal noise level) 173 psphotSubNoise (readout, sources, recipe); 158 // NOTE: this needs to operate only on the OLD sources 159 psphotSubNoise (config, view); // pass 1 (detections->allSources) 174 160 175 161 // define new sources based on only the new peaks 176 psArray *newSources = psphotSourceStats (config, readout, detections, false); 162 // NOTE: new sources are saved on detections->newSources 163 psphotSourceStats (config, view, false); // pass 2 (detections->newSources) 177 164 178 165 // set source type 179 if (!psphotRoughClass (readout, newSources, recipe, havePSF)) { 166 // NOTE: apply only to detections->newSources 167 if (!psphotRoughClass (config, view)) { // pass 2 (detections->newSources) 180 168 psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image"); 181 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);169 return psphotReadoutCleanup (config, view); 182 170 } 183 171 184 172 // create full input models, set the radius to fitRadius, set circular fit mask 185 psphotGuessModels (config, readout, newSources, psf); 173 // NOTE: apply only to detections->newSources 174 psphotGuessModels (config, view); // pass 2 (detections->newSources) 186 175 187 176 // replace all sources so fit below applies to all at once 188 psphotReplaceAllSources (sources, recipe); 177 // NOTE: apply only to OLD sources (which have been subtracted) 178 psphotReplaceAllSources (config, view); // pass 2 189 179 190 180 // 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); 181 // NOTE: merge OLD and NEW 182 // XXX check on free of sources... 183 psphotMergeSources (config, view); // (detections->newSources + detections->allSources -> detections->allSources) 184 185 // NOTE: apply to ALL sources 186 psphotFitSourcesLinear (config, view, true); // pass 3 (detections->allSources) 196 187 197 188 pass1finish: 198 189 199 190 // 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);191 // NOTE: applies only to NEW (unmeasured) sources 192 psphotSourceSize (config, view, false); // pass 2 (detections->allSources) 193 194 psphotExtendedSourceAnalysis (config, view); // pass 1 (detections->allSources) 195 psphotExtendedSourceFits (config, view); // pass 1 (detections->allSources) 205 196 206 197 finish: … … 210 201 211 202 // measure aperture photometry corrections 212 if (!psphotApResid (config, readout, sources, psf)) {203 if (!psphotApResid (config, view)) { // pass 1 (detections->allSources) 213 204 psLogMsg ("psphot", 3, "failed on psphotApResid"); 214 return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);205 return psphotReadoutCleanup (config, view); 215 206 } 216 207 217 208 // calculate source magnitudes 218 psphotMagnitudes(config, readout, view, sources, psf);219 220 if (!psphotEfficiency(config, readout, view, psf, recipe, sources)) {209 psphotMagnitudes(config, view); // pass 1 (detections->allSources) 210 211 if (!psphotEfficiency(config, view)) { // pass 1 221 212 psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources"); 222 213 psErrorClear(); … … 227 218 228 219 // replace background in residual image 229 psphotSkyReplace (config, view); 220 psphotSkyReplace (config, view); // pass 1 230 221 231 222 // drop the references to the image pixels held by each source 232 psphotSourceFreePixels ( sources);223 psphotSourceFreePixels (config, view); // pass 1 233 224 234 225 // create the exported-metadata and free local data 235 return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);226 return psphotReadoutCleanup(config, view); 236 227 } 237 -
trunk/psphot/src/psphotReadoutCleanup.c
r24203 r26894 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->allSources; 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 74 // XXX not sure we want / need this test 42 75 if (!psf) { 43 76 bool mdok; // Status of MD lookup … … 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 } -
trunk/psphot/src/psphotReadoutFindPSF.c
r25755 r26894 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 } -
trunk/psphot/src/psphotReadoutKnownSources.c
r25755 r26894 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 } -
trunk/psphot/src/psphotReadoutMinimal.c
r25755 r26894 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 } -
trunk/psphot/src/psphotReplaceUnfit.c
r25755 r26894 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 -
trunk/psphot/src/psphotRoughClass.c
r25989 r26894 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 // loop over the available readouts 22 for (int i = 0; i < num; i++) { 23 if (!psphotRoughClassReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 24 psError (PSPHOT_ERR_CONFIG, false, "failed on rough classification for PSPHOT.INPUT entry %d", i); 25 return false; 26 } 27 } 28 return true; 29 } 30 31 bool psphotRoughClassReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe) { 13 32 14 33 bool status; 15 34 16 35 psTimerStart ("psphot.rough"); 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 // if we have a PSF, use the existing PSF clump region below 45 bool havePSF = false; 46 if (psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF")) { 47 havePSF = 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 rough classification"); 58 return true; 59 } 17 60 18 61 // we make this measurement on a NxM grid of regions across the readout … … 75 118 // determine the PSF parameters from the source moment values 76 119 // XXX why not save the psfClump as a PTR? 77 psfClump = pmSourcePSFClump (region, sources, recipe); 120 121 float PSF_SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM"); 122 float MOMENTS_AR_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_AR_MAX"); psAssert (status, "missing MOMENTS_AR_MAX"); 123 124 float PSF_CLUMP_GRID_SCALE = psMetadataLookupF32(&status, analysis, "PSF_CLUMP_GRID_SCALE"); 125 if (!status) { 126 PSF_CLUMP_GRID_SCALE = psMetadataLookupF32(&status, recipe, "PSF_CLUMP_GRID_SCALE"); 127 psAssert (status, "missing PSF_CLUMP_GRID_SCALE"); 128 } 129 float MOMENTS_SX_MAX = psMetadataLookupF32(&status, analysis, "MOMENTS_SX_MAX"); 130 if (!status) { 131 MOMENTS_SX_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_SX_MAX"); 132 psAssert (status, "missing MOMENTS_SX_MAX"); 133 } 134 float MOMENTS_SY_MAX = psMetadataLookupF32(&status, analysis, "MOMENTS_SY_MAX"); 135 if (!status) { 136 MOMENTS_SY_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_SY_MAX"); 137 psAssert (status, "missing MOMENTS_SY_MAX"); 138 } 139 140 psfClump = pmSourcePSFClump (NULL, region, sources, PSF_SN_LIM, PSF_CLUMP_GRID_SCALE, MOMENTS_SX_MAX, MOMENTS_SY_MAX, MOMENTS_AR_MAX); 141 78 142 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.X", PS_META_REPLACE, "psf clump center", psfClump.X); 79 143 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.Y", PS_META_REPLACE, "psf clump center", psfClump.Y); … … 103 167 psLogMsg ("psphot", 3, "psf clump DX, DY: %f, %f\n", psfClump.dX, psfClump.dY); 104 168 169 // get basic parameters, or set defaults 170 float PSF_SN_LIM = psMetadataLookupF32 (&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM"); 171 float PSF_CLUMP_NSIGMA = psMetadataLookupF32 (&status, recipe, "PSF_CLUMP_NSIGMA"); psAssert (status, "missing PSF_CLUMP_NSIGMA"); 172 105 173 // group into STAR, COSMIC, EXTENDED, SATURATED, etc. 106 if (!pmSourceRoughClass (region, sources, recipe, psfClump, maskSat)) {174 if (!pmSourceRoughClass (region, sources, PSF_SN_LIM, PSF_CLUMP_NSIGMA, psfClump, maskSat)) { 107 175 psError(PSPHOT_ERR_PROG, false, "programming error calling pmSourceRoughClass"); 108 176 return false; -
trunk/psphot/src/psphotSetThreads.c
r25755 r26894 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); -
trunk/psphot/src/psphotSignificanceImage.c
r25383 r26894 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 -
trunk/psphot/src/psphotSkyReplace.c
r21183 r26894 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 // loop over the available readouts 11 for (int i = 0; i < num; i++) { 12 if (!psphotSkyReplaceReadout (config, view, "PSPHOT.INPUT", i)) { 13 psError (PSPHOT_ERR_CONFIG, false, "failed to replace sky for PSPHOT.INPUT entry %d", i); 14 return false; 15 } 16 } 17 return true; 18 } 2 19 3 20 // XXX make this an option? 4 21 // in order to successfully replace the sky, we must define a corresponding file... 5 bool psphotSkyReplace (pmConfig *config, const pmFPAview *view) {22 bool psphotSkyReplaceReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index) { 6 23 7 24 psTimerStart ("psphot.skyreplace"); 8 25 9 26 // find the currently selected readout 10 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT"); 11 if (readout == NULL) psAbort("input not defined"); 27 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 28 psAssert (file, "missing file?"); 29 30 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 31 psAssert (readout, "missing readout?"); 12 32 13 33 // select background pixels, from output background file, or create -
trunk/psphot/src/psphotSourceFits.c
r25755 r26894 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)) { -
trunk/psphot/src/psphotSourceFreePixels.c
r12792 r26894 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 } -
trunk/psphot/src/psphotSourceSize.c
r26618 r26894 15 15 } psphotSourceSizeOptions; 16 16 17 // local functions: 17 18 bool psphotSourceSizePSF (psphotSourceSizeOptions *options, psArray *sources, pmPSF *psf); 18 19 bool psphotSourceClass (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options); 19 20 bool psphotSourceClassRegion (psRegion *region, pmPSFClump *psfClump, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options); 20 21 bool psphotSourceSizeCR (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options); 21 bool psphotMaskCosmicRay (p sImage *mask, pmSource *source, psImageMaskType maskVal, psImageMaskType crMask);22 bool psphotMaskCosmicRay Isophot (pmSource *source, psImageMaskType maskVal, psImageMaskType crMask);22 bool psphotMaskCosmicRay (pmReadout *readout, pmSource *source, psImageMaskType maskVal); 23 bool psphotMaskCosmicRayFootprintCheck (psArray *sources); 23 24 24 25 // we need to call this function after sources have been fitted to the PSF model and … … 28 29 // deviation from the psf model at the r = FWHM/2 position 29 30 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) 31 // for now, let's store the detections on the readout->analysis for each readout 32 bool psphotSourceSize (pmConfig *config, const pmFPAview *view, bool getPSFsize) 33 { 34 bool status = true; 35 36 // select the appropriate recipe information 37 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 38 psAssert (recipe, "missing recipe?"); 39 40 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 41 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 42 43 // loop over the available readouts 44 for (int i = 0; i < num; i++) { 45 if (!psphotSourceSizeReadout (config, view, "PSPHOT.INPUT", i, recipe, getPSFsize)) { 46 psError (PSPHOT_ERR_CONFIG, false, "failed on source size analysis for PSPHOT.INPUT entry %d", i); 47 return false; 48 } 49 } 50 return true; 51 } 52 53 // this function use an internal flag to mark sources which have already been measured 54 bool psphotSourceSizeReadout(pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool getPSFsize) 32 55 { 33 56 bool status; … … 35 58 36 59 psTimerStart ("psphot.size"); 60 61 // find the currently selected readout 62 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 63 psAssert (file, "missing file?"); 64 65 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 66 psAssert (readout, "missing readout?"); 67 68 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 69 psAssert (detections, "missing detections?"); 70 71 psArray *sources = detections->allSources; 72 psAssert (sources, "missing sources?"); 73 74 if (!sources->n) { 75 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping source size"); 76 return true; 77 } 78 79 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); 80 psAssert (psf, "missing psf?"); 37 81 38 82 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) … … 70 114 71 115 // 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 test116 // of an object. We need to model this distribution for the PSF stars before we can test 73 117 // the significance for a specific object 74 118 // XXX move this to the code that generates the PSF? 75 119 // XXX store the results on pmPSF? 76 psphotSourceSizePSF (&options, sources, psf); 120 121 // XXX this should only be done on the first pass (ie, if we have newSources or allSources?) 122 if (getPSFsize) { 123 psphotSourceSizePSF (&options, sources, psf); 124 } 77 125 78 126 // classify the sources based on ApResid and Moments (extended sources) 127 // NOTE: only sources not already measured !(source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) 79 128 psphotSourceClass(readout, sources, recipe, psf, &options); 80 129 130 // NOTE: only sources not already measured !(source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) 81 131 psphotSourceSizeCR (readout, sources, &options); 82 132 83 psLogMsg ("psphot.size", PS_LOG_INFO, "measure source sizes for %ld sources: %f sec\n", sources->n - first, psTimerMark ("psphot.size")); 133 // XXX fix this (was source->n - first) 134 psLogMsg ("psphot.size", PS_LOG_INFO, "measure source sizes for %ld sources: %f sec\n", sources->n, psTimerMark ("psphot.size")); 84 135 85 136 psphotVisualPlotSourceSize (recipe, readout->analysis, sources); 86 137 psphotVisualShowSourceSize (readout, sources); 87 138 psphotVisualPlotApResid (sources, options.ApResid, options.ApSysErr); 88 89 return true; 90 } 91 92 bool psphotMaskCosmicRay (psImage *mask, pmSource *source, psImageMaskType maskVal, psImageMaskType crMask) { 139 psphotVisualShowSatStars (recipe, psf, sources); 140 141 return true; 142 } 143 144 // model the apmifit distribution for the psf stars: 145 bool psphotSourceSizePSF (psphotSourceSizeOptions *options, psArray *sources, pmPSF *psf) { 146 147 // select stats from the psf stars 148 psVector *Ap = psVectorAllocEmpty (100, PS_TYPE_F32); 149 psVector *ApErr = psVectorAllocEmpty (100, PS_TYPE_F32); 150 151 psImageMaskType maskVal = options->maskVal | options->markVal; 152 153 // XXX why PHOT_WEIGHT?? 154 pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_WEIGHT; 155 156 for (int i = 0; i < sources->n; i++) { 157 pmSource *source = sources->data[i]; 158 if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue; 159 160 // replace object in image 161 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) { 162 pmSourceAdd (source, PM_MODEL_OP_FULL, options->maskVal); 163 } 164 165 // clear the mask bit and set the circular mask pixels 166 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal)); 167 psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, source->apRadius, "OR", options->markVal); 168 169 // XXX can we test if psfMag is set and calculate only if needed? 170 pmSourceMagnitudes (source, psf, photMode, maskVal); // maskVal includes markVal 171 172 // clear the mask bit 173 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal)); 174 175 // re-subtract the object, leave local sky 176 pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal); 177 178 float apMag = -2.5*log10(source->moments->Sum); 179 float dMag = source->psfMag - apMag; 180 181 psVectorAppend (Ap, dMag); 182 psVectorAppend (ApErr, source->errMag); 183 } 184 185 // model the distribution as a mean or median value and a systematic error from that value: 186 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); 187 psVectorStats (stats, Ap, NULL, NULL, 0); 188 189 psVector *dAp = psVectorAlloc (Ap->n, PS_TYPE_F32); 190 for (int i = 0; i < Ap->n; i++) { 191 dAp->data.F32[i] = Ap->data.F32[i] - stats->robustMedian; 192 } 193 194 options->ApResid = stats->robustMedian; 195 options->ApSysErr = psVectorSystematicError(dAp, ApErr, 0.05); 196 // XXX this is quite arbitrary... 197 if (!isfinite(options->ApSysErr)) options->ApSysErr = 0.01; 198 psLogMsg ("psphot", PS_LOG_DETAIL, "psf - Sum: %f +/- %f\n", options->ApResid, options->ApSysErr); 199 200 psFree (Ap); 201 psFree (ApErr); 202 psFree (stats); 203 psFree (dAp); 204 205 return true; 206 } 207 208 // classify sources based on the combination of psf-mag, Mxx, Myy 209 bool psphotSourceClass (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options) { 210 211 bool status; 212 pmPSFClump psfClump; 213 char regionName[64]; 214 215 psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4s %4s %4s %4s %4s %4s", "Npsf", "Next", "Nsat", "Ncr", "Nmiss", "Nskip"); 216 217 int nRegions = psMetadataLookupS32 (&status, readout->analysis, "PSF.CLUMP.NREGIONS"); 218 for (int i = 0; i < nRegions; i ++) { 219 snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", i); 220 psMetadata *regionMD = psMetadataLookupPtr (&status, readout->analysis, regionName); 221 psAssert (regionMD, "regions must be defined by earlier call to psphotRoughClassRegion"); 222 223 psRegion *region = psMetadataLookupPtr (&status, regionMD, "REGION"); 224 psAssert (region, "regions must be defined by earlier call to psphotRoughClassRegion"); 225 226 // pull FWHM_X,Y from the recipe, use to define psfClump.X,Y 227 psfClump.X = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X"); psAssert (status, "missing PSF.CLUMP.X"); 228 psfClump.Y = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y"); psAssert (status, "missing PSF.CLUMP.Y"); 229 psfClump.dX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX"); psAssert (status, "missing PSF.CLUMP.DX"); 230 psfClump.dY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY"); psAssert (status, "missing PSF.CLUMP.DY"); 231 232 if ((psfClump.X < 0) || (psfClump.Y < 0) || !psfClump.X || !psfClump.Y || isnan(psfClump.X) || isnan(psfClump.Y)) { 233 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); 234 continue; 235 } 236 237 if (!psphotSourceClassRegion (region, &psfClump, sources, recipe, psf, options)) { 238 psLogMsg ("psphot", 4, "Failed to determine source classification for region %f,%f - %f,%f\n", region->x0, region->y0, region->x1, region->y1); 239 continue; 240 } 241 } 242 243 return true; 244 } 245 246 bool psphotSourceClassRegion (psRegion *region, pmPSFClump *psfClump, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options) { 247 248 PS_ASSERT_PTR_NON_NULL(sources, false); 249 PS_ASSERT_PTR_NON_NULL(recipe, false); 250 251 int Nsat = 0; 252 int Next = 0; 253 int Npsf = 0; 254 int Ncr = 0; 255 int Nmiss = 0; 256 int Nskip = 0; 257 258 pmSourceMode noMoments = PM_SOURCE_MODE_MOMENTS_FAILURE | PM_SOURCE_MODE_SKYVAR_FAILURE | PM_SOURCE_MODE_SKY_FAILURE | PM_SOURCE_MODE_BELOW_MOMENTS_SN; 259 pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_WEIGHT; 260 261 psImageMaskType maskVal = options->maskVal | options->markVal; 262 263 for (psS32 i = 0 ; i < sources->n ; i++) { 264 265 pmSource *source = (pmSource *) sources->data[i]; 266 267 // psfClumps are found for image subregions: 268 // skip sources not in this region 269 if (source->peak->x < region->x0) continue; 270 if (source->peak->x >= region->x1) continue; 271 if (source->peak->y < region->y0) continue; 272 if (source->peak->y >= region->y1) continue; 273 274 // skip source if it was already measured 275 if (source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) { 276 psTrace("psphot", 7, "Not calculating source size since it has already been measured\n"); 277 continue; 278 } 279 280 // source must have been subtracted 281 if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) { 282 source->mode |= PM_SOURCE_MODE_SIZE_SKIPPED; 283 psTrace("psphot", 7, "Not calculating source size since source is not subtracted\n"); 284 continue; 285 } 286 287 // we are basically classifying by moments; use the default if not found 288 psAssert (source->moments, "why is this source missing moments?"); 289 if (source->mode & noMoments) { 290 Nskip ++; 291 continue; 292 } 293 294 psF32 Mxx = source->moments->Mxx; 295 psF32 Myy = source->moments->Myy; 296 297 // replace object in image 298 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) { 299 pmSourceAdd (source, PM_MODEL_OP_FULL, options->maskVal); 300 } 301 302 // clear the mask bit and set the circular mask pixels 303 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal)); 304 psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, source->apRadius, "OR", options->markVal); 305 306 // XXX can we test if psfMag is set and calculate only if needed? 307 pmSourceMagnitudes (source, psf, photMode, maskVal); // maskVal includes markVal 308 309 // clear the mask bit 310 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal)); 311 312 // re-subtract the object, leave local sky 313 pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal); 314 315 float apMag = -2.5*log10(source->moments->Sum); 316 float dMag = source->psfMag - apMag; 317 float nSigma = (dMag - options->ApResid) / hypot(source->errMag, options->ApSysErr); 318 319 source->extNsigma = nSigma; 320 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED; 321 322 // Anything within this region is a probably PSF-like object. Saturated stars may land 323 // in this region, but are detected elsewhere on the basis of their peak value. 324 bool isPSF = ((fabs(nSigma) < options->nSigmaApResid) && 325 (fabs(Mxx - psfClump->X) < options->nSigmaMoments*psfClump->dX) && 326 (fabs(Myy - psfClump->Y) < options->nSigmaMoments*psfClump->dY)); 327 if (isPSF) { 328 psTrace("psphot.czw",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g PSF\t%g %g\n", 329 source->peak->xf,source->peak->yf,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigma, 330 options->nSigmaApResid,options->nSigmaMoments); 331 Npsf ++; 332 continue; 333 } 334 335 // Defects may not always match CRs from peak curvature analysis 336 // Defects may also be marked as SATSTAR -- XXX deactivate this flag? 337 // XXX this rule is not great 338 if ((Mxx < psfClump->X) || (Myy < psfClump->Y)) { 339 340 psTrace("psphot.czw",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g CR\t%g %g\n", 341 source->peak->xf,source->peak->yf,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigma, 342 options->nSigmaApResid,options->nSigmaMoments); 343 source->mode |= PM_SOURCE_MODE_DEFECT; 344 Ncr ++; 345 continue; 346 } 347 348 // saturated star (determined in PSF fit). These may also be saturated galaxies, or 349 // just large saturated regions. 350 if (source->mode & PM_SOURCE_MODE_SATSTAR) { 351 psTrace("psphot.czw",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g SAT\t%g %g\n", 352 source->peak->xf,source->peak->yf,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigma, 353 options->nSigmaApResid,options->nSigmaMoments); 354 355 Nsat ++; 356 continue; 357 } 358 359 // XXX allow the Mxx, Myy to be less than psfClump->X,Y (by some nSigma)? 360 bool isEXT = (nSigma > options->nSigmaApResid) || ((Mxx > psfClump->X) && (Myy > psfClump->Y)); 361 if (isEXT) { 362 psTrace("psphot.czw",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g Ext\t%g %g\n", 363 source->peak->xf,source->peak->yf,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigma, 364 options->nSigmaApResid,options->nSigmaMoments); 365 366 source->mode |= PM_SOURCE_MODE_EXT_LIMIT; 367 Next ++; 368 continue; 369 } 370 psTrace("psphot.czw",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g Unk\t%g %g\n", 371 source->peak->xf,source->peak->yf,Mxx,Myy,psfClump->X,psfClump->Y,psfClump->dX,psfClump->dY,apMag,dMag,nSigma, 372 options->nSigmaApResid,options->nSigmaMoments); 373 374 psWarning ("sourse size was missed for %f,%f : %f %f -- %f\n", source->peak->xf, source->peak->yf, Mxx, Myy, nSigma); 375 Nmiss ++; 376 } 377 378 psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4d %4d %4d %4d %4d %4d", Npsf, Next, Nsat, Ncr, Nmiss, Nskip); 379 380 return true; 381 } 382 383 // given an object suspected to be a defect, generate a pixel mask using the Lapacian transform 384 // if enough of the object is detected as 'sharp', consider the object a cosmic ray 385 bool psphotSourceSizeCR (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options) { 386 387 for (int i = 0; i < sources->n; i++) { 388 pmSource *source = sources->data[i]; 389 390 // skip source if it was already measured 391 if (source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) { 392 psTrace("psphot", 7, "Not calculating source size since it has already been measured\n"); 393 continue; 394 } 395 396 // Integer position of peak 397 int xPeak = source->peak->xf - source->pixels->col0 + 0.5; 398 int yPeak = source->peak->yf - source->pixels->row0 + 0.5; 399 400 // Skip sources which are too close to a boundary. These are mostly caught as DEFECT 401 if (xPeak < 1 || xPeak > source->pixels->numCols - 2 || 402 yPeak < 1 || yPeak > source->pixels->numRows - 2) { 403 psTrace("psphot", 7, "Not calculating crNsigma due to edge\n"); 404 // psTrace("psphot.czw", 2, "Not calculating crNsigma due to edge\n"); 405 continue; 406 } 407 408 // this source is thought to be a cosmic ray. flag the detection and mask the pixels 409 if (source->mode & PM_SOURCE_MODE_DEFECT) { 410 // XXX this is running slowly and is too agressive, but it more-or-less works 411 // psphotMaskCosmicRayCZW(readout, source, options->crMask); 412 413 // XXX these are the old versions which we are not using 414 // psphotMaskCosmicRay (readout->mask, source, maskVal, crMask); 415 // psphotMaskCosmicRay_Old (source, maskVal, crMask); 416 } 417 } 418 419 // now that we have masked pixels associated with CRs, we can grow the mask 420 if (options->grow > 0) { 421 bool oldThreads = psImageConvolveSetThreads(true); // Old value of threading for psImageConvolveMask 422 psImage *newMask = psImageConvolveMask(NULL, readout->mask, options->crMask, options->crMask, -options->grow, options->grow, -options->grow, options->grow); 423 psImageConvolveSetThreads(oldThreads); 424 if (!newMask) { 425 psError(PS_ERR_UNKNOWN, false, "Unable to grow CR mask"); 426 return false; 427 } 428 psFree(readout->mask); 429 readout->mask = newMask; 430 } 431 432 // XXX test : save the mask image 433 if (0) { 434 psphotSaveImage (NULL, readout->mask, "mask.fits"); 435 } 436 return true; 437 } 438 439 // Comments by CZW 20091209 : Mechanics of how to identify CR pixels taken from "Cosmic-Ray 440 // Rejection by Laplacian Edge Detection" by Pieter van Dokkum, arXiv:astro-ph/0108003. This 441 // does no repair or recovery of the CR pixels, it only masks them out. My test code can be 442 // found at /data/ipp031.0/watersc1/psphot.20091209/algo_check.c 443 bool psphotMaskCosmicRay (pmReadout *readout, pmSource *source, psImageMaskType maskVal) { 444 445 // Get the actual images and information about the peak. 446 psImage *mask = readout->mask; 447 pmPeak *peak = source->peak; 448 pmFootprint *footprint = peak->footprint; 449 450 int xm = footprint->bbox.x0; 451 int xM = footprint->bbox.x1; 452 int ym = footprint->bbox.y0; 453 int yM = footprint->bbox.y1; 454 455 if (xm < 0) { xm = 0; } 456 if (ym < 0) { ym = 0; } 457 if (xM > mask->numCols) { xM = mask->numCols; } 458 if (yM > mask->numRows) { yM = mask->numRows; } 459 int dx = xM - xm; 460 int dy = yM - ym; 461 462 // Bounding boxes are inclusive of final pixel 463 // XXX ensure dx,dy do not become too large here 464 dx++; 465 dy++; 466 467 psImage *image= readout->image; 468 psImage *variance = readout->variance; 469 470 int binning = 1; 471 float sigma_thresh = 2.0; 472 int iteration = 0; 473 int max_iter = 5; 474 float noise_factor = 5.0 / 4.0; // Intrinsic to the Laplacian making noise spikes spikier. 475 476 // Temporary images. 477 psImage *mypix = psImageAlloc(dx,dy,image->type.type); 478 psImage *myvar = psImageAlloc(dx,dy,image->type.type); 479 psImage *binned = psImageAlloc(dx * binning,dy * binning,image->type.type); 480 psImage *conved = psImageAlloc(dx * binning,dy * binning,image->type.type); 481 psImage *edges = psImageAlloc(dx,dy,image->type.type); 482 psImage *mymask = psImageAlloc(dx,dy,PS_TYPE_IMAGE_MASK); 483 484 int x,y; 485 // Load my copy of things. 486 for (x = 0; x < dx; x++) { 487 for (y = 0; y < dy; y++) { 488 psImageSet(mypix,x,y,psImageGet(image,x+xm,y+ym)); 489 psImageSet(myvar,x,y,psImageGet(variance,x+xm,y+ym)); 490 mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = 0x00; 491 } 492 } 493 // Mask so I can see on the output image where the footprint is. 494 for (int i = 0; i < footprint->spans->n; i++) { 495 pmSpan *sp = footprint->spans->data[i]; 496 for (int j = sp->x0; j <= sp->x1; j++) { 497 y = sp->y - ym; 498 x = j - xm; 499 mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= 0x01; 500 } 501 } 502 503 int CRpix_count = 0; 504 do { 505 CRpix_count = 0; 506 // Zero out my temp images. 507 for (x = 0; x < binning * dx; x++) { 508 for (y = 0; y < binning * dy; y++) { 509 psImageSet(binned,x,y,0.0); 510 psImageSet(conved,x,y,0.0); 511 psImageSet(edges,x/binning,y/ binning,0.0); 512 } 513 } 514 // Make subsampled image. Maybe this should be called "unbinned" or something 515 for (x = 0; x < binning * dx; x++) { 516 for (y = 0; y < binning * dy; y++) { 517 psImageSet(binned,x,y,psImageGet(mypix,x / binning,y / binning)); 518 } 519 } 520 // Apply Laplace transform (kernel = [[0 -0.25 0][-0.25 1 -0.25][0 -0.25 0]]), clipping at zero 521 for (x = 1; x < dx - 1; x++) { 522 for (y = 1; y < dy - 1; y++) { 523 psImageSet(conved,x,y,psImageGet(binned,x,y) - 0.25 * 524 (psImageGet(binned,x-1,y) + psImageGet(binned,x+1,y) + 525 psImageGet(binned,x,y-1) + psImageGet(binned,x,y+1))); 526 if (psImageGet(conved,x,y) < 0.0) { 527 psImageSet(conved,x,y,0.0); 528 } 529 } 530 } 531 // Create an edge map by rebinning 532 for (x = 0; x < binning * dx; x++) { 533 for (y = 0; y < binning * dy; y++) { 534 psImageSet(edges,x / binning, y / binning, 535 psImageGet(edges, x / binning, y / binning) + 536 psImageGet(conved,x,y)); 537 } 538 } 539 // Modify my mask if we're above the significance threshold 540 for (x = 0; x < dx; x++) { 541 for (y = 0; y < dy; y++) { 542 if ( psImageGet(edges,x,y) / (binning * sqrt(noise_factor * psImageGet(myvar,x,y))) > sigma_thresh ) { 543 if (mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & 0x01) { 544 mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] |= 0x40; 545 CRpix_count++; 546 } 547 } 548 } 549 } 550 551 // "Repair" Masked pixels for the next round. 552 for (x = 1; x < dx - 1; x++) { 553 for (y = 1; y < dy - 1; y++) { 554 if (mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & 0x40) { 555 psImageSet(mypix,x,y,0.25 * 556 (psImageGet(mypix,x-1,y) + psImageGet(mypix,x+1,y) + 557 psImageGet(mypix,x,y-1) + psImageGet(mypix,x,y+1))); 558 } 559 } 560 } 561 562 # if 0 563 if ((psTraceGetLevel("psphot.czw") >= 2)&&(abs(xm - 2770) < 5)&&(abs(ym - 2581) < 5)&&(iteration == 0)) { 564 psTrace("psphot.czw",2,"TRACEMOTRON %d %d %d %d %d\n",xm,ym,dx,dy,iteration); 565 psphotSaveImage (NULL, mypix, "czw.pix.fits"); 566 psphotSaveImage (NULL, myvar, "czw.var.fits"); 567 psphotSaveImage (NULL, binned, "czw.binn.fits"); 568 psphotSaveImage (NULL, conved, "czw.conv.fits"); 569 psphotSaveImage (NULL, edges, "czw.edge.fits"); 570 psphotSaveImage (NULL, mymask, "czw.mask.fits"); 571 } 572 # endif 573 574 psTrace("psphot.czw",2,"Iter: %d Count: %d",iteration,CRpix_count); 575 iteration++; 576 } while ((iteration < max_iter)&&(CRpix_count > 0)); 577 578 // A solitary masked pixel is likely a lie. Remove those. 579 for (x = 0; x < dx; x++) { 580 for (y = 0; y < dy; y++) { 581 if (mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & 0x40) { 582 if ((x-1 >= 0)&&(mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x-1] & 0x40)) { 583 continue; 584 } 585 if ((y-1 >= 0)&&(mymask->data.PS_TYPE_IMAGE_MASK_DATA[y-1][x] & 0x40)) { 586 continue; 587 } 588 if ((x+1 < dx)&&(mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x+1] & 0x40)) { 589 continue; 590 } 591 if ((y+1 < dy)&&(mymask->data.PS_TYPE_IMAGE_MASK_DATA[y+1][x] & 0x40)) { 592 continue; 593 } 594 mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] ^= 0x40; 595 } 596 } 597 } 598 599 // transfer temporary mask to real mask 600 for (x = 0; x < dx; x++) { 601 for (y = 0; y < dy; y++) { 602 if (mymask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & 0x40) { 603 mask->data.PS_TYPE_IMAGE_MASK_DATA[y+ym+mask->row0][x+xm+mask->col0] |= maskVal; 604 } 605 } 606 } 607 608 // XXX if we decide this REALLY is a cosmic ray, set the CR_LIMIT bit 609 source->mode |= PM_SOURCE_MODE_CR_LIMIT; 610 611 psFree(mypix); 612 psFree(myvar); 613 psFree(binned); 614 psFree(conved); 615 psFree(edges); 616 psFree(mymask); 617 618 return true; 619 } 620 621 bool psphotMaskCosmicRayFootprintCheck (psArray *sources) { 622 623 for (int i = 0; i < sources->n; i++) { 624 pmSource *source = sources->data[i]; 625 pmPeak *peak = source->peak; 626 pmFootprint *footprint = peak->footprint; 627 if (!footprint) continue; 628 for (int j = 0; j < footprint->spans->n; j++) { 629 pmSpan *sp = footprint->spans->data[j]; 630 psAssert (sp, "missing span"); 631 } 632 } 633 return true; 634 } 635 636 /**** ------ old versions of cosmic ray masking ----- ****/ 637 638 bool psphotMaskCosmicRayIsophot (pmSource *source, psImageMaskType maskVal, psImageMaskType crMask); 639 640 // This attempt to mask the cosmic rays used the isophotal boundary 641 bool psphotMaskCosmicRay_V1 (psImage *mask, pmSource *source, psImageMaskType maskVal, psImageMaskType crMask) { 93 642 94 643 // replace the source flux … … 103 652 pmFootprint *footprint = peak->footprint; 104 653 if (!footprint) { 654 psTrace("psphot.czw",2,"Using isophot CR mask code."); 655 105 656 // if we have not footprint, use the old code to mask by isophot 106 657 psphotMaskCosmicRayIsophot (source, maskVal, crMask); … … 109 660 110 661 if (!footprint->spans) { 662 psTrace("psphot.czw",2,"Using isophot CR mask code."); 663 111 664 // if we have no footprint, use the old code to mask by isophot 112 665 psphotMaskCosmicRayIsophot (source, maskVal, crMask); 113 666 return true; 114 667 } 115 668 psphotMaskCosmicRayIsophot (source, maskVal, crMask); 116 669 // mask all of the pixels covered by the spans of the footprint 117 for (int j = 1; j < footprint->spans->n; j++) { 118 pmSpan *span1 = footprint->spans->data[j]; 119 120 int iy = span1->y; 121 int xs = span1->x0; 122 int xe = span1->x1; 123 124 for (int ix = xs; ix < xe; ix++) { 125 mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= crMask; 126 } 127 } 670 for (int j = 1; j < footprint->spans->n; j++) { 671 pmSpan *span1 = footprint->spans->data[j]; 672 673 int iy = span1->y; 674 int xs = span1->x0; 675 int xe = span1->x1; 676 677 for (int ix = xs; ix < xe; ix++) { 678 mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= crMask; 679 } 680 } 128 681 return true; 129 682 } … … 192 745 } 193 746 } 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, dMag);235 psVectorAppend (ApErr, 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 // XXX this is quite arbitrary...250 if (!isfinite(options->ApSysErr)) options->ApSysErr = 0.01;251 psLogMsg ("psphot", PS_LOG_DETAIL, "psf - Sum: %f +/- %f\n", options->ApResid, options->ApSysErr);252 253 psFree (Ap);254 psFree (ApErr);255 psFree (stats);256 psFree (dAp);257 258 return true;259 }260 261 // classify sources based on the combination of psf-mag, Mxx, Myy262 bool psphotSourceClass (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options) {263 264 bool status;265 pmPSFClump psfClump;266 char regionName[64];267 268 psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4s %4s %4s %4s %4s %4s", "Npsf", "Next", "Nsat", "Ncr", "Nmiss", "Nskip");269 270 int nRegions = psMetadataLookupS32 (&status, readout->analysis, "PSF.CLUMP.NREGIONS");271 for (int i = 0; i < nRegions; i ++) {272 snprintf (regionName, 64, "PSF.CLUMP.REGION.%03d", i);273 psMetadata *regionMD = psMetadataLookupPtr (&status, readout->analysis, regionName);274 psAssert (regionMD, "regions must be defined by earlier call to psphotRoughClassRegion");275 276 psRegion *region = psMetadataLookupPtr (&status, regionMD, "REGION");277 psAssert (region, "regions must be defined by earlier call to psphotRoughClassRegion");278 279 // pull FWHM_X,Y from the recipe, use to define psfClump.X,Y280 psfClump.X = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.X"); psAssert (status, "missing PSF.CLUMP.X");281 psfClump.Y = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.Y"); psAssert (status, "missing PSF.CLUMP.Y");282 psfClump.dX = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DX"); psAssert (status, "missing PSF.CLUMP.DX");283 psfClump.dY = psMetadataLookupF32 (&status, regionMD, "PSF.CLUMP.DY"); psAssert (status, "missing PSF.CLUMP.DY");284 285 if ((psfClump.X < 0) || (psfClump.Y < 0) || !psfClump.X || !psfClump.Y || isnan(psfClump.X) || isnan(psfClump.Y)) {286 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);287 continue;288 }289 290 if (!psphotSourceClassRegion (region, &psfClump, sources, recipe, psf, options)) {291 psLogMsg ("psphot", 4, "Failed to determine source classification for region %f,%f - %f,%f\n", region->x0, region->y0, region->x1, region->y1);292 continue;293 }294 }295 296 return true;297 }298 299 bool psphotSourceClassRegion (psRegion *region, pmPSFClump *psfClump, psArray *sources, psMetadata *recipe, pmPSF *psf, psphotSourceSizeOptions *options) {300 301 PS_ASSERT_PTR_NON_NULL(sources, false);302 PS_ASSERT_PTR_NON_NULL(recipe, false);303 304 int Nsat = 0;305 int Next = 0;306 int Npsf = 0;307 int Ncr = 0;308 int Nmiss = 0;309 int Nskip = 0;310 311 pmSourceMode noMoments = PM_SOURCE_MODE_MOMENTS_FAILURE | PM_SOURCE_MODE_SKYVAR_FAILURE | PM_SOURCE_MODE_SKY_FAILURE | PM_SOURCE_MODE_BELOW_MOMENTS_SN;312 pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_WEIGHT;313 314 psImageMaskType maskVal = options->maskVal | options->markVal;315 316 for (psS32 i = 0 ; i < sources->n ; i++) {317 318 pmSource *source = (pmSource *) sources->data[i];319 320 // psfClumps are found for image subregions:321 // skip sources not in this region322 if (source->peak->x < region->x0) continue;323 if (source->peak->x >= region->x1) continue;324 if (source->peak->y < region->y0) continue;325 if (source->peak->y >= region->y1) continue;326 327 // skip source if it was already measured328 if (source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) {329 psTrace("psphot", 7, "Not calculating source size since it has already been measured\n");330 continue;331 }332 333 // source must have been subtracted334 if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) {335 source->mode |= PM_SOURCE_MODE_SIZE_SKIPPED;336 psTrace("psphot", 7, "Not calculating source size since source is not subtracted\n");337 continue;338 }339 340 // we are basically classifying by moments; use the default if not found341 psAssert (source->moments, "why is this source missing moments?");342 if (source->mode & noMoments) {343 Nskip ++;344 continue;345 }346 347 psF32 Mxx = source->moments->Mxx;348 psF32 Myy = source->moments->Myy;349 350 // replace object in image351 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) {352 pmSourceAdd (source, PM_MODEL_OP_FULL, options->maskVal);353 }354 355 // clear the mask bit and set the circular mask pixels356 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal));357 psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, source->apRadius, "OR", options->markVal);358 359 // XXX can we test if psfMag is set and calculate only if needed?360 pmSourceMagnitudes (source, psf, photMode, maskVal); // maskVal includes markVal361 362 // clear the mask bit363 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(options->markVal));364 365 // re-subtract the object, leave local sky366 pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal);367 368 float apMag = -2.5*log10(source->moments->Sum);369 float dMag = source->psfMag - apMag;370 float nSigma = (dMag - options->ApResid) / hypot(source->errMag, options->ApSysErr);371 372 source->extNsigma = nSigma;373 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED;374 375 // Anything within this region is a probably PSF-like object. Saturated stars may land376 // in this region, but are detected elsewhere on the basis of their peak value.377 bool isPSF = (fabs(nSigma) < options->nSigmaApResid) && (fabs(Mxx - psfClump->X) < options->nSigmaMoments*psfClump->dX) && (fabs(Myy - psfClump->Y) < options->nSigmaMoments*psfClump->dY);378 if (isPSF) {379 Npsf ++;380 continue;381 }382 383 // Defects may not always match CRs from peak curvature analysis384 // Defects may also be marked as SATSTAR -- XXX deactivate this flag?385 // XXX this rule is not great386 if ((Mxx < psfClump->X) || (Myy < psfClump->Y)) {387 source->mode |= PM_SOURCE_MODE_DEFECT;388 Ncr ++;389 continue;390 }391 392 // saturated star (determined in PSF fit). These may also be saturated galaxies, or393 // just large saturated regions.394 if (source->mode & PM_SOURCE_MODE_SATSTAR) {395 Nsat ++;396 continue;397 }398 399 // XXX allow the Mxx, Myy to be less than psfClump->X,Y (by some nSigma)?400 bool isEXT = (nSigma > options->nSigmaApResid) || ((Mxx > psfClump->X) && (Myy > psfClump->Y));401 if (isEXT) {402 source->mode |= PM_SOURCE_MODE_EXT_LIMIT;403 Next ++;404 continue;405 }406 407 psWarning ("sourse size was missed for %f,%f : %f %f -- %f\n", source->peak->xf, source->peak->yf, Mxx, Myy, nSigma);408 Nmiss ++;409 }410 411 psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4d %4d %4d %4d %4d %4d", Npsf, Next, Nsat, Ncr, Nmiss, Nskip);412 413 747 return true; 414 748 } … … 488 822 } 489 823 490 bool psphotSourceSizeCR (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options) { 824 // this was an old attempt to identify cosmic rays based on the peak curvature 825 bool psphotSourcePeakCurvature (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options) { 491 826 492 827 // classify the sources based on the CR test (place this in a function?) … … 620 955 return true; 621 956 } 957 -
trunk/psphot/src/psphotSourceStats.c
r25988 r26894 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 bool psphotSourceStats (pmConfig *config, const pmFPAview *view, bool setWindow) 6 { 7 bool status = true; 8 9 // select the appropriate recipe information 10 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 11 psAssert (recipe, "missing recipe?"); 12 13 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 14 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 15 16 // loop over the available readouts 17 for (int i = 0; i < num; i++) { 18 if (!psphotSourceStatsReadout (config, view, "PSPHOT.INPUT", i, recipe, setWindow)) { 19 psError (PSPHOT_ERR_CONFIG, false, "failed to find initial detections for PSPHOT.INPUT entry %d", i); 20 return false; 21 } 22 } 23 return true; 24 } 25 26 bool psphotSourceStatsReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, psMetadata *recipe, bool setWindow) { 6 27 7 28 bool status = false; … … 10 31 psTimerStart ("psphot.stats"); 11 32 12 // select the appropriate recipe information 13 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 14 assert (recipe); 33 // find the currently selected readout 34 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest 35 psAssert (file, "missing file?"); 36 37 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 38 psAssert (readout, "missing readout?"); 39 40 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 41 psAssert (detections, "missing detections?"); 42 psAssert (!detections->newSources, "new sources already defined?"); 43 44 // XXX TEST: 45 if (detections->allSources) { 46 psphotMaskCosmicRayFootprintCheck(detections->allSources); 47 } 48 if (detections->newSources) { 49 psphotMaskCosmicRayFootprintCheck(detections->newSources); 50 } 15 51 16 52 // determine the number of allowed threads … … 21 57 22 58 // determine properties (sky, moments) of initial sources 23 float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 24 if (!status) return NULL; 25 59 float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 60 psAssert (status, "missing SKY_OUTER_RADIUS in recipe?"); 61 62 // XXX this seems like an arbitrary number... 26 63 OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius 27 64 28 65 char *breakPt = psMetadataLookupStr (&status, recipe, "BREAK_POINT"); 29 if (!status) return NULL; 66 psAssert (status, "missing BREAK_POINT?"); 67 68 float INNER = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS"); psAssert (status, "missing SKY_INNER_RADIUS"); 69 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); psAssert (status, "missing MOMENTS_SN_MIN"); 70 71 // bit-masks to test for good/bad pixels 72 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); 73 psAssert (maskVal, "missing MASK.PSPHOT"); 74 75 // bit-mask to mark pixels not used in analysis 76 psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); 77 psAssert (markVal, "missing MARK.PSPHOT"); 30 78 31 79 psArray *peaks = detections->peaks; 32 80 if (!peaks) { 33 81 psError(PS_ERR_UNEXPECTED_NULL, false, "No peaks found!"); 34 return NULL;82 return false; 35 83 } 36 84 37 85 // generate the array of sources, define the associated pixel 38 86 sources = psArrayAllocEmpty (peaks->n); 87 88 // if there are no peaks, we save the empty source array and return 89 if (!peaks->n) { 90 // save the new sources on the detection structure: 91 detections->newSources = sources; 92 return true; 93 } 39 94 40 95 for (int i = 0; i < peaks->n; i++) { … … 58 113 psArrayAdd (sources, 100, source); 59 114 psFree (source); 115 } 116 117 if (!strcasecmp (breakPt, "PEAKS")) { 118 psLogMsg ("psphot", PS_LOG_INFO, "%ld sources : %f sec\n", sources->n, psTimerMark ("psphot.stats")); 119 psLogMsg ("psphot", PS_LOG_INFO, "break point PEAKS, skipping MOMENTS\n"); 120 psphotVisualShowMoments (sources); 121 detections->newSources = sources; 122 return true; 123 } 124 125 if (setWindow) { 126 if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) { 127 psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!"); 128 psFree(sources); 129 return false; 130 } 131 } 132 133 // if we have measured the window, we will be saving the modified version of these recipe values on readout->analysis 134 float SIGMA = psMetadataLookupF32 (&status, readout->analysis, "MOMENTS_GAUSS_SIGMA"); 135 if (!status) { 136 SIGMA = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA"); 137 } 138 float RADIUS = psMetadataLookupF32 (&status, readout->analysis, "PSF_MOMENTS_RADIUS"); 139 if (!status) { 140 RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS"); 141 } 142 143 // threaded measurement of the source magnitudes 144 int Nfail = 0; 145 int Nmoments = 0; 146 int Nfaint = 0; 147 148 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) 149 int Cx = 1, Cy = 1; 150 psphotChooseCellSizes (&Cx, &Cy, readout, nThreads); 151 152 psArray *cellGroups = psphotAssignSources (Cx, Cy, sources); 153 154 for (int i = 0; i < cellGroups->n; i++) { 155 156 psArray *cells = cellGroups->data[i]; 157 158 for (int j = 0; j < cells->n; j++) { 159 160 // allocate a job -- if threads are not defined, this just runs the job 161 psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS"); 162 163 psArrayAdd(job->args, 1, cells->data[j]); // sources 164 165 PS_ARRAY_ADD_SCALAR(job->args, INNER, PS_TYPE_F32); 166 PS_ARRAY_ADD_SCALAR(job->args, MIN_SN, PS_TYPE_F32); 167 PS_ARRAY_ADD_SCALAR(job->args, RADIUS, PS_TYPE_F32); 168 PS_ARRAY_ADD_SCALAR(job->args, SIGMA, PS_TYPE_F32); 169 170 PS_ARRAY_ADD_SCALAR(job->args, maskVal, PS_TYPE_IMAGE_MASK); 171 PS_ARRAY_ADD_SCALAR(job->args, markVal, PS_TYPE_IMAGE_MASK); 172 173 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nmoments 174 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail 175 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfaint 176 177 if (!psThreadJobAddPending(job)) { 178 psError(PS_ERR_UNKNOWN, false, "Unable to launch thread job PSPHOT_SOURCE_STATS"); 179 psFree (job); 180 psFree(sources); 181 return false; 182 } 183 psFree(job); 184 } 185 186 // wait for the threads to finish and manage results 187 if (!psThreadPoolWait (false)) { 188 psError(PS_ERR_UNKNOWN, false, "Failure in thread job PSPHOT_SOURCE_STATS"); 189 psFree(sources); 190 return false; 191 } 192 193 // we have only supplied one type of job, so we can assume the types here 194 psThreadJob *job = NULL; 195 while ((job = psThreadJobGetDone()) != NULL) { 196 if (job->args->n < 1) { 197 fprintf (stderr, "error with job\n"); 198 } else { 199 psScalar *scalar = NULL; 200 scalar = job->args->data[7]; 201 Nmoments += scalar->data.S32; 202 scalar = job->args->data[8]; 203 Nfail += scalar->data.S32; 204 scalar = job->args->data[9]; 205 Nfaint += scalar->data.S32; 206 } 207 psFree(job); 208 } 209 } 210 211 psFree (cellGroups); 212 213 psLogMsg ("psphot", PS_LOG_INFO, "%ld sources, %d moments, %d faint, %d failed: %f sec\n", sources->n, Nmoments, Nfaint, Nfail, psTimerMark ("psphot.stats")); 214 215 psphotVisualShowMoments (sources); 216 217 // save the new sources on the detection structure: 218 detections->newSources = sources; 219 220 221 if (detections->allSources) { 222 psphotMaskCosmicRayFootprintCheck(detections->allSources); 223 } 224 if (detections->newSources) { 225 psphotMaskCosmicRayFootprintCheck(detections->newSources); 226 } 227 228 return true; 229 } 230 231 // this function is currently only called by psphotCheckExtSources 232 bool psphotSourceStatsUpdate (psArray *sources, pmConfig *config, pmReadout *readout) { 233 234 bool status = false; 235 236 psTimerStart ("psphot.stats"); 237 238 // select the appropriate recipe information 239 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 240 assert (recipe); 241 242 // determine the number of allowed threads 243 int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads 244 if (!status) { 245 nThreads = 0; 246 } 247 248 // determine properties (sky, moments) of initial sources 249 float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 250 if (!status) return false; 251 252 OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius 253 254 char *breakPt = psMetadataLookupStr (&status, recipe, "BREAK_POINT"); 255 if (!status) return false; 256 257 for (int i = 0; i < sources->n; i++) { 258 259 pmSource *source = sources->data[i]; 260 if (!source->peak) continue; // XXX how can we have a peak-less source? 261 262 // allocate space for moments 263 if (!source->moments) { 264 source->moments = pmMomentsAlloc(); 265 } 266 267 // allocate image, weight, mask arrays for each peak (square of radius OUTER) 268 pmSourceDefinePixels (source, readout, source->peak->x, source->peak->y, OUTER); 269 source->peak->assigned = true; 60 270 } 61 271 … … 67 277 } 68 278 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 } 279 // XXX how else could we get the window size in? 280 if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) { 281 psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!"); 282 return NULL; 74 283 } 75 284 … … 94 303 psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS"); 95 304 305 // XXX: this must match the above 96 306 psArrayAdd(job->args, 1, cells->data[j]); // sources 97 307 psArrayAdd(job->args, 1, recipe); … … 141 351 } 142 352 143 bool psphotSourceStatsUpdate (psArray *sources, pmConfig *config, pmReadout *readout) {144 145 bool status = false;146 147 psTimerStart ("psphot.stats");148 149 // select the appropriate recipe information150 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);151 assert (recipe);152 153 // determine the number of allowed threads154 int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads155 if (!status) {156 nThreads = 0;157 }158 159 // determine properties (sky, moments) of initial sources160 float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");161 if (!status) return NULL;162 163 OUTER = PS_MAX(OUTER, 20.0); // XXX Guarantee that we can encompass the max moments radius164 165 char *breakPt = psMetadataLookupStr (&status, recipe, "BREAK_POINT");166 if (!status) return NULL;167 168 for (int i = 0; i < sources->n; i++) {169 170 pmSource *source = sources->data[i];171 if (!source->peak) continue; // XXX how can we have a peak-less source?172 173 // allocate space for moments174 if (!source->moments) {175 source->moments = pmMomentsAlloc();176 }177 178 // allocate image, weight, mask arrays for each peak (square of radius OUTER)179 pmSourceDefinePixels (source, readout, source->peak->x, source->peak->y, OUTER);180 source->peak->assigned = true;181 }182 183 if (!strcasecmp (breakPt, "PEAKS")) {184 psLogMsg ("psphot", PS_LOG_INFO, "%ld sources : %f sec\n", sources->n, psTimerMark ("psphot.stats"));185 psLogMsg ("psphot", PS_LOG_INFO, "break point PEAKS, skipping MOMENTS\n");186 psphotVisualShowMoments (sources);187 return sources;188 }189 190 // XXX how else could we get the window size in?191 if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) {192 psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!");193 return NULL;194 }195 196 // threaded measurement of the source magnitudes197 int Nfail = 0;198 int Nmoments = 0;199 int Nfaint = 0;200 201 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts)202 int Cx = 1, Cy = 1;203 psphotChooseCellSizes (&Cx, &Cy, readout, nThreads);204 205 psArray *cellGroups = psphotAssignSources (Cx, Cy, sources);206 207 for (int i = 0; i < cellGroups->n; i++) {208 209 psArray *cells = cellGroups->data[i];210 211 for (int j = 0; j < cells->n; j++) {212 213 // allocate a job -- if threads are not defined, this just runs the job214 psThreadJob *job = psThreadJobAlloc ("PSPHOT_SOURCE_STATS");215 216 psArrayAdd(job->args, 1, cells->data[j]); // sources217 psArrayAdd(job->args, 1, recipe);218 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nmoments219 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail220 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfaint221 222 if (!psThreadJobAddPending(job)) {223 psError(PS_ERR_UNKNOWN, false, "Unable to launch thread job PSPHOT_SOURCE_STATS");224 psFree (job);225 return NULL;226 }227 psFree(job);228 }229 230 // wait for the threads to finish and manage results231 if (!psThreadPoolWait (false)) {232 psError(PS_ERR_UNKNOWN, false, "Failure in thread job PSPHOT_SOURCE_STATS");233 return NULL;234 }235 236 // we have only supplied one type of job, so we can assume the types here237 psThreadJob *job = NULL;238 while ((job = psThreadJobGetDone()) != NULL) {239 if (job->args->n < 1) {240 fprintf (stderr, "error with job\n");241 } else {242 psScalar *scalar = NULL;243 scalar = job->args->data[2];244 Nmoments += scalar->data.S32;245 scalar = job->args->data[3];246 Nfail += scalar->data.S32;247 scalar = job->args->data[4];248 Nfaint += scalar->data.S32;249 }250 psFree(job);251 }252 }253 254 psFree (cellGroups);255 256 psLogMsg ("psphot", PS_LOG_INFO, "%ld sources, %d moments, %d faint, %d failed: %f sec\n", sources->n, Nmoments, Nfaint, Nfail, psTimerMark ("psphot.stats"));257 258 psphotVisualShowMoments (sources);259 260 return (sources);261 }262 263 353 bool psphotSourceStats_Threaded (psThreadJob *job) { 264 354 … … 268 358 269 359 psArray *sources = job->args->data[0]; 270 psMetadata *recipe = job->args->data[1]; 271 272 float INNER = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS"); 273 if (!status) return false; 274 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); 275 if (!status) return false; 276 float RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS"); 277 if (!status) return false; 278 float SIGMA = psMetadataLookupF32 (&status, recipe, "MOMENTS_GAUSS_SIGMA"); 279 if (!status) return false; 280 281 // bit-masks to test for good/bad pixels 282 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); 283 assert (maskVal); 284 285 // bit-mask to mark pixels not used in analysis 286 psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); 287 assert (markVal); 360 361 float INNER = PS_SCALAR_VALUE(job->args->data[1],F32); 362 float MIN_SN = PS_SCALAR_VALUE(job->args->data[2],F32); 363 float RADIUS = PS_SCALAR_VALUE(job->args->data[3],F32); 364 float SIGMA = PS_SCALAR_VALUE(job->args->data[4],F32); 365 366 psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA); 367 psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[6],PS_TYPE_IMAGE_MASK_DATA); 288 368 289 369 // maskVal is used to test for rejected pixels, and must include markVal … … 325 405 326 406 // measure basic source moments (no S/N clipping on input pixels) 327 status = pmSourceMoments (source, RADIUS, SIGMA, 0.0 );407 status = pmSourceMoments (source, RADIUS, SIGMA, 0.0, maskVal); 328 408 if (status) { 329 409 Nmoments ++; … … 335 415 BIG_RADIUS = PS_MIN (INNER, 3*RADIUS); 336 416 psTrace ("psphot", 4, "retrying moments for %d, %d\n", source->peak->x, source->peak->y); 337 status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, 0.0 );417 status = pmSourceMoments (source, BIG_RADIUS, 3.0*SIGMA, 0.0, maskVal); 338 418 if (status) { 339 419 source->mode |= PM_SOURCE_MODE_BIG_RADIUS; … … 349 429 350 430 // change the value of a scalar on the array (wrap this and put it in psArray.h) 351 scalar = job->args->data[ 2];431 scalar = job->args->data[7]; 352 432 scalar->data.S32 = Nmoments; 353 433 354 scalar = job->args->data[ 3];434 scalar = job->args->data[8]; 355 435 scalar->data.S32 = Nfail; 356 436 357 scalar = job->args->data[ 4];437 scalar = job->args->data[9]; 358 438 scalar->data.S32 = Nfaint; 359 439 … … 367 447 bool status; 368 448 369 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); 370 if (!status) return false; 449 float MIN_SN = psMetadataLookupF32 (&status, recipe, "MOMENTS_SN_MIN"); psAssert (status, "missing MOMENTS_SN_MIN"); 450 float PSF_SN_LIM = psMetadataLookupF32(&status, recipe, "PSF_SN_LIM"); psAssert (status, "missing PSF_SN_LIM"); 451 psF32 MOMENTS_AR_MAX = psMetadataLookupF32(&status, recipe, "MOMENTS_AR_MAX"); psAssert (status, "missing MOMENTS_AR_MAX"); 371 452 372 453 // XXX move this to a config file? … … 394 475 395 476 // measure basic source moments (no S/N clipping on input pixels) 396 status = pmSourceMoments (source, 4*sigma[i], sigma[i], 0.0 );477 status = pmSourceMoments (source, 4*sigma[i], sigma[i], 0.0, 0xffff); 397 478 } 398 479 399 480 // choose a grid scale that is a fixed fraction of the psf sigma^2 400 psMetadataAddF32(recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(sigma[i]));401 psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i]));402 psMetadataAddF32(recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(sigma[i]));481 float PSF_CLUMP_GRID_SCALE = 0.1*PS_SQR(sigma[i]); 482 float MOMENTS_SX_MAX = 2.0*PS_SQR(sigma[i]); 483 float MOMENTS_SY_MAX = 2.0*PS_SQR(sigma[i]); 403 484 404 485 // determine the PSF parameters from the source moment values 405 pmPSFClump psfClump = pmSourcePSFClump (NULL, sources, recipe);486 pmPSFClump psfClump = pmSourcePSFClump (NULL, NULL, sources, PSF_SN_LIM, PSF_CLUMP_GRID_SCALE, MOMENTS_SX_MAX, MOMENTS_SY_MAX, MOMENTS_AR_MAX); 406 487 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]); 407 488 … … 418 499 psMetadataAddF32 (regionMD, PS_LIST_TAIL, "PSF.CLUMP.DY", PS_META_REPLACE, "psf clump center", psfClump.dY); 419 500 420 // psphotVisualPlotMoments (recipe, sources);501 psphotVisualPlotMoments (recipe, analysis, sources); 421 502 422 503 Sout[i] = sqrt(0.5*(psfClump.X + psfClump.Y)) / sigma[i]; … … 442 523 443 524 // choose a grid scale that is a fixed fraction of the psf sigma^2 444 psMetadataAddF32( recipe, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(Sigma));445 psMetadataAddF32( recipe, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));446 psMetadataAddF32( recipe, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma));447 psMetadataAddF32( recipe, PS_LIST_TAIL, "MOMENTS_GAUSS_SIGMA", PS_META_REPLACE, "moments limit", Sigma);448 psMetadataAddF32( recipe, PS_LIST_TAIL, "PSF_MOMENTS_RADIUS", PS_META_REPLACE, "moments limit", 4.0*Sigma);525 psMetadataAddF32(analysis, PS_LIST_TAIL, "PSF_CLUMP_GRID_SCALE", PS_META_REPLACE, "clump grid", 0.1*PS_SQR(Sigma)); 526 psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_SX_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma)); 527 psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_SY_MAX", PS_META_REPLACE, "moments limit", 2.0*PS_SQR(Sigma)); 528 psMetadataAddF32(analysis, PS_LIST_TAIL, "MOMENTS_GAUSS_SIGMA", PS_META_REPLACE, "moments limit", Sigma); 529 psMetadataAddF32(analysis, PS_LIST_TAIL, "PSF_MOMENTS_RADIUS", PS_META_REPLACE, "moments limit", 4.0*Sigma); 449 530 450 531 psLogMsg ("psphot", 3, "using window function with sigma = %f\n", Sigma); 451 532 return true; 452 533 } 534 535 // if we use the footprints, the output peaks list contains both old and new peaks, 536 // otherwise it only contains the new peaks. 537 -
trunk/psphot/src/psphotSubtractBackground.c
r23287 r26894 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 pmReadout *model = pmFPAviewThisReadout (view, modelFile->fpa); 23 26 assert (model); 24 25 // select the appropriate recipe information26 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);27 assert (recipe);28 27 29 28 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) … … 35 34 36 35 // select background pixels, from output background file, or create 36 // XXX for now, we will only allow a single background image to be generated 37 37 file = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKGND"); 38 38 if (file) { … … 66 66 67 67 // back-sub image pixels, from output background file (don't create if not requested) 68 // XXX for now, we will only allow a single background-subtracted image to be generated 68 69 file = psMetadataLookupPtr (&status, config->files, "PSPHOT.BACKSUB"); 69 70 if (file) { … … 109 110 // the pmReadout selected in this function are all view on entries in config->files 110 111 112 // display the backsub and backgnd images 113 // move this inthe the subtract background loop 114 psphotVisualShowBackground (config, view, readout); 115 111 116 npass ++; 112 117 return true; 113 118 } 119 120 bool psphotSubtractBackground (pmConfig *config, const pmFPAview *view) 121 { 122 bool status = false; 123 124 // select the appropriate recipe information 125 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 126 psAssert (recipe, "missing recipe?"); 127 128 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 129 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 130 131 // loop over the available readouts 132 for (int i = 0; i < num; i++) { 133 if (!psphotSubtractBackgroundReadout (config, view, "PSPHOT.INPUT", i, recipe)) { 134 psError (PSPHOT_ERR_CONFIG, false, "failed to subtract background for PSPHOT.INPUT entry %d", i); 135 return false; 136 } 137 } 138 return true; 139 } -
trunk/psphot/src/psphotVisual.c
r26003 r26894 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 … … 171 185 if (kapa == -1) return false; 172 186 173 //psphotVisualShowMask (kapa, readout->mask, "mask", 2);187 psphotVisualShowMask (kapa, readout->mask, "mask", 2); 174 188 psphotVisualScaleImage (kapa, readout->variance, readout->mask, "variance", 1); 175 189 psphotVisualScaleImage (kapa, readout->image, readout->mask, "image", 0); … … 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"); … … 1905 1888 psFree (ySAT); 1906 1889 psFree (mSAT); 1890 psFree (sSAT); 1907 1891 1908 1892 psFree (xEXT); 1909 1893 psFree (yEXT); 1910 1894 psFree (mEXT); 1895 psFree (sEXT); 1911 1896 1912 1897 psFree (xPSF); 1913 1898 psFree (yPSF); 1914 1899 psFree (mPSF); 1900 psFree (sPSF); 1915 1901 1916 1902 psFree (xDEF); 1917 1903 psFree (yDEF); 1918 1904 psFree (mDEF); 1905 psFree (sDEF); 1919 1906 1920 1907 psFree (xCR); 1921 1908 psFree (yCR); 1922 1909 psFree (mCR); 1910 psFree (sCR); 1923 1911 1924 1912 pmVisualAskUser(NULL);
Note:
See TracChangeset
for help on using the changeset viewer.
