Changeset 37066 for branches/eam_branches/ipp-ops-20130712/psphot/src
- Timestamp:
- Jul 17, 2014, 12:30:45 PM (12 years ago)
- Location:
- branches/eam_branches/ipp-ops-20130712/psphot
- Files:
-
- 40 edited
- 14 copied
-
. (modified) (1 prop)
-
src (modified) (2 props)
-
src/Makefile.am (modified) (9 diffs)
-
src/psmakecff.c (copied) (copied from trunk/psphot/src/psmakecff.c )
-
src/psphot.h (modified) (9 diffs)
-
src/psphotApResid.c (modified) (2 diffs)
-
src/psphotArguments.c (modified) (1 diff)
-
src/psphotBlendFit.c (modified) (3 diffs)
-
src/psphotChooseAnalysisOptions.c (copied) (copied from trunk/psphot/src/psphotChooseAnalysisOptions.c )
-
src/psphotChoosePSF.c (modified) (2 diffs)
-
src/psphotCleanup.c (modified) (1 diff)
-
src/psphotDeblendSatstars.c (modified) (3 diffs)
-
src/psphotDefineFiles.c (modified) (1 diff)
-
src/psphotEfficiency.c (modified) (2 diffs)
-
src/psphotEllipticalContour.c (modified) (1 diff)
-
src/psphotEvalFLT.c (modified) (1 diff)
-
src/psphotExtendedSourceAnalysis.c (modified) (8 diffs)
-
src/psphotExtendedSourceFits.c (modified) (20 diffs)
-
src/psphotFullForce.SourceStats.c (copied) (copied from trunk/psphot/src/psphotFullForce.SourceStats.c )
-
src/psphotFullForce.c (copied) (copied from trunk/psphot/src/psphotFullForce.c )
-
src/psphotFullForceArguments.c (copied) (copied from trunk/psphot/src/psphotFullForceArguments.c )
-
src/psphotFullForceImageLoop.c (copied) (copied from trunk/psphot/src/psphotFullForceImageLoop.c )
-
src/psphotFullForceReadout.c (copied) (copied from trunk/psphot/src/psphotFullForceReadout.c )
-
src/psphotFullForceSummary.c (copied) (copied from trunk/psphot/src/psphotFullForceSummary.c )
-
src/psphotFullForceSummaryReadout.c (copied) (copied from trunk/psphot/src/psphotFullForceSummaryReadout.c )
-
src/psphotGalaxyShape.c (copied) (copied from trunk/psphot/src/psphotGalaxyShape.c )
-
src/psphotImageLoop.c (modified) (1 diff)
-
src/psphotKronFlux.c (copied) (copied from trunk/psphot/src/psphotKronFlux.c )
-
src/psphotKronIterate.c (modified) (2 diffs)
-
src/psphotLensing.c (copied) (copied from trunk/psphot/src/psphotLensing.c )
-
src/psphotLoadPSF.c (modified) (2 diffs)
-
src/psphotLoadSRCTEXT.c (modified) (1 diff)
-
src/psphotMakeFluxScale.c (modified) (1 diff)
-
src/psphotMergeSources.c (modified) (9 diffs)
-
src/psphotModelTestReadout.c (modified) (1 diff)
-
src/psphotOldCode.c (copied) (copied from trunk/psphot/src/psphotOldCode.c )
-
src/psphotPetroFlux.c (copied) (copied from trunk/psphot/src/psphotPetroFlux.c )
-
src/psphotPetrosianRadialBins.c (modified) (3 diffs)
-
src/psphotPetrosianStats.c (modified) (7 diffs)
-
src/psphotRadialBins.c (modified) (2 diffs)
-
src/psphotRadialProfile.c (modified) (7 diffs)
-
src/psphotRadiusChecks.c (modified) (4 diffs)
-
src/psphotReadout.c (modified) (3 diffs)
-
src/psphotRoughClass.c (modified) (1 diff)
-
src/psphotSersicModelClass.c (modified) (1 diff)
-
src/psphotSetThreads.c (modified) (1 diff)
-
src/psphotSourceFits.c (modified) (10 diffs)
-
src/psphotSourceSize.c (modified) (15 diffs)
-
src/psphotSourceStats.c (modified) (3 diffs)
-
src/psphotStackImageLoop.c (modified) (9 diffs, 1 prop)
-
src/psphotStackMatchPSFsNext.c (modified) (2 diffs)
-
src/psphotStackMatchPSFsUtils.c (modified) (1 diff)
-
src/psphotStackReadout.c (modified) (16 diffs)
-
src/psphotVisual.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-ops-20130712/psphot
- Property svn:mergeinfo deleted
-
branches/eam_branches/ipp-ops-20130712/psphot/src
- Property svn:ignore
-
old new 24 24 psphotModelTest 25 25 psphotMinimal 26 psphotFullForce 27 psmakecff 28 psphotFullForceSummary
-
- Property svn:mergeinfo deleted
- Property svn:ignore
-
branches/eam_branches/ipp-ops-20130712/psphot/src/Makefile.am
r34317 r37066 25 25 libpsphot_la_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 26 26 27 bin_PROGRAMS = psphot psphotForced psphot Minimal psphotMakePSF psphotStack psphotModelTest27 bin_PROGRAMS = psphot psphotForced psphotFullForce psphotFullForceSummary psphotMinimal psphotMakePSF psphotStack psphotModelTest psmakecff 28 28 # bin_PROGRAMS = psphotPetrosianStudy psphotTest psphotMomentsStudy 29 29 … … 36 36 psphotForced_LDADD = libpsphot.la 37 37 38 psphotFullForce_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 39 psphotFullForce_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 40 psphotFullForce_LDADD = libpsphot.la 41 42 psphotFullForceSummary_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 43 psphotFullForceSummary_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 44 psphotFullForceSummary_LDADD = libpsphot.la 45 38 46 psphotMinimal_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 39 47 psphotMinimal_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) … … 51 59 psphotModelTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 52 60 psphotModelTest_LDADD = libpsphot.la 61 62 psmakecff_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 63 psmakecff_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 64 psmakecff_LDADD = libpsphot.la 65 53 66 54 67 # psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) … … 81 94 psphotMosaicChip.c \ 82 95 psphotCleanup.c 96 97 # generalized forced photometry (including Kron, Petro, and Models) of specified positions given a specified psf 98 psphotFullForce_SOURCES = \ 99 psphotFullForce.c \ 100 psphotFullForceArguments.c \ 101 psphotParseCamera.c \ 102 psphotImageLoop.c \ 103 psphotMosaicChip.c \ 104 psphotCleanup.c 105 106 # combine full force results from several inputs 107 psphotFullForceSummary_SOURCES = \ 108 psphotFullForceSummary.c \ 109 psphotFullForceSummaryReadout.c 83 110 84 111 # forced photometry of specified positions given a specified psf … … 129 156 psphotCleanup.c 130 157 158 # a program that takes a cmf file and makes a cff file (input file for psphotFullForce 159 psmakecff_SOURCES = \ 160 psmakecff.c 161 131 162 # psphotTest_SOURCES = \ 132 163 # psphotTest.c … … 155 186 psphotReadoutMinimal.c \ 156 187 psphotForcedReadout.c \ 188 psphotFullForceReadout.c \ 189 psphotFullForce.SourceStats.c \ 157 190 psphotMakePSFReadout.c \ 158 191 psphotModelBackground.c \ … … 175 208 psphotMakeGrowthCurve.c \ 176 209 psphotMagnitudes.c \ 210 psphotLensing.c \ 177 211 psphotSetMaskBits.c \ 178 212 psphotSkyReplace.c \ … … 181 215 psphotSourceFits.c \ 182 216 psphotRadiusChecks.c \ 217 psphotChooseAnalysisOptions.c \ 183 218 psphotOutput.c \ 184 219 psphotFakeSources.c \ … … 198 233 psphotRadialPlot.c \ 199 234 psphotKronIterate.c \ 235 psphotKronFlux.c \ 236 psphotPetroFlux.c \ 237 psphotGalaxyShape.c \ 200 238 psphotRadialProfileWings.c \ 201 239 psphotDeblendSatstars.c \ -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphot.h
r35769 r37066 18 18 PSPHOT_SINGLE, 19 19 PSPHOT_FORCED, 20 PSPHOT_FULL_FORCE, 20 21 PSPHOT_MAKE_PSF, 21 22 PSPHOT_MODEL_TEST, … … 81 82 bool psphotSourceStatsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, bool setWindow); 82 83 84 bool psphotFullForceSourceStats (pmConfig *config, const pmFPAview *view, const char *filerule, bool setWindow); 85 bool psphotFullForceSourceStatsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, bool setWindow); 86 83 87 bool psphotDeblendSatstars (pmConfig *config, const pmFPAview *view, const char *filerule); 84 88 bool psphotDeblendSatstarsReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe); … … 122 126 bool psphotAddOrSubNoise_Threaded (psThreadJob *job); 123 127 128 bool psphotChooseAnalysisOptions (pmConfig *config, const pmFPAview *view, const char *filerule); 129 bool psphotChooseAnalysisOptionsReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe); 130 bool psphotChooseAnalysisOptionsByObject(pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects); 131 124 132 bool psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule); 125 133 bool psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe); … … 136 144 bool psphotMagnitudesReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf); 137 145 bool psphotMagnitudes_Threaded (psThreadJob *job); 146 147 bool psphotLensing (pmConfig *config, const pmFPAview *view, const char *filerule); 148 bool psphotLensingReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe); 149 bool psphotLensingPSFtrendsReadout(pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe); 138 150 139 151 bool psphotEfficiency (pmConfig *config, const pmFPAview *view, const char *filerule); … … 341 353 bool psphotForcedReadout(pmConfig *config, const pmFPAview *view, const char *filerule); 342 354 355 pmConfig *psphotFullForceArguments(int argc, char **argv); 356 bool psphotFullForceReadout(pmConfig *config, const pmFPAview *view, const char *filerule); 357 343 358 pmConfig *psphotMinimalArguments(int argc, char **argv); 344 359 bool psphotReadoutMinimal(pmConfig *config, const pmFPAview *view, const char *filerule); … … 349 364 pmConfig *psphotModelTestArguments(int argc, char **argv); 350 365 bool psphotModelTestReadout(pmConfig *config, const pmFPAview *view, const char *filerule); 366 367 bool psphotFullForceSummaryReadout (pmConfig * config, const pmFPAview *view); 351 368 352 369 int psphotFileruleCount(const pmConfig *config, const char *filerule); … … 414 431 } psphotStackOptions; 415 432 433 typedef struct { 434 float Q; 435 float NSigma; 436 float clampSN; 437 int extModelType; 438 } psphotGalaxyShapeOptions; 439 416 440 /*** psphotStackMatchPSF prototypes ***/ 417 441 bool psphotStackMatchPSFs (pmConfig *config, const pmFPAview *view); … … 475 499 bool psphotSourceChildren (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc); 476 500 bool psphotSourceChildrenReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index); 477 psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc );501 psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc, bool sourcesSubtracted); 478 502 479 503 bool psphotSourceParents (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc); … … 496 520 bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf, int index, int pass); 497 521 bool psphotKronIterate_Threaded (psThreadJob *job); 522 523 bool psphotKronFlux (pmConfig *config, const pmFPAview *view, const char *filerule); 524 bool psphotKronFluxReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char *filerule, pmReadout *readout, psArray *sources); 525 bool psphotKronFlux_Threaded (psThreadJob *job); 526 bool psphotKronFluxSource (pmSource *source, psImageMaskType maskVal); 527 528 bool psphotPetroFlux (pmConfig *config, const pmFPAview *view, const char *filerule); 529 bool psphotPetroFluxReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources); 530 bool psphotPetroFlux_Threaded (psThreadJob *job); 531 bool psphotPetroFluxSource (pmSource *source, psImageMaskType maskVal); 532 533 bool psphotGalaxyShape (pmConfig *config, const pmFPAview *view, const char *filerule); 534 bool psphotGalaxyShapeReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, const char * filerule, pmReadout *readout, psArray *sources, pmPSF *psf); 535 bool psphotGalaxyShape_Threaded (psThreadJob *job); 536 bool psphotGalaxyShapeGrid (pmSource *source, pmSourceFitOptions *fitOptions, psphotGalaxyShapeOptions *opt, psImageMaskType maskVal, int psfSize); 537 bool psphotGalaxyShapeSource (pmPCMdata *pcm, pmSource *source, pmSourceGalaxyFits *galaxyFits, psImageMaskType maskVal, int psfSize, bool saveResults); 538 psphotGalaxyShapeOptions *psphotGalaxyShapeOptionsAlloc(); 539 bool psphotGalaxyShapeOptionsSet(pmSource *source, pmSourceGalaxyFits *galaxyFits, psphotGalaxyShapeOptions *defaultOptions); 498 540 499 541 bool psphotRadialProfileWings (pmConfig *config, const pmFPAview *view, const char *filerule); -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotApResid.c
r34404 r37066 214 214 215 215 // XXX make this user-configurable? 216 if (source->psfMagErr > 0.0 1) continue;216 if (source->psfMagErr > 0.03) continue; 217 217 218 218 // aperture residual for this source … … 267 267 268 268 // set the max order (0 = constant) which the number of psf stars can support: 269 // rule of thumb: require 3 stars per 'cell' (order+1)^2269 // we require only 3 stars for n = 0, increase stars / cell for higher order 270 270 int MaxOrderForStars = 0; 271 if (Npsf >= 12) MaxOrderForStars = 1; // 4 cells 272 if (Npsf >= 27) MaxOrderForStars = 2; // 9 cells 273 if (Npsf >= 48) MaxOrderForStars = 3; // 16 cells 274 if (Npsf > 75) MaxOrderForStars = 4; // 25 cells 271 if (Npsf >= 16) MaxOrderForStars = 1; // 4 cells 272 if (Npsf >= 54) MaxOrderForStars = 2; // 9 cells 273 if (Npsf >= 128) MaxOrderForStars = 3; // 16 cells 274 if (Npsf >= 300) MaxOrderForStars = 4; // 25 cells 275 if (Npsf > 576) MaxOrderForStars = 5; // 36 cells 275 276 276 277 pmTrend2DMode mode = PM_TREND_MAP; -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotArguments.c
r33690 r37066 217 217 pmConfigFileSetsMD (config->arguments, &argc, argv, "PSPHOT.PSF", "-psf", "-psflist"); 218 218 pmConfigFileSetsMD (config->arguments, &argc, argv, "SRC", "-src", "-srclist"); 219 // XXX allow this format? pmConfigFileSetsMD (config->arguments, &argc, argv, "FORCE", "-force", "-forcelist"); 219 220 pmConfigFileSetsMD (config->arguments, &argc, argv, "EXPNUM", "-expnum", "-expnumlist"); 220 221 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotBlendFit.c
r35769 r37066 273 273 pmSource *source = sources->data[i]; 274 274 275 int TEST_ON = false; 276 # if (0) 275 # if (PS_TRACE_ON) 277 276 # define TEST_X 653 278 277 # define TEST_Y 466 279 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 278 # define TESTING 1 279 int TEST_ON = false; 280 if (TESTING && (fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 280 281 fprintf (stderr, "test object\n"); 281 282 psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5); … … 342 343 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 343 344 if (psphotFitBlob (readout, source, newSources, psf, fitOptions, maskVal, markVal)) { 345 # if (PS_TRACE_ON) 344 346 if (TEST_ON) { 345 347 psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); 346 348 } 349 # endif 347 350 psTrace ("psphot", 5, "source at %7.1f, %7.1f is ext", source->peak->xf, source->peak->yf); 348 351 Next ++; … … 351 354 } else { 352 355 if (psphotFitBlend (readout, source, psf, fitOptions, maskVal, markVal)) { 356 # if (PS_TRACE_ON) 353 357 if (TEST_ON) { 354 358 psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); 355 359 } 360 # endif 356 361 source->type = PM_SOURCE_TYPE_STAR; 357 362 psTrace ("psphot", 5, "source at %7.1f, %7.1f is psf", source->peak->xf, source->peak->yf); -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotChoosePSF.c
r35769 r37066 399 399 char *modelName = pmModelClassGetName (psf->type); 400 400 psLogMsg ("psphot.pspsf", PS_LOG_WARN, "select psf model: %f sec\n", psTimerMark ("psphot.choose.psf")); 401 psLogMsg ("psphot.pspsf", PS_LOG_INFO, "psf model %s, ApResid: %f +/- %f \n", modelName, psf->ApResid, psf->dApResid);401 psLogMsg ("psphot.pspsf", PS_LOG_INFO, "psf model %s, ApResid: %f +/- %f (%d x %d model)\n", modelName, psf->ApResid, psf->dApResid, psf->trendNx, psf->trendNy); 402 402 403 403 psFree (options); … … 448 448 449 449 // get the model full-width at half-max 450 float FWHM_MAJOR = 2*modelPSF-> modelRadius (modelPSF->params, 0.5);450 float FWHM_MAJOR = 2*modelPSF->class->modelRadius (modelPSF->params, 0.5); 451 451 452 452 // XXX make sure this is consistent with the re-definition of PM_PAR_SXX -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotCleanup.c
r34086 r37066 22 22 pmVisualCleanup (); 23 23 psLibFinalize(); 24 #if (PS_TRACE_ON) 25 // don't display memory leaks unless trace is on. 24 26 // fprintf (stderr, "found %d leaks at %s\n", psMemCheckLeaks (0, NULL, NULL, false), "psphot"); 25 27 fprintf (stderr, "found %d leaks at %s\n", psMemCheckLeaks (0, NULL, stdout, false), "psphot"); 28 #endif 26 29 return; 27 30 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotDeblendSatstars.c
r34708 r37066 128 128 // int display = psphotKapaChannel (1); 129 129 // psphotVisualScaleImage (display, (psImage *) source->pixels->parent, NULL, "image", 1.0, 0); 130 131 int Nsatstar = 0; 130 132 131 133 // examine sources in decreasing SN order … … 179 181 source->mode2 |= PM_SOURCE_MODE2_SATSTAR_PROFILE; // and we have in fact subtracted the profile 180 182 183 Nsatstar ++; 184 181 185 // XXX visualize, model, and subtract 182 186 // if (!psphotVisualRadialProfileSatstar (source, maskVal)) { … … 192 196 psFree (index); 193 197 194 psLogMsg ("psphot", PS_LOG_INFO, "deblend satstar: %f sec\n", psTimerMark ("psphot.deblend.sat"));198 psLogMsg ("psphot", PS_LOG_INFO, "deblend %d satstars: %f sec\n", Nsatstar, psTimerMark ("psphot.deblend.sat")); 195 199 return true; 196 200 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotDefineFiles.c
r34528 r37066 150 150 } 151 151 152 if (psMetadataLookupPtr(NULL, config->arguments, "FORCE")) { 153 if (!pmFPAfileDefineFromArgs (&status, config, "PSPHOT.INPUT.CFF", "FORCE")) { 154 psError(PSPHOT_ERR_CONFIG, false, "Failed to find/build PSPHOT.INPUT.CFF"); 155 return status; 156 } 157 } 158 152 159 if (psMetadataLookupPtr(NULL, config->arguments, "SRCTEXT")) { 153 160 // XXX cannot use pmFPAfileDefineFromArgs: this is explicitly a FITS-based I/O function -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotEfficiency.c
r34353 r37066 71 71 continue; 72 72 } 73 float flux = normModel-> modelFlux(normModel->params); // Total flux for peak of 1.073 float flux = normModel->class->modelFlux(normModel->params); // Total flux for peak of 1.0 74 74 psFree(normModel); 75 75 if (!isfinite(flux)) { … … 424 424 continue; 425 425 } 426 float sourceRadius = PS_MAX(radius, model-> modelRadius(model->params, minFlux)); // Radius for source426 float sourceRadius = PS_MAX(radius, model->class->modelRadius(model->params, minFlux)); // Radius for source 427 427 psFree(model); 428 428 if (!isfinite(sourceRadius)) { -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotEllipticalContour.c
r32348 r37066 64 64 psFree (y); 65 65 psFree (yErr); 66 source->mode2 |= PM_SOURCE_MODE2_ECONTOUR_FEW_PTS; 66 67 return false; 67 68 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotEvalFLT.c
r17396 r37066 53 53 } 54 54 55 keep = model-> modelFitStatus(model);55 keep = model->class->modelFitStatus(model); 56 56 if (keep) return true; 57 57 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotExtendedSourceAnalysis.c
r34404 r37066 1 1 # include "psphotInternal.h" 2 3 // measure the elliptical radial profile and use this to measure the petrosian parameters for the sources 2 void psphotRadialProfileShowSkips (); 3 4 // measure the petrosian parameters for the sources 4 5 5 6 // for now, let's store the detections on the readout->analysis for each readout … … 15 16 psAssert (recipe, "missing recipe?"); 16 17 17 // perform full non-linear fits / extended source analysis? 18 if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANALYSIS")) { 18 bool doPetrosian = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN"); 19 bool doAnnuli = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI"); 20 21 // measure petrosians? 22 if (!doPetrosian && !doAnnuli) { 19 23 psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n"); 20 24 return true; … … 33 37 } 34 38 39 /*** for the moment, this test code : it is not thread safe ***/ 40 int Nall = 0; 41 int Nskip1 = 0; 42 int Nskip2 = 0; 43 int Nskip3 = 0; 44 int Nskip4 = 0; 45 int Nskip5 = 0; 46 int Nskip6 = 0; 47 48 # define SKIP(VALUE) { VALUE++; continue; } 49 35 50 // aperture-like measurements for extended sources 36 51 bool psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe) { … … 110 125 111 126 // set this to 0 to run without threading 112 # if ( 1)127 # if (0) 113 128 if (!psThreadJobAddPending(job)) { 114 129 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); … … 164 179 psLogMsg ("psphot", PS_LOG_INFO, " %d annuli\n", Nannuli); 165 180 181 # if (PS_TRACE_ON) 182 fprintf (stderr, "ext analysis skipped @ 1 : %d\n", Nskip1); 183 fprintf (stderr, "ext analysis skipped @ 2 : %d\n", Nskip2); 184 fprintf (stderr, "ext analysis skipped @ 3 : %d\n", Nskip3); 185 fprintf (stderr, "ext analysis skipped @ 4 : %d\n", Nskip4); 186 fprintf (stderr, "ext analysis skipped @ 5 : %d\n", Nskip5); 187 fprintf (stderr, "ext analysis skipped @ 6 : %d\n", Nskip6); 188 #endif 189 190 psphotRadialProfileShowSkips (); 191 166 192 psphotVisualShowResidualImage (readout, false); 167 193 168 bool doPetrosian = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN"); 169 if (doPetrosian) { 170 psphotVisualShowPetrosians (sources); 171 } 194 psphotVisualShowPetrosians (sources); 172 195 173 196 return true; … … 190 213 float skynoise = PS_SCALAR_VALUE(job->args->data[4],F32); 191 214 192 // S/N limit to perform full non-linear fits193 float SN_LIM = psMetadataLookupF32 (&status, recipe, "EXTENDED_SOURCE_SN_LIM");194 195 // which extended source analyses should we perform?196 215 bool doPetrosian = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN"); 197 bool doAnnuli = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_ANNULI");198 bool doPetroStars = psMetadataLookupBool (&status, recipe, "PETROSIAN_FOR_STARS");199 216 200 217 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) … … 207 224 pmSource *source = sources->data[i]; 208 225 209 // if we have checked the source validity on the basis of the object set, then 210 // we either skip these tests below or we skip the source completely 211 if (source->tmpFlags & PM_SOURCE_TMPF_PETRO_SKIP) continue; 212 if (source->tmpFlags & PM_SOURCE_TMPF_PETRO_KEEP) goto keepSource; 213 214 // skip PSF-like and non-astronomical objects 215 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 216 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 217 if (source->mode & PM_SOURCE_MODE_DEFECT) continue; 218 if (source->mode & PM_SOURCE_MODE_SATSTAR) continue; 219 220 // skip saturated stars modeled with a radial profile 221 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 222 223 // optionally allow non-extended objects to get petrosians as well 224 if (!doPetroStars) { 225 if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue; 226 if (source->type == PM_SOURCE_TYPE_STAR) continue; 227 } 228 229 // limit selection to some SN limit 230 // assert (source->peak); // how can a source not have a peak? 231 // limit selection to some SN limit 232 bool skipSource = false; 233 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 234 skipSource = (source->moments->KronFlux < SN_LIM * source->moments->KronFluxErr); 235 } else { 236 skipSource = (sqrt(source->peak->detValue) < SN_LIM); 237 } 238 if (skipSource) continue; 239 240 // limit selection by analysis region (this automatically apply 241 if (source->peak->x < region->x0) continue; 242 if (source->peak->y < region->y0) continue; 243 if (source->peak->x > region->x1) continue; 244 if (source->peak->y > region->y1) continue; 245 246 keepSource: 226 Nall ++; 227 228 // rules for measuring petrosian parameters for specific objects are set in 229 // psphotChooseAnalysisOptions.c 230 if (!(source->tmpFlags & PM_SOURCE_TMPF_PETRO)) SKIP (Nskip1); 231 232 // limit selection by analysis region (XXX move this into psphotChooseAnalysisOption?) 233 if (source->peak->x < region->x0) SKIP (Nskip2); 234 if (source->peak->y < region->y0) SKIP (Nskip3); 235 if (source->peak->x > region->x1) SKIP (Nskip4); 236 if (source->peak->y > region->y1) SKIP (Nskip5); 247 237 248 238 // replace object in image … … 259 249 pmSourceRedefinePixels (source, readout, source->peak->xf, source->peak->yf, 1.5*radius); 260 250 261 // if we request any of these measurements, we require the radial profile 262 if (doPetrosian || doAnnuli) { 263 if (!psphotRadialProfile (source, recipe, skynoise, maskVal)) { 264 // all measurements below require the radial profile; skip them all 265 // re-subtract the object, leave local sky 266 psTrace ("psphot", 5, "failed to extract radial profile for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); 267 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 268 continue; 269 } 270 Nannuli ++; 271 source->mode |= PM_SOURCE_MODE_RADIAL_FLUX; 272 } 251 // measure the radial profile 252 if (!psphotRadialProfile (source, recipe, skynoise, maskVal)) { 253 // re-subtract the object, leave local sky 254 psTrace ("psphot", 5, "failed to extract radial profile for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); 255 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 256 SKIP (Nskip6); 257 } 258 259 Nannuli ++; 260 source->mode |= PM_SOURCE_MODE_RADIAL_FLUX; 273 261 274 262 // Petrosian Mags 275 263 if (doPetrosian) { 276 if (!psphotPetrosian (source, recipe, skynoise, maskVal)) {277 psTrace ("psphot", 5, "FAILED petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);278 } else {279 psTrace ("psphot", 5, "measured petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My);280 Npetro ++;281 source->mode |= PM_SOURCE_MODE_EXTENDED_STATS;282 }264 if (!psphotPetrosian (source, recipe, skynoise, maskVal)) { 265 psTrace ("psphot", 5, "FAILED petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); 266 } else { 267 psTrace ("psphot", 5, "measured petrosian flux & radius for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); 268 Npetro ++; 269 source->mode |= PM_SOURCE_MODE_EXTENDED_STATS; 270 } 283 271 } 284 272 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotExtendedSourceFits.c
r35769 r37066 111 111 } 112 112 113 float fitNsigmaConv = psMetadataLookupF32 (&status, recipe, "EXT_FIT_NSIGMA_CONV"); // number of sigma for the convolution 114 if (!status || !isfinite(fitNsigmaConv) || fitNsigmaConv <= 0) { 115 fitNsigmaConv = 5.0; 116 } 117 113 118 bool chisqConvergence = psMetadataLookupBool (&status, recipe, "LMM_FIT_CHISQ_CONVERGENCE"); // Fit tolerance 114 119 if (!status) { … … 123 128 } 124 129 130 // perform full extended source non-linear fits? 131 bool isInteractive = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS_INTERACTIVE"); 132 if (!status) isInteractive = false; 133 125 134 // Define source fitting parameters for extended source fits 126 135 pmSourceFitOptions *fitOptions = pmSourceFitOptionsAlloc(); 127 fitOptions->mode = PM_SOURCE_FIT_EXT ;136 fitOptions->mode = PM_SOURCE_FIT_EXT_AND_SKY; 128 137 fitOptions->saveCovariance = true; // XXX make this a user option? 129 138 fitOptions->covarFactor = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix … … 131 140 fitOptions->minTol = fitMinTol; 132 141 fitOptions->maxTol = fitMaxTol; 142 fitOptions->nsigma = fitNsigmaConv; 133 143 134 144 fitOptions->gainFactorMode = gainFactorMode; 135 145 fitOptions->chisqConvergence = chisqConvergence; 146 fitOptions->isInteractive = isInteractive; 147 148 // use poissonian errors or local-sky errors 149 fitOptions->poissonErrors = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS_POISSON"); 150 if (!status) fitOptions->poissonErrors = true; 136 151 137 152 // maskVal is used to test for rejected pixels, and must include markVal … … 278 293 psArrayAdd(job->args, 1, cells->data[j]); // sources 279 294 psArrayAdd(job->args, 1, models); 295 280 296 // Allocate a metadata iterator here because psMetadataIteratorAlloc/Free are not thread safe 281 297 psMetadataIterator *iter = psMetadataIteratorAlloc (models, PS_LIST_HEAD, NULL); … … 296 312 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nfail 297 313 298 // set this to 0 to run without threading 299 # if (1) 300 if (!psThreadJobAddPending(job)) { 301 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 302 psFree(AnalysisRegion); 303 psFree (fitOptions); 304 psFree (models); 305 psphotSersicModelClassCleanup(); 306 return false; 307 } 308 # else 309 if (!psphotExtendedSourceFits_Threaded(job)) { 310 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 311 psFree(AnalysisRegion); 312 psFree (fitOptions); 313 psFree (models); 314 psphotSersicModelClassCleanup(); 315 return false; 314 // XXX TEST 315 if (!isInteractive) { 316 if (!psThreadJobAddPending(job)) { 317 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 318 psFree(AnalysisRegion); 319 psFree (fitOptions); 320 psFree (models); 321 psphotSersicModelClassCleanup(); 322 return false; 323 } 324 } else { 325 // run without threading 326 if (!psphotExtendedSourceFits_Threaded(job)) { 327 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 328 psFree(AnalysisRegion); 329 psFree (fitOptions); 330 psFree (models); 331 psphotSersicModelClassCleanup(); 332 return false; 333 } 334 psScalar *scalar = NULL; 335 scalar = job->args->data[9]; 336 Next += scalar->data.S32; 337 scalar = job->args->data[10]; 338 Nconvolve += scalar->data.S32; 339 scalar = job->args->data[11]; 340 NconvolvePass += scalar->data.S32; 341 scalar = job->args->data[12]; 342 Nplain += scalar->data.S32; 343 scalar = job->args->data[13]; 344 NplainPass += scalar->data.S32; 345 scalar = job->args->data[14]; 346 Nfaint += scalar->data.S32; 347 scalar = job->args->data[15]; 348 Nfail += scalar->data.S32; 349 psFree(job->args->data[3]); // iterator allocated above 350 psFree(job); 316 351 } 317 psScalar *scalar = NULL;318 scalar = job->args->data[9];319 Next += scalar->data.S32;320 scalar = job->args->data[10];321 Nconvolve += scalar->data.S32;322 scalar = job->args->data[11];323 NconvolvePass += scalar->data.S32;324 scalar = job->args->data[12];325 Nplain += scalar->data.S32;326 scalar = job->args->data[13];327 NplainPass += scalar->data.S32;328 scalar = job->args->data[14];329 Nfaint += scalar->data.S32;330 scalar = job->args->data[15];331 Nfail += scalar->data.S32;332 psFree(job->args->data[3]); // iterator allocated above333 psFree(job);334 # endif335 352 } 336 353 … … 418 435 // psTraceSetLevel ("psLib.math.psMinimizeLMChi2_Alt", 5); 419 436 437 pmModelStatus badModel = PM_MODEL_STATUS_NONE; 438 badModel |= PM_MODEL_STATUS_BADARGS; 439 badModel |= PM_MODEL_STATUS_OFFIMAGE; 440 badModel |= PM_MODEL_STATUS_NAN_CHISQ; 441 badModel |= PM_MODEL_SERSIC_PCM_FAIL_GUESS; 442 badModel |= PM_MODEL_SERSIC_PCM_FAIL_GRID; 443 badModel |= PM_MODEL_PCM_FAIL_GUESS; 444 420 445 // choose the sources of interest 421 446 for (int i = 0; i < sources->n; i++) { … … 423 448 pmSource *source = sources->data[i]; 424 449 425 // skip PSF-like and non-astronomical objects 426 if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue; 427 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 428 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 429 430 // skip saturated stars modeled with a radial profile 431 if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) continue; 432 433 // XXX this should use peak? 450 // rules for measuring petrosian parameters for specific objects are set in 451 // psphotChooseAnalysisOptions.c 452 if (!(source->tmpFlags & PM_SOURCE_TMPF_EXT_FIT)) continue; 453 454 // limit selection by analysis region (XXX move this into psphotChooseAnalysisOption?) 434 455 if (source->peak->x < region->x0) continue; 435 456 if (source->peak->y < region->y0) continue; 436 457 if (source->peak->x > region->x1) continue; 437 458 if (source->peak->y > region->y1) continue; 438 439 440 // XXX for a test, just do the obvious trail441 // XXX if (source->peak->xf < 1100) continue;442 // XXX if (source->peak->xf > 1400) continue;443 // XXX if (source->peak->yf > 245) continue;444 459 445 460 // replace object in image … … 452 467 psphotSetRadiusMomentsExact(&fitRadius, &windowRadius, readout, source, markVal); // NOTE : 6 allocs 453 468 454 // XXX WATCH OUT HERE!!455 // fitRadius = 30;456 457 469 // UPDATE : we have changed the moments calculation. There is now an iteration within 458 470 // psphotKronMasked to determine moments appropriate for a larger object. The values … … 464 476 source->modelFits = psArrayAllocEmpty (models->list->n); 465 477 } 478 479 # ifdef TEST_OBJECT 480 bool testObject = false; 481 testObject |= ((fabs(source->peak->xf - 179) < 5) && (fabs(source->peak->yf - 1138) < 5)); 482 if (testObject) { 483 fprintf (stderr, "test object @ %f, %f\n", source->peak->xf, source->peak->yf); 484 psTraceSetLevel ("psModules.objects.pmPCM_MinimizeChisq", 5); 485 psTraceSetLevel ("psphot.psphotExtendedSourceFits_Threaded", 5); 486 } 487 # endif 466 488 467 489 // loop here over the models chosen for each source (exclude by S/N) … … 479 501 assert (status); 480 502 481 // limit selection to some SN limit 482 bool skipSource = false; 483 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 484 skipSource = (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr); 485 } else { 486 skipSource = (sqrt(source->peak->detValue) < FIT_SN_LIM); 487 } 488 if (skipSource) { 503 // limit selection to some SN limit for specific models (this value only applies if > EXTENDED_SOURCE_SN_LIM) 504 if (isfinite(FIT_SN_LIM)) { 505 if (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr) { 489 506 Nfaint ++; 490 507 continue; 508 } 491 509 } 510 511 source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_RUN; 492 512 493 513 // check on the model type … … 507 527 psTrace ("psphot", 5, "failed to fit psf-conv model for object at %f, %f", source->moments->Mx, source->moments->My); 508 528 Nfail ++; 529 source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_FAIL; 509 530 continue; 510 531 } … … 512 533 source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter); 513 534 Nconvolve ++; 514 if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {535 if (!(modelFit->flags & badModel)) { 515 536 NconvolvePass ++; 516 537 source->mode |= PM_SOURCE_MODE_EXTENDED_FIT; … … 526 547 Nfail ++; 527 548 doneFits = true; 549 source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_FAIL; 528 550 continue; 529 551 } 530 552 psTrace ("psphot", 4, "fit plain model for %f, %f : %s chisq = %f (npix: %d, niter: %d)\n", source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter); 531 553 Nplain ++; 532 if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) {554 if (!(modelFit->flags & badModel)) { 533 555 NplainPass ++; 534 556 source->mode |= PM_SOURCE_MODE_EXTENDED_FIT; … … 544 566 float Ymax = PAR[PM_PAR_YPOS] + 0.5*PAR[PM_PAR_LENGTH]*cos(PAR[PM_PAR_THETA]); 545 567 546 if (false && (source->peak->xf > 1100) && 547 (source->peak->xf < 1400) && 548 (source->peak->yf < 245)) { 568 if ((fabs(source->peak->xf - 2572) < 20) && (fabs(source->peak->yf - 5874) < 20)) { 549 569 fprintf (stderr, "src vs fit : %d %d - %d %d | %f %f - %f %f\n", 550 570 source->pixels->col0, source->pixels->row0, … … 556 576 fprintf (stderr, "update window : %f %f : %f -> %f\n", source->peak->xf, source->peak->yf, fitRadius, 2*fitRadius); 557 577 psphotSetWindowTrail (&fitRadius, &windowRadius, readout, source, markVal, fitRadius*2.0); 578 source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_RETRY; 558 579 } 559 580 } 560 581 } 561 582 } 562 // XXX really need to do this in a cleaner way: 563 if (!modelFit) continue; 583 psAssert (modelFit, "modelFit not set?"); 564 584 565 585 // test for fit quality / result … … 570 590 } 571 591 592 // we are allowed to fit both stars and non-stars here -- if we have fitted 593 // something which we think is a star, we should use that model to subtract the 594 // object from the image. 595 if (source->type == PM_SOURCE_TYPE_STAR) { 596 // ensure the modelPSF is cached 597 pmSourceCacheModel (source, maskVal); 598 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 599 continue; 600 } 601 572 602 // evaluate the relative quality of the models, choose one 603 // the PSF model might be the best fit : allow it to succeed 573 604 float minChisq = NAN; 574 605 int minModel = -1; … … 576 607 pmModel *model = source->modelFits->data[i]; 577 608 609 // skip the really bad fits 578 610 if (!(model->flags & PM_MODEL_STATUS_FITTED)) continue; 579 580 if (model->flags & (PM_MODEL_STATUS_BADARGS)) continue; 581 if (model->flags & (PM_MODEL_STATUS_NONCONVERGE)) continue; 582 if (model->flags & (PM_MODEL_STATUS_OFFIMAGE)) continue; 611 if (model->flags & badModel) continue; 612 613 // if (model->flags & (PM_MODEL_STATUS_NONCONVERGE)) continue; 583 614 584 615 if ((minModel < 0) || (model->chisq < minChisq)) { … … 598 629 pmSourceCacheModel (source, maskVal); 599 630 631 # if (PS_TRACE_ON) 632 pmModel *model = source->modelFits->data[0]; 633 int flags = 0xffffffff; 634 if (model) { 635 flags = model->flags; 636 } 637 fprintf (stderr, "failed to fit extended source model to object %d @ %f, %f (%x)\n", source->id, source->moments->Mx, source->moments->My, flags); 638 #endif 600 639 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 601 640 641 source->mode2 |= PM_SOURCE_MODE2_EXT_FITS_NONE; 602 642 continue; 603 643 } … … 615 655 // cache the model flux 616 656 if (source->modelEXT->isPCM) { 617 pmPCMCacheModel (source, maskVal, psfSize); 657 // fprintf (stderr, "subtract PCM extended source model for object %d @ %f, %f\n", source->id, source->moments->Mx, source->moments->My); 658 pmPCMCacheModel (source, maskVal, psfSize, fitOptions->nsigma); 618 659 } else { 660 // fprintf (stderr, "subtract non-PCM extended source model for object %d @ %f, %f\n", source->id, source->moments->Mx, source->moments->My); 619 661 pmSourceCacheModel (source, maskVal); 620 662 } 663 source->modelEXT->flags |= PM_MODEL_BEST_FIT; 621 664 622 665 // subtract the best fit from the object, leave local sky … … 625 668 psTrace ("psphot", 4, "best ext model for %f, %f : %s chisq = %f\n", source->moments->Mx, source->moments->My, pmModelClassGetName (source->modelEXT->type), source->modelEXT->chisq); 626 669 psTrace ("psphot", 5, "extended source model for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); 670 671 # ifdef TEST_OBJECT 672 if (testObject) { 673 psTraceSetLevel ("psModules.objects.pmPCM_MinimizeChisq", 0); 674 psTraceSetLevel ("psphot.psphotExtendedSourceFits_Threaded", 0); 675 } 676 # endif 627 677 } 628 678 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotImageLoop.c
r34258 r37066 132 132 } 133 133 break; 134 case PSPHOT_FULL_FORCE: 135 if (!psphotFullForceReadout (config, view, "PSPHOT.INPUT")) { 136 psError(psErrorCodeLast(), false, "failure in psphotReadout for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout); 137 psFree (view); 138 return false; 139 } 140 break; 134 141 case PSPHOT_MAKE_PSF: 135 142 if (!psphotMakePSFReadout (config, view, "PSPHOT.INPUT")) { -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotKronIterate.c
r35769 r37066 166 166 } 167 167 168 # if (PS_TRACE_ON) 168 169 fprintf (stderr, "--- starting KRON ---\n"); 170 #endif 169 171 170 172 // We measure the Kron Radius on a smoothed copy of the readout image … … 530 532 source->moments->KronFlux = NAN; 531 533 source->moments->KronFluxErr = NAN; 534 source->moments->KronFinner = NAN; 535 source->moments->KronFouter = NAN; 532 536 return false; 533 537 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotLoadPSF.c
r29936 r37066 1 1 # include "psphotInternal.h" 2 3 // PSPHOT.PSF.LOAD vs input file -- see note at top 4 bool psphotLoadPSF (pmConfig *config, const pmFPAview *view, const char *filerule) { 5 6 int num = psphotFileruleCount(config, filerule); 7 8 // loop over the available readouts 9 for (int i = 0; i < num; i++) { 10 11 // Generate the mask and weight images, including the user-defined analysis region of interest 12 if (!psphotLoadPSFReadout (config, view, filerule, "PSPHOT.PSF.LOAD", i)) { 13 psError (PSPHOT_ERR_CONFIG, false, "failed to load PSF model for PSPHOT.PSF.LOAD entry %d", i); 14 return false; 15 } 16 } 17 return true; 18 } 2 19 3 20 // NOTE : pmPSF_IO.c functions must load the psf model onto the chip->analysis metadata because … … 58 75 return true; 59 76 } 60 61 // PSPHOT.PSF.LOAD vs input file -- see note at top62 bool psphotLoadPSF (pmConfig *config, const pmFPAview *view, const char *filerule) {63 64 int num = psphotFileruleCount(config, filerule);65 66 // loop over the available readouts67 for (int i = 0; i < num; i++) {68 69 // Generate the mask and weight images, including the user-defined analysis region of interest70 if (!psphotLoadPSFReadout (config, view, filerule, "PSPHOT.PSF.LOAD", i)) {71 psError (PSPHOT_ERR_CONFIG, false, "failed to load PSF model for PSPHOT.PSF.LOAD entry %d", i);72 return false;73 }74 }75 return true;76 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotLoadSRCTEXT.c
r32348 r37066 73 73 dPAR[PM_PAR_I0] = 0.0; 74 74 75 pmPSF_AxesToModel (PAR, axes, model Type);75 pmPSF_AxesToModel (PAR, axes, model->class->useReff); 76 76 77 77 float peakFlux = 1.0; -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotMakeFluxScale.c
r30624 r37066 38 38 } else { 39 39 // measure the fitMag for this model 40 fitSum = model-> modelFlux (model->params);40 fitSum = model->class->modelFlux (model->params); 41 41 } 42 42 if (fitSum < 1.e-6) continue; -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotMergeSources.c
r34266 r37066 39 39 psAssert (newSources, "missing sources?"); 40 40 41 // XXX TEST:42 if (detections->allSources) {43 psphotMaskCosmicRayFootprintCheck(detections->allSources);44 }45 if (detections->newSources) {46 psphotMaskCosmicRayFootprintCheck(detections->newSources);47 }48 49 41 if (!detections->allSources) { 50 42 detections->allSources = psArrayAllocEmpty(newSources->n); … … 65 57 // Merge the externally supplied sources with the existing sources. Mark them as having mode 66 58 // PM_SOURCE_MODE_EXTERNAL. 59 60 // XXX this function needs to be updated slightly for psphotFullForce: 61 // * load the additional parameters to guide the new concepts 67 62 68 63 // XXX This function needs to be updated to loop over set of input files. At the moment, we … … 73 68 bool status; 74 69 pmDetections *extCMF = NULL; 70 pmDetections *extCFF = NULL; 75 71 psArray *extSourcesTXT = NULL; 76 72 int index = 0; … … 102 98 { 103 99 pmReadout *readoutCMF = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT.CMF"); 104 if (!readoutCMF) goto load TXT;100 if (!readoutCMF) goto loadCFF; 105 101 106 102 extCMF = psMetadataLookupPtr (NULL, readoutCMF->analysis, "PSPHOT.DETECTIONS"); … … 125 121 } 126 122 123 loadCFF: 124 // load data from input CFF file: 125 { 126 pmReadout *readoutCFF = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT.CFF"); 127 if (!readoutCFF) goto loadTXT; 128 129 extCFF = psMetadataLookupPtr (NULL, readoutCFF->analysis, "PSPHOT.DETECTIONS"); 130 if (extCFF) { 131 psF32 exptime = psMetadataLookupF32(NULL, readout->parent->concepts, "CELL.EXPOSURE"); 132 for (int i = 0; i < extCFF->allSources->n; i++) { 133 pmSource *source = extCFF->allSources->data[i]; 134 135 // setting this bit not only tracks the inputs, it makes pmSourceMoments 136 // keep the Mx,My values for the centroid. 137 source->mode |= PM_SOURCE_MODE_EXTERNAL; 138 139 // source->peak->detValue,rawFlux,smoothFlux all set to input flux value which is scaled 140 // to 1 second exposure time. Scale to this image's exposure. 141 source->peak->rawFlux *= exptime; 142 source->peak->smoothFlux *= exptime; 143 source->peak->detValue *= exptime; 144 // source->peak->xf,yf, moments->Mx,My all set to input position 145 146 // drop the loaded source modelPSF 147 psFree (source->modelPSF); 148 source->modelPSF = NULL; 149 source->imageID = index; 150 151 psArrayAdd (detections->newSources, 100, source); 152 } 153 } 154 } 155 127 156 loadTXT: 128 157 … … 157 186 psFree (detections); 158 187 159 if (! extCMF && !extSourcesTXT) {188 if (!(extCMF || extCFF || extSourcesTXT)) { 160 189 psLogMsg ("psphot", 3, "no external sources for this readout"); 161 190 return true; … … 163 192 164 193 int nCMF = extCMF ? extCMF->allSources->n : 0; 165 int nTXT = extSourcesTXT ? extSourcesTXT->n : 0; 166 167 psLogMsg ("psphot", 3, "%d external sources (%d cmf, %d text) merged to yield %ld total sources", 168 nCMF + nTXT, nCMF, nTXT, sources->n); 194 int nCFF = extCFF ? extCFF->allSources->n : 0; 195 int nTXT = extSourcesTXT ? extSourcesTXT->n : 0; 196 197 psLogMsg ("psphot", 3, "%d external sources (%d cmf, %d cff, %d text) merged to yield %ld total sources", 198 nCMF + nCFF + nTXT, nCMF, nCFF, nTXT, sources->n); 169 199 return true; 170 200 } … … 812 842 // array containing the child sources. XXX currently, this is only used by psphotStackReadout 813 843 // (sources go on allSources so that psphotChoosePSF can be called repeatedly) 814 psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc ) {844 psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc, bool sourcesSubtracted) { 815 845 816 846 bool status; … … 919 949 // child sources have not been subtracted in this image, but this flag may be raised if 920 950 // they were subtracted in the parent's image 921 sourceOut->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED; 951 // XXX NOTE : in the pre-20130914 version of psphotStack, we carried a copy of the pixels 952 // generated before the subtraction took place (and then we smoothed to match the desired PSF). 953 // in the new version, we copy the image after subtraction; we need to distinguish these cases 954 if (!sourcesSubtracted) { 955 sourceOut->tmpFlags &= ~PM_SOURCE_TMPF_SUBTRACTED; 956 } 922 957 923 958 // set the output detections: -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotModelTestReadout.c
r35769 r37066 125 125 126 126 // get the source moments 127 status = pmSourceMoments (source, radius, 0.25*radius, 0.0, MIN_KRON_RADIUS, maskVal);127 status = pmSourceMoments (source, radius, 0.25*radius, 0.0, MIN_KRON_RADIUS, maskVal); 128 128 if (!status) psAbort("psSourceMoments error"); 129 129 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotPetrosianRadialBins.c
r31154 r37066 36 36 pmSourceRadialProfile *profile = source->extpars->petProfile; 37 37 38 float skyModelErrorSQ = PS_SQR(skynoise);38 // float skyModelErrorSQ = PS_SQR(skynoise); 39 39 40 40 int nMax = radiusMax; … … 133 133 if (radius->data.F32[i] > Rmax) { 134 134 // calculate the value for the nOut bin 135 float value , dvalue;135 float value; // , dvalue; 136 136 if (values->n > 0) { 137 137 psVectorStats (stats, values, NULL, NULL, 0); 138 138 value = stats->robustMedian; 139 dvalue = stats->robustStdev;139 // dvalue = stats->robustStdev; 140 140 } else { 141 141 value = NAN; 142 dvalue = NAN;142 // dvalue = NAN; 143 143 } 144 144 145 145 binSB->data.F32[nOut] = value; 146 binSBstdev->data.F32[nOut] = sqrt(PS_SQR(dvalue) / values->n + skyModelErrorSQ); 146 // binSBstdev->data.F32[nOut] = sqrt(PS_SQR(dvalue) / values->n + skyModelErrorSQ); 147 binSBstdev->data.F32[nOut] = skynoise / sqrt(values->n); 147 148 binFill->data.F32[nOut] = values->n / binArea->data.F32[nOut]; 148 149 … … 185 186 psFree(values); 186 187 psFree(stats); 188 source->mode2 |= PM_SOURCE_MODE2_RADBIN_NAN_CENTER; 187 189 return true; 188 190 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotPetrosianStats.c
r34086 r37066 6 6 // generate the Petrosian radius and flux from the mean surface brightness (r_i) 7 7 8 float InterpolateValuesQuadratic (float *Xin, float *Yin, float X); 8 9 float InterpolateValues (float X0, float Y0, float X1, float Y1, float X); 9 10 float InterpolateValuesErrX (float X0, float Y0, float X1, float Y1, float X, float dX0, float dX1); … … 20 21 if (!profile->binSB) { 21 22 psLogMsg ("psphot", PS_LOG_DETAIL, "no petrosian profile, skipping source %f, %f", source->peak->xf, source->peak->yf); 23 source->mode2 |= PM_SOURCE_MODE2_PETRO_NO_PROFILE; 22 24 return true; 23 25 } … … 53 55 float dFsum2 = 0.0; 54 56 55 float nSigma = 3.0;57 float nSigma = 2.0; 56 58 int lowestSignificantRadius = 0; 57 59 float lowestSignificantRatio = 1.0; … … 117 119 petRadius = InterpolateValues (1.0, 0.0, petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO); 118 120 petRadiusErr = InterpolateValuesErrX (1.0, 0.0, petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO, 0.0, petRatioErr->data.F32[nOut]); 119 } else { 120 petRadius = InterpolateValues (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO); 121 petRadiusErr = InterpolateValuesErrX (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO, petRatioErr->data.F32[nOut-1], petRatioErr->data.F32[nOut]); 121 source->mode2 |= PM_SOURCE_MODE2_PETRO_RATIO_ZEROBIN; 122 } else { 123 // petRadius = InterpolateValues (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO); 124 if (nOut > 1) { 125 petRadius = InterpolateValuesQuadratic (&petRatio->data.F32[nOut-2], &refRadius->data.F32[nOut-2], PETROSIAN_RATIO); 126 } else { 127 petRadius = InterpolateValuesQuadratic (&petRatio->data.F32[nOut-3], &refRadius->data.F32[nOut-3], PETROSIAN_RATIO); 128 } 129 # if (PS_TRACE_ON) 130 float petRadiusLinear = InterpolateValues (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO); 131 if (fabs(petRadius - petRadiusLinear) > fabs(refRadius->data.F32[nOut] - refRadius->data.F32[nOut-1])) { 132 fprintf (stderr, "big difference : %f vs %f\n", petRadius, petRadiusLinear); 133 } 134 #endif 135 petRadiusErr = InterpolateValuesErrX (petRatio->data.F32[nOut-1], refRadius->data.F32[nOut-1], petRatio->data.F32[nOut], refRadius->data.F32[nOut], PETROSIAN_RATIO, petRatioErr->data.F32[nOut-1], petRatioErr->data.F32[nOut]); 122 136 } 123 137 above = false; … … 148 162 fprintf (stderr, "nan pet radius\n"); 149 163 } 164 source->mode2 |= PM_SOURCE_MODE2_PETRO_INSIG_RATIO; 150 165 } 151 166 … … 180 195 bool found50 = false; 181 196 bool found90 = false; 197 182 198 // XXX use bisection to do this faster: 183 199 for (int i = 0; !(found50 && found90) && i < refRadius->n; i++) { … … 235 251 } 236 252 253 // Lagrange's form of the interpolating polynomial... 254 float InterpolateValuesQuadratic (float *Xin, float *Yin, float X) { 255 256 float dx01 = Xin[0] - Xin[1]; 257 float dx02 = Xin[0] - Xin[2]; 258 float dx12 = Xin[1] - Xin[2]; 259 260 float dx0 = X - Xin[0]; 261 float dx1 = X - Xin[1]; 262 float dx2 = X - Xin[2]; 263 264 float y0 = Yin[0]*dx1*dx2/(dx01*dx02); 265 float y1 = Yin[1]*dx0*dx2/(dx01*dx12); // need - sign 266 float y2 = Yin[2]*dx0*dx1/(dx02*dx12); 267 268 float Y = y0 - y1 + y2; 269 return Y; 270 } 271 237 272 float InterpolateValues (float X0, float Y0, float X1, float Y1, float X) { 238 273 float dydx = (Y1 - Y0) / (X1 - X0); -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotRadialBins.c
r34226 r37066 44 44 psVector *radMin = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.LOWER"); 45 45 psVector *radMax = psMetadataLookupPtr (&status, recipe, "RADIAL.ANNULAR.BINS.UPPER"); 46 if (!radMin || !radMin->n) { 47 psError (PSPHOT_ERR_CONFIG, true, "error in definition of annular bins (radMin missing or empty)"); 48 return false; 49 } 50 if (!radMax || !radMax->n) { 51 psError (PSPHOT_ERR_CONFIG, true, "error in definition of annular bins (radMax missing or empty)"); 52 return false; 53 } 46 psAssert (radMin, "RADIAL.ANNULAR.BINS.LOWER is missing from recipe"); 47 psAssert (radMin->n, "RADIAL.ANNULAR.BINS.LOWER is empty in recipe"); 48 psAssert (radMax, "RADIAL.ANNULAR.BINS.UPPER is missing from recipe"); 49 psAssert (radMax->n, "RADIAL.ANNULAR.BINS.UPPER is empty in recipe"); 54 50 55 51 psVector *binSB = psVectorAllocEmpty(radMin->n, PS_TYPE_F32); // surface brightness of radial bin … … 161 157 psFree(values); 162 158 psFree(stats); 159 source->mode2 |= PM_SOURCE_MODE2_RADBIN_NAN_CENTER; 163 160 return true; 164 161 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotRadialProfile.c
r32348 r37066 1 1 # include "psphotInternal.h" 2 3 static int Nskip1 = 0; 4 static int Nskip2 = 0; 5 static int Nskip3 = 0; 6 static int Nskip4 = 0; 7 static int Nskip5 = 0; 8 9 # define SKIP(VALUE) { VALUE++; return false; } 2 10 3 11 bool psphotRadialProfile (pmSource *source, psMetadata *recipe, float skynoise, psImageMaskType maskVal) { … … 23 31 if (!psphotRadialProfilesByAngles (source, Nsec, Rmax)) { 24 32 psError (PS_ERR_UNKNOWN, false, "failed to measure radial profile for petrosian"); 25 return false;33 SKIP (Nskip1); 26 34 } 27 35 // allocate: extpars->radFlux->radii,fluxes,theta … … 32 40 if (!psphotRadiiFromProfiles (source, fluxMin, fluxMax)) { 33 41 psError (PS_ERR_UNKNOWN, false, "failed to measure isophotal radii from profiles"); 34 return false;42 SKIP (Nskip2); 35 43 } 36 44 // allocate : extpars->radFlux->isophotalRadii (use profile->radii,fluxes) … … 40 48 if (!psphotEllipticalContour (source)) { 41 49 // psLogMsg ("psphot", 3, "failed to measure elliptical contour"); 42 return false;50 SKIP (Nskip3); 43 51 } 44 52 // use extpars->radFlux->isophotalRadii,theta (result in extpars->axes) … … 48 56 if (!psphotEllipticalProfile (source, RAW_RADIUS)) { 49 57 psError (PS_ERR_UNKNOWN, false, "failed to generate elliptical profile"); 50 return false;58 SKIP (Nskip4); 51 59 } 52 60 // allocate extpars->ellipticalFlux->radiusElliptical,fluxElliptical (use axes to scale raw pixels) … … 55 63 if (!psphotRadialBins (recipe, source, Rmax, skynoise)) { 56 64 psError (PS_ERR_UNKNOWN, false, "failed to generate radial bins"); 57 return false;65 SKIP (Nskip5); 58 66 } 59 67 // allocate extpars->radProfile->binSB, binSBstdv, binSum, binFill, radialBins, area (small lengths) … … 62 70 return true; 63 71 } 72 73 void psphotRadialProfileShowSkips () { 74 # if (PS_TRACE_ON) 75 fprintf (stderr, "radial profile skipped @ 1 : %d\n", Nskip1); 76 fprintf (stderr, "radial profile skipped @ 2 : %d\n", Nskip2); 77 fprintf (stderr, "radial profile skipped @ 3 : %d\n", Nskip3); 78 fprintf (stderr, "radial profile skipped @ 4 : %d\n", Nskip4); 79 fprintf (stderr, "radial profile skipped @ 5 : %d\n", Nskip5); 80 #endif 81 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotRadiusChecks.c
r32348 r37066 60 60 if (radiusFit <= 0) { // use fixed radius 61 61 if (moments == NULL) { 62 radiusFit = model-> modelRadius(model->params, PSF_FIT_NSIGMA*moments->dSky);62 radiusFit = model->class->modelRadius(model->params, PSF_FIT_NSIGMA*moments->dSky); 63 63 } else { 64 radiusFit = model-> modelRadius(model->params, 1.0);64 radiusFit = model->class->modelRadius(model->params, 1.0); 65 65 } 66 66 model->fitRadius = (RADIUS_TYPE)(radiusFit + PSF_FIT_PADDING); … … 95 95 if (radiusFit <= 0) { // use fixed radius 96 96 if (moments == NULL) { 97 radiusFit = model-> modelRadius(model->params, PSF_FIT_NSIGMA*moments->dSky);97 radiusFit = model->class->modelRadius(model->params, PSF_FIT_NSIGMA*moments->dSky); 98 98 } else { 99 radiusFit = model-> modelRadius(model->params, 1.0);99 radiusFit = model->class->modelRadius(model->params, 1.0); 100 100 } 101 101 model->fitRadius = (RADIUS_TYPE)(radiusFit + PSF_FIT_PADDING); … … 171 171 # undef MIN_WINDOW 172 172 173 // XXX EAM : 20130724 : for a test, double the window size parameters 174 // # define MIN_WINDOW 10.0 175 // # define SCALE1 7.0 173 176 # define MIN_WINDOW 5.0 174 # define SCALE1 5.0177 # define SCALE1 3.0 175 178 # define PAD_WINDOW 3.0 176 179 … … 291 294 float flux = deep ? EXT_FIT_NSIGMA*EXT_FIT_SKY_SIG : 0.1 * model->params->data.F32[PM_PAR_I0]; 292 295 293 float rawRadius = model-> modelRadius (model->params, flux);296 float rawRadius = model->class->modelRadius (model->params, flux); 294 297 if (isnan(rawRadius)) return false; 295 298 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotReadout.c
r34418 r37066 316 316 psphotSourceSize (config, view, filerule, false); // pass 2 (detections->allSources) 317 317 318 // XXX currently we are doing both the analysis of the size and the assessment of "fit ext" 319 // in source size. this overloads the bit MODE_EXT_LIMIT to mean "fit ext" not just 320 // "bigger than a PSF" 321 322 // decide which source(s) are to be fitted with the extended source analysis code. 323 psphotChooseAnalysisOptions (config, view, filerule); 324 318 325 psphotExtendedSourceAnalysis (config, view, filerule); // pass 1 (detections->allSources) 319 326 psphotExtendedSourceFits (config, view, filerule); // pass 1 (detections->allSources) … … 333 340 // calculate source magnitudes 334 341 if (!psphotMagnitudes(config, view, filerule)) { // pass 1 (detections->allSources) 335 psErrorStackPrint(stderr, "Unable to do magnitudes.");342 psErrorStackPrint(stderr, "Unable to do magnitudes."); 336 343 psErrorClear(); 337 344 } 345 346 // calculate lensing parameters 347 if (!psphotLensing(config, view, filerule)) { 348 psErrorStackPrint(stderr, "Unable to do lensing parameters."); 349 psErrorClear(); 350 } 351 338 352 if (!psphotEfficiency(config, view, filerule)) { // pass 1 339 353 psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources"); … … 346 360 // replace background in residual image 347 361 if (!psphotSkyReplace (config, view, filerule)) { // pass 1 348 psErrorStackPrint(stderr, "Unable to replace sky");349 psErrorClear();362 psErrorStackPrint(stderr, "Unable to replace sky"); 363 psErrorClear(); 350 364 } 351 365 352 366 // drop the references to the image pixels held by each source 353 367 if (!psphotSourceFreePixels (config, view, filerule)) { // pass 1 354 psErrorStackPrint(stderr, "Unable to free source pixels");355 psErrorClear();368 psErrorStackPrint(stderr, "Unable to free source pixels"); 369 psErrorClear(); 356 370 } 357 371 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotRoughClass.c
r32348 r37066 87 87 if (NX > NY) { 88 88 NXuse = ScaleForClump; 89 NYuse = (int) (ScaleForClump * (N Y / NX) + 0.5);89 NYuse = (int) (ScaleForClump * (NX / NY) + 0.5); 90 90 } else { 91 91 NYuse = ScaleForClump; -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotSersicModelClass.c
r33410 r37066 586 586 coord->data.F32[1] = (psF32) (i + source->pixels->row0); 587 587 588 pcm->modelConvFlux->data.F32[i][j] = pcm->modelConv-> modelFunc (NULL, params, coord);588 pcm->modelConvFlux->data.F32[i][j] = pcm->modelConv->class->modelFunc (NULL, params, coord); 589 589 } 590 590 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotSetThreads.c
r35769 r37066 47 47 psFree(task); 48 48 49 task = psThreadTaskAlloc("PSPHOT_KRON_FLUX", 4); 50 task->function = &psphotKronFlux_Threaded; 51 psThreadTaskAdd(task); 52 psFree(task); 53 54 task = psThreadTaskAlloc("PSPHOT_PETRO_FLUX", 4); 55 task->function = &psphotPetroFlux_Threaded; 56 psThreadTaskAdd(task); 57 psFree(task); 58 59 task = psThreadTaskAlloc("PSPHOT_GALAXY_SHAPES", 7); 60 task->function = &psphotGalaxyShape_Threaded; 61 psThreadTaskAdd(task); 62 psFree(task); 63 49 64 task = psThreadTaskAlloc("PSPHOT_BLEND_FIT", 10); 50 65 task->function = &psphotBlendFit_Threaded; -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotSourceFits.c
r35769 r37066 19 19 static int NfitIterPCM = 0; 20 20 static int NfitPixPCM = 0; 21 22 bool psphotPCMfitCheckSize (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize); 23 bool psphotPCMfitRetry (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, float psfSize); 21 24 22 25 bool psphotFitInit (int nThreads) { … … 559 562 560 563 # define TIMING 0 564 # define EXTRA_VERBOSE 0 565 566 bool psphotSersicModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize); 567 bool psphotFitSersicShapeAndIndex (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 568 bool psphotFitSersicShapeAndIndexGrid (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 569 bool psphotFitSersicShapeAndIndexGridAuto (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 561 570 562 571 pmModel *psphotFitPCM (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { … … 573 582 maskVal |= markVal; 574 583 575 // allocate the model 584 // allocate the model (this can only fail on a config error) 576 585 pmModel *model = pmModelAlloc(modelType); 577 if (!model) { 578 return NULL; 579 } 580 581 float t1, t2, t4, t5; 586 psAssert (model, "invalid extended model name"); 587 588 float t1, t2, t3, t4, t5; 589 t1 = t2 = t3 = t4 = t5 = 0.0; 582 590 if (TIMING) { psTimerStart ("psphotFitPCM"); } 591 592 // if we are ever (in a given psphot implementation) going to fit a parameter, we must set the options here to include 593 // that parameter (otherwise pmPCMupdate will fail to allocate the dmodelFlux image) 594 // thus, if the sersic analysis below uses an index fit, need to use this EXT_AND_SKY mode for init 595 596 options.mode = PM_SOURCE_FIT_EXT; 597 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { 598 options.mode = PM_SOURCE_FIT_EXT_AND_SKY; 599 } 600 if (modelType == pmModelClassGetType("PS_MODEL_DEV")) { 601 options.mode = PM_SOURCE_FIT_SHAPE; 602 options.mode = PM_SOURCE_FIT_EXT_AND_SKY; 603 } 604 if (modelType == pmModelClassGetType("PS_MODEL_EXP")) { 605 options.mode = PM_SOURCE_FIT_EXT_AND_SKY; 606 } 583 607 584 608 pmPCMdata *pcm = pmPCMinit (source, &options, model, maskVal, psfSize); … … 594 618 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { 595 619 // use the source moments, etc to guess basic model parameters 596 if (!psphotSersicModel ClassGuessPCM (pcm, source)) {620 if (!psphotSersicModelGuessPCM (pcm, source, maskVal, psfSize)) { 597 621 psFree (pcm); 598 model->flags |= PM_MODEL_STATUS_BADARGS; 622 model->flags |= PM_MODEL_SERSIC_PCM_FAIL_GUESS; 623 return model; 624 } 625 if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); } 626 627 // psphotFitSersicShapeAndIndex (pcm, readout, source, fitOptions, maskVal, markVal, psfSize); 628 options.mode = PM_SOURCE_FIT_NO_INDEX; 629 if (!psphotFitSersicShapeAndIndexGridAuto (pcm, readout, source, &options, maskVal, markVal, psfSize)) { 630 psFree (pcm); 631 model->flags |= PM_MODEL_SERSIC_PCM_FAIL_GRID; 632 psError(PS_ERR_UNKNOWN, true, "Failed to find a index & shape"); 633 psErrorClear (); // clear the polynomial error 599 634 return model; 600 635 } … … 603 638 if (!pmSourceModelGuessPCM (pcm, source, maskVal, markVal)) { 604 639 psFree (pcm); 605 model->flags |= PM_MODEL_ STATUS_BADARGS;640 model->flags |= PM_MODEL_PCM_FAIL_GUESS; 606 641 return model; 607 642 } 608 643 } 609 644 610 if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); } 611 612 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { 613 options.mode = PM_SOURCE_FIT_NO_INDEX; 614 } else { 615 options.mode = PM_SOURCE_FIT_EXT; 616 } 617 // update the pcm elements if we have changed the circumstance (options.mode or source->pixels) 618 pmPCMupdate(pcm, source, &options, model); 619 if (TIMING) { t4 = psTimerMark ("psphotFitPCM"); } 645 if (TIMING) { t3 = psTimerMark ("psphotFitPCM"); } 620 646 621 647 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5); … … 623 649 NfitIterPCM += pcm->modelConv->nIter; 624 650 NfitPixPCM += pcm->modelConv->nDOF; 651 if (TIMING) { t4 = psTimerMark ("psphotFitPCM"); } 652 653 // XXX we might make this more efficient by setting NITER to be fairly small. if we hit the iteration 654 // limit, then we could do a small grid search on the size and try again from the best fit 655 656 if (options.isInteractive) psphotPCMfitCheckSize (pcm, source, maskVal, psfSize); 657 // if (pcm->modelConv->nIter == fitOptions->nIter) { 658 // psphotPCMfitRetry (pcm, source, &options, maskVal, markVal, psfSize); 659 // } 625 660 if (TIMING) { t5 = psTimerMark ("psphotFitPCM"); } 626 661 627 662 if (TIMING) { 628 663 int nPixBig = source->pixels->numCols * source->pixels->numRows; 629 fprintf (stderr, "psphotFitPCM : nIter: %2d, radius: %6.1f, npix: %5d of %5d, t1: %6.4f, t2: %6.4f, t4: %6.4f, t5: %6.4f\n", model->nIter, model->fitRadius, model->nPix, nPixBig, t1, t2, t4, t5); 630 } 631 632 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); 664 fprintf (stderr, "psphotFitPCM : nIter: %2d, radius: %6.1f, npix: %5d of %5d, t1: %6.4f, t2: %6.4f, t3: %6.4f, t4: %6.4f, t5: %6.4f\n", model->nIter, model->fitRadius, model->nPix, nPixBig, t1, t2, t3, t4, t5); 665 } 666 if (EXTRA_VERBOSE && !TIMING) { 667 int nPixBig = source->pixels->numCols * source->pixels->numRows; 668 float *PAR = model->params->data.F32; 669 fprintf (stderr, "source %d : %f - %f %f - %f %f %f - %f | nIter: %2d, radius: %6.1f, npix: %5d of %5d, chisq %f\n", source->id, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1], model->nIter, model->fitRadius, model->nPix, nPixBig, model->chisqNorm); 670 } 671 633 672 psFree (pcm); 634 673 … … 661 700 model->params->data.F32[PM_PAR_7] = 0.5/indexGuess[i]; 662 701 663 if (!model-> modelGuess(model, source, maskVal, markVal)) {702 if (!model->class->modelGuess(model, source, maskVal, markVal)) { 664 703 model->flags |= PM_MODEL_STATUS_BADARGS; 665 704 return false; … … 684 723 model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it 685 724 model->params->data.F32[PM_PAR_7] = 0.5/indexGuess[iMin]; 686 model-> modelGuess(model, source, maskVal, markVal);725 model->class->modelGuess(model, source, maskVal, markVal); 687 726 688 727 return true; … … 713 752 model->params->data.F32[PM_PAR_7] = indexGuess[i]; 714 753 715 if (!model-> modelGuess(model, source, maskVal, markVal)) {754 if (!model->class->modelGuess(model, source, maskVal, markVal)) { 716 755 model->flags |= PM_MODEL_STATUS_BADARGS; 717 756 return false; … … 748 787 return true; 749 788 } 789 790 // 0.5 / n for (1.0, 1.25, 1.66, 2.0, 3.33, 4.0) 791 // float indexGuessInv[] = {0.5, 0.4, 0.3, 0.25, 0.20, 0.15, 0.125}; 792 793 // 0.5 / n for (0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0) 794 float indexGuessInv[] = {1.00, 0.50, 0.333, 0.25, 0.166, 0.125, 0.10, 0.0833}; 795 float indexGuessR1q[] = {1.06, 1.19, 1.335, 1.48, 1.840, 2.290, 2.84, 3.5300}; 796 # define N_INDEX_GUESS_INV 8 797 798 // we are going to guess in fractions about the R1-based guess 799 float reffGuess[] = {0.8, 0.9, 1.0, 1.12, 1.25}; 800 # define N_REFF_GUESS 5 801 802 // A sersic model is very sensitive to the index. attempt to find the index first by grid search in just the index 803 // for a sersic model, attempt to fit just the index and normalization with a modest number of iterations 804 bool psphotSersicModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize) { 805 806 // we get a reasonable guess from: 807 // * Reff = Kron R1 / Q(index) -- Q comes from Graham & Driver 808 // * Rmajor / Rminor & Theta from moments 809 // * Io from total Kron flux 810 811 // the guesses are used to fill in PAR: 812 psF32 *PAR = pcm->modelConv->params->data.F32; 813 814 // convert the moments to Major,Minor,Theta 815 psEllipseMoments moments; 816 817 if (!isfinite(source->moments->Mrf)) return false; 818 if (!isfinite(source->moments->Mxx)) return false; 819 if (!isfinite(source->moments->Mxy)) return false; 820 if (!isfinite(source->moments->Myy)) return false; 821 822 moments.x2 = source->moments->Mxx; 823 moments.y2 = source->moments->Myy; 824 moments.xy = source->moments->Mxy; 825 826 // limit axis ratio < 20.0 827 psEllipseAxes momentAxes = psEllipseMomentsToAxes (moments, 20.0); 828 829 // set the model position 830 if (!pmModelSetPosition(&PAR[PM_PAR_XPOS], &PAR[PM_PAR_YPOS], source)) { 831 return false; 832 } 833 834 // sky is zero (no longer fitted, but not yet deprecated) 835 PAR[PM_PAR_SKY] = 0.0; 836 837 // for the index loop, use Io = 1.0, use fitted values to determine Io 838 PAR[PM_PAR_I0] = 1.0; 839 840 float xMin = NAN; 841 float iMin = NAN; 842 float sMin = NAN; 843 float rMin = NAN; 844 845 // loop over index and Reff, keeping the ARatio and Theta constant? 846 // loop over index guesses and find the best fit 847 for (int j = 0; j < N_REFF_GUESS; j++) { 848 for (int i = 0; i < N_INDEX_GUESS_INV; i++) { 849 PAR[PM_PAR_7] = indexGuessInv[i]; 850 851 psEllipseAxes guessAxes; 852 guessAxes.major = reffGuess[j] * source->moments->Mrf / indexGuessR1q[i]; 853 guessAxes.minor = guessAxes.major * (momentAxes.minor / momentAxes.major); 854 guessAxes.theta = momentAxes.theta; 855 856 if (!isfinite(guessAxes.major)) return false; 857 if (!isfinite(guessAxes.minor)) return false; 858 if (!isfinite(guessAxes.theta)) return false; 859 860 // convert the major,minor,theta to shape parameters for an Reff-like model 861 pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true); 862 863 // generated the modelFlux 864 // XXX note that this does not add sky to model 865 pmPCMMakeModel (source, pcm->modelConv, pcm->nsigma, maskVal, psfSize); 866 867 float YY = 0.0; 868 float YM = 0.0; 869 float MM = 0.0; 870 bool usePoisson = false; 871 872 for (int iy = 0; iy < source->pixels->numRows; iy++) { 873 for (int ix = 0; ix < source->pixels->numCols; ix++) { 874 // skip masked points 875 if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) { 876 continue; 877 } 878 // skip zero-variance points 879 if (source->variance->data.F32[iy][ix] == 0) { 880 continue; 881 } 882 // skip nan value points 883 if (!isfinite(source->pixels->data.F32[iy][ix])) { 884 continue; 885 } 886 887 float fy = source->pixels->data.F32[iy][ix]; 888 float fm = source->modelFlux->data.F32[iy][ix]; 889 float wt = (usePoisson) ? 1.0 / source->variance->data.F32[iy][ix] : 1.0; 890 891 YY += PS_SQR(fy) * wt; 892 YM += fm * fy * wt; 893 MM += PS_SQR(fm) * wt; 894 } 895 } 896 897 float Io = YM / MM; 898 float Chisq = YY - 2 * Io * YM + Io * Io * MM; 899 if (isnan(xMin) || (Chisq < xMin)) { 900 xMin = Chisq; 901 iMin = Io; 902 sMin = indexGuessInv[i]; 903 rMin = reffGuess[j] / indexGuessR1q[i]; 904 } 905 if (EXTRA_VERBOSE) { 906 fprintf (stderr, "%d | %f %f %f %f | %f %f %f %f", i, indexGuessInv[i], reffGuess[j], Io, Chisq, sMin, rMin, iMin, xMin); 907 fprintf (stderr, "\n"); 908 } 909 } 910 } 911 912 { 913 psEllipseAxes guessAxes; 914 guessAxes.major = rMin * source->moments->Mrf; 915 guessAxes.minor = guessAxes.major * (momentAxes.minor / momentAxes.major); 916 guessAxes.theta = momentAxes.theta; 917 918 if (!isfinite(guessAxes.major)) return false; 919 if (!isfinite(guessAxes.minor)) return false; 920 if (!isfinite(guessAxes.theta)) return false; 921 922 // convert the major,minor,theta to shape parameters for an Reff-like model 923 pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true); 924 } 925 926 PAR[PM_PAR_I0] = iMin; 927 PAR[PM_PAR_7] = sMin; 928 929 return true; 930 } 931 932 // we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX 933 bool psphotFitSersicShapeAndIndex (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 934 935 pmModel *model = pcm->modelConv; 936 937 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); 938 939 pmSourceFitOptions options = *fitOptions; 940 941 for (int i = 0; i < 3; i++) { 942 // fit EXT (not PSF) model (set/unset the pixel mask) 943 options.mode = PM_SOURCE_FIT_SHAPE; 944 options.nIter = 2; 945 946 // update the pcm elements if we have changed the circumstance (here, options.mode) 947 pmPCMupdate(pcm, source, &options, model); 948 949 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 950 if (EXTRA_VERBOSE) { 951 float *PAR = model->params->data.F32; 952 fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 953 } 954 955 // fit EXT (not PSF) model (set/unset the pixel mask) 956 options.mode = PM_SOURCE_FIT_INDEX; 957 // options.mode = PM_SOURCE_FIT_EXT_AND_SKY; 958 options.nIter = 30; 959 960 // update the pcm elements if we have changed the circumstance (here, options.mode) 961 pmPCMupdate(pcm, source, &options, model); 962 963 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 964 if (EXTRA_VERBOSE) { 965 float *PAR = model->params->data.F32; 966 fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 967 } 968 } 969 970 // update the pcm elements if we have changed the circumstance (here, options.mode) 971 pmPCMupdate(pcm, source, fitOptions, model); 972 973 return true; 974 } 975 976 // we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX 977 bool psphotFitSersicShapeAndIndexGridAuto (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 978 979 pmModel *model = pcm->modelConv; 980 981 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); 982 983 pmSourceFitOptions options = *fitOptions; 984 985 psF32 *PAR = pcm->modelConv->params->data.F32; 986 987 options.mode = PM_SOURCE_FIT_SHAPE; 988 options.nIter = 7; 989 990 // update the pcm elements if we have changed the circumstance (here, options.mode) 991 pmPCMupdate(pcm, source, &options, model); 992 993 // we have been provided a guess at the index (P[7]) from the list of indexGuessInv 994 995 // find the matching indexGuessInv 996 int nStart = -1; 997 for (int i = 0; i < N_INDEX_GUESS_INV; i++) { 998 if (fabs(PAR[PM_PAR_7] - indexGuessInv[i]) < 0.01) { 999 nStart = i; 1000 break; 1001 } 1002 } 1003 if (nStart == -1) { 1004 fprintf (stderr, "WARNING: could not find start guess %f\n", PAR[PM_PAR_7]); 1005 return false; 1006 } 1007 1008 psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32); 1009 psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32); 1010 1011 float Sm = NAN, Sp = NAN, So = NAN; 1012 if (nStart == 0) { 1013 Sm = indexGuessInv[nStart]; 1014 So = 0.5*(indexGuessInv[nStart + 1] + indexGuessInv[nStart]); 1015 Sp = indexGuessInv[nStart + 1]; 1016 } else if (nStart == N_INDEX_GUESS_INV - 1) { 1017 Sp = indexGuessInv[nStart]; 1018 So = 0.5*(indexGuessInv[nStart - 1] + indexGuessInv[nStart]); 1019 Sm = indexGuessInv[nStart - 1]; 1020 } else { 1021 Sm = 0.5*(indexGuessInv[nStart - 1] + indexGuessInv[nStart]); 1022 So = indexGuessInv[nStart]; 1023 Sp = 0.5*(indexGuessInv[nStart + 1] + indexGuessInv[nStart]); 1024 } 1025 1026 PAR[PM_PAR_7] = Sm; 1027 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1028 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1029 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1030 psVectorAppend (chi2, model->chisqNorm); 1031 1032 PAR[PM_PAR_7] = So; 1033 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1034 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1035 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1036 psVectorAppend (chi2, model->chisqNorm); 1037 1038 PAR[PM_PAR_7] = Sp; 1039 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1040 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1041 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1042 psVectorAppend (chi2, model->chisqNorm); 1043 1044 psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2); 1045 if (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) { 1046 psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola"); 1047 psFree (chi2); 1048 psFree (Sidx); 1049 psFree (poly); 1050 return false; 1051 } 1052 1053 // where is the minimum of this polynomial fit? 1054 float Smin = -0.5 * poly->coeff[1] / poly->coeff[2] / 100.0; 1055 1056 // constrain Smin to be in a valid range: allow the fitted range to go a bit beyond the 3 trial points, but no further 1057 float Smx = Sm - 0.25*(So - Sm); 1058 float Spx = Sp + 0.25*(Sp - So); 1059 Smin = PS_MAX(PS_MIN(Smin, Smx), Spx); 1060 PAR[PM_PAR_7] = Smin; 1061 1062 // XXX I could set the error on PAR_7 here if I knew how to roughly convert these chisq values to true chisq values 1063 1064 // return to the original fitting mode (fitOptions) 1065 pmPCMupdate(pcm, source, fitOptions, model); 1066 1067 psFree (chi2); 1068 psFree (Sidx); 1069 psFree (poly); 1070 1071 return true; 1072 } 1073 1074 1075 // we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX 1076 bool psphotFitSersicShapeAndIndexGridAutoScaled (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 1077 1078 pmModel *model = pcm->modelConv; 1079 1080 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); 1081 1082 pmSourceFitOptions options = *fitOptions; 1083 1084 psF32 *PAR = pcm->modelConv->params->data.F32; 1085 1086 options.mode = PM_SOURCE_FIT_SHAPE; 1087 options.nIter = 5; 1088 1089 // update the pcm elements if we have changed the circumstance (here, options.mode) 1090 pmPCMupdate(pcm, source, &options, model); 1091 1092 float parStart[8]; 1093 for (int i = 0; i < 8; i++) parStart[i] = PAR[i]; 1094 1095 // we start with a guess at the index (P[7]) 1096 1097 // get chisq for P[7], P[7]*1.1, P[7]*1.25 (or *0.75 depending on the result of 1.1) 1098 1099 psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32); 1100 psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32); 1101 1102 PAR[PM_PAR_7] = parStart[7]; 1103 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1104 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1105 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1106 psVectorAppend (chi2, model->chisqNorm); 1107 1108 float fI = 1.1; 1109 PAR[PM_PAR_7] = parStart[7]*fI; 1110 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1111 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1112 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1113 psVectorAppend (chi2, model->chisqNorm); 1114 1115 if (chi2->data.F32[1] < chi2->data.F32[0]) { 1116 fI = 1.3; 1117 } else { 1118 fI = 1.0 / 1.3; 1119 } 1120 1121 PAR[PM_PAR_7] = parStart[7]*fI; 1122 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1123 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1124 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1125 psVectorAppend (chi2, model->chisqNorm); 1126 1127 // can we fit the 3 pts with a parabola? 1128 int nTry = 0; 1129 psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2); 1130 while (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) { 1131 psErrorClear (); // clear the polynomial error 1132 if (nTry > 4) { 1133 psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola"); 1134 psFree (chi2); 1135 psFree (Sidx); 1136 psFree (poly); 1137 return false; 1138 } 1139 fI = (fI < 1.0) ? fI / 1.3 : fI * 1.3; 1140 PAR[PM_PAR_7] = parStart[7]*fI; 1141 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1142 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1143 psVectorAppend (Sidx, 100*PAR[PM_PAR_7]); 1144 psVectorAppend (chi2, model->chisqNorm); 1145 nTry ++; 1146 } 1147 1148 // where is the minimum of this polynomial fit? 1149 float Smin = -0.5 * poly->coeff[1] / poly->coeff[2] / 100.0; 1150 1151 // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev) 1152 Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1); 1153 PAR[PM_PAR_7] = Smin; 1154 1155 // pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1156 // if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1157 1158 //// for (int i = 0; i < 8; i++) PAR[i] = parStart[i]; 1159 //// 1160 //// for (float fI = 0.0; fI < 0.15; fI += 0.01) { 1161 //// PAR[PM_PAR_7] = parStart[7] - fI; 1162 //// 1163 //// // fit EXT (not PSF) model (set/unset the pixel mask) 1164 //// 1165 //// pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1166 //// if (TIMING) { 1167 //// float *PAR = model->params->data.F32; 1168 //// fprintf (stderr, "%d %f : %f - %f %f %f - %f\n", model->nIter, model->chisqNorm, PAR[7], PAR[4], PAR[5], PAR[6], PAR[1]); 1169 //// } 1170 //// } 1171 1172 // return to the original fitting mode (fitOptions) 1173 pmPCMupdate(pcm, source, fitOptions, model); 1174 1175 psFree (chi2); 1176 psFree (Sidx); 1177 psFree (poly); 1178 1179 return true; 1180 } 1181 1182 1183 // we have a set of guess parameters, do a small number of iterations fitting only SHAPE then only INDEX 1184 bool psphotFitSersicShapeAndIndexGrid (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 1185 1186 pmModel *model = pcm->modelConv; 1187 1188 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); 1189 1190 pmSourceFitOptions options = *fitOptions; 1191 1192 psF32 *PAR = pcm->modelConv->params->data.F32; 1193 1194 options.mode = PM_SOURCE_FIT_SHAPE; 1195 options.nIter = 10; 1196 1197 // update the pcm elements if we have changed the circumstance (here, options.mode) 1198 pmPCMupdate(pcm, source, &options, model); 1199 1200 psVector *chi2 = psVectorAllocEmpty (16, PS_TYPE_F32); 1201 psVector *Sidx = psVectorAllocEmpty (16, PS_TYPE_F32); 1202 1203 float par7[] = {0.100, 0.125, 0.150, 0.175, 0.200, 0.225, 0.250}; 1204 for (int i = 0; i < 7; i++) { 1205 PAR[PM_PAR_7] = par7[i]; 1206 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1207 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1208 psVectorAppend (Sidx, PAR[PM_PAR_7]); 1209 psVectorAppend (chi2, model->chisqNorm); 1210 } 1211 1212 psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 2); 1213 if (!psVectorFitPolynomial1D (poly, NULL, 0, chi2, NULL, Sidx)) { 1214 psError(PS_ERR_UNKNOWN, true, "Failed to find a good chisq parabola"); 1215 psFree (chi2); 1216 psFree (Sidx); 1217 psFree (poly); 1218 return false; 1219 } 1220 1221 // where is the minimum of this polynomial fit? 1222 fprintf (stderr, "fit1d: %f + %f x + %f x^2\n", poly->coeff[0], poly->coeff[1], poly->coeff[2]); 1223 float Smin = -0.5 * poly->coeff[1] / poly->coeff[2]; 1224 1225 // constrain Smin to be in a valid range (1.0 - 0.1, corresponding to 0.5 (Gauss) to 5.0 (slightly peakier than Dev) 1226 Smin = PS_MAX(PS_MIN(Smin, 1.0), 0.1); 1227 PAR[PM_PAR_7] = Smin; 1228 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1229 if (EXTRA_VERBOSE) fprintf (stderr, "%d >>> %d %f : %f - %f %f - %f %f %f - %f\n", source->id, model->nIter, model->chisqNorm, PAR[7], PAR[2], PAR[3], PAR[4], PAR[5], PAR[6], PAR[1]); 1230 1231 //// for (int i = 0; i < 8; i++) PAR[i] = parStart[i]; 1232 //// 1233 //// for (float fI = 0.0; fI < 0.15; fI += 0.01) { 1234 //// PAR[PM_PAR_7] = parStart[7] - fI; 1235 //// 1236 //// // fit EXT (not PSF) model (set/unset the pixel mask) 1237 //// 1238 //// pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 1239 //// if (TIMING) { 1240 //// float *PAR = model->params->data.F32; 1241 //// fprintf (stderr, "%d %f : %f - %f %f %f - %f\n", model->nIter, model->chisqNorm, PAR[7], PAR[4], PAR[5], PAR[6], PAR[1]); 1242 //// } 1243 //// } 1244 1245 // return to the original fitting mode (fitOptions) 1246 pmPCMupdate(pcm, source, fitOptions, model); 1247 1248 psFree (chi2); 1249 psFree (Sidx); 1250 psFree (poly); 1251 1252 return true; 1253 } 1254 1255 // # define N_REFF_CHECK 11 1256 // float drefCheck[] = {-0.02, -0.04, -0.06, 0.0, 0.85, 0.90, 0.95, 1.00, 1.05, 1.10, 1.15, 1.20, 1.25}; 1257 1258 // we have an initial fit, check to see if the current size is besst 1259 bool psphotPCMfitCheckSize (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, float psfSize) { 1260 1261 // PAR is already at my current best guess 1262 psF32 *PAR = pcm->modelConv->params->data.F32; 1263 1264 // store best guess as a shape 1265 psEllipseAxes centerAxes; 1266 pmModelParamsToAxes (¢erAxes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 1267 1268 float xMin = NAN; 1269 float iMin = NAN; 1270 float rMin = NAN; 1271 1272 // loop over Reff, keeping the ARatio and Theta constant 1273 for (int j = -4; j <= 4; j++) { 1274 1275 float dref = j * 0.01; 1276 1277 psEllipseAxes guessAxes; 1278 guessAxes.major = centerAxes.major + dref; 1279 guessAxes.minor = guessAxes.major * centerAxes.minor / centerAxes.major; 1280 guessAxes.theta = centerAxes.theta; 1281 1282 if (!isfinite(guessAxes.major)) return false; 1283 if (!isfinite(guessAxes.minor)) return false; 1284 if (!isfinite(guessAxes.theta)) return false; 1285 1286 // convert the major,minor,theta to shape parameters for an Reff-like model 1287 pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true); 1288 1289 // generated the modelFlux 1290 // XXX note that this does not add sky to model 1291 pmPCMMakeModel (source, pcm->modelConv, pcm->nsigma, maskVal, psfSize); 1292 1293 float YY = 0.0; 1294 float YM = 0.0; 1295 float MM = 0.0; 1296 bool usePoisson = false; 1297 1298 for (int iy = 0; iy < source->pixels->numRows; iy++) { 1299 for (int ix = 0; ix < source->pixels->numCols; ix++) { 1300 // skip masked points 1301 if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) { 1302 continue; 1303 } 1304 // skip zero-variance points 1305 if (source->variance->data.F32[iy][ix] == 0) { 1306 continue; 1307 } 1308 // skip nan value points 1309 if (!isfinite(source->pixels->data.F32[iy][ix])) { 1310 continue; 1311 } 1312 1313 float fy = source->pixels->data.F32[iy][ix]; 1314 float fm = source->modelFlux->data.F32[iy][ix]; 1315 float wt = (usePoisson) ? 1.0 / source->variance->data.F32[iy][ix] : 1.0; 1316 1317 YY += PS_SQR(fy) * wt; 1318 YM += fm * fy * wt; 1319 MM += PS_SQR(fm) * wt; 1320 } 1321 } 1322 1323 float Io = YM / MM; 1324 float Chisq = YY - 2 * Io * YM + Io * Io * MM; 1325 if (isnan(xMin) || (Chisq < xMin)) { 1326 xMin = Chisq; 1327 iMin = Io; 1328 rMin = dref; 1329 } 1330 // fprintf (stderr, "%d | %f %f %f | %f %f %f\n", j, dref, Io, Chisq, rMin, iMin, xMin); 1331 } 1332 1333 psEllipseAxes guessAxes; 1334 guessAxes.major = centerAxes.major + rMin; 1335 guessAxes.minor = guessAxes.major * centerAxes.minor / centerAxes.major; 1336 guessAxes.theta = centerAxes.theta; 1337 1338 if (!isfinite(guessAxes.major)) return false; 1339 if (!isfinite(guessAxes.minor)) return false; 1340 if (!isfinite(guessAxes.theta)) return false; 1341 1342 // convert the major,minor,theta to shape parameters for an Reff-like model 1343 pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true); 1344 PAR[PM_PAR_I0] = iMin; 1345 1346 return true; 1347 } 1348 1349 // we have an initial fit, check to see if the current size is besst 1350 bool psphotPCMfitRetry (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, float psfSize) { 1351 1352 // PAR is already at my current best guess 1353 psF32 *PAR = pcm->modelConv->params->data.F32; 1354 1355 // store best guess as a shape 1356 psEllipseAxes centerAxes; 1357 pmModelParamsToAxes (¢erAxes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true); 1358 1359 // retry with axes smaller by 1 pixel 1360 psEllipseAxes guessAxes; 1361 guessAxes.major = centerAxes.major - 0.08; 1362 guessAxes.minor = guessAxes.major * centerAxes.minor / centerAxes.major; 1363 guessAxes.theta = centerAxes.theta; 1364 1365 if (!isfinite(guessAxes.major)) return false; 1366 if (!isfinite(guessAxes.minor)) return false; 1367 if (!isfinite(guessAxes.theta)) return false; 1368 1369 // convert the major,minor,theta to shape parameters for an Reff-like model 1370 pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], guessAxes, true); 1371 1372 // generated the modelFlux 1373 // XXX note that this does not add sky to model 1374 pmPCMMakeModel (source, pcm->modelConv, pcm->nsigma, maskVal, psfSize); 1375 1376 float YY = 0.0; 1377 float YM = 0.0; 1378 float MM = 0.0; 1379 bool usePoisson = false; 1380 1381 for (int iy = 0; iy < source->pixels->numRows; iy++) { 1382 for (int ix = 0; ix < source->pixels->numCols; ix++) { 1383 // skip masked points 1384 if (source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix]) { 1385 continue; 1386 } 1387 // skip zero-variance points 1388 if (source->variance->data.F32[iy][ix] == 0) { 1389 continue; 1390 } 1391 // skip nan value points 1392 if (!isfinite(source->pixels->data.F32[iy][ix])) { 1393 continue; 1394 } 1395 1396 float fy = source->pixels->data.F32[iy][ix]; 1397 float fm = source->modelFlux->data.F32[iy][ix]; 1398 float wt = (usePoisson) ? 1.0 / source->variance->data.F32[iy][ix] : 1.0; 1399 1400 YY += PS_SQR(fy) * wt; 1401 YM += fm * fy * wt; 1402 MM += PS_SQR(fm) * wt; 1403 } 1404 } 1405 1406 float Io = YM / MM; 1407 PAR[PM_PAR_I0] = Io; 1408 1409 pmSourceFitPCM (pcm, source, fitOptions, maskVal, markVal, psfSize); // NOTE : 1687 allocs in here 1410 1411 return true; 1412 } 1413 1414 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotSourceSize.c
r35180 r37066 1 1 # include "psphotInternal.h" 2 # include <gsl/gsl_sf_gamma.h> 3 2 3 // this structure is only used internally to simplify the function parameters 4 4 typedef struct { 5 5 psImageMaskType maskVal; … … 13 13 bool altDiffExt; 14 14 float altDiffExtThresh; 15 bool extFitAll;16 bool extFitAllReadout;17 float extFitAllThresh;18 15 float soft; 19 16 int grow; … … 33 30 bool psphotSourceSelectCR (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options); 34 31 bool psphotMaskCosmicRay (pmReadout *readout, pmSource *source, psImageMaskType maskVal, int maxWindowCR); 35 bool psphotMaskCosmicRayFootprintCheck (psArray *sources);36 32 int psphotMaskCosmicRayConnected (int xPeak, int yPeak, psImage *mymask, psImage *myvar, psImage *edges, int binning, float sigma_thresh); 37 33 float psphotSourceSizeFindThreshold (psVector *value, psVector *mask, int maskValue, float minValue, float maxValue, float delta, float guess, float fraction); … … 41 37 42 38 // we need to call this function after sources have been fitted to the PSF model and 43 // subtracted. To determine the CR-nature, this function examines the 9 pixels in the 3x3 44 // square containing the peak and compares the observed flux to the model. To determine 45 // the EXT-nature, this function measures the amount of positive or negative total 46 // deviation from the psf model at the r = FWHM/2 position 39 // subtracted. 47 40 48 41 // for now, let's store the detections on the readout->analysis for each readout … … 121 114 assert (status); 122 115 123 // XXX recipe name is not great 116 // XXX recipe name is not great (NOTE : not used!) 124 117 options.nSigmaMoments = psMetadataLookupF32 (&status, recipe, "PSPHOT.EXT.NSIGMA.MOMENTS"); 125 118 assert (status); 126 119 127 // Optional extended source measurement algorithm to improve diff image trails120 // Optional algorithm to define if a source is extended (used by DIFF analysis) 128 121 options.altDiffExt = psMetadataLookupBool(&status, recipe, "PSPHOT.EXT.DIFF.ALTERNATE"); 129 122 assert (status); 123 130 124 // Threshold for this alternate method 131 125 options.altDiffExtThresh = psMetadataLookupF32(&status, recipe, "PSPHOT.EXT.DIFF.ALTERNATE.THRESH"); 132 126 assert (status); 133 // Option to enable fitting of all objects with extended model. 134 options.extFitAll = psMetadataLookupBool(&status, recipe, "PSPHOT.EXT.FIT.ALL.SOURCES"); 135 assert (status); 136 // Fitting everything is fine, but if the source density is high, we probably shouldn't. 137 options.extFitAllThresh = psMetadataLookupF32(&status, recipe, "PSPHOT.EXT.FIT.ALL.THRESH"); 138 assert (status); 139 127 140 128 // location of a single test source 141 129 options.xtest = psMetadataLookupS32 (&status, recipe, "PSPHOT.CRMASK.XTEST"); … … 422 410 423 411 psLogMsg("psModules.objects", PS_LOG_INFO, "Source Size classifications: %4s %4s %4s %4s %4s", "Npsf", "Next", "Nsat", "Ncr", "Nskip"); 424 // Determine if this readout is above the threshold to ext fit all sources 425 options->extFitAllReadout = false; 426 if (options->extFitAll) { 427 float maskFrac = psMetadataLookupF32(&status,readout->analysis,"READOUT.MASK.FRAC"); 428 if (status) { 429 maskFrac = 0.0; 430 } 431 if (sources->n * (1.0 - maskFrac) > options->extFitAllThresh) { 432 options->extFitAllReadout = false; 433 } 434 else { 435 options->extFitAllReadout = true; 436 } 437 } 438 412 439 413 if (!psphotSourceClassRegion (NULL, &psfClump, sources, recipe, psf, options)) { 440 414 psLogMsg ("psphot", 4, "Failed to determine source classification for full image\n"); … … 444 418 return true; 445 419 420 // NOTE : this section is deactivated (EAM : I think we were getting poor boundary effects?) 446 421 int nRegions = psMetadataLookupS32 (&status, readout->analysis, "PSF.CLUMP.NREGIONS"); 447 422 for (int i = 0; i < nRegions; i ++) { … … 582 557 // * SAT stars should not be faint, but defects may? 583 558 584 // If the recipe requests we do extended source fits to everything, set585 // the EXT_LIMIT flag586 if (options->extFitAllReadout) {587 psTrace("psphotSourceClassRegion.EXTALT",10,"In extFitAll: %d %d\n",options->extFitAll,options->extFitAllReadout);588 source->mode |= PM_SOURCE_MODE_EXT_LIMIT;589 }590 559 // Defects may not always match CRs from peak curvature analysis 591 560 // Defects may also be marked as SATSTAR -- XXX deactivate this flag? … … 595 564 596 565 // saturated star (too many saturated pixels or peak above saturation limit). These 597 // may also be saturated galaxies, or just large saturated regions. 566 // may also be saturated galaxies, or just large saturated regions. They are never 567 // marked as 'extended' 598 568 if (source->mode & PM_SOURCE_MODE_SATSTAR) { 599 569 psTrace("psphotSourceClassRegion.SAT",4,"CLASS: %g %g\t%g %g\t%g %g\t%g %g\t%g SAT\n", … … 604 574 } 605 575 606 // any sources missing a large fraction should just be treated as PSFs 576 // any sources missing a large fraction should just be treated as PSFs. They are never 577 // marked as 'extended' 607 578 if ((source->pixWeightNotBad < 0.9) || (source->pixWeightNotPoor < 0.9)) { 608 579 psTrace("psphotSourceClassRegion.PSF",4,"CLASS: %g %g\t%g %g %g %g %g %g\t%g %g\t%g PSF\t%g %g\n", … … 634 605 psTrace("psphotSourceClassRegion.EXT",4,"CLASS: %g %g\t%g %g\t%g %g\t%g %g\t%g EXT\n", 635 606 source->peak->xf, source->peak->yf, Mminor, kMag, dMag, nSigmaMAG, options->sizeLimitCR, options->magLimitCR, options->nSigmaApResid); 607 source->type = PM_SOURCE_TYPE_EXTENDED; 636 608 source->mode |= PM_SOURCE_MODE_EXT_LIMIT; 637 609 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED; … … 639 611 continue; 640 612 } 613 641 614 // Alternate extended source limit calculation 642 615 if (options->altDiffExt) { … … 652 625 source->peak->xf, source->peak->yf, Mminor, kMag, dMag, nSigmaMAG, options->sizeLimitCR, options->magLimitCR, options->nSigmaApResid, 653 626 momentRatioVeres,options->altDiffExtThresh); 627 source->type = PM_SOURCE_TYPE_EXTENDED; 654 628 source->mode |= PM_SOURCE_MODE_EXT_LIMIT; 655 629 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED; … … 968 942 } 969 943 970 bool psphotMaskCosmicRayFootprintCheck (psArray *sources) {971 #ifdef CHECK_FOOTPRINTS972 // This gets really expensive for complex images973 for (int i = 0; i < sources->n; i++) {974 pmSource *source = sources->data[i];975 pmPeak *peak = source->peak;976 pmFootprint *footprint = peak->footprint;977 if (!footprint) continue;978 for (int j = 0; j < footprint->spans->n; j++) {979 pmSpan *sp = footprint->spans->data[j];980 psAssert (sp, "missing span");981 }982 }983 #endif984 return true;985 }986 987 /**** ------ old versions of cosmic ray masking ----- ****/988 989 bool psphotMaskCosmicRayIsophot (pmSource *source, psImageMaskType maskVal, psImageMaskType crMask);990 991 // This attempt to mask the cosmic rays used the isophotal boundary992 bool psphotMaskCosmicRay_V1 (psImage *mask, pmSource *source, psImageMaskType maskVal, psImageMaskType crMask) {993 994 // replace the source flux995 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal);996 997 // flag this as a CR998 source->mode |= PM_SOURCE_MODE_CR_LIMIT;999 pmPeak *peak = source->peak;1000 psAssert (peak, "NULL peak");1001 1002 // grab the matching footprint1003 pmFootprint *footprint = peak->footprint;1004 if (!footprint) {1005 psTrace("psphot.czw",2,"Using isophot CR mask code.");1006 1007 // if we have not footprint, use the old code to mask by isophot1008 psphotMaskCosmicRayIsophot (source, maskVal, crMask);1009 return true;1010 }1011 1012 if (!footprint->spans) {1013 psTrace("psphot.czw",2,"Using isophot CR mask code.");1014 1015 // if we have no footprint, use the old code to mask by isophot1016 psphotMaskCosmicRayIsophot (source, maskVal, crMask);1017 return true;1018 }1019 psphotMaskCosmicRayIsophot (source, maskVal, crMask);1020 // mask all of the pixels covered by the spans of the footprint1021 for (int j = 1; j < footprint->spans->n; j++) {1022 pmSpan *span1 = footprint->spans->data[j];1023 1024 int iy = span1->y;1025 int xs = span1->x0;1026 int xe = span1->x1;1027 1028 for (int ix = xs; ix < xe; ix++) {1029 mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= crMask;1030 }1031 }1032 return true;1033 }1034 1035 944 # define VERBOSE 0 1036 945 int psphotMaskCosmicRayConnected (int xPeak, int yPeak, psImage *mymask, psImage *myvar, psImage *edges, int binning, float sigma_thresh) { … … 1176 1085 } 1177 1086 1178 bool psphotMaskCosmicRayIsophot (pmSource *source, psImageMaskType maskVal, psImageMaskType crMask) {1179 1180 source->mode |= PM_SOURCE_MODE_CR_LIMIT;1181 pmPeak *peak = source->peak;1182 psAssert (peak, "NULL peak");1183 1184 psImage *mask = source->maskView;1185 psImage *pixels = source->pixels;1186 psImage *variance = source->variance;1187 1188 // XXX This should be a recipe variable1189 # define SN_LIMIT 5.01190 1191 int xo = peak->x - pixels->col0;1192 int yo = peak->y - pixels->row0;1193 1194 // mark the pixels in this row to the left, then the right1195 for (int ix = xo; ix >= 0; ix--) {1196 float SN = pixels->data.F32[yo][ix] / sqrt(variance->data.F32[yo][ix]);1197 if (SN > SN_LIMIT) {1198 mask->data.PS_TYPE_IMAGE_MASK_DATA[yo][ix] |= crMask;1199 }1200 }1201 for (int ix = xo + 1; ix < pixels->numCols; ix++) {1202 float SN = pixels->data.F32[yo][ix] / sqrt(variance->data.F32[yo][ix]);1203 if (SN > SN_LIMIT) {1204 mask->data.PS_TYPE_IMAGE_MASK_DATA[yo][ix] |= crMask;1205 }1206 }1207 1208 // for each of the neighboring rows, mark the high pixels if they have a marked neighbor1209 // first go up:1210 for (int iy = PS_MIN(yo, mask->numRows-2); iy >= 0; iy--) {1211 // mark the pixels in this row to the left, then the right1212 for (int ix = 0; ix < pixels->numCols; ix++) {1213 float SN = pixels->data.F32[iy][ix] / sqrt(variance->data.F32[iy][ix]);1214 if (SN < SN_LIMIT) continue;1215 1216 bool valid = false;1217 valid |= (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy+1][ix] & crMask);1218 valid |= (ix > 0) ? (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy+1][ix-1] & crMask) : 0;1219 valid |= (ix <= mask->numCols) ? (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy+1][ix+1] & crMask) : 0;1220 1221 if (!valid) continue;1222 mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= crMask;1223 }1224 }1225 // next go down:1226 for (int iy = PS_MIN(yo+1, mask->numRows-1); iy < pixels->numRows; iy++) {1227 // mark the pixels in this row to the left, then the right1228 for (int ix = 0; ix < pixels->numCols; ix++) {1229 float SN = pixels->data.F32[iy][ix] / sqrt(variance->data.F32[iy][ix]);1230 if (SN < SN_LIMIT) continue;1231 1232 bool valid = false;1233 valid |= (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy-1][ix] & crMask);1234 valid |= (ix > 0) ? (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy-1][ix-1] & crMask) : 0;1235 valid |= (ix <= mask->numCols) ? (mask->data.PS_TYPE_IMAGE_MASK_DATA[iy-1][ix+1] & crMask) : 0;1236 1237 if (!valid) continue;1238 mask->data.PS_TYPE_IMAGE_MASK_DATA[iy][ix] |= crMask;1239 }1240 }1241 return true;1242 }1243 1244 // given the PSF ellipse parameters, navigate around the 1sigma contour, return the total1245 // deviation in sigmas. This is measured on the residual image - should we ignore negative1246 // deviations? NOTE: This function was an early attempt to classify extended objects, and is1247 // no longer used by psphot.1248 float psphotModelContour(const psImage *image, const psImage *variance, const psImage *mask,1249 psImageMaskType maskVal, const pmModel *model, float Ro)1250 {1251 psF32 *PAR = model->params->data.F32; // Model parameters1252 float sxx = PAR[PM_PAR_SXX], sxy = PAR[PM_PAR_SXY], syy = PAR[PM_PAR_SYY]; // Ellipse parameters1253 1254 // We treat the contour as an ellipse:1255 // Ro = (x / SXX)^2 + (y / SYY)^2 + x y SXY1256 // y^2 (1/SYY^2) + y (x SXY) + (x / SXX)^2 - Ro = 0;1257 // This is a quadratic, Ay^2 + By + C with A = 1/SYY^2, B = x*SXY, C = (x / SXX)^2 - Ro1258 // The solution is y = [-B +/- sqrt (B^2 - 4 A C)] / [2 A], so:1259 // y = [-(x SXY) +/- sqrt ((x SXY)^2 - 4 (1/SYY^2) ((x/SXX)^2 - Ro))] * [SYY^2 / 2]1260 1261 // min/max value of x is where B^2 - 4AC = 0; solve this for x1262 float Q = Ro * PS_SQR(sxx) / (1.0 - PS_SQR(sxx * syy * sxy) / 4.0);1263 if (Q < 0.0) {1264 // ellipse is imaginary1265 return NAN;1266 }1267 1268 int radius = sqrtf(Q) + 0.5; // Radius of ellipse1269 int nPts = 0; // Number of points in ellipse1270 float nSigma = 0.0; //1271 1272 for (int x = -radius; x <= radius; x++) {1273 // Polynomial coefficients1274 // XXX Should we be using the centre of the pixel as x or x+0.5?1275 float A = PS_SQR (1.0 / syy);1276 float B = x * sxy;1277 float C = PS_SQR (x / sxx) - Ro;1278 float T = PS_SQR(B) - 4*A*C;1279 if (T < 0.0) {1280 continue;1281 }1282 1283 // y position in source frame1284 float yP = (-B + sqrt (T)) / (2.0 * A);1285 float yM = (-B - sqrt (T)) / (2.0 * A);1286 1287 // Get the closest pixel positions (image frame)1288 int xPix = x + PAR[PM_PAR_XPOS] - image->col0 + 0.5;1289 int yPixM = yM + PAR[PM_PAR_YPOS] - image->row0 + 0.5;1290 int yPixP = yP + PAR[PM_PAR_YPOS] - image->row0 + 0.5;1291 1292 if (xPix < 0 || xPix >= image->numCols) {1293 continue;1294 }1295 1296 if (yPixM >= 0 && yPixM < image->numRows &&1297 !(mask && (mask->data.PS_TYPE_IMAGE_MASK_DATA[yPixM][xPix] & maskVal))) {1298 float dSigma = image->data.F32[yPixM][xPix] / sqrtf(variance->data.F32[yPixM][xPix]);1299 nSigma += dSigma;1300 nPts++;1301 }1302 1303 if (yPixM == yPixP) {1304 continue;1305 }1306 1307 if (yPixP >= 0 && yPixP < image->numRows &&1308 !(mask && (mask->data.PS_TYPE_IMAGE_MASK_DATA[yPixP][xPix] & maskVal))) {1309 float dSigma = image->data.F32[yPixP][xPix] / sqrtf(variance->data.F32[yPixP][xPix]);1310 nSigma += dSigma;1311 nPts++;1312 }1313 }1314 nSigma /= nPts;1315 return nSigma;1316 }1317 1318 // this was an old attempt to identify cosmic rays based on the peak curvature1319 bool psphotSourcePeakCurvature (pmReadout *readout, psArray *sources, psphotSourceSizeOptions *options) {1320 1321 // classify the sources based on the CR test (place this in a function?)1322 // XXX use an internal flag to mark sources which have already been measured1323 for (int i = 0; i < sources->n; i++) {1324 pmSource *source = sources->data[i];1325 1326 // skip source if it was already measured1327 if (source->tmpFlags & PM_SOURCE_TMPF_SIZE_MEASURED) {1328 psTrace("psphot", 7, "Not calculating source size since it has already been measured\n");1329 continue;1330 }1331 1332 // source must have been subtracted1333 if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) {1334 source->mode |= PM_SOURCE_MODE_SIZE_SKIPPED;1335 psTrace("psphot", 7, "Not calculating source size since source is not subtracted\n");1336 continue;1337 }1338 1339 psF32 **resid = source->pixels->data.F32;1340 psF32 **variance = source->variance->data.F32;1341 psImageMaskType **mask = source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA;1342 1343 // Integer position of peak1344 int xPeak = source->peak->xf - source->pixels->col0 + 0.5;1345 int yPeak = source->peak->yf - source->pixels->row0 + 0.5;1346 1347 // Skip sources which are too close to a boundary. These are mostly caught as DEFECT1348 if (xPeak < 1 || xPeak > source->pixels->numCols - 2 ||1349 yPeak < 1 || yPeak > source->pixels->numRows - 2) {1350 psTrace("psphot", 7, "Not calculating crNsigma due to edge\n");1351 continue;1352 }1353 1354 // Skip sources with masked pixels. These are mostly caught as DEFECT1355 bool keep = true;1356 for (int iy = -1; (iy <= +1) && keep; iy++) {1357 for (int ix = -1; (ix <= +1) && keep; ix++) {1358 if (mask[yPeak+iy][xPeak+ix] & options->maskVal) {1359 keep = false;1360 }1361 }1362 }1363 if (!keep) {1364 psTrace("psphot", 7, "Not calculating crNsigma due to masked pixels\n");1365 continue;1366 }1367 1368 // Compare the central pixel with those on either side, for the four possible lines through it.1369 1370 // Soften variances (add systematic error)1371 float softening = options->soft * PS_SQR(source->peak->rawFlux); // Softening for variances1372 1373 // Across the middle: y = 01374 float cX = 2*resid[yPeak][xPeak] - resid[yPeak+0][xPeak-1] - resid[yPeak+0][xPeak+1];1375 float dcX = 4*variance[yPeak][xPeak] + variance[yPeak+0][xPeak-1] + variance[yPeak+0][xPeak+1];1376 float nX = cX / sqrtf(dcX + softening);1377 1378 // Up the centre: x = 01379 float cY = 2*resid[yPeak][xPeak] - resid[yPeak-1][xPeak+0] - resid[yPeak+1][xPeak+0];1380 float dcY = 4*variance[yPeak][xPeak] + variance[yPeak-1][xPeak+0] + variance[yPeak+1][xPeak+0];1381 float nY = cY / sqrtf(dcY + softening);1382 1383 // Diagonal: x = y1384 float cL = 2*resid[yPeak][xPeak] - resid[yPeak-1][xPeak-1] - resid[yPeak+1][xPeak+1];1385 float dcL = 4*variance[yPeak][xPeak] + variance[yPeak-1][xPeak-1] + variance[yPeak+1][xPeak+1];1386 float nL = cL / sqrtf(dcL + softening);1387 1388 // Diagonal: x = - y1389 float cR = 2*resid[yPeak][xPeak] - resid[yPeak+1][xPeak-1] - resid[yPeak-1][xPeak+1];1390 float dcR = 4*variance[yPeak][xPeak] + variance[yPeak+1][xPeak-1] + variance[yPeak-1][xPeak+1];1391 float nR = cR / sqrtf(dcR + softening);1392 1393 // P(chisq > chisq_obs; Ndof) = gamma_Q (Ndof/2, chisq/2)1394 // Ndof = 4 ? (four measurements, no free parameters)1395 // XXX this value is going to be biased low because of systematic errors.1396 // we need to calibrate it somehow1397 // source->psfProb = gsl_sf_gamma_inc_Q (2, 0.5*chisq);1398 1399 // not strictly accurate: overcounts the chisq contribution from the center pixel (by1400 // factor of 4); also biases a bit low if any pixels are masked1401 // XXX I am not sure I want to keep this value...1402 source->psfChisq = PS_SQR(nX) + PS_SQR(nY) + PS_SQR(nL) + PS_SQR(nR);1403 1404 float fCR = 0.0;1405 int nCR = 0;1406 if (nX > 0.0) {1407 fCR += nX;1408 nCR ++;1409 }1410 if (nY > 0.0) {1411 fCR += nY;1412 nCR ++;1413 }1414 if (nL > 0.0) {1415 fCR += nL;1416 nCR ++;1417 }1418 if (nR > 0.0) {1419 fCR += nR;1420 nCR ++;1421 }1422 source->crNsigma = (nCR > 0) ? fCR / nCR : 0.0;1423 source->tmpFlags |= PM_SOURCE_TMPF_SIZE_MEASURED;1424 1425 if (!isfinite(source->crNsigma)) {1426 continue;1427 }1428 1429 // this source is thought to be a cosmic ray. flag the detection and mask the pixels1430 if (source->crNsigma > options->nSigmaCR) {1431 source->mode |= PM_SOURCE_MODE_CR_LIMIT;1432 // XXX still testing... : psphotMaskCosmicRay (readout->mask, source, maskVal, crMask);1433 // XXX acting strange... psphotMaskCosmicRay_Old (source, maskVal, crMask);1434 }1435 }1436 1437 // now that we have masked pixels associated with CRs, we can grow the mask1438 if (options->grow > 0) {1439 bool oldThreads = psImageConvolveSetThreads(true); // Old value of threading for psImageConvolveMask1440 psImage *newMask = psImageConvolveMask(NULL, readout->mask, options->crMask, options->crMask, -options->grow, options->grow, -options->grow, options->grow);1441 psImageConvolveSetThreads(oldThreads);1442 if (!newMask) {1443 psError(PS_ERR_UNKNOWN, false, "Unable to grow CR mask");1444 return false;1445 }1446 psFree(readout->mask);1447 readout->mask = newMask;1448 }1449 return true;1450 }1451 1452 1087 float psphotSourceSizeFindThreshold (psVector *value, psVector *mask, int maskValue, float minValue, float maxValue, float delta, float guess, float fraction) { 1453 1088 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotSourceStats.c
r35112 r37066 58 58 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 59 59 psAssert (detections, "missing detections?"); 60 61 // XXX TEST:62 if (detections->allSources) {63 psphotMaskCosmicRayFootprintCheck(detections->allSources);64 }65 if (detections->newSources) {66 psphotMaskCosmicRayFootprintCheck(detections->newSources);67 }68 60 69 61 // determine the number of allowed threads … … 246 238 psphotVisualShowMoments (sources); 247 239 248 // clear the mark bits249 // psImageMaskPixels (readout->mask, "AND", PS_NOT_IMAGE_MASK(markVal));250 251 if (detections->allSources) {252 psphotMaskCosmicRayFootprintCheck(detections->allSources);253 }254 if (detections->newSources) {255 psphotMaskCosmicRayFootprintCheck(detections->newSources);256 }257 258 240 return true; 259 241 } … … 572 554 573 555 // measure basic source moments (no S/N clipping on input pixels) 556 // sources with (mode & MODE_EXTERNAL) or (mode2 & MODE2_MATCHED) use the 557 // supplied Mx,My value for the centroid (not recalculated) 574 558 status = pmSourceMoments (source, 4*sigma[i], sigma[i], 0.0, 0.0, maskVal); 575 559 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotStackImageLoop.c
- Property svn:mergeinfo deleted
r35769 r37066 22 22 23 23 pmFPAview *view = pmFPAviewAlloc (0); 24 pmFPAfile *inputRaw = psMetadataLookupPtr (&status, config->files, "PSPHOT.STACK.INPUT.RAW"); 25 pmFPAfile *inputCnv = psMetadataLookupPtr (&status, config->files, "PSPHOT.STACK.INPUT.CNV"); 26 pmFPAfile *input = inputRaw ? inputRaw : inputCnv; 24 pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSPHOT.STACK.INPUT.RAW"); 27 25 28 26 if (!input) { … … 32 30 33 31 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE); 34 bool useRaw = psMetadataLookupBool (NULL, recipe, "PSPHOT.STACK.USE.RAW");35 if (useRaw && inputRaw == NULL) {36 psLogMsg ("psphot", 1, "PSPHOT.STACK.USE.RAW set but no raw input.");37 useRaw = false;38 }39 40 bool radial_apertures = psMetadataLookupBool(NULL, recipe, "RADIAL_APERTURES");41 bool match_psfs = radial_apertures;42 bool needConvolved = radial_apertures || !useRaw;43 if (!needConvolved) {44 pmFPAfileActivate (config->files, false, "PSPHOT.STACK.INPUT.CNV");45 pmFPAfileActivate (config->files, false, "PSPHOT.STACK.MASK.CNV");46 pmFPAfileActivate (config->files, false, "PSPHOT.STACK.VARIANCE.CNV");47 pmFPAfileActivate (config->files, false, "PSPHOT.STACK.PSF.CNV");48 }49 32 50 33 // just load the full set of images up front except for EXPNUM which we defer 51 34 pmFPAfileActivate (config->files, false, "PSPHOT.STACK.EXPNUM.RAW"); 52 pmFPAfileActivate (config->files, false, "PSPHOT.STACK.EXPNUM.CNV");53 35 if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE ("failed input for fpa in psphot."); 54 36 … … 71 53 psMemDump("load"); 72 54 73 if (match_psfs) { 74 // Generate the 1st PSF-matched image set (larger target PSFs are generated by smoothing this image) 75 if (!psphotStackMatchPSFs (config, view)) { 76 psError(psErrorCodeLast(), false, "failure in psphotStackMatchPSFs for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout); 77 psFree (view); 78 return false; 79 } 80 } else { 81 if (!psphotStackAllocateOutput (config, view, recipe)) { 82 psError(psErrorCodeLast(), false, "failure in psphotStackAllocateOutput for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout); 83 psFree (view); 84 return false; 85 } 55 if (!psphotStackAllocateOutput (config, view, recipe)) { 56 psError(psErrorCodeLast(), false, "failure in psphotStackAllocateOutput for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout); 57 psFree (view); 58 return false; 86 59 } 87 60 psMemDump("stackmatch"); … … 126 99 127 100 // Load the appropriate EXPNUM image 128 pmFPAfileActivate (config->files, true, useRaw ? "PSPHOT.STACK.EXPNUM.RAW" : "PSPHOT.STACK.EXPNUM.CNV");101 pmFPAfileActivate (config->files, true, "PSPHOT.STACK.EXPNUM.RAW"); 129 102 130 103 if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE ("failed input for fpa EXPNUM in psphot."); … … 146 119 if (! readout->data_exists) { continue; } 147 120 148 if (!psphotSetNFrames (config, view, useRaw ? inputRaw->name : inputCnv->name)) ESCAPE ("failed to setNFrames.");121 if (!psphotSetNFrames (config, view, input->name)) ESCAPE ("failed to setNFrames."); 149 122 } 150 123 } … … 167 140 bool UpdateHeadersForReadout (pmConfig *config, pmFPAview *view) { 168 141 169 psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, PSPHOT_RECIPE);170 bool useRaw = psMetadataLookupBool (NULL, recipe, "PSPHOT.STACK.USE.RAW");171 172 142 int num = psphotFileruleCount(config, "PSPHOT.INPUT"); 173 143 … … 179 149 psAssert (output, "missing file?"); 180 150 181 pmFPAfile *inputRaw = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest 182 pmFPAfile *inputCnv = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.CNV", i); // File of interest 183 pmFPAfile *input = useRaw ? inputRaw : inputCnv; 151 pmFPAfile *input = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest 184 152 psAssert (input, "missing input file"); 185 153 … … 205 173 psAssert (output, "missing file?"); 206 174 207 pmFPAfile *inputRaw = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest 208 pmFPAfile *inputCnv = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.CNV", i); // File of interest 209 pmFPAfile *input = inputRaw ? inputRaw : inputCnv; 175 pmFPAfile *input = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest 210 176 psAssert (input, "missing input file"); 211 177 … … 242 208 psAssert (output, "missing file?"); 243 209 244 pmFPAfile *inputRaw = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest 245 pmFPAfile *inputCnv = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.CNV", i); // File of interest 246 pmFPAfile *input = inputRaw ? inputRaw : inputCnv; 210 pmFPAfile *input = pmFPAfileSelectSingle(config->files, "PSPHOT.STACK.INPUT.RAW", i); // File of interest 247 211 psAssert (input, "missing input file"); 248 212 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotStackMatchPSFsNext.c
r34317 r37066 43 43 for (int i = 0; i < num; i++) { 44 44 if (!psphotStackMatchPSFsNextReadout (config, view, filerule, i, lastSize)) { 45 psError (PSPHOT_ERR_CONFIG, false, "failed to smooth image %s (%d) to target PSF", filerule, i);45 psLogMsg ("psphot", PS_LOG_INFO, "failed to smooth image %s (%d) to target PSF", filerule, i); 46 46 psImageConvolveSetThreads(oldThreads); 47 47 return false; … … 102 102 103 103 if (targetFWHM <= currentFWHM) { 104 psError (PSPHOT_ERR_CONFIG, true, "target FWHM cannot be smaller than current FWHM"); 104 // psError (PSPHOT_ERR_CONFIG, true, "target FWHM cannot be smaller than current FWHM"); 105 psLogMsg ("psphot", PS_LOG_INFO, "target FWHM (%f) is smaller than current FWHM (%f), not smoothing\n", targetFWHM, currentFWHM); 106 fwhmValues->data.F32[lastSize + 1] = currentFWHM; 107 pmReadoutMaskInvalid(readout, maskVal, maskSat); 105 108 return false; 106 109 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotStackMatchPSFsUtils.c
r34721 r37066 325 325 if (deconv > deconvLimit) { 326 326 rejectReadout = true; 327 psLogMsg("psphot", PS_LOG_WARN, "Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting i mage for matched psf analysis%d\n", deconv, deconvLimit, index);327 psLogMsg("psphot", PS_LOG_WARN, "Maximum deconvolution fraction (%f) exceeds limit (%f) --- rejecting input %d for matched psf analysis\n", deconv, deconvLimit, index); 328 328 } 329 329 -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotStackReadout.c
r34721 r37066 1 1 # include "psphotInternal.h" 2 2 3 static bool psphotStackMatchPSFsetup (pmConfig *config, const pmFPAview *view, const char *filerule, const char *fPSF); 4 static bool psphotStackMatchPSFsetupReadout (pmConfig *config, const pmFPAview *view, const char *filerule, const char *fPSF, int index); 3 5 static bool psphotStackLoadWCS(pmConfig *config, const pmFPAview *view, const char *filerule); 4 6 static void logMemStats(const char *heading); 5 7 6 // we have 3 possible realfilesets:8 // relevant filesets: 7 9 # define STACK_RAW "PSPHOT.STACK.INPUT.RAW" 8 # define STACK_CNV "PSPHOT.STACK.INPUT.CNV" 9 # define STACK_OUT "PSPHOT.STACK.OUTPUT.IMAGE" /* the psf-matched image */ 10 11 // we have 3 files on which we operate: 12 // DET (detection image) : nominally RAW (optionally CNV?) 13 // SRC (source analysis image) : nominally CNV (optionally RAW) 14 // OUT (psf-matched images) : always OUT 10 # define STACK_OUT "PSPHOT.STACK.OUTPUT.IMAGE" 11 12 // XXX STACK_OUT currently is a copy of STACK_RAW, but should be a pointer to is as in psphot (single) 13 14 // TEST CODE, can be removed 15 bool psphotDumpImages (pmConfig *config, const pmFPAview *view, const char *filerule, char *base) { 16 17 // XXX do nothing 18 return true; 19 20 int num = psphotFileruleCount(config, "PSPHOT.INPUT"); 21 22 for (int i = 0; i < num; i++) { 23 // find the currently selected readout 24 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, i); // File of interest 25 psAssert (file, "missing file?"); 26 27 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 28 psAssert (readout, "missing readout?"); 29 30 char line[256]; 31 snprintf (line, 256, "%s.%d.im.fits", base, i); 32 psphotSaveImage (NULL, readout->image, line); 33 34 snprintf (line, 256, "%s.%d.wt.fits", base, i); 35 psphotSaveImage (NULL, readout->variance, line); 36 37 snprintf (line, 256, "%s.%d.mk.fits", base, i); 38 psphotSaveImage (NULL, readout->mask, line); 39 } 40 return true; 41 } 15 42 16 43 bool psphotStackVisualFilerule(pmConfig *config, const pmFPAview *view, const char *filerule) { … … 67 94 psAssert (breakPt, "configuration error: set BREAK_POINT"); 68 95 69 // we have 3 relevant files: RAW (unconvolved), CNV (convolved stack), OUT (psf-matched stack)70 // select which image (RAW or CNV) is used for analysis (RAW always used for detection)71 bool useRaw = psMetadataLookupBool (NULL, recipe, "PSPHOT.STACK.USE.RAW");72 char *STACK_SRC = useRaw ? STACK_RAW : STACK_CNV;73 char *STACK_DET = STACK_RAW;74 75 96 // load WCS 76 if (!psphotStackLoadWCS(config, view, STACK_ SRC)) {77 psError (PSPHOT_ERR_CONFIG, false, "trouble loading WCS for %s", STACK_ SRC);97 if (!psphotStackLoadWCS(config, view, STACK_RAW)) { 98 psError (PSPHOT_ERR_CONFIG, false, "trouble loading WCS for %s", STACK_RAW); 78 99 return false; 79 100 } 80 101 81 102 // set the photcode for each image 82 if (!psphotAddPhotcode (config, view, STACK_ SRC)) {103 if (!psphotAddPhotcode (config, view, STACK_RAW)) { 83 104 psError (PSPHOT_ERR_CONFIG, false, "trouble defining the photcode"); 84 105 return false; … … 86 107 87 108 // Generate the mask and weight images (if not supplied) and set mask bits. 88 // This also insures that all invalid pixels are masked (this is done for STACK_CNV in psphotStackMatchPSFs) 89 if (!psphotSetMaskAndVariance (config, view, STACK_DET)) { 90 return psphotReadoutCleanup (config, view, STACK_SRC); 91 } 92 if (!psphotSetMaskAndVariance (config, view, STACK_OUT)) { 93 return psphotReadoutCleanup (config, view, STACK_SRC); 109 if (!psphotSetMaskAndVariance (config, view, STACK_RAW)) { 110 return psphotReadoutCleanup (config, view, STACK_RAW); 94 111 } 95 112 if (!strcasecmp (breakPt, "NOTHING")) { 96 return psphotReadoutCleanup (config, view, STACK_ SRC);113 return psphotReadoutCleanup (config, view, STACK_RAW); 97 114 } 98 115 99 116 // generate a background model (median, smoothed image) 100 if (!psphotModelBackground (config, view, STACK_DET)) { 101 return psphotReadoutCleanup (config, view, STACK_SRC); 102 } 103 if (!psphotSubtractBackground (config, view, STACK_DET)) { 104 return psphotReadoutCleanup (config, view, STACK_SRC); 105 } 106 if (strcmp(STACK_SRC, STACK_DET)) { 107 #define MODEL_BACKGROUND_SRC 1 108 #ifdef MODEL_BACKGROUND_SRC 109 // work around the fact that the background levels on the convolved 110 // and unconvolved stacks can be different 111 if (!psphotModelBackground (config, view, STACK_SRC)) { 112 return psphotReadoutCleanup (config, view, STACK_SRC); 113 } 114 #endif 115 if (!psphotSubtractBackground (config, view, STACK_SRC)) { 116 return psphotReadoutCleanup (config, view, STACK_SRC); 117 } 117 if (!psphotModelBackground (config, view, STACK_RAW)) { 118 return psphotReadoutCleanup (config, view, STACK_RAW); 119 } 120 if (!psphotSubtractBackground (config, view, STACK_RAW)) { 121 return psphotReadoutCleanup (config, view, STACK_RAW); 118 122 } 119 123 if (!strcasecmp (breakPt, "BACKMDL")) { 120 return psphotReadoutCleanup (config, view, STACK_ SRC);124 return psphotReadoutCleanup (config, view, STACK_RAW); 121 125 } 122 126 123 127 #ifdef MAKE_CHISQ_IMAGE 124 128 // also make the chisq detection image 125 if (!psphotStackChisqImage(config, view, STACK_ DET, STACK_SRC)) {129 if (!psphotStackChisqImage(config, view, STACK_RAW, STACK_RAW)) { 126 130 psError (PSPHOT_ERR_UNKNOWN, false, "failure to generate chisq image"); 127 return psphotReadoutCleanup (config, view, STACK_SRC); 131 return psphotReadoutCleanup (config, view, STACK_RAW); 132 } 133 if (!strcasecmp (breakPt, "CHISQ")) { 134 return psphotReadoutCleanup (config, view, STACK_RAW); 128 135 } 129 136 #endif 130 if (!strcasecmp (breakPt, "CHISQ")) {131 return psphotReadoutCleanup (config, view, STACK_SRC);132 }133 137 134 138 // find the detections (by peak and/or footprint) in the image. 135 139 // This finds the detections on Chisq image as well as the individuals 136 if (!psphotFindDetections (config, view, STACK_DET, true)) { // pass 1 137 // this only happens if we had an error in psphotFindDetections 140 if (!psphotFindDetections (config, view, STACK_RAW, true)) { // pass 1 138 141 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis"); 139 return psphotReadoutCleanup (config, view, STACK_SRC); 140 } 141 142 // If DET and SRC are different images, copy the detections from DET to SRC. This 'copy' 143 // is just a copy of the container pointer; the sources on both DET and SRC are the same 144 // memory objects 145 if (strcmp(STACK_SRC, STACK_DET)) { 146 if (!psphotCopySources (config, view, STACK_SRC, STACK_DET)) { 147 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis"); 148 return psphotReadoutCleanup (config, view, STACK_SRC); 149 } 142 return psphotReadoutCleanup (config, view, STACK_RAW); 150 143 } 151 144 152 145 // construct sources and measure basic stats (saved on detections->newSources) 153 if (!psphotSourceStats (config, view, STACK_ SRC, true)) { // pass 1146 if (!psphotSourceStats (config, view, STACK_RAW, true)) { // pass 1 154 147 psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources"); 155 return psphotReadoutCleanup (config, view, STACK_ SRC);148 return psphotReadoutCleanup (config, view, STACK_RAW); 156 149 } 157 150 if (!strcasecmp (breakPt, "PEAKS")) { 158 return psphotReadoutCleanup (config, view, STACK_ SRC);159 } 160 // psphotDumpTest (config, view, STACK_ SRC);151 return psphotReadoutCleanup (config, view, STACK_RAW); 152 } 153 // psphotDumpTest (config, view, STACK_RAW); 161 154 psMemDump("sourcestats"); 162 155 logMemStats("sourcestats"); … … 164 157 // classify sources based on moments, brightness 165 158 // only run this on detections from the input images, not chisq image 166 if (!psphotRoughClass (config, view, STACK_ SRC)) {159 if (!psphotRoughClass (config, view, STACK_RAW)) { 167 160 psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough classifications"); 168 return psphotReadoutCleanup (config, view, STACK_SRC); 169 } 170 171 // If DET and SRC are different images, subtract radial profiles for the convolved 172 // image first. The profiles found on the convolved image will be replaced by those 173 // found for the unconvolved image. Downstream, in psphotFindDetections, we will 174 // replace the the profiles (and re-subtract them) for the detection image, so we want 175 // to keep those versions of the profiles on the sources. 176 if (strcmp(STACK_SRC, STACK_DET)) { 177 // find and subtract radial profile models for saturated stars (XXX change name eventually) 178 if (!psphotDeblendSatstars (config, view, STACK_SRC)) { 161 return psphotReadoutCleanup (config, view, STACK_RAW); 162 } 163 164 // find and subtract radial profile models for saturated stars (XXX change name eventually) 165 if (!psphotDeblendSatstars (config, view, STACK_RAW)) { 179 166 psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis"); 180 return psphotReadoutCleanup (config, view, STACK_SRC); 181 } 182 } 183 // find and subtract radial profile models for saturated stars (XXX change name eventually) 184 if (!psphotDeblendSatstars (config, view, STACK_DET)) { 185 psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis"); 186 return psphotReadoutCleanup (config, view, STACK_SRC); 167 return psphotReadoutCleanup (config, view, STACK_RAW); 187 168 } 188 169 189 170 // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources) 190 171 // only run this on detections from the input images, not chisq image 191 if (!psphotImageQuality (config, view, STACK_ SRC)) { // pass 1172 if (!psphotImageQuality (config, view, STACK_RAW)) { // pass 1 192 173 psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality"); 193 return psphotReadoutCleanup (config, view, STACK_ SRC);174 return psphotReadoutCleanup (config, view, STACK_RAW); 194 175 } 195 176 if (!strcasecmp (breakPt, "MOMENTS")) { 196 return psphotReadoutCleanup (config, view, STACK_ SRC);177 return psphotReadoutCleanup (config, view, STACK_RAW); 197 178 } 198 179 199 180 // use bright stellar objects to measure PSF 200 if (!psphotChoosePSF (config, view, STACK_ SRC, true)) { // pass 1181 if (!psphotChoosePSF (config, view, STACK_RAW, true)) { // pass 1 201 182 psLogMsg ("psphot", 3, "failure to construct a psf model"); 202 return psphotReadoutCleanup (config, view, STACK_ SRC);183 return psphotReadoutCleanup (config, view, STACK_RAW); 203 184 } 204 185 if (!strcasecmp (breakPt, "PSFMODEL")) { 205 return psphotReadoutCleanup (config, view, STACK_ SRC);186 return psphotReadoutCleanup (config, view, STACK_RAW); 206 187 } 207 188 208 189 // merge the newly selected sources into the existing list 209 190 // NOTE: merge OLD and NEW 210 psphotMergeSources (config, view, STACK_ SRC);191 psphotMergeSources (config, view, STACK_RAW); 211 192 212 193 // Construct an initial model for each object, set the radius to fitRadius, set circular 213 194 // fit mask. NOTE: only applied to sources without guess models 214 psphotGuessModels (config, view, STACK_ SRC);195 psphotGuessModels (config, view, STACK_RAW); 215 196 216 197 // linear PSF fit to source peaks, subtract the models from the image (in PSF mask) 217 psphotFitSourcesLinear (config, view, STACK_ SRC, false, false);218 psphotStackVisualFilerule(config, view, STACK_ SRC);198 psphotFitSourcesLinear (config, view, STACK_RAW, false, false); 199 psphotStackVisualFilerule(config, view, STACK_RAW); 219 200 220 201 // measure the radial profiles to the sky 221 psphotRadialProfileWings (config, view, STACK_ SRC);202 psphotRadialProfileWings (config, view, STACK_RAW); 222 203 223 204 // re-measure the kron mags with models subtracted. this pass starts with a circular … … 225 206 // but iterates to an appropriately larger size 226 207 logMemStats("before.kron.1"); 227 psphotKronIterate(config, view, STACK_ SRC, 1);208 psphotKronIterate(config, view, STACK_RAW, 1); 228 209 logMemStats("after.kron.1"); 229 210 230 211 // identify CRs and extended sources 231 psphotSourceSize (config, view, STACK_ SRC, true);212 psphotSourceSize (config, view, STACK_RAW, true); 232 213 233 214 // non-linear PSF and EXT fit to brighter sources 234 215 // replace model flux, adjust mask as needed, fit, subtract the models (full stamp) 235 psphotBlendFit (config, view, STACK_ SRC); // pass 1 (detections->allSources)216 psphotBlendFit (config, view, STACK_RAW); // pass 1 (detections->allSources) 236 217 237 218 // replace all sources (do NOT ignore subtraction state) 238 psphotReplaceAllSources (config, view, STACK_ SRC, false); // pass 1 (detections->allSources)219 psphotReplaceAllSources (config, view, STACK_RAW, false); // pass 1 (detections->allSources) 239 220 240 221 logMemStats("pass1"); … … 245 226 // linear fit to include all sources (subtract again) 246 227 // NOTE : apply to ALL sources (extended + psf) 247 // NOTE 2 : this function subtracts the models from the given filerule (SRC), not DET248 psphotFitSourcesLinear (config, view, STACK_ SRC, true, false); // pass 2 (detections->allSources)228 // NOTE 2 : this function subtracts the models from the given filerule 229 psphotFitSourcesLinear (config, view, STACK_RAW, true, false); // pass 2 (detections->allSources) 249 230 250 231 // NOTE: possibly re-measure background model here with objects subtracted / or masked … … 252 233 // NOTE: this block performs the 2nd pass low-significance PSF detection stage 253 234 { 254 // if DET and SRC are different images, generate children sources for all sources in255 // the SRC image. This operation replaces the existing DETECTION container on DET256 // which is currently a view to the one on SRC). children sources go to257 // det->allSources258 if (strcmp(STACK_SRC, STACK_DET)) {259 psphotSourceChildren (config, view, STACK_DET, STACK_SRC);260 261 // subtract all sources from DET (this will subtract using the psf model for SRC, which262 // will somewhat oversubtract the sources -- this is OK263 psphotRemoveAllSources (config, view, STACK_DET, false); // do not ignore subtraction state for sources264 }265 266 235 // add noise for subtracted objects 267 psphotAddNoise (config, view, STACK_ DET); // pass 1 (detections->allSources)236 psphotAddNoise (config, view, STACK_RAW); // pass 1 (detections->allSources) 268 237 269 238 // find fainter sources 270 239 // NOTE: finds new peaks and new footprints, OLD and FULL set are saved on detections 271 psphotFindDetections (config, view, STACK_ DET, false); // pass 2 (detections->peaks, detections->footprints)240 psphotFindDetections (config, view, STACK_RAW, false); // pass 2 (detections->peaks, detections->footprints) 272 241 273 242 // remove noise for subtracted objects (ie, return to normal noise level) … … 276 245 bool footprintsUseUnsubtracted = psMetadataLookupBool(NULL, recipe, "FOOTPRINT_USE_UNSUBTRACTED"); 277 246 if (!footprintsUseUnsubtracted) { 278 psphotSubNoise (config, view, STACK_ DET); // pass 1 (detections->allSources)247 psphotSubNoise (config, view, STACK_RAW); // pass 1 (detections->allSources) 279 248 } 280 281 // if DET and SRC are different images, copy the detections from DET to SRC282 // (this operation just ensures the metadata container has a view on SRC as well283 if (strcmp(STACK_SRC, STACK_DET)) {284 // replace all sources in DET285 psphotReplaceAllSources (config, view, STACK_DET, false); // ignore subtraction state for sources286 287 // copy the newly detected peaks from DET to SRC so SourceStats below can operate on them288 if (!psphotCopyPeaks (config, view, STACK_SRC, STACK_DET)) {289 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");290 return psphotReadoutCleanup (config, view, STACK_SRC);291 }292 }293 249 294 250 // define new sources based on only the new peaks & measure moments 295 251 // NOTE: new sources are saved on detections->newSources 296 psphotSourceStats (config, view, STACK_ SRC, false); // pass 2 (detections->newSources)252 psphotSourceStats (config, view, STACK_RAW, false); // pass 2 (detections->newSources) 297 253 298 254 // set source type 299 255 // NOTE: apply only to detections->newSources 300 if (!psphotRoughClass (config, view, STACK_ SRC)) { // pass 2 (detections->newSources)256 if (!psphotRoughClass (config, view, STACK_RAW)) { // pass 2 (detections->newSources) 301 257 psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image"); 302 return psphotReadoutCleanup (config, view, STACK_ SRC);258 return psphotReadoutCleanup (config, view, STACK_RAW); 303 259 } 304 260 305 261 // replace all sources so fit below applies to all at once 306 262 // NOTE: apply only to OLD sources (which have been subtracted) 307 psphotReplaceAllSources (config, view, STACK_ SRC, false); // pass 2263 psphotReplaceAllSources (config, view, STACK_RAW, false); // pass 2 308 264 309 265 // merge the newly selected sources into the existing list 310 266 // NOTE: merge OLD and NEW 311 267 // XXX check on free of sources... 312 psphotMergeSources (config, view, STACK_ SRC); // (detections->newSources + detections->allSources -> detections->allSources)268 psphotMergeSources (config, view, STACK_RAW); // (detections->newSources + detections->allSources -> detections->allSources) 313 269 314 270 // Construct an initial model for each object, set the radius to fitRadius, set circular 315 271 // fit mask. NOTE: only applied to sources without guess models 316 psphotGuessModels (config, view, STACK_ SRC);272 psphotGuessModels (config, view, STACK_RAW); 317 273 } 318 274 … … 325 281 if (splitLinearFit) { 326 282 psLogMsg ("psphot", 3, "splitting fit of detected and matched soures\n"); 327 // Fit the detected sources separately from matched that weaare about to create.283 // Fit the detected sources separately from matched ones that we are about to create. 328 284 // NOTE: apply to ALL sources but only include sources with postitive flux in the fit 329 psphotFitSourcesLinear (config, view, STACK_ SRC, true, true); // pass 3 (detections->allSources)285 psphotFitSourcesLinear (config, view, STACK_RAW, true, true); // pass 3 (detections->allSources) 330 286 } 331 287 … … 335 291 // this just match the detections for the chisq image, and not bother measuring the source 336 292 // stats in that case...? 337 objects = psphotMatchSources (config, view, STACK_ SRC);293 objects = psphotMatchSources (config, view, STACK_RAW); 338 294 psMemDump("matchsources"); 339 295 … … 344 300 // Construct an initial model for each object, set the radius to fitRadius, set circular 345 301 // fit mask. NOTE: only applied to sources without guess models 346 psphotGuessModels (config, view, STACK_ SRC);302 psphotGuessModels (config, view, STACK_RAW); 347 303 348 304 psphotStackObjectsUnifyPosition (objects); 349 305 350 psphotStackObjectsSelectForAnalysis (config, view, STACK_SRC, objects);306 // psphotStackObjectsSelectForAnalysis (config, view, STACK_RAW, objects); 351 307 352 308 // final linear fit. NOTE: if splitLinearFit is true above, this pass will only fit 353 309 // the unsubtracted (matched) sources (the sources that we fit above are subtracted) 354 psphotFitSourcesLinear (config, view, STACK_ SRC, true, false); // pass 4 (detections->allSources)310 psphotFitSourcesLinear (config, view, STACK_RAW, true, false); // pass 4 (detections->allSources) 355 311 356 312 // measure the radial profiles to the sky (only measures new objects) 357 psphotRadialProfileWings (config, view, STACK_ SRC);313 psphotRadialProfileWings (config, view, STACK_RAW); 358 314 359 315 // re-measure the kron mags with models subtracted 360 316 // psphotKronMasked(config, view, STACK_SRC); 361 317 logMemStats("before.kron.2"); 362 psphotKronIterate(config, view, STACK_ SRC, 2);318 psphotKronIterate(config, view, STACK_RAW, 2); 363 319 logMemStats("after.kron.2"); 364 320 365 321 // measure source size for the remaining sources 366 322 // NOTE: applies only to NEW (unmeasured) sources 367 psphotSourceSize (config, view, STACK_ SRC, false); // pass 2 (detections->allSources)323 psphotSourceSize (config, view, STACK_RAW, false); // pass 2 (detections->allSources) 368 324 369 325 psMemDump("psfstats"); … … 371 327 // drop matched sources without any useful measurements and set kron radii for the ones 372 328 // we decide to keep 373 psphotFilterMatchedSources (config, view, STACK_ SRC, objects);329 psphotFilterMatchedSources (config, view, STACK_RAW, objects); 374 330 375 331 // measure kron fluxes for the matched sources only 376 psphotKronIterate(config, view, STACK_SRC, 3); 332 psphotKronIterate(config, view, STACK_RAW, 3); 333 334 // decide which source(s) are to be fitted with the extended source analysis code. 335 psphotChooseAnalysisOptionsByObject (config, view, STACK_RAW, objects); 377 336 378 337 // measure elliptical apertures, petrosians (objects sorted by S/N) 379 338 // psphotExtendedSourceAnalysisByObject (config, objects, view, STACK_SRC); // pass 1 (detections->allSources) 380 psphotExtendedSourceAnalysis (config, view, STACK_ SRC); // pass 1 (detections->allSources)339 psphotExtendedSourceAnalysis (config, view, STACK_RAW); // pass 1 (detections->allSources) 381 340 382 341 // measure non-linear extended source models (exponential, deVaucouleur, Sersic) (sources sorted by S/N) 383 psphotExtendedSourceFits (config, view, STACK_ SRC); // pass 1 (detections->allSources)342 psphotExtendedSourceFits (config, view, STACK_RAW); // pass 1 (detections->allSources) 384 343 385 344 // create source children for the OUT filerule (for radial aperture photometry and output) 386 psArray *objectsOut = psphotSourceChildrenByObject (config, view, STACK_OUT, objects); 345 // NOTE: The new source children have image arrays pointing to the readout associated with 346 // STACK_OUT. in psphotStackMatchPSFsetup, we copy the current pixel values from RAW to OUT, 347 // but keep the pointers the same so we do not break these source image references 348 // XXX NOTE : if we use the pre-20130914 psphotStackReadout code, we need to use 'false' for the 349 // sourcesSubtracted argument 350 psArray *objectsOut = psphotSourceChildrenByObject (config, view, STACK_OUT, objects, true); 387 351 if (!objectsOut) { 388 352 psFree(objects); 389 353 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis"); 390 return psphotReadoutCleanup (config, view, STACK_ SRC);354 return psphotReadoutCleanup (config, view, STACK_RAW); 391 355 } 392 356 … … 396 360 // this forces photometry on the undetected sources from other images 397 361 398 // NOTE: we always do the radial apertures analysis on the convolved image since 399 // those are the ones that are psf matched and are the source of STACK_OUT's pixels 400 // XXX: Actually if PSPHOT.STACK.MATCH.PSF.SOURCE were set to RAW this wouldn't be true. 401 // but in that case we don't get past the psf matching step because there is no 402 // target psf for the RAW inputs 403 404 // If useRaw copy the sources to the convolved readout 405 if (strcmp(STACK_SRC, STACK_CNV)) { 406 if (!psphotCopySources (config, view, STACK_CNV, STACK_SRC)) { 407 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis"); 408 return psphotReadoutCleanup (config, view, STACK_SRC); 409 } 410 } 411 // mark any inputs that we want to skip the matched apertures for 412 psphotStackSetInputsToSkip(config, view, STACK_CNV, true); 413 psphotStackSetInputsToSkip(config, view, STACK_OUT, true); 414 psphotRadialApertures (config, view, STACK_CNV, 0); // entry 0 == unmatched 415 psMemDump("extmeas"); 416 362 // set up the FWHM vector 363 psphotStackMatchPSFsetup (config, view, STACK_OUT, STACK_RAW); 364 psphotDumpImages (config, view, STACK_RAW, "raw.t0"); 365 psphotDumpImages (config, view, STACK_OUT, "out.t0"); 417 366 418 367 int nRadialEntries = psphotStackMatchPSFsEntries(config, view, STACK_OUT); 419 for (int entry = 1; entry < nRadialEntries; entry++) { 368 369 for (int entry = 0; entry < nRadialEntries; entry++) { 420 370 // NOTE: entry 0 is the unmatched image set 421 371 422 // re-measure the PSF for the smoothed image (using entries in 'allSources') 423 psphotChoosePSF (config, view, STACK_OUT, false); 424 425 // this is necessary to update the models based on the new PSF 426 psphotResetModels (config, view, STACK_OUT); 427 428 // this is necessary to get the right normalization for the new models 429 psphotFitSourcesLinear (config, view, STACK_OUT, false, false); 372 char line[256]; 430 373 431 374 // measure circular, radial apertures (objects sorted by S/N) 432 375 psphotRadialApertures (config, view, STACK_OUT, entry); 376 snprintf (line, 256, "%s.%d", "out.t1", entry); 377 psphotDumpImages (config, view, STACK_OUT, line); 433 378 434 379 // replace the flux in the image so it is returned to its original state 435 380 psphotReplaceAllSources (config, view, STACK_OUT, false); 436 437 // smooth to the next FWHM, or set 'smoothAgain' to false if no more 438 psphotStackMatchPSFsNext(config, view, STACK_OUT, entry); 439 psMemDump("matched"); 381 snprintf (line, 256, "%s.%d", "out.t2", entry); 382 psphotDumpImages (config, view, STACK_OUT, line); 383 384 if (entry < nRadialEntries - 1) { 385 // smooth to the next FWHM 386 // this function does nothing if the targetFWHM is smaller than the currentFWHM 387 psphotStackMatchPSFsNext(config, view, STACK_OUT, entry); 388 snprintf (line, 256, "%s.%d", "out.t3", entry); 389 psphotDumpImages (config, view, STACK_OUT, line); 390 psMemDump("matched"); 391 392 // re-measure the PSF for the smoothed image (using entries in 'allSources') 393 if (!psphotChoosePSF (config, view, STACK_OUT, false)) { 394 psLogMsg ("psphot", 3, "failure to construct a psf model in radial aperture loop for entry :%d", entry); 395 return psphotReadoutCleanup (config, view, STACK_RAW); 396 } 397 398 // this is necessary to update the models based on the new PSF 399 psphotResetModels (config, view, STACK_OUT); 400 401 // this is necessary to get the right normalization for the new models 402 // and to subtract the sources 403 psphotFitSourcesLinear (config, view, STACK_OUT, false, false); 404 snprintf (line, 256, "%s.%d", "out.t4", entry); 405 psphotDumpImages (config, view, STACK_OUT, line); 406 } 440 407 } 441 408 } 442 psphotStackSetInputsToSkip(config, view, STACK_CNV, false);443 psphotStackSetInputsToSkip(config, view, STACK_OUT, false);444 409 445 410 // measure aperture photometry corrections 446 if (!psphotApResid (config, view, STACK_ SRC)) {411 if (!psphotApResid (config, view, STACK_RAW)) { 447 412 psFree (objects); 448 413 psFree (objectsOut); 449 414 psLogMsg ("psphot", 3, "failed on psphotApResid"); 450 return psphotReadoutCleanup (config, view, STACK_ SRC);415 return psphotReadoutCleanup (config, view, STACK_RAW); 451 416 } 452 417 453 418 // calculate source magnitudes 454 psphotMagnitudes(config, view, STACK_SRC); 455 456 if (!useRaw) { 457 // psphotEfficiency wants to have the PSF of the image, but since we are measuring on 458 // the convolved images we need to generate PSFs for the DET images 459 if (!psphotChoosePSF (config, view, STACK_DET, false)) { 460 psLogMsg ("psphot", 3, "failure to construct a psf model for raw input"); 461 return psphotReadoutCleanup (config, view, STACK_DET); 462 } 463 } 464 if (!psphotEfficiency(config, view, STACK_DET)) { 419 psphotMagnitudes(config, view, STACK_RAW); 420 421 // calculate lensing parameters 422 if (!psphotLensing(config, view, STACK_RAW)) { 423 psErrorStackPrint(stderr, "Unable to do lensing parameters."); 424 psErrorClear(); 425 } 426 427 if (!psphotEfficiency(config, view, STACK_RAW)) { 465 428 psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources"); 466 429 psErrorClear(); 467 430 } 468 psphotCopyEfficiency (config, view, STACK_OUT, STACK_ DET);431 psphotCopyEfficiency (config, view, STACK_OUT, STACK_RAW); 469 432 470 433 logMemStats("final"); 471 434 #if (1) 472 psphotSourceMemory(config, view, STACK_ SRC);435 psphotSourceMemory(config, view, STACK_RAW); 473 436 psphotSourceMemory(config, view, STACK_OUT); 474 437 #endif 475 438 476 // replace failed sources?477 // psphotReplaceUnfitSources (sources);478 479 439 // replace background in residual image 480 psphotSkyReplace (config, view, STACK_ DET);440 psphotSkyReplace (config, view, STACK_RAW); 481 441 482 442 // drop the references to the image pixels held by each source 443 psphotSourceFreePixels (config, view, STACK_RAW); 483 444 psphotSourceFreePixels (config, view, STACK_OUT); 484 psphotSourceFreePixels (config, view, STACK_SRC);485 445 486 446 #ifdef MAKE_CHISQ_IMAGE 487 447 // remove chisq image from config->file:PSPHOT.INPUT 488 psphotStackRemoveChisqFromInputs(config, STACK_DET); 489 if (strcmp(STACK_SRC, STACK_DET)) { 490 psphotStackRemoveChisqFromInputs(config, STACK_SRC); 491 } 448 psphotStackRemoveChisqFromInputs(config, STACK_RAW); 492 449 #endif 493 450 … … 496 453 497 454 // create the exported-metadata and free local data 498 return psphotReadoutCleanup (config, view, STACK_ SRC);455 return psphotReadoutCleanup (config, view, STACK_RAW); 499 456 } 500 457 … … 552 509 } 553 510 554 555 556 511 /* here is the process: 557 512 558 * we have three(*) images: 559 * RAW : unconvolved image stack 560 * CNV : input convolved image 513 * we have two image sets: 514 * RAW : unconvolved image stacks 561 515 562 516 * OUT : psf-matched output image (there may be more than one of … … 649 603 650 604 */ 605 606 607 // generate a vector fwhmValues where the first has the fwhm of the raw image and the 608 // successive entries have the target values 609 610 bool psphotStackMatchPSFsetup (pmConfig *config, const pmFPAview *view, const char *filerule, const char *filerulePSF) { 611 612 bool status; 613 614 int num = psphotFileruleCount(config, filerule); 615 616 // skip the chisq image (optionally?) 617 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 618 if (!status) chisqNum = -1; 619 620 // loop over the available readouts 621 for (int i = 0; i < num; i++) { 622 if (i == chisqNum) continue; // skip chisq image 623 624 if (!psphotStackMatchPSFsetupReadout (config, view, filerule, filerulePSF, i)) { 625 psError (PSPHOT_ERR_CONFIG, false, "failed to define target PSF sizes"); 626 return false; 627 } 628 } 629 630 return true; 631 } 632 633 float psphotPSFseeing (pmPSF *psf, pmReadout *readout, int index); 634 635 // copy the pixels from RAW to OUT ( 636 637 bool psphotStackMatchPSFsetupReadout (pmConfig *config, const pmFPAview *view, const char *fileruleOut, const char *fileruleRaw, int index) { 638 639 bool status; 640 641 // select the appropriate recipe information 642 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 643 644 // find the currently selected readout 645 pmFPAfile *fileOut = pmFPAfileSelectSingle(config->files, fileruleOut, index); // File of interest 646 psAssert (fileOut, "missing file?"); 647 648 pmReadout *readoutOut = pmFPAviewThisReadout(view, fileOut->fpa); 649 psAssert (readoutOut, "missing readout?"); 650 651 // find the currently selected readout 652 pmFPAfile *fileRaw = pmFPAfileSelectSingle(config->files, fileruleRaw, index); // File of interest 653 psAssert (fileRaw, "missing file?"); 654 655 pmReadout *readoutRaw = pmFPAviewThisReadout(view, fileRaw->fpa); 656 psAssert (readoutRaw, "missing readout?"); 657 658 readoutOut->image = psImageCopy(readoutOut->image, readoutRaw->image, PS_TYPE_F32); 659 if (readoutRaw->variance) { 660 readoutOut->variance = psImageCopy(readoutOut->variance, readoutRaw->variance, PS_TYPE_F32); 661 } 662 if (readoutRaw->mask) { 663 readoutOut->mask = psImageCopy(readoutOut->mask, readoutRaw->mask, PS_TYPE_IMAGE_MASK); 664 } 665 666 // pmChip *chipRaw = pmFPAviewThisChip(view, fileRaw->fpa); // The chip holds the PSF 667 // psAssert (chipRaw, "missing chip"); 668 669 pmPSF *psf = psMetadataLookupPtr(&status, readoutRaw->analysis, "PSPHOT.PSF"); // PSF 670 if (!psf) { 671 // we should have a PSF by this point in psphot 672 psError(PSPHOT_ERR_PROG, true, "Unable to find PSF."); 673 return false; 674 } 675 676 float fwhmRaw = psphotPSFseeing (psf, readoutRaw, index); 677 678 psVector *fwhmValues = psVectorAllocEmpty(10, PS_TYPE_F32); 679 psVectorAppend(fwhmValues, fwhmRaw); 680 681 // is a single target FWHM specified, or a set of values? set up the vector options->targetSeeing and the local 1st value 682 float targetSeeing = psMetadataLookupF32 (&status, recipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); 683 if (!status) { 684 psVector *targetSeeing = psMetadataLookupVector(&status, recipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); // Magnitude offsets 685 psAssert (status, "missing psphot recipe value PSPHOT.STACK.TARGET.PSF.FWHM"); 686 for (int i = 0; i < targetSeeing->n; i++) { 687 psVectorAppend(fwhmValues, targetSeeing->data.F32[i]); 688 } 689 } else { 690 psVectorAppend(fwhmValues, targetSeeing); 691 } 692 693 psMetadataAddVector(readoutOut->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues); 694 psFree (fwhmValues); 695 696 return true; 697 } 698 699 float psphotPSFseeing (pmPSF *psf, pmReadout *readout, int index) { 700 701 psImage *image = readout->image; 702 703 int Nx = image->numCols; 704 int Ny = image->numRows; 705 706 float sumFWHM = 0.0; // FWHM for image 707 int numFWHM = 0; // Number of FWHM measurements 708 for (float x = 0; x < Nx; x += 0.25*Nx) { 709 for (float y = 0; y < Ny; y += 0.25*Ny) { 710 float fwhm = pmPSFtoFWHM(psf, x, y); 711 if (isfinite(fwhm)) { 712 sumFWHM += fwhm; 713 numFWHM++; 714 } 715 } 716 } 717 if (numFWHM == 0) { 718 psLogMsg("ppStack", PS_LOG_INFO, "Unable to measure PSF FWHM for image %d --- rejected.", index); 719 return NAN; 720 } 721 722 float fwhm = sumFWHM / (float) numFWHM; 723 psLogMsg ("psphotStack", PS_LOG_INFO, "Input Seeing for %d: %f\n", index, fwhm); 724 725 return fwhm; 726 } -
branches/eam_branches/ipp-ops-20130712/psphot/src/psphotVisual.c
r35769 r37066 1444 1444 coord->data.F32[1] = r; 1445 1445 coord->data.F32[0] = 0.0; 1446 fmaj->data.F32[i] = log10(source->modelPSF-> modelFunc (NULL, params, coord));1446 fmaj->data.F32[i] = log10(source->modelPSF->class->modelFunc (NULL, params, coord)); 1447 1447 1448 1448 coord->data.F32[0] = r; 1449 1449 coord->data.F32[1] = 0.0; 1450 fmin->data.F32[i] = log10(source->modelPSF-> modelFunc (NULL, params, coord));1450 fmin->data.F32[i] = log10(source->modelPSF->class->modelFunc (NULL, params, coord)); 1451 1451 } 1452 1452 psFree (coord); 1453 1453 psFree (params); 1454 1454 1455 float FWHM_MAJOR = 2.0*source->modelPSF-> modelRadius (source->modelPSF->params, 0.5*source->modelPSF->params->data.F32[PM_PAR_I0]);1455 float FWHM_MAJOR = 2.0*source->modelPSF->class->modelRadius (source->modelPSF->params, 0.5*source->modelPSF->params->data.F32[PM_PAR_I0]); 1456 1456 float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major); 1457 1457 if (FWHM_MAJOR < FWHM_MINOR) PS_SWAP (FWHM_MAJOR, FWHM_MINOR);
Note:
See TracChangeset
for help on using the changeset viewer.
