Changeset 32348
- Timestamp:
- Sep 6, 2011, 1:32:31 PM (15 years ago)
- Location:
- trunk/psphot
- Files:
-
- 50 edited
- 23 copied
-
. (modified) (1 prop)
-
doc/sourcepixels.txt (copied) (copied from branches/eam_branches/ipp-20110710/psphot/doc/sourcepixels.txt )
-
src (modified) (1 prop)
-
src/Makefile.am (modified) (8 diffs)
-
src/psphot.c (modified) (1 diff)
-
src/psphot.h (modified) (9 diffs)
-
src/psphotAddNoise.c (modified) (1 diff)
-
src/psphotApResid.c (modified) (3 diffs)
-
src/psphotBlendFit.c (modified) (6 diffs)
-
src/psphotChoosePSF.c (modified) (4 diffs)
-
src/psphotEfficiency.c (modified) (10 diffs)
-
src/psphotEllipticalContour.c (modified) (3 diffs)
-
src/psphotExtendedSourceAnalysis.c (modified) (8 diffs)
-
src/psphotExtendedSourceFits.c (modified) (17 diffs)
-
src/psphotFindDetections.c (modified) (1 diff)
-
src/psphotFindFootprints.c (modified) (1 diff)
-
src/psphotFindPeaks.c (modified) (1 diff)
-
src/psphotFitSourcesLinear.c (modified) (5 diffs)
-
src/psphotFitSourcesLinearStack.c (modified) (4 diffs)
-
src/psphotFootprintSaddles.c (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotFootprintSaddles.c )
-
src/psphotGuessModels.c (modified) (1 diff)
-
src/psphotImageLoop.c (modified) (1 diff)
-
src/psphotImageQuality.c (modified) (1 diff)
-
src/psphotKronIterate.c (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotKronIterate.c )
-
src/psphotKronMasked.c (modified) (13 diffs)
-
src/psphotLoadSRCTEXT.c (modified) (1 diff)
-
src/psphotMagnitudes.c (modified) (2 diffs)
-
src/psphotModelBackground.c (modified) (6 diffs)
-
src/psphotModelTest.c (modified) (1 diff)
-
src/psphotModelTestArguments.c (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotModelTestArguments.c )
-
src/psphotModelTestReadout.c (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotModelTestReadout.c )
-
src/psphotOutput.c (modified) (1 diff)
-
src/psphotPetrosianProfile.c (modified) (1 diff)
-
src/psphotPetrosianStats.c (modified) (4 diffs)
-
src/psphotRadialApertures.c (modified) (9 diffs)
-
src/psphotRadialAperturesByObject.c (modified) (1 diff)
-
src/psphotRadialProfile.c (modified) (1 diff)
-
src/psphotRadiusChecks.c (modified) (2 diffs)
-
src/psphotReadout.c (modified) (8 diffs)
-
src/psphotRoughClass.c (modified) (2 diffs)
-
src/psphotSersicGuess.00.00.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.00.00.h )
-
src/psphotSersicGuess.00.01.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.00.01.h )
-
src/psphotSersicGuess.00.02.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.00.02.h )
-
src/psphotSersicGuess.00.03.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.00.03.h )
-
src/psphotSersicGuess.01.00.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.01.00.h )
-
src/psphotSersicGuess.01.01.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.01.01.h )
-
src/psphotSersicGuess.01.02.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.01.02.h )
-
src/psphotSersicGuess.01.03.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.01.03.h )
-
src/psphotSersicGuess.02.00.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.02.00.h )
-
src/psphotSersicGuess.02.01.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.02.01.h )
-
src/psphotSersicGuess.02.02.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.02.02.h )
-
src/psphotSersicGuess.02.03.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.02.03.h )
-
src/psphotSersicGuess.03.00.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.03.00.h )
-
src/psphotSersicGuess.03.01.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.03.01.h )
-
src/psphotSersicGuess.03.02.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.03.02.h )
-
src/psphotSersicGuess.03.03.h (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicGuess.03.03.h )
-
src/psphotSersicModelClass.c (copied) (copied from branches/eam_branches/ipp-20110710/psphot/src/psphotSersicModelClass.c )
-
src/psphotSetThreads.c (modified) (2 diffs)
-
src/psphotSourceFits.c (modified) (25 diffs)
-
src/psphotSourceMatch.c (modified) (2 diffs)
-
src/psphotSourceSize.c (modified) (4 diffs)
-
src/psphotSourceStats.c (modified) (3 diffs)
-
src/psphotStackImageLoop.c (modified) (1 diff)
-
src/psphotStackMatchPSFs.c (modified) (4 diffs)
-
src/psphotStackMatchPSFsNext.c (modified) (7 diffs)
-
src/psphotStackMatchPSFsPrepare.c (modified) (1 diff)
-
src/psphotStackMatchPSFsUtils.c (modified) (5 diffs)
-
src/psphotStackObjects.c (modified) (1 diff)
-
src/psphotStackOptions.c (modified) (4 diffs)
-
src/psphotStackPSF.c (modified) (3 diffs)
-
src/psphotStackReadout.c (modified) (10 diffs)
-
src/psphotSubtractBackground.c (modified) (1 diff)
-
test/tap_dense.pro (copied) (copied from branches/eam_branches/ipp-20110710/psphot/test/tap_dense.pro )
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot
-
trunk/psphot/src
- Property svn:ignore
-
old new 22 22 psphotMakePSF 23 23 psphotStack 24 psphotModelTest
-
- Property svn:ignore
-
trunk/psphot/src/Makefile.am
r31452 r32348 25 25 libpsphot_la_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 26 26 27 bin_PROGRAMS = psphot psphotForced psphotMakePSF psphotStack 27 bin_PROGRAMS = psphot psphotForced psphotMakePSF psphotStack psphotModelTest 28 28 # bin_PROGRAMS = psphotPetrosianStudy psphotTest psphotMomentsStudy 29 29 … … 43 43 psphotStack_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 44 44 psphotStack_LDADD = libpsphot.la 45 46 psphotModelTest_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) 47 psphotModelTest_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS) 48 psphotModelTest_LDADD = libpsphot.la 45 49 46 50 # psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS) … … 102 106 psphotCleanup.c 103 107 108 # a psphot-variant that simply generates the PSF model 109 psphotModelTest_SOURCES = \ 110 psphotModelTest.c \ 111 psphotModelTestArguments.c \ 112 psphotParseCamera.c \ 113 psphotImageLoop.c \ 114 psphotMosaicChip.c \ 115 psphotCleanup.c 116 104 117 # psphotTest_SOURCES = \ 105 118 # psphotTest.c … … 117 130 psphotVisual.c \ 118 131 psphotCullPeaks.c \ 132 psphotFootprintSaddles.c \ 119 133 psphotVersion.c \ 120 134 psphotModelGroupInit.c \ … … 129 143 psphotMakePSFReadout.c \ 130 144 psphotModelBackground.c \ 145 psphotModelTestReadout.c \ 131 146 psphotMaskBackground.c \ 132 147 psphotSubtractBackground.c \ … … 157 172 psphotExtendedSourceAnalysisByObject.c \ 158 173 psphotExtendedSourceFits.c \ 174 psphotSersicModelClass.c \ 159 175 psphotKernelFromPSF.c \ 160 176 psphotFitSet.c \ … … 168 184 psphotRadialPlot.c \ 169 185 psphotKronMasked.c \ 186 psphotKronIterate.c \ 170 187 psphotDeblendSatstars.c \ 171 188 psphotMosaicSubimage.c \ … … 191 208 psphotEfficiency.c 192 209 193 # XXX need to fix this for the new apis194 # psphotModelTest.c195 196 210 # re-instate these 197 211 # psphotIsophotal.c \ -
trunk/psphot/src/psphot.c
r31673 r32348 27 27 } 28 28 29 psLogMsg ("psphot", 3, "complete psphot run: %f sec\n", psTimerMark ("complete"));29 psLogMsg ("psphot", PS_LOG_WARN, "complete psphot run: %f sec\n", psTimerMark ("complete")); 30 30 31 31 psErrorCode exit_status = psphotGetExitStatus(); -
trunk/psphot/src/psphot.h
r31452 r32348 19 19 PSPHOT_FORCED, 20 20 PSPHOT_MAKE_PSF, 21 PSPHOT_MODEL_TEST, 21 22 } psphotImageLoopMode; 22 23 … … 117 118 bool psphotExtendedSourceAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule); 118 119 bool psphotExtendedSourceAnalysisReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe); 120 bool psphotExtendedSourceAnalysis_Threaded (psThreadJob *job); 119 121 120 122 bool psphotExtendedSourceFits (pmConfig *config, const pmFPAview *view, const char *filerule); … … 327 329 bool psphotMakePSFReadout(pmConfig *config, const pmFPAview *view, const char *filerule); 328 330 331 pmConfig *psphotModelTestArguments(int argc, char **argv); 332 bool psphotModelTestReadout(pmConfig *config, const pmFPAview *view, const char *filerule); 333 329 334 int psphotFileruleCount(const pmConfig *config, const char *filerule); 330 335 bool psphotFileruleCountSet(const pmConfig *config, const char *filerule, int num); … … 372 377 bool convolve; // Convolve images? 373 378 psphotStackConvolveSource convolveSource; 374 // psArray *convImages, *convMasks, *convVariances; // Filenames for the temporary convolved images375 376 // bool matchZPs; // Adjust relative fluxes based on transparency analysis?377 // bool photometry; // Perform photometry?378 // psMetadata *stats; // Statistics for output379 // FILE *statsFile; // File to which to write statistics380 // psArray *origImages, *origMasks, *origVariances; // Filenames of the original images381 // psArray *origCovars; // Original covariances matrices382 // int quality; // Bad data quality flag383 379 384 380 // Prepare … … 387 383 psVector *inputMask; // Mask for inputs 388 384 389 float targetSeeing; // Target seeing FWHM385 psVector *targetSeeing; // Target seeing FWHMs 390 386 psArray *sourceLists; // Individual lists of sources for matching 391 387 psVector *norm; // Normalisation for each image 392 388 psArray *psfs; 393 394 // psVector *exposures; // Exposure times395 // float sumExposure; // Sum of exposure times396 // float zp; // Zero point for output397 // psVector *inputMask; // Mask for inputs398 // psArray *sources; // Matched sources399 389 400 390 // Convolve … … 402 392 psArray *regions; // PSF-matching regions --- required in the stacking 403 393 psVector *matchChi2; // chi^2 for stamps from matching 404 psVector *weightings; // Combination weightings for images (1/noise^2)405 // psArray *cells; // Cells for convolved images --- a handle for reading again406 // int numCols, numRows; // Size of image407 // psArray *convCovars; // Convolved covariance matrices408 409 // Combine initial410 // pmReadout *outRO; // Output readout411 // pmReadout *expRO; // Exposure readout412 // psArray *inspect; // Array of arrays of pixels to inspect413 414 // Rejection415 // psArray *rejected; // Rejected pixels416 394 } psphotStackOptions; 417 395 … … 420 398 bool psphotStackMatchPSFsReadout (pmConfig *config, const pmFPAview *view, psphotStackOptions *options, int index); 421 399 bool psphotStackMatchPSFsPrepare (pmConfig *config, const pmFPAview *view, psphotStackOptions *options, int index); 422 bool psphotStackMatchPSFsNext (bool *smoothAgain, pmConfig *config, const pmFPAview *view, const char *filerule, int lastSize); 423 bool psphotStackMatchPSFsNextReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, psVector *fwhmValues, int lastSize); 400 401 bool psphotStackMatchPSFsNext (pmConfig *config, const pmFPAview *view, const char *filerule, int lastSize); 402 bool psphotStackMatchPSFsNextReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, int lastSize); 403 int psphotStackMatchPSFsEntries (pmConfig *config, const pmFPAview *view, const char *filerule); 424 404 425 405 // psphotStackMatchPSFsUtils 426 psVector *SetOptWidths (bool *optimum, psMetadata *recipe);427 pmReadout *makeFakeReadout(pmConfig *config, pmReadout *raw, psArray *sources, pmPSF *psf, psImageMaskType maskVal, int fullSize);428 bool rescaleData(pmReadout *readout, pmConfig *config, psphotStackOptions *options, int index);429 bool renormKernel(pmReadout *readout, psphotStackOptions *options, int index);406 // psVector *SetOptWidths (bool *optimum, psMetadata *recipe); 407 // pmReadout *makeFakeReadout(pmConfig *config, pmReadout *raw, psArray *sources, pmPSF *psf, psImageMaskType maskVal, int fullSize); 408 // bool rescaleData(pmReadout *readout, pmConfig *config, psphotStackOptions *options, int index); 409 // bool renormKernel(pmReadout *readout, psphotStackOptions *options, int index); 430 410 bool saveMatchData (pmReadout *readout, psphotStackOptions *options, int index); 431 411 bool matchKernel(pmConfig *config, pmReadout *cnv, pmReadout *raw, psphotStackOptions *options, int index); 432 bool dumpImageDiff(pmReadout *readoutConv, pmReadout *readoutFake, pmReadout *readoutRef, int index, char *rootname); 433 bool dumpImage(pmReadout *readoutOut, pmReadout *readoutRef, int index, char *rootname); 434 bool loadKernel (pmConfig *config, pmReadout *readoutCnv, psphotStackOptions *options, int index); 435 436 pmPSF *psphotStackPSF(const pmConfig *config, int numCols, int numRows, const psArray *psfs, const psVector *inputMask); 412 // bool dumpImageDiff(pmReadout *readoutConv, pmReadout *readoutFake, pmReadout *readoutRef, int index, char *rootname); 413 // bool dumpImage(pmReadout *readoutOut, pmReadout *readoutRef, int index, char *rootname); 414 // bool loadKernel (pmConfig *config, pmReadout *readoutCnv, psphotStackOptions *options, int index); 415 416 bool psphotStackRenormaliseVariance(const pmConfig *config, pmReadout *readout); 417 418 bool psphotStackPSF(const pmConfig *config, psphotStackOptions *options); 437 419 438 420 psphotStackOptions *psphotStackOptionsAlloc (int num); … … 443 425 bool psphotCopySourcesReadout (pmConfig *config, const pmFPAview *view, const char *ruleOut, const char *ruleSrc, int index); 444 426 445 bool psphotRadialApertures (pmConfig *config, const pmFPAview *view, const char *filerule); 446 bool psphotRadialAperturesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe); 427 bool psphotRadialApertures (pmConfig *config, const pmFPAview *view, const char *filerule, int entry); 428 bool psphotRadialAperturesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, int entry); 429 bool psphotRadialApertures_Threaded (psThreadJob *job); 447 430 bool psphotRadialApertureSource (pmSource *source, psMetadata *recipe, psImageMaskType maskVal, const psVector *radMax, int entry); 448 431 … … 469 452 psArray *psphotSourceChildrenByObject (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objectsSrc); 470 453 454 bool psphotSersicModelClassGuessPCM (pmPCMdata *pcm, pmSource *source); 455 void psphotSersicModelClassInit (); 456 void psphotSersicModelClassCleanup (); 457 458 bool psphotSetRadiusMoments (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal); 459 bool psphotSetRadiusMomentsExact (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal); 460 461 bool psphotFootprintSaddles(pmReadout *readout, psArray *footprints); 462 bool psphotMaskFootprint (pmReadout *readout, pmSource *source, psImageMaskType markVal); 463 464 bool psphotKronIterate (pmConfig *config, const pmFPAview *view, const char *filerule); 465 bool psphotKronIterateReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf); 466 bool psphotKronIterate_Threaded (psThreadJob *job); 467 468 bool psphotStackObjectsSelectForAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects); 469 471 470 #endif -
trunk/psphot/src/psphotAddNoise.c
r29936 r32348 85 85 } 86 86 if (add) { 87 psLogMsg ("psphot.noise", PS_LOG_ INFO, "add noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));87 psLogMsg ("psphot.noise", PS_LOG_WARN, "add noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise")); 88 88 } else { 89 psLogMsg ("psphot.noise", PS_LOG_ INFO, "sub noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise"));89 psLogMsg ("psphot.noise", PS_LOG_WARN, "sub noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise")); 90 90 } 91 91 -
trunk/psphot/src/psphotApResid.c
r31452 r32348 1 1 # include "psphotInternal.h" 2 # define DEBUG2 // # define DEBUG 3 3 4 4 # define SKIPSTAR(MSG) { psTrace ("psphot", 3, "invalid : %s", MSG); continue; } … … 9 9 { 10 10 bool status = true; 11 12 fprintf (stdout, "\n"); 13 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Aperture Residuals ---"); 11 14 12 15 // select the appropriate recipe information … … 347 350 348 351 psLogMsg ("psphot.apresid", PS_LOG_DETAIL, "aperture residual: %f +/- %f\n", psf->ApResid, psf->dApResid); 349 psLogMsg ("psphot.apresid", PS_LOG_ INFO, "measure full-frame aperture residuals for %d sources: %f sec\n", Npsf, psTimerMark ("psphot.apresid"));352 psLogMsg ("psphot.apresid", PS_LOG_WARN, "measure full-frame aperture residuals for %d sources: %f sec\n", Npsf, psTimerMark ("psphot.apresid")); 350 353 351 354 psFree (xPos); -
trunk/psphot/src/psphotBlendFit.c
r31452 r32348 5 5 { 6 6 bool status = true; 7 8 fprintf (stdout, "\n"); 9 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Fit Sources (Non-Linear) ---"); 7 10 8 11 // select the appropriate recipe information … … 186 189 psFree (fitOptions); 187 190 188 psLogMsg ("psphot.psphotBlendFit", PS_LOG_ INFO, "fit models: %f sec for %d objects (%d psf, %d ext, %d failed, %ld skipped)\n", psTimerMark ("psphot.fit.nonlinear"), Nfit, Npsf, Next, Nfail, sources->n - Nfit);191 psLogMsg ("psphot.psphotBlendFit", PS_LOG_WARN, "fit models: %f sec for %d objects (%d psf, %d ext, %d failed, %ld skipped)\n", psTimerMark ("psphot.fit.nonlinear"), Nfit, Npsf, Next, Nfail, sources->n - Nfit); 189 192 190 193 psphotVisualShowResidualImage (readout, false); … … 233 236 pmSource *source = sources->data[i]; 234 237 238 # define TEST_X -420.0 239 # define TEST_Y 300.0 240 241 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 242 fprintf (stderr, "test galaxy\n"); 243 } 244 245 # undef TEST_X 246 # undef TEST_Y 247 235 248 // skip non-astronomical objects (very likely defects) 236 249 if (source->mode & PM_SOURCE_MODE_BLEND) continue; … … 246 259 247 260 // limit selection to some SN limit 248 if (sqrt(source->peak->detValue) < FIT_SN_LIM) continue; 249 261 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 262 if (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr) continue; 263 } else { 264 if (sqrt(source->peak->detValue) < FIT_SN_LIM) continue; 265 } 250 266 // exclude sources outside optional analysis region 251 267 if (source->peak->xf < AnalysisRegion.x0) continue; … … 267 283 } 268 284 269 // replace object in image 285 // replace object in image & remove excess noise 270 286 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) { 271 287 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal); … … 305 321 Nfail ++; 306 322 307 // re-subtract the object, leave local sky 323 // re-subtract the object, leave local sky, re-bump noise 308 324 pmSourceCacheModel (source, maskVal); 309 325 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); -
trunk/psphot/src/psphotChoosePSF.c
r31673 r32348 5 5 { 6 6 bool status = true; 7 8 fprintf (stdout, "\n"); 9 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Choose PSF ---"); 7 10 8 11 // select the appropriate recipe information … … 376 379 377 380 char *modelName = pmModelClassGetName (psf->type); 378 psLogMsg ("psphot.pspsf", PS_LOG_ INFO, "select psf model: %f sec\n", psTimerMark ("psphot.choose.psf"));381 psLogMsg ("psphot.pspsf", PS_LOG_WARN, "select psf model: %f sec\n", psTimerMark ("psphot.choose.psf")); 379 382 psLogMsg ("psphot.pspsf", PS_LOG_INFO, "psf model %s, ApResid: %f +/- %f\n", modelName, psf->ApResid, psf->dApResid); 380 383 … … 443 446 psVectorAppend (fwhmMinor, FWHM_MINOR); 444 447 445 if (modelPSF->params->n > =7) {448 if (modelPSF->params->n > 7) { 446 449 psVectorAppend (psfExtra1, modelPSF->params->data.F32[7]); 447 450 } 448 if (modelPSF->params->n > =8) {451 if (modelPSF->params->n > 8) { 449 452 psVectorAppend (psfExtra2, modelPSF->params->data.F32[8]); 450 453 } … … 517 520 } 518 521 519 //psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", axes.theta);522 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "ANGLE", PS_META_REPLACE, "PSF angle", axes.theta); 520 523 psMetadataAddS32 (readout->analysis, PS_LIST_TAIL, "NPSFSTAR", PS_META_REPLACE, "Number of stars used to make PSF", psf->nPSFstars); 521 524 -
trunk/psphot/src/psphotEfficiency.c
r31452 r32348 99 99 100 100 /// Generate a fake image and add it in to the existing readout 101 static booleffGenerate(psImage **xSrc, psImage **ySrc, // Positions of sources101 static pmReadout *effGenerate(psImage **xSrc, psImage **ySrc, // Positions of sources 102 102 const pmReadout *ro, // Readout of interest 103 103 const pmPSF *psf, // Point-spread function … … 152 152 psFree(xAll); 153 153 psFree(yAll); 154 return false;154 return NULL; 155 155 } 156 156 psFree(magAll); … … 161 161 162 162 psBinaryOp(ro->image, ro->image, "+", fakeRO->image); 163 psFree(fakeRO); 164 165 return true;163 164 // return the readout so we can subtract it later 165 return fakeRO; 166 166 } 167 167 … … 169 169 { 170 170 bool status = true; 171 172 fprintf (stdout, "\n"); 173 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Efficiency ---"); 171 174 172 175 // select the appropriate recipe information … … 290 293 291 294 psImage *xFake = NULL, *yFake = NULL; // Coordinates of sources, each bin in a row 292 if (!effGenerate(&xFake, &yFake, readout, psf, magOffsets,293 numSources, magLim, radius, minFlux)) {295 pmReadout *fakeRO = effGenerate(&xFake, &yFake, readout, psf, magOffsets, numSources, magLim, radius, minFlux); 296 if (!fakeRO) { 294 297 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake sources"); 295 298 psFree(xFake); … … 416 419 psFree(significance); 417 420 421 // psphotFitSourcesLinearReadout subtracts the model fits 418 422 if (!psphotFitSourcesLinearReadout(recipe, readout, fakeSourcesAll, psf, true)) { 419 423 psError(PS_ERR_UNKNOWN, false, "Unable to perform linear fit on fake sources."); … … 427 431 psf->ApTrend = NULL; 428 432 433 // measure the magnitudes and fluxes for the sources 429 434 if (!psphotMagnitudesReadout(config, recipe, view, readout, fakeSourcesAll, psf)) { 430 435 psError(PS_ERR_UNKNOWN, false, "Unable to measure magnitudes of fake sources."); … … 433 438 psf->ApTrend = apTrend; // Casting away const! 434 439 return false; 440 } 441 442 // replace the subtracted model fits 443 for (int i = 0; i < fakeSourcesAll->n; i++) { 444 pmSource *source = fakeSourcesAll->data[i]; 445 446 // replace other sources? 447 if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) continue; 448 449 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal); 435 450 } 436 451 psFree(fakeSourcesAll); … … 515 530 psFree(fakeSources); 516 531 532 // subtract the faked sources from the original image 533 psBinaryOp(readout->image, readout->image, "-", fakeRO->image); 534 psFree(fakeRO); 535 517 536 pmDetEff *de = pmDetEffAlloc(magLim, numSources, numBins); // Detection efficiency 518 537 de->magOffsets = psVectorCopy(NULL, magOffsets, PS_TYPE_F32); … … 529 548 psFree(de); 530 549 531 psLogMsg("psphot", PS_LOG_ INFO, "Detection efficiency: %lf sec\n", psTimerClear("psphot.fake"));550 psLogMsg("psphot", PS_LOG_WARN, "Detection efficiency: %lf sec\n", psTimerClear("psphot.fake")); 532 551 533 552 return true; -
trunk/psphot/src/psphotEllipticalContour.c
r29004 r32348 127 127 psF32 psphotEllipticalContourFunc (psVector *deriv, const psVector *params, const psVector *coord) { 128 128 129 static int pass = 0;130 131 129 psF32 *par = params->data.F32; 132 130 … … 145 143 146 144 // value is X 147 // if (coord->data.F32[1] == 0) { 148 if (pass == 0) { 149 pass = 1; 150 145 if (coord->data.F32[1] < 0.5) { 151 146 float value = par[PAR_RMIN]*cs_alpha*r; 152 147 … … 161 156 162 157 // value is Y 163 // if (coord->data.F32[1] == 1) { 164 if (pass == 1) { 165 pass = 0; 166 158 if (coord->data.F32[1] > 0.5) { 167 159 float value = par[PAR_RMIN]*sn_alpha*r; 168 160 -
trunk/psphot/src/psphotExtendedSourceAnalysis.c
r31154 r32348 2 2 3 3 // measure the elliptical radial profile and use this to measure the petrosian parameters for the sources 4 // XXX this function needs to be threaded5 4 6 5 // for now, let's store the detections on the readout->analysis for each readout … … 8 7 { 9 8 bool status = true; 9 10 fprintf (stdout, "\n"); 11 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Extended Source Analysis (Petrosians) ---"); 10 12 11 13 // select the appropriate recipe information … … 59 61 } 60 62 61 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 62 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 63 assert (maskVal); 63 // determine the number of allowed threads 64 int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads 65 if (!status) { 66 nThreads = 0; 67 } 64 68 65 69 // get the sky noise from the background analysis; if this is missing, get the user-supplied value … … 70 74 } 71 75 76 // source analysis is done in S/N order (brightest first) 77 sources = psArraySort (sources, pmSourceSortByFlux); 78 79 // option to limit analysis to a specific region 80 char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION"); 81 psRegion *AnalysisRegion = psRegionAlloc(0,0,0,0); 82 *AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region)); 83 if (psRegionIsNaN (*AnalysisRegion)) psAbort("analysis region mis-defined"); 84 85 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) 86 int Cx = 1, Cy = 1; 87 psphotChooseCellSizes (&Cx, &Cy, readout, nThreads); 88 89 psArray *cellGroups = psphotAssignSources (Cx, Cy, sources); 90 91 for (int i = 0; i < cellGroups->n; i++) { 92 93 psArray *cells = cellGroups->data[i]; 94 95 for (int j = 0; j < cells->n; j++) { 96 97 // allocate a job -- if threads are not defined, this just runs the job 98 psThreadJob *job = psThreadJobAlloc ("PSPHOT_EXTENDED_ANALYSIS"); 99 100 psArrayAdd(job->args, 1, readout); 101 psArrayAdd(job->args, 1, cells->data[j]); // sources 102 psArrayAdd(job->args, 1, AnalysisRegion); 103 psArrayAdd(job->args, 1, recipe); 104 105 PS_ARRAY_ADD_SCALAR(job->args, skynoise, PS_TYPE_F32); 106 107 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Next 108 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Npetro 109 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nannuli 110 111 // set this to 0 to run without threading 112 # if (1) 113 if (!psThreadJobAddPending(job)) { 114 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 115 psFree(AnalysisRegion); 116 return false; 117 } 118 # else 119 if (!psphotExtendedSourceAnalysis_Threaded(job)) { 120 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 121 psFree(AnalysisRegion); 122 return false; 123 } 124 psScalar *scalar = NULL; 125 scalar = job->args->data[5]; 126 Next += scalar->data.S32; 127 scalar = job->args->data[6]; 128 Npetro += scalar->data.S32; 129 scalar = job->args->data[7]; 130 Nannuli += scalar->data.S32; 131 psFree(job); 132 # endif 133 } 134 135 // wait for the threads to finish and manage results 136 if (!psThreadPoolWait (false)) { 137 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 138 psFree(AnalysisRegion); 139 return false; 140 } 141 142 // we have only supplied one type of job, so we can assume the types here 143 psThreadJob *job = NULL; 144 while ((job = psThreadJobGetDone()) != NULL) { 145 if (job->args->n < 1) { 146 fprintf (stderr, "error with job\n"); 147 } else { 148 psScalar *scalar = NULL; 149 scalar = job->args->data[5]; 150 Next += scalar->data.S32; 151 scalar = job->args->data[6]; 152 Npetro += scalar->data.S32; 153 scalar = job->args->data[7]; 154 Nannuli += scalar->data.S32; 155 } 156 psFree(job); 157 } 158 } 159 psFree (cellGroups); 160 psFree(AnalysisRegion); 161 162 psLogMsg ("psphot", PS_LOG_WARN, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next); 163 psLogMsg ("psphot", PS_LOG_INFO, " %d petrosian\n", Npetro); 164 psLogMsg ("psphot", PS_LOG_INFO, " %d annuli\n", Nannuli); 165 166 psphotVisualShowResidualImage (readout, false); 167 168 bool doPetrosian = psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_PETROSIAN"); 169 if (doPetrosian) { 170 psphotVisualShowPetrosians (sources); 171 } 172 173 return true; 174 } 175 176 bool psphotExtendedSourceAnalysis_Threaded (psThreadJob *job) { 177 178 bool status; 179 180 int Next = 0; 181 int Npetro = 0; 182 int Nannuli = 0; 183 184 // arguments: readout, sources, models, region, psfSize, maskVal, markVal 185 pmReadout *readout = job->args->data[0]; 186 psArray *sources = job->args->data[1]; 187 psRegion *region = job->args->data[2]; 188 psMetadata *recipe = job->args->data[3]; 189 190 float skynoise = PS_SCALAR_VALUE(job->args->data[4],F32); 191 72 192 // S/N limit to perform full non-linear fits 73 193 float SN_LIM = psMetadataLookupF32 (&status, recipe, "EXTENDED_SOURCE_SN_LIM"); … … 78 198 bool doPetroStars = psMetadataLookupBool (&status, recipe, "PETROSIAN_FOR_STARS"); 79 199 80 // source analysis is done in S/N order (brightest first) 81 sources = psArraySort (sources, pmSourceSortByFlux); 82 83 // option to limit analysis to a specific region 84 char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION"); 85 psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region)); 86 if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined"); 200 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 201 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels 202 assert (maskVal); 87 203 88 204 // choose the sources of interest … … 90 206 91 207 pmSource *source = sources->data[i]; 208 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_STACK_SKIP) continue; 212 if (source->tmpFlags & PM_SOURCE_TMPF_STACK_KEEP) goto keepSource; 92 213 93 214 // skip PSF-like and non-astronomical objects … … 104 225 105 226 // limit selection to some SN limit 106 assert (source->peak); // how can a source not have a peak? 107 if (sqrt(source->peak->detValue) < SN_LIM) continue; 108 109 // limit selection by analysis region 110 if (source->peak->x < AnalysisRegion.x0) continue; 111 if (source->peak->y < AnalysisRegion.y0) continue; 112 if (source->peak->x > AnalysisRegion.x1) continue; 113 if (source->peak->y > AnalysisRegion.y1) continue; 227 // assert (source->peak); // how can a source not have a peak? 228 // limit selection to some SN limit 229 bool skipSource = false; 230 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 231 skipSource = (source->moments->KronFlux < SN_LIM * source->moments->KronFluxErr); 232 } else { 233 skipSource = (sqrt(source->peak->detValue) < SN_LIM); 234 } 235 if (skipSource) continue; 236 237 // limit selection by analysis region (this automatically apply 238 if (source->peak->x < region->x0) continue; 239 if (source->peak->y < region->y0) continue; 240 if (source->peak->x > region->x1) continue; 241 if (source->peak->y > region->y1) continue; 242 243 keepSource: 114 244 115 245 // replace object in image … … 159 289 } 160 290 161 ps LogMsg ("psphot", PS_LOG_INFO, "extended source analysis: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next);162 psLogMsg ("psphot", PS_LOG_INFO, " %d petrosian\n", Npetro); 163 psLogMsg ("psphot", PS_LOG_INFO, " %d annuli\n", Nannuli);164 165 psphotVisualShowResidualImage (readout, false);166 167 if (doPetrosian) {168 psphotVisualShowPetrosians (sources);169 } 170 171 // fprintf (stderr, "xsrc : tried %ld objects\n", sources->n);291 psScalar *scalar = NULL; 292 293 // change the value of a scalar on the array (wrap this and put it in psArray.h) 294 scalar = job->args->data[5]; 295 scalar->data.S32 = Next; 296 297 scalar = job->args->data[6]; 298 scalar->data.S32 = Npetro; 299 300 scalar = job->args->data[7]; 301 scalar->data.S32 = Nannuli; 172 302 173 303 return true; -
trunk/psphot/src/psphotExtendedSourceFits.c
r31673 r32348 6 6 bool status = true; 7 7 8 fprintf (stdout, "\n"); 9 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Extended Source Fits ---"); 10 8 11 // select the appropriate recipe information 9 12 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); … … 12 15 // perform full extended source non-linear fits? 13 16 if (!psMetadataLookupBool (&status, recipe, "EXTENDED_SOURCE_FITS")) { 14 psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source measurements\n");17 psLogMsg ("psphot", PS_LOG_INFO, "skipping extended source fits\n"); 15 18 return true; 16 19 } … … 45 48 int Nfail = 0; 46 49 50 psphotSersicModelClassInit(); 51 47 52 psTimerStart ("psphot.extended"); 48 53 … … 103 108 104 109 if (item->type != PS_DATA_METADATA) { 110 // XXX we could cull the bad entries or build a validated model folder 105 111 psAbort ("Invalid type for EXTENDED_SOURCE_MODEL entry %s, not a metadata folder", item->name); 106 // XXX we could cull the bad entries or build a validated model folder107 112 } 108 113 … … 247 252 psFree(AnalysisRegion); 248 253 249 psLogMsg ("psphot", PS_LOG_INFO, "extended source model fits: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next); 254 psphotSersicModelClassCleanup(); 255 256 psphotVisualShowResidualImage (readout, false); 257 258 psLogMsg ("psphot", PS_LOG_WARN, "extended source model fits: %f sec for %d objects\n", psTimerMark ("psphot.extended"), Next); 250 259 psLogMsg ("psphot", PS_LOG_INFO, " %d convolved models (%d passed)\n", Nconvolve, NconvolvePass); 251 260 psLogMsg ("psphot", PS_LOG_INFO, " %d plain models (%d passed)\n", Nplain, NplainPass); … … 265 274 int Nplain = 0; 266 275 int NplainPass = 0; 267 bool savePics = false; 268 float radius; 276 float fitRadius, windowRadius; 269 277 psScalar *scalar = NULL; 270 pmMoments psfMoments;271 278 272 279 // arguments: readout, sources, models, region, psfSize, maskVal, markVal … … 275 282 psMetadata *models = job->args->data[2]; 276 283 psRegion *region = job->args->data[3]; 277 int psfSize = PS_SCALAR_VALUE(job->args->data[4], PS_TYPE_IMAGE_MASK_DATA);284 int psfSize = PS_SCALAR_VALUE(job->args->data[4],S32); 278 285 psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA); 279 286 psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[6],PS_TYPE_IMAGE_MASK_DATA); 280 281 // pthread_t tid = pthread_self(); // Thread identifier282 287 283 288 // Define source fitting parameters for extended source fits … … 299 304 300 305 // skip PSF-like and non-astronomical objects 301 if ( source->type == PM_SOURCE_TYPE_STAR) continue;306 if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue; 302 307 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 303 308 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; … … 309 314 if (source->peak->y > region->y1) continue; 310 315 311 // if model is NULL, we don't have a starting guess312 // XXX use the parameters guessed from moments313 // if (source->modelEXT == NULL) continue;314 315 // fprintf (stderr, "fit %d,%d in thread %d\n", source->peak->x, source->peak->y, (int) tid);316 317 316 // replace object in image 318 317 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) { … … 321 320 Next ++; 322 321 323 // set the radius based on the footprint (also sets the mask pixels) 324 if (!psphotSetRadiusFootprint(&radius, readout, source, markVal, 1.0)) { 325 fprintf (stderr, "skipping (1) %f, %f\n", source->peak->xf, source->peak->yf); 326 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 327 // XXX raise an error of some kind 328 continue; 329 } 330 331 // XXX note that this changes the source moments that are published... 332 // recalculate the source moments using the larger extended-source moments radius 333 // at this stage, skip Gaussian windowing, and do not clip pixels by S/N 334 // this uses the footprint to judge both radius and aperture? 335 // XXX save the psf-based moments for output 336 psfMoments = *source->moments; 337 if (!pmSourceMoments (source, radius, 0.0, 0.0, 0.0, maskVal)) { 338 // subtract the best fit from the object, leave local sky 339 fprintf (stderr, "skipping (2) %f, %f\n", source->peak->xf, source->peak->yf); 340 *source->moments = psfMoments; 341 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 342 // XXX raise an error flag of some kind 343 continue; 344 } 345 346 // save the modelFlux here in case we need to subtract it (for failure) 347 psImage *modelFluxStart = psMemIncrRefCounter (source->modelFlux); 348 if (!modelFluxStart) { 349 pmSourceCacheModel (source, maskVal); 350 modelFluxStart = psMemIncrRefCounter (source->modelFlux); 351 if (!modelFluxStart) { 352 fprintf (stderr, "skipping (3) %f, %f\n", source->peak->xf, source->peak->yf); 353 *source->moments = psfMoments; 354 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 355 // XXX raise an error of some kind? 356 continue; 357 } 358 } 359 360 if (savePics) { 361 psphotSaveImage (NULL, readout->image, "image.xp.fits"); 362 } 363 364 // array to store the pointers to the model flux images while the models are being fitted 365 psArray *modelFluxes = psArrayAllocEmpty (models->list->n); 322 // set the fit radius based on the first radial moment (also sets the mask pixels) 323 psphotSetRadiusMomentsExact(&fitRadius, &windowRadius, readout, source, markVal); 324 325 // UPDATE : we have changed the moments calculation. There is now an iteration within 326 // psphotKronMasked to determine moments appropriate for a larger object. The values 327 // Mrf, KronFlux, and KronFluxErr are calculated for the iterated radius. The other 328 // values are left at the psf-based values. 366 329 367 330 // allocate the array to store the model fits … … 380 343 381 344 // check the SNlim and skip model if source is too faint 382 float SNlim= psMetadataLookupF32 (&status, model, "SNLIM_VALUE");345 float FIT_SN_LIM = psMetadataLookupF32 (&status, model, "SNLIM_VALUE"); 383 346 assert (status); 384 347 385 348 // limit selection to some SN limit 386 349 // assert (source->peak); // how can a source not have a peak? 387 if (sqrt(source->peak->detValue) < SNlim) { 350 // limit selection to some SN limit 351 bool skipSource = false; 352 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 353 skipSource = (source->moments->KronFlux < FIT_SN_LIM * source->moments->KronFluxErr); 354 } else { 355 skipSource = (sqrt(source->peak->detValue) < FIT_SN_LIM); 356 } 357 if (skipSource) { 388 358 Nfaint ++; 389 359 continue; … … 397 367 bool convolved = psMetadataLookupBool (&status, model, "PSF_CONVOLVED_VALUE"); 398 368 assert (status); 399 400 // XXX psTraceSetLevel ("psLib.math.psMinimizeLMChi2", 6);401 // XXX psTraceSetLevel ("psphot.psphotModelWithPSF_LMM", 6);402 369 403 370 // fit the model as convolved or not … … 410 377 continue; 411 378 } 412 psTrace ("psphot", 4, "fit psf-conv model for %f, %f : %s chisq = %f\n", source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq); 379 psTrace ("psphot", 4, "fit psf-conv model for %f, %f : %s chisq = %f (npix: %d, niter: %d)\n", 380 source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter); 413 381 Nconvolve ++; 414 382 if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) { … … 425 393 continue; 426 394 } 427 p mSourceCacheModel (source, maskVal);428 psTrace ("psphot", 4, "fit plain model for %f, %f : %s chisq = %f\n", source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq);395 psTrace ("psphot", 4, "fit plain model for %f, %f : %s chisq = %f (npix: %d, niter: %d)\n", 396 source->moments->Mx, source->moments->My, pmModelClassGetName (modelFit->type), modelFit->chisq, modelFit->nPix, modelFit->nIter); 429 397 Nplain ++; 430 398 if (!(modelFit->flags & (PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE))) { … … 434 402 } 435 403 436 // save each of the model flux images and store the best 437 psArrayAdd (modelFluxes, 4, source->modelFlux); 404 // XXX deprecate? 405 // XXX pmSourceExtFitPars *extFitPars = pmSourceExtFitParsAlloc(); 406 // XXX extFitPars->Mxx = source->moments->Mxx; 407 // XXX extFitPars->Mxy = source->moments->Mxy; 408 // XXX extFitPars->Myy = source->moments->Myy; 409 // XXX extFitPars->Mrf = source->moments->Mrf; 410 // XXX extFitPars->Mrh = source->moments->Mrh; 411 // XXX extFitPars->peakMag = (source->peak->rawFlux > 0) ? -2.5*log10(source->peak->rawFlux) : NAN; 412 413 // save kron mag, but assign apMag & psfMag on output (not yet calculated) 414 // XXX extFitPars->krMag = -2.5*log10(source->moments->KronFlux); 415 416 // psArrayAdd (source->extFitPars, 4, extFitPars); 417 // psFree (extFitPars); 438 418 439 419 // test for fit quality / result 440 modelFit->fitRadius = radius;420 modelFit->fitRadius = fitRadius; 441 421 psArrayAdd (source->modelFits, 4, modelFit); 442 422 … … 463 443 } 464 444 445 // clear the circular mask 446 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); 447 465 448 if (minModel == -1) { 466 // re-subtract the object, leave local sky449 // no valid extended fit; re-subtract the object, leave local sky 467 450 psTrace ("psphot", 5, "failed to fit extended source model to object at %f, %f", source->moments->Mx, source->moments->My); 468 451 469 // replace original model, subtract it 470 psFree (source->modelFlux); 471 source->modelFlux = modelFluxStart; 472 473 *source->moments = psfMoments; 452 // ensure the modelEXT is cached 453 pmSourceCacheModel (source, maskVal); 454 474 455 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 475 456 476 psFree (modelFluxes);477 478 if (savePics) {479 psphotSaveImage (NULL, readout->image, "image.xp.fits");480 char key[10];481 fprintf (stdout, "continue? ");482 if (!fgets (key, 8, stdin)) {483 psWarning("Couldn't read anything.");484 } else if (key[0] == 'n') {485 savePics = false;486 }487 }488 457 continue; 489 458 } … … 493 462 source->modelEXT = psMemIncrRefCounter (source->modelFits->data[minModel]); 494 463 495 // save the modelFlux for the best model 496 psFree (source->modelFlux); 497 source->modelFlux = psMemIncrRefCounter (modelFluxes->data[minModel]); 498 499 // replace the original moments 500 *source->moments = psfMoments; 464 // adjust the window so the subtraction covers the faint wings 465 psphotSetRadiusMoments(&fitRadius, &windowRadius, readout, source, markVal); 466 467 // cache the model flux 468 if (source->modelEXT->isPCM) { 469 pmPCMCacheModel (source, maskVal, psfSize); 470 } else { 471 pmSourceCacheModel (source, maskVal); 472 } 501 473 502 474 // subtract the best fit from the object, leave local sky 503 475 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 504 476 505 // the initial model flux is no longer needed506 psFree (modelFluxStart);507 psFree (modelFluxes);508 509 477 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); 510 478 psTrace ("psphot", 5, "extended source model for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); 511 512 if (savePics) {513 psphotSaveImage (NULL, readout->image, "image.xm.fits");514 char key[10];515 fprintf (stdout, "continue? ");516 if (!fgets (key, 8, stdin)) {517 psWarning("Couldn't read anything.");518 } else if (key[0] == 'n') {519 savePics = false;520 }521 }522 479 } 523 480 psFree (fitOptions); 524 525 // fprintf (stderr, "xfit : tried %ld objects\n", sources->n);526 481 527 482 // change the value of a scalar on the array (wrap this and put it in psArray.h) -
trunk/psphot/src/psphotFindDetections.c
r31154 r32348 7 7 { 8 8 bool status = true; 9 10 fprintf (stdout, "\n"); 11 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Find Detections ---"); 9 12 10 13 // select the appropriate recipe information -
trunk/psphot/src/psphotFindFootprints.c
r31154 r32348 58 58 psphotCullPeaks(readout, significance, recipe, detections->footprints); 59 59 detections->peaks = pmFootprintArrayToPeaks(detections->footprints); 60 psLogMsg ("psphot", PS_LOG_INFO, "%ld peaks, %ld total footprints: %f sec\n", detections->peaks->n, detections->footprints->n, psTimerMark ("psphot.footprints")); 60 61 // psphotFootprintSaddles (readout, detections->footprints); 62 // 63 // int nSaddle = 0; 64 // for (int i = 0; i < detections->peaks->n; i++) { 65 // pmPeak *peak = detections->peaks->data[i]; 66 // 67 // if (peak->saddlePoints) nSaddle += peak->saddlePoints->n; 68 // } 69 // fprintf (stderr, "%d saddle points for %ld peaks\n", nSaddle, detections->peaks->n); 70 71 psLogMsg ("psphot", PS_LOG_WARN, "%ld peaks, %ld total footprints: %f sec\n", detections->peaks->n, detections->footprints->n, psTimerMark ("psphot.footprints")); 61 72 62 73 return detections; -
trunk/psphot/src/psphotFindPeaks.c
r31154 r32348 68 68 pmPeaksWriteText (peaks, output); 69 69 } 70 psLogMsg ("psphot", PS_LOG_ INFO, "%ld peaks: %f sec\n", peaks->n, psTimerMark ("psphot.peaks"));70 psLogMsg ("psphot", PS_LOG_WARN, "%ld peaks: %f sec\n", peaks->n, psTimerMark ("psphot.peaks")); 71 71 72 72 return peaks; -
trunk/psphot/src/psphotFitSourcesLinear.c
r31452 r32348 17 17 bool status = true; 18 18 19 fprintf (stdout, "\n"); 20 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Fit Source (Linear) ---"); 21 19 22 // select the appropriate recipe information 20 23 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); … … 23 26 int num = psphotFileruleCount(config, filerule); 24 27 28 // skip the chisq image (optionally?) 29 int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM"); 30 if (!status) chisqNum = -1; 31 25 32 // loop over the available readouts 26 33 for (int i = 0; i < num; i++) { 34 if (i == chisqNum) continue; // skip chisq image 27 35 28 36 // find the currently selected readout … … 190 198 pmModel *model = pmSourceGetModel (&isPSF, source); 191 199 200 // clear the 'mark' pixels and remask on the fit aperture 192 201 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); 193 202 psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, model->fitRadius, "OR", markVal); … … 349 358 model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i]; 350 359 351 // subtract object 360 // clear the 'mark' pixels so the subtraction covers the full window 361 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); 362 363 // subtract object & add noise 352 364 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 353 365 } … … 374 386 psFree (border); 375 387 376 psLogMsg ("psphot.ensemble", PS_LOG_ INFO, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear"));388 psLogMsg ("psphot.ensemble", PS_LOG_WARN, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear")); 377 389 378 390 psphotVisualPlotChisq (sources); -
trunk/psphot/src/psphotFitSourcesLinearStack.c
r31452 r32348 64 64 // turn this bit off and turn it on again if we keep this source 65 65 source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT; 66 67 // skip non-astronomical objects (very likely defects) 68 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 69 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 70 71 // do not include CRs in the full ensemble fit 72 if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue; 73 74 // do not include MOMENTS_FAILURES in the fit 75 if (source->mode & PM_SOURCE_MODE_MOMENTS_FAILURE) continue; 76 77 if (final) { 78 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue; 79 } else { 80 // if (source->mode & PM_SOURCE_MODE_BLEND) continue; 81 } 66 82 67 83 // generate model for sources without, or skip if we can't … … 83 99 } 84 100 85 source->mode |= PM_SOURCE_MODE_LINEAR_FIT; 101 bool isPSF = false; 102 pmModel *model = pmSourceGetModel (&isPSF, source); 103 104 // clear the 'mark' pixels and remask on the fit aperture 105 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); 106 psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, model->fitRadius, "OR", markVal); 107 108 // we call this function multiple times. for the first time, we have only PSF models for all objects 109 // the second time has extended sources. If we ever fit the PSF model, we should raise this bit 110 source->mode |= PM_SOURCE_MODE_LINEAR_FIT; 111 if (isPSF) { 112 source->mode |= PM_SOURCE_MODE_PSFMODEL; 113 } 86 114 psArrayAdd (fitSources, 100, source); 87 115 } … … 166 194 model->params->data.F32[PM_PAR_I0] = norm->data.F32[i]; 167 195 model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i]; 196 197 // clear the 'mark' pixels so the subtraction covers the full window 198 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); 168 199 169 200 // subtract object … … 190 221 psFree (errors); 191 222 192 psLogMsg ("psphot.ensemble", PS_LOG_ INFO, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear"));223 psLogMsg ("psphot.ensemble", PS_LOG_WARN, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear")); 193 224 return true; 194 225 } -
trunk/psphot/src/psphotGuessModels.c
r31452 r32348 141 141 psFree (cellGroups); 142 142 143 psLogMsg ("psphot.models", 4, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.models"));143 psLogMsg ("psphot.models", PS_LOG_WARN, "built models for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.models")); 144 144 return true; 145 145 } -
trunk/psphot/src/psphotImageLoop.c
r31154 r32348 129 129 } 130 130 break; 131 case PSPHOT_MODEL_TEST: 132 if (!psphotModelTestReadout (config, view, "PSPHOT.INPUT")) { 133 psError(psErrorCodeLast(), false, "failure in psphotReadout for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout); 134 psFree (view); 135 return false; 136 } 137 break; 131 138 } 132 139 } -
trunk/psphot/src/psphotImageQuality.c
r30624 r32348 289 289 #endif 290 290 291 psLogMsg ("psphot", PS_LOG_ INFO, "Image Quality Stats from %ld psf stars : FWHM (major, minor) [pixels]: %f, %f\n",291 psLogMsg ("psphot", PS_LOG_WARN, "Image Quality Stats from %ld psf stars : FWHM (major, minor) [pixels]: %f, %f\n", 292 292 M2->n, fwhm_major, fwhm_minor); 293 293 -
trunk/psphot/src/psphotKronMasked.c
r31673 r32348 1 1 # include "psphotInternal.h" 2 2 # ifndef ROUND 3 # define ROUND(X) ((int) ((X) + 0.5*SIGN(X))) 4 # endif 5 6 bool psphotKronMask (pmSource *source, psImage *kronMask, psImageMaskType markVal); 3 7 bool psphotKronMag (pmSource *source, float radius, float minKronRadius, psImageMaskType maskVal); 4 8 … … 45 49 } 46 50 51 int psphotKapaChannel (int channel); 52 bool psphotVisualShowMask (int kapaFD, psImage *inImage, const char *name, int channel); 53 bool psphotVisualRangeImage (int kapaFD, psImage *inImage, const char *name, int channel, float min, float max); 54 47 55 bool psphotKronMaskedReadout(pmConfig *config, psMetadata *recipe, const pmFPAview *view, pmReadout *readout, psArray *sources, pmPSF *psf) { 48 56 … … 72 80 } 73 81 82 float EXT_FIT_MAX_RADIUS = psMetadataLookupF32 (&status, recipe, "EXT_FIT_MAX_RADIUS"); 83 74 84 // bit-masks to test for good/bad pixels 75 85 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); … … 83 93 maskVal |= markVal; 84 94 95 // psphotSaveImage (NULL, readout->mask, "kron.unmasked.fits"); 96 97 pmSourcePhotometryMode photMode = PM_SOURCE_PHOT_PSFONLY; 98 99 // XXX tmp visualization 100 // int kapa = psphotKapaChannel (1); 101 85 102 // generate the mask image: increment counter for every source overlapping the pixel 86 psImage *kronMask = psImageAlloc (readout->image->numCols, readout->image->numRows, PS_TYPE_ U8);103 psImage *kronMask = psImageAlloc (readout->image->numCols, readout->image->numRows, PS_TYPE_S32); 87 104 psImageInit (kronMask, 0); 88 int Nx = kronMask->numCols;89 int Ny = kronMask->numRows;90 105 for (int i = 0; i < sources->n; i++) { 91 106 … … 96 111 if (!source->moments) continue; 97 112 98 // replace object in image 99 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) { 100 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal); 101 } 102 103 psphotKronMag (source, RADIUS, MIN_KRON_RADIUS, maskVal); 104 105 // re-subtract the object, leave local sky 106 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 107 108 continue; 109 110 // XXX skip this code 111 // generate the pixel masks 112 // int Xo = source->moments->Mx; 113 // int Yo = source->moments->My; 114 float dX = source->moments->Mx - source->peak->xf; 115 float dY = source->moments->My - source->peak->yf; 116 float dR = hypot(dX, dY); 117 118 float Xo = (dR < 2.0) ? source->moments->Mx : source->peak->xf; 119 float Yo = (dR < 2.0) ? source->moments->My : source->peak->yf; 120 121 int Kr = 2.5*source->moments->Mrf; 122 int Kr2 = Kr*Kr; 123 124 for (int iy = Yo - Kr; iy < Yo + Kr + 1; iy++) { 125 if (iy < 0) continue; 126 if (iy >= Ny) continue; 127 for (int ix = Xo - Kr; ix < Xo + Kr + 1; ix++) { 128 if (ix < 0) continue; 129 if (ix >= Nx) continue; 130 131 if (PS_SQR(ix - Xo) + PS_SQR(iy - Yo) > Kr2) continue; 132 if (kronMask->data.U8[iy][ix] < 0xff) { 133 kronMask->data.U8[iy][ix] ++; 134 } 135 } 136 } 137 } 113 // replace object in image 114 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) { 115 pmSourceAdd (source, PM_MODEL_OP_FULL, maskVal); 116 } 117 118 // save the PSF-based values 119 // source->moments->KronFluxPSF = source->moments->KronFlux; 120 // source->moments->KronFluxPSFErr = source->moments->KronFluxErr; 121 // source->moments->KronRadiusPSF = source->moments->Mrf; 122 123 // iterate to the window radius 124 float windowRadius = RADIUS; 125 for (int j = 0; j < 4; j++) { 126 // XXX use some S/N criterion to limit? 127 // if (source->moments->KronFlux / source->moments->KronFluxErr > 10.0) { 128 // windowRadius = PS_MAX (RADIUS, 10*source->moments->Mrf); 129 // } 130 131 // re-allocate image, weight, mask arrays for each peak with box big enough to fit BIG_RADIUS 132 pmSourceRedefinePixels (source, readout, source->peak->x, source->peak->y, windowRadius + 2); 133 134 // mask the pixels not contained by the footprint 135 // if (psphotMaskFootprint (readout, source, markVal)) { 136 // // psphotVisualShowMask (kapa, source->maskObj, "mask", 2); 137 // // psphotVisualRangeImage (kapa, source->pixels, "image", 1, -50, 300); 138 // // fprintf (stderr, "masked\n"); 139 // } 140 141 // mask the pixels associated with near neighbors 142 if (psphotKronMask (source, kronMask, markVal)) { 143 // psphotVisualShowMask (kapa, source->maskObj, "mask", 2); 144 // psphotVisualRangeImage (kapa, source->pixels, "image", 1, -50, 300); 145 // fprintf (stderr, "masked\n"); 146 } 147 // this function populates moments->Mrf,KronFlux,KronFluxErr 148 // XXX what about KronInner, KronOuter, etc? 149 psphotKronMag (source, windowRadius, MIN_KRON_RADIUS, maskVal); 150 windowRadius = PS_MIN(PS_MAX(RADIUS, 4.0*source->moments->Mrf), EXT_FIT_MAX_RADIUS); 151 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); 152 } 153 pmSourceMagnitudes (source, psf, photMode, maskVal, markVal, source->apRadius); 154 float kmag = -2.5*log10(source->moments->KronFlux); 155 if (source->psfMag - kmag > 0.25) { 156 // psphotVisualShowMask (kapa, source->maskObj, "mask", 1); 157 // psphotVisualRangeImage (kapa, source->pixels, "image", 0, -50, 300); 158 // fprintf (stderr, "psf: %f, kron: %f, dmag: %f\n", source->psfMag, kmag, source->psfMag - kmag); 159 // fprintf (stderr, "continue\n"); 160 } 161 // re-subtract the object, leave local sky 162 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 163 } 164 165 // psphotSaveImage (NULL, readout->mask, "kron.masked.fits"); 138 166 // psphotSaveImage (NULL, kronMask, "kronmask.fits"); 167 139 168 psLogMsg ("psphot.kron", PS_LOG_DETAIL, "measure masked kron magnitudes : %f sec for %ld objects\n", psTimerMark ("psphot.kron"), sources->n); 140 169 … … 142 171 return true; 143 172 } 173 174 # define WEIGHTED 0 144 175 145 176 bool psphotKronMag (pmSource *source, float radius, float minKronRadius, psImageMaskType maskVal) { … … 150 181 PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false); 151 182 152 psF32 Sum = 0.0;153 psF32 Var = 0.0;154 183 psF32 R2 = PS_SQR(radius); 184 185 # if (WEIGHTED) 186 float rsigma2 = 0.5 / PS_SQR(radius / 4.0); // use a Gaussian window with sigma = R_window / 2 187 # endif 155 188 156 189 // a note about coordinates: coordinates of objects throughout psphot refer to the primary … … 168 201 psF32 RS = 0.0; 169 202 170 # if (1) 203 // the peak position is less accurate but less subject to extreme deviations 171 204 float dX = source->moments->Mx - source->peak->xf; 172 205 float dY = source->moments->My - source->peak->yf; … … 174 207 float Xo = (dR < 2.0) ? source->moments->Mx : source->peak->xf; 175 208 float Yo = (dR < 2.0) ? source->moments->My : source->peak->yf; 176 # else177 float Xo = source->moments->Mx;178 float Yo = source->moments->My;179 # endif180 209 181 210 // center of mass in subimage. Note: the calculation below uses pixel index, so we correct … … 210 239 if (r2 > R2) continue; 211 240 241 # if (WEIGHTED) 242 float z = r2 * rsigma2; 243 assert (z >= 0.0); 244 float weight = exp(-z); 245 psF32 pDiff = *vPix * weight; 246 # else 212 247 psF32 pDiff = *vPix; 213 214 Sum += pDiff; 215 216 // Kron Flux uses the 1st radial moment (NOT Gaussian windowed) 248 # endif 249 250 // Kron Flux uses the 1st radial moment (maybe Gaussian windowed?) 217 251 psF32 rf = pDiff * sqrt(r2); 218 252 psF32 rs = pDiff; … … 234 268 235 269 int nKronPix = 0; 236 Sum = Var = 0.0; 270 float Sum = 0.0; 271 float Var = 0.0; 237 272 238 273 for (psS32 row = 0; row < source->pixels->numRows ; row++) { … … 263 298 if (r2 > radKron2) continue; 264 299 300 # if (WEIGHTED) 301 float z = r2 * rsigma2; 302 assert (z >= 0.0); 303 float weight = exp(-z); 304 psF32 pDiff = *vPix * weight; 305 psF32 wDiff = *vWgt * weight; 306 # else 265 307 psF32 pDiff = *vPix; 266 308 psF32 wDiff = *vWgt; 309 # endif 267 310 268 311 Sum += pDiff; … … 272 315 } 273 316 274 source->moments->Mrh = Mrf; 275 276 // XXX for a test, save the old values here: 277 source->moments->KronFouter = source->moments->KronFlux; 278 source->moments->KronCoreErr = source->moments->KronFluxErr; 279 280 source->moments->KronFlux = Sum * M_PI * PS_SQR(radKron) / nKronPix; 281 source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix; 317 source->moments->Mrf = Mrf; 318 source->moments->KronFlux = Sum; 319 source->moments->KronFluxErr = sqrt(Var); 320 // source->moments->KronFlux = Sum * M_PI * PS_SQR(radKron) / nKronPix; 321 // source->moments->KronFluxErr = sqrt(Var) * M_PI * PS_SQR(radKron) / nKronPix; 282 322 283 323 return true; 284 324 } 325 326 enum {Y_P, Y_M, X_P, X_M}; 327 328 bool psphotKronMask (pmSource *source, psImage *kronMask, psImageMaskType markVal) { 329 330 int X, Y, e, dXs, dYs; 331 332 if (!source->peak) return false; 333 if (!source->peak->saddlePoints) return false; 334 if (!source->peak->saddlePoints->n) return false; 335 336 // return true; 337 338 int xMax = source->maskObj->numCols; 339 int yMax = source->maskObj->numRows; 340 // int xOff = source->maskObj->col0; 341 // int yOff = source->maskObj->row0; 342 343 int Xo = ROUND(source->peak->xf) - source->maskObj->col0; 344 int Yo = ROUND(source->peak->yf) - source->maskObj->row0; 345 346 for (int i = 0; i < source->peak->saddlePoints->n; i++) { 347 348 psVector *saddlePoint = source->peak->saddlePoints->data[i]; 349 int Xs = ROUND(saddlePoint->data.S32[0]) - source->maskObj->col0; 350 int Ys = ROUND(saddlePoint->data.S32[1]) - source->maskObj->row0; 351 352 // fprintf (stderr, "mask %d,%d @ %d,%d (%d,%d)\n", Xo, Yo, Xs, Ys, saddlePoint->data.S32[0], saddlePoint->data.S32[1]); 353 354 // We want to mask the pixels between the edge of the image and the line perpendicular 355 // to the connecting line. Call dX,dY = (Xs-Xo,Ys-Yo). There are 4 cases: 356 // +y : dY > 0, fabs(dY) > fabs(dX) 357 // -y : dY < 0, fabs(dY) > fabs(dX) 358 // +x : dX > 0, fabs(dX) > fabs(dY) 359 // -x : dX < 0, fabs(dX) > fabs(dY) 360 361 int dX = Xs - Xo; 362 int dY = Ys - Yo; 363 364 // +y : dY > 0, fabs(dY) > fabs(dX) 365 // -y : dY < 0, fabs(dY) > fabs(dX) 366 if (fabs(dY) > fabs(dX)) { 367 // points to right of saddle 368 Y = Ys; 369 e = 0; 370 dXs = (dY > 0) ? +dY : -dY; // this forces dXs > 0 371 dYs = (dY > 0) ? -dX : +dX; 372 for (X = Xs; X < xMax; X++) { 373 if (dY > 0) { 374 for (int Ym = Y; Ym < yMax; Ym++) { 375 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Ym][X] |= markVal; 376 // kronMask->data.S32[Ym+yOff][X+xOff] = source->id; 377 } 378 } else { 379 for (int Ym = Y; Ym >= 0; Ym--) { 380 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Ym][X] |= markVal; 381 // kronMask->data.S32[Ym+yOff][X+xOff] = source->id; 382 } 383 } 384 e += dYs; 385 int e2 = 2 * e; 386 if (e2 > dXs) { 387 Y ++; 388 e -= dXs; 389 } 390 if (e2 < -dXs) { 391 Y --; 392 e += dXs; 393 } 394 if (Y >= yMax) break; 395 if (Y < 0) break; 396 } 397 // points to left of saddle 398 Y = Ys; 399 e = 0; 400 for (X = Xs; X >= 0; X--) { 401 if (dY > 0) { 402 for (int Ym = Y; Ym < yMax; Ym++) { 403 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Ym][X] |= markVal; 404 // kronMask->data.S32[Ym+yOff][X+xOff] = source->id; 405 } 406 } else { 407 for (int Ym = Y; Ym >= 0; Ym--) { 408 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Ym][X] |= markVal; 409 // kronMask->data.S32[Ym+yOff][X+xOff] = source->id; 410 } 411 } 412 e -= dYs; 413 int e2 = 2 * e; 414 if (e2 > dXs) { 415 Y ++; 416 e -= dXs; 417 } 418 if (e2 < -dXs) { 419 Y --; 420 e += dXs; 421 } 422 if (Y >= yMax) break; 423 if (Y < 0) break; 424 } 425 } else { 426 // points to right of saddle 427 X = Xs; 428 e = 0; 429 dXs = (dX > 0) ? -dY : +dY; 430 dYs = (dX > 0) ? +dX : -dX; // this forces dYs > 0 431 for (Y = Ys; Y < yMax; Y++) { 432 if (dX > 0) { 433 for (int Xm = X; Xm < xMax; Xm++) { 434 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Y][Xm] |= markVal; 435 // kronMask->data.S32[Y+yOff][Xm+xOff] = source->id; 436 } 437 } else { 438 for (int Xm = X; Xm >= 0; Xm--) { 439 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Y][Xm] |= markVal; 440 // kronMask->data.S32[Y+yOff][Xm+xOff] = source->id; 441 } 442 } 443 e += dXs; 444 int e2 = 2 * e; 445 if (e2 > dYs) { 446 X ++; 447 e -= dYs; 448 } 449 if (e2 < -dYs) { 450 X --; 451 e += dYs; 452 } 453 if (X >= yMax) break; 454 if (X < 0) break; 455 } 456 // points to left of saddle 457 X = Xs; 458 e = 0; 459 for (Y = Ys; Y >= 0; Y--) { 460 if (dX > 0) { 461 for (int Xm = X; Xm < xMax; Xm++) { 462 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Y][Xm] |= markVal; 463 // kronMask->data.S32[Y+yOff][Xm+xOff] = source->id; 464 } 465 } else { 466 for (int Xm = X; Xm >= 0; Xm--) { 467 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[Y][Xm] |= markVal; 468 // kronMask->data.S32[Y+yOff][Xm+xOff] = source->id; 469 } 470 } 471 e -= dXs; 472 int e2 = 2 * e; 473 if (e2 > dYs) { 474 X ++; 475 e -= dYs; 476 } 477 if (e2 < -dYs) { 478 X --; 479 e += dYs; 480 } 481 if (X >= yMax) break; 482 if (X < 0) break; 483 } 484 } 485 } 486 return true; 487 } -
trunk/psphot/src/psphotLoadSRCTEXT.c
r31452 r32348 73 73 dPAR[PM_PAR_I0] = 0.0; 74 74 75 pmPSF_AxesToModel (PAR, axes );75 pmPSF_AxesToModel (PAR, axes, modelType); 76 76 77 77 float peakFlux = 1.0; -
trunk/psphot/src/psphotMagnitudes.c
r31673 r32348 4 4 { 5 5 bool status = true; 6 7 fprintf (stdout, "\n"); 8 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Magnitudes ---"); 6 9 7 10 // select the appropriate recipe information … … 146 149 psFree (cellGroups); 147 150 148 psLogMsg ("psphot.magnitudes", PS_LOG_ DETAIL, "measure magnitudes : %f sec for %ld objects (%d with apertures)\n", psTimerMark ("psphot.mags"), sources->n, Nap);151 psLogMsg ("psphot.magnitudes", PS_LOG_WARN, "measure magnitudes : %f sec for %ld objects (%d with apertures)\n", psTimerMark ("psphot.mags"), sources->n, Nap); 149 152 return true; 150 153 } -
trunk/psphot/src/psphotModelBackground.c
r31154 r32348 145 145 psMetadataAddPtr(analysis, PS_LIST_TAIL, "PSPHOT.BACKGROUND.BINNING", PS_DATA_UNKNOWN | PS_META_REPLACE, "Background binning", binning); 146 146 147 psVector *dQ = psVectorAllocEmpty (100, PS_TYPE_F32); 147 148 psF32 **modelData = model->data.F32; 148 149 psF32 **modelStdevData = modelStdev->data.F32; … … 216 217 } 217 218 modelStdevData[iy][ix] = psStatsGetValue(stats, statsOptionWidth); 219 // fprintf (stderr, "dQ : %f - %f - %f = %f\n", stats->robustLQ, stats->robustMedian, stats->robustUQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian); 220 psVectorAppend (dQ, stats->robustUQ + stats->robustLQ - 2*stats->robustMedian); 218 221 219 222 // supply sample to plotting routing … … 322 325 } 323 326 324 psLogMsg ("psphot", PS_LOG_INFO, "built background image: %f sec\n", psTimerMark ("psphot.background")); 325 326 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_MEAN", PS_META_REPLACE, "sky mean", Value); 327 psLogMsg ("psphot", PS_LOG_WARN, "built background image: %f sec\n", psTimerMark ("psphot.background")); 328 329 psStats *statsDQ = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN); 330 psVectorStats (statsDQ, dQ, NULL, NULL, 0); 331 332 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_MEAN", PS_META_REPLACE, "sky mean", Value); 327 333 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_STDEV", PS_META_REPLACE, "sky stdev", ValueStdev); 328 psLogMsg ("psphot", PS_LOG_INFO, "image sky : mean %f stdev %f", Value, ValueStdev); 334 psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SKY_DQ", PS_META_REPLACE, "sky quartile slope", statsDQ->sampleMedian); 335 psLogMsg ("psphot", PS_LOG_INFO, "image sky : mean %f, stdev %f, dQ %f", Value, ValueStdev, statsDQ->sampleMedian); 329 336 330 337 // measure image and background stats and save for later output … … 334 341 PS_STAT_MAX); 335 342 psImageStats (statsBck, model, NULL, 0); 336 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MN", PS_META_REPLACE, "sky model mean", statsBck->sampleMean);343 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MN", PS_META_REPLACE, "sky model mean", statsBck->sampleMean); 337 344 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_SIG", PS_META_REPLACE, "sky model stdev", statsBck->sampleStdev); 345 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_DEV", PS_META_REPLACE, "sky stdev", ValueStdev); 346 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_DQ", PS_META_REPLACE, "sky quartile slope", statsDQ->sampleMedian); 338 347 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MAX", PS_META_REPLACE, "sky model maximum value", statsBck->max); 339 348 psMetadataAddF32 (readout->analysis, PS_LIST_TAIL, "MSKY_MIN", PS_META_REPLACE, "sky model minimum value", statsBck->min); … … 343 352 statsBck->min, statsBck->sampleMean, statsBck->max, statsBck->sampleStdev); 344 353 354 psFree(statsDQ); 355 psFree(dQ); 356 345 357 psFree(stats); 346 358 psFree(statsBck); … … 401 413 int num = psphotFileruleCount(config, filerule); 402 414 415 fprintf (stdout, "\n"); 416 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Model Background ---"); 417 403 418 // loop over the available readouts 404 419 for (int i = 0; i < num; i++) { -
trunk/psphot/src/psphotModelTest.c
r31452 r32348 1 # include "psphotInternal.h" 2 # define PM_SOURCE_FIT_PSF_X_EXT PM_SOURCE_FIT_PSF_AND_SKY 1 # include "psphotStandAlone.h" 3 2 4 // XXX add more test information? 5 bool psphotModelTest (pmConfig *config, const pmFPAview *view, const char *filerule, psMetadata *recipe) { 3 int main (int argc, char **argv) { 6 4 7 bool status; 8 int modelType = -1; 9 float obsMag, fitMag, value; 10 char name[64]; 11 pmPSF *psf = NULL; 12 pmSourceFitMode fitMode; 5 psMemInit(); 6 psTimerStart ("complete"); 7 pmErrorRegister(); // register psModule's error codes/messages 8 psphotInit(); 13 9 14 // bit-masks to test for good/bad pixels15 p sImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT");16 assert (maskVal);10 // load command-line arguments, options, and system config data 11 pmConfig *config = psphotModelTestArguments (argc, argv); 12 assert(config); 17 13 18 // bit-mask to mark pixels not used in analysis 19 psImageMaskType markVal = psMetadataLookupImageMask(&status, recipe, "MARK.PSPHOT"); 20 assert (markVal); 14 psphotVersionPrint(); 21 15 22 // maskVal is used to test for rejected pixels, and must include markVal 23 maskVal |= markVal; 24 25 // run model fitting tests on a single source? 26 if (!psMetadataLookupBool (&status, recipe, "TEST_FIT")) return false; 27 28 psTimerStart ("modelTest"); 29 30 // find the currently selected readout 31 pmReadout *readout = pmFPAfileThisReadout (config->files, view, "PSPHOT.INPUT"); 32 PS_ASSERT_PTR_NON_NULL (readout, false); 33 34 // use poissonian errors or local-sky errors 35 bool POISSON_ERRORS = psMetadataLookupBool (&status, recipe, filerule); 36 if (!status) POISSON_ERRORS = true; 37 pmSourceFitModelInit (15, 0.1, 1.0, POISSON_ERRORS); 38 39 // find the various fitting parameters (try test values first) 40 float INNER = psMetadataLookupF32 (&status, recipe, "TEST_FIT_INNER_RADIUS"); 41 if (!status || !isfinite(INNER)) { 42 INNER = psMetadataLookupF32 (&status, recipe, "SKY_INNER_RADIUS"); 43 } 44 float OUTER = psMetadataLookupF32 (&status, recipe, "TEST_FIT_OUTER_RADIUS"); 45 if (!status || !isfinite(OUTER)) { 46 OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS"); 47 } 48 float RADIUS = psMetadataLookupF32 (&status, recipe, "TEST_FIT_RADIUS"); 49 if (!status || !isfinite(RADIUS)) { 50 RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_FIT_RADIUS"); 51 } 52 float mRADIUS = psMetadataLookupF32 (&status, recipe, "TEST_MOMENTS_RADIUS"); 53 if (!status || !isfinite(mRADIUS)) { 54 mRADIUS = psMetadataLookupF32 (&status, recipe, "PSF_MOMENTS_RADIUS"); 16 // load input data (config and images (signal, noise, mask) 17 if (!psphotParseCamera (config)) { 18 psErrorStackPrint(stderr, "Error setting up the camera\n"); 19 exit (psphotGetExitStatus()); 55 20 } 56 21 57 // define the source of interest 58 float xObj = psMetadataLookupF32 (&status, recipe, "TEST_FIT_X"); 59 float yObj = psMetadataLookupF32 (&status, recipe, "TEST_FIT_Y"); 60 if (!isfinite(xObj) || !isfinite(yObj)) psAbort ("object position is not defined"); 61 62 // what fitting mode to use? 63 fitMode = PM_SOURCE_FIT_EXT; 64 char *fitModeWord = psMetadataLookupStr (&status, recipe, "TEST_FIT_MODE"); 65 if (fitModeWord && !strcasecmp (fitModeWord, "PSF")) fitMode = PM_SOURCE_FIT_PSF; 66 if (fitModeWord && !strcasecmp (fitModeWord, "CONV")) fitMode = PM_SOURCE_FIT_PSF_X_EXT; 67 if (fitModeWord && !strcasecmp (fitModeWord, "DEFAULT")) fitMode = PM_SOURCE_FIT_EXT; 68 69 // construct the source structures 70 pmSource *source = pmSourceAlloc(); 71 source->peak = pmPeakAlloc (xObj, yObj, 0, 0); 72 pmSourceDefinePixels (source, readout, xObj, yObj, OUTER); 73 74 // in fitMode, psf sets the model type 75 if (fitMode == PM_SOURCE_FIT_PSF) { 76 psf = psphotLoadPSF (config, view, recipe); 77 if (!psf) psAbort("PSF_INPUT_FILE not supplied"); 78 modelType = psf->type; 79 source->type = PM_SOURCE_TYPE_STAR; 80 } 81 if (fitMode == PM_SOURCE_FIT_EXT) { 82 // find the model: supplied by user or first in the PSF_MODEL list 83 char *modelName = psMetadataLookupStr (&status, recipe, "TEST_FIT_MODEL"); 84 if (!status || !strcasecmp (modelName, "DEFAULT")) { 85 // get the list pointers for the PSF_MODEL entries 86 87 psList *list = NULL; 88 psMetadataItem *mdi = psMetadataLookup (recipe, "PSF_MODEL"); 89 if (mdi == NULL) psAbort("missing PSF_MODEL selection"); 90 if (mdi->type == PS_DATA_STRING) { 91 list = psListAlloc(NULL); 92 psListAdd (list, PS_LIST_HEAD, mdi); 93 } else { 94 if (mdi->type != PS_DATA_METADATA_MULTI) psAbort("missing PSF_MODEL selection"); 95 list = psMemIncrRefCounter(mdi->data.list); 96 } 97 98 // take the first list element 99 psMetadataItem *item = psListGet (list, PS_LIST_HEAD); 100 modelName = item->data.V; 101 } 102 modelType = pmModelClassGetType (modelName); 103 if (modelType < 0) psAbort("unknown model %s", modelName); 104 source->type = PM_SOURCE_TYPE_EXTENDED; 105 } 106 if (fitMode == PM_SOURCE_FIT_PSF_X_EXT) { 107 // we need to load BOTH a psf and an ext model 108 psf = psphotLoadPSF (config, view, recipe); 109 if (!psf) psAbort("PSF_INPUT_FILE not supplied"); 110 111 // find the model: supplied by user or first in the PSF_MODEL list 112 char *modelName = psMetadataLookupStr (&status, recipe, "TEST_FIT_MODEL"); 113 if (!status || !strcasecmp (modelName, "DEFAULT")) { 114 // get the list pointers for the PSF_MODEL entries 115 116 psList *list = NULL; 117 psMetadataItem *mdi = psMetadataLookup (recipe, "PSF_MODEL"); 118 if (mdi == NULL) psAbort("missing PSF_MODEL selection"); 119 if (mdi->type == PS_DATA_STRING) { 120 list = psListAlloc(NULL); 121 psListAdd (list, PS_LIST_HEAD, mdi); 122 } else { 123 if (mdi->type != PS_DATA_METADATA_MULTI) psAbort("missing PSF_MODEL selection"); 124 list = psMemIncrRefCounter(mdi->data.list); 125 } 126 127 // take the first list element 128 psMetadataItem *item = psListGet (list, PS_LIST_HEAD); 129 modelName = item->data.V; 130 } 131 modelType = pmModelClassGetType (modelName); 132 if (modelType < 0) psAbort("unknown model %s", modelName); 133 source->type = PM_SOURCE_TYPE_EXTENDED; 22 // call psphot for each readout 23 if (!psphotImageLoop (config, PSPHOT_MODEL_TEST)) { 24 psErrorStackPrint(stderr, "Error in the psphot image loop\n"); 25 exit (psphotGetExitStatus()); 134 26 } 135 27 136 // find the local sky 137 status = pmSourceLocalSky (source, PS_STAT_SAMPLE_MEDIAN, INNER, maskVal, markVal); 138 if (!status) psAbort("pmSourceLocalSky error"); 28 psLogMsg ("psphot", 3, "complete psphot run: %f sec\n", psTimerMark ("complete")); 139 29 140 // get the source moments141 status = pmSourceMoments (source, mRADIUS, 0.0, 1.0, maskVal);142 if (!status) psAbort("psSourceMoments error");143 source->peak->value = source->moments->Peak; 30 psErrorCode exit_status = psphotGetExitStatus(); 31 psphotCleanup (config); 32 exit (exit_status); 33 } 144 34 145 fprintf (stderr, "sum: %f @ (%f, %f)\n", source->moments->Sum, source->moments->Mx, source->moments->My); 146 fprintf (stderr, "moments: %f, %f - %f\n", source->moments->Mxx, source->moments->Myy, source->moments->Mxy); 147 148 psEllipseMoments moments; 149 moments.x2 = source->moments->Mxx; 150 moments.y2 = source->moments->Myy; 151 moments.xy = source->moments->Mxy; 152 psEllipseAxes axes = psEllipseMomentsToAxes (moments, 20.0); 153 154 fprintf (stderr, "axes: %f @ (%f, %f)\n", axes.theta*180/M_PI, axes.major, axes.minor); 155 156 // get the initial model parameter guess 157 pmModel *model = pmSourceModelGuess (source, modelType); 158 source->modelEXT = model; 159 160 // if any parameters are defined by the user, take those values 161 int nParams = pmModelClassParameterCount (modelType); 162 psF32 *params = model->params->data.F32; 163 params[PM_PAR_XPOS] = xObj; // XXX use the user-supplied value, 164 params[PM_PAR_YPOS] = yObj; // XXX or use the centroid 165 for (int i = 0; i < nParams; i++) { 166 if (i == PM_PAR_XPOS) continue; 167 if (i == PM_PAR_YPOS) continue; 168 169 sprintf (name, "TEST_FIT_PAR%d", i); 170 value = psMetadataLookupF32 (&status, recipe, name); 171 if (status && isfinite (value)) { 172 params[i] = value; 173 } 174 } 175 176 float area = params[4]*params[5]; 177 fprintf (stderr, "peak: %f @ (%f, %f)\n", source->moments->Sum*area, (double)source->peak->x, (double)source->peak->y); 178 179 // for PSF fitting, set the shape parameters based on the PSF & source position 180 if (fitMode == PM_SOURCE_FIT_PSF) { 181 source->modelPSF = pmModelFromPSF (model, psf); 182 psFree (model); 183 model = source->modelPSF; 184 params = model->params->data.F32; 185 } 186 187 // list model input shape 188 psEllipseShape shape; 189 shape.sx = 1.4 / model->params->data.F32[4]; 190 shape.sy = 1.4 / model->params->data.F32[5]; 191 shape.sxy = model->params->data.F32[6]; 192 axes = psEllipseShapeToAxes (shape, 20.0); 193 194 fprintf (stderr, "guess: %f @ (%f, %f)\n", axes.theta*180/M_PI, axes.major, axes.minor); 195 196 fprintf (stderr, "input parameters: \n"); 197 for (int i = 0; i < nParams; i++) { 198 fprintf (stderr, "%d : %f\n", i, params[i]); 199 } 200 201 // define the pixels used for the fit 202 psImageKeepCircle (source->maskObj, xObj, yObj, RADIUS, "OR", markVal); 203 psphotSaveImage (NULL, source->maskObj, "mask1.fits"); 204 205 char *fitset = psMetadataLookupStr (&status, recipe, "TEST_FIT_SET"); 206 if (status) { 207 status = psphotFitSet (source, model, fitset, fitMode, maskVal); 208 exit (0); 209 } 210 211 if (fitMode == PM_SOURCE_FIT_PSF_X_EXT) { 212 // build the psf for the object 213 source->modelPSF = pmModelFromPSF (model, psf); 214 source->modelEXT = model; 215 216 // what fraction of the PSF is used? (radius in pixels : 2 -> 5x5 box) 217 int psfSize = psMetadataLookupS32 (&status, recipe, "PCM_BOX_SIZE"); 218 assert (status); 219 220 model = psphotPSFConvModel (readout, source, modelType, maskVal, markVal, psfSize); 221 params = model->params->data.F32; 222 } else { 223 status = pmSourceFitModel (source, model, fitMode, maskVal); 224 } 225 226 // measure the source mags 227 pmSourcePhotometryModel (&fitMag, model); 228 pmSourcePhotometryAper (NULL, &obsMag, NULL, NULL, model, source->pixels, source->variance, source->maskObj, maskVal); 229 fprintf (stderr, "ap: %f, fit: %f, apmifit: %f, nIter: %d\n", obsMag, fitMag, obsMag - fitMag, model->nIter); 230 231 // write out positive object 232 psphotSaveImage (NULL, source->pixels, "object.fits"); 233 234 // subtract object, leave local sky 235 // pmModelSub (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL, maskVal); 236 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 237 238 fprintf (stderr, "output parameters: \n"); 239 for (int i = 0; i < nParams; i++) { 240 fprintf (stderr, "%d : %f\n", i, params[i]); 241 } 242 243 // write out 244 psphotSaveImage (NULL, source->pixels, "resid.fits"); 245 psphotSaveImage (NULL, source->maskObj, "mask.fits"); 246 247 psLogMsg ("psphot", PS_LOG_INFO, "model test : %f sec\n", psTimerMark ("modelTest")); 248 249 exit (0); 250 } 35 // all functions which return to this level must raise one of the top-level error codes if they 36 // exit with an error. these error codes are used to specify the program exit status -
trunk/psphot/src/psphotOutput.c
r31452 r32348 325 325 psMetadataItemSupplement (&status, header, analysis, "MSKY_NY"); 326 326 327 psMetadataItemSupplement (&status, header, analysis, "MSKY_DEV"); 328 psMetadataItemSupplement (&status, header, analysis, "MSKY_DQ"); 329 327 330 psMetadataItemSupplement (&status, header, analysis, "DETEFF.MAGREF"); 328 331 -
trunk/psphot/src/psphotPetrosianProfile.c
r30624 r32348 38 38 // convert the isophotal radius vs angle measurements to an elliptical contour 39 39 if (!psphotEllipticalContour (source, petrosian)) { 40 psLogMsg ("psphot", 3, "failed to measure elliptical contour");40 // psLogMsg ("psphot", 3, "failed to measure elliptical contour"); 41 41 psFree (petrosian); 42 42 return false; -
trunk/psphot/src/psphotPetrosianStats.c
r31452 r32348 143 143 // if we failed to reach the PETROSIAN_RATIO, use the lowest significant ratio instead (flag this!) 144 144 if (!anyPetro) { 145 // interpolate Rvec between i-1 and i to PETROSIAN_RATIO to get flux (Fvec) and radius (rvec) 146 if (lowestSignificantRadius == 0) { 147 // assume Fmax @ R = 0.0 148 petRadius = InterpolateValues (1.0, 0.0, petRatio->data.F32[lowestSignificantRadius], refRadius->data.F32[lowestSignificantRadius], PETROSIAN_RATIO); 149 petRadiusErr = InterpolateValuesErrX (1.0, 0.0, petRatio->data.F32[lowestSignificantRadius], refRadius->data.F32[lowestSignificantRadius], PETROSIAN_RATIO, 0.0, petRatioErr->data.F32[lowestSignificantRadius]); 150 151 } else { 152 int n0 = lowestSignificantRadius-1; 153 int n1 = lowestSignificantRadius; 154 petRadius = InterpolateValues (petRatio->data.F32[n0], refRadius->data.F32[n0], petRatio->data.F32[n1], refRadius->data.F32[n1], PETROSIAN_RATIO); 155 petRadiusErr = InterpolateValuesErrX (petRatio->data.F32[n0], refRadius->data.F32[n0], petRatio->data.F32[n1], refRadius->data.F32[n1], PETROSIAN_RATIO, petRatioErr->data.F32[n0], petRatioErr->data.F32[n1]); 145 petRadius = refRadius->data.F32[lowestSignificantRadius]; 146 petRadiusErr = NAN; 147 if (!isfinite(petRadius)) { 148 fprintf (stderr, "nan pet radius\n"); 156 149 } 157 150 } … … 170 163 petArea = InterpolateValues (refRadius->data.F32[i-1], areaSum->data.F32[i-1], refRadius->data.F32[i], areaSum->data.F32[i], apRadius); 171 164 petApix = InterpolateValues (refRadius->data.F32[i-1], apixSum->data.F32[i-1], refRadius->data.F32[i], apixSum->data.F32[i], apRadius); 165 if (!isfinite(petFlux)) { 166 fprintf (stderr, "nan pet flux\n"); 167 } 172 168 break; 173 169 } … … 188 184 if (!found50 && (fluxSum->data.F32[i] > flux50)) { 189 185 if (i == 0) { 190 psWarning ("does this case make any sense? (fluxSum[0] %f > flux50 %f)", fluxSum->data.F32[i], flux50); 191 continue; 186 R50 = InterpolateValues (fluxSum->data.F32[i], refRadius->data.F32[i], fluxSum->data.F32[i+1], refRadius->data.F32[i+1], flux50); 187 R50err = InterpolateValuesErrX (fluxSum->data.F32[i], refRadius->data.F32[i], fluxSum->data.F32[i+1], refRadius->data.F32[i+1], flux50, sqrt(fluxSumErr2->data.F32[i]), sqrt(fluxSumErr2->data.F32[i+1])); 188 found50 = true; 192 189 } else { 193 190 R50 = InterpolateValues (fluxSum->data.F32[i-1], refRadius->data.F32[i-1], fluxSum->data.F32[i], refRadius->data.F32[i], flux50); … … 198 195 if (!found90 && (fluxSum->data.F32[i] > flux90)) { 199 196 if (i == 0) { 200 psWarning ("does this case make any sense? (fluxSum[0] %f > flux90 %f)", fluxSum->data.F32[i], flux90); 201 continue; 197 R90 = InterpolateValues (fluxSum->data.F32[i], refRadius->data.F32[i], fluxSum->data.F32[i+1], refRadius->data.F32[i+1], flux90); 198 R90err = InterpolateValuesErrX (fluxSum->data.F32[i], refRadius->data.F32[i], fluxSum->data.F32[i+1], refRadius->data.F32[i+1], flux90, sqrt(fluxSumErr2->data.F32[i]), sqrt(fluxSumErr2->data.F32[i+1])); 199 found90 = true; 202 200 } else { 203 201 R90 = InterpolateValues (fluxSum->data.F32[i-1], refRadius->data.F32[i-1], fluxSum->data.F32[i], refRadius->data.F32[i], flux90); -
trunk/psphot/src/psphotRadialApertures.c
r31452 r32348 3 3 bool psphotRadialAperturesSortFlux (psVector *radius, psVector *pixFlux, psVector *pixVar); 4 4 5 // this function measures the radial aperture fluxes for the set of readouts. this function 6 // may be called multiple times, presumably for different versions of PSF-matched or unmatched images. 7 5 8 // for now, let's store the detections on the readout->analysis for each readout 6 bool psphotRadialApertures (pmConfig *config, const pmFPAview *view, const char *filerule )9 bool psphotRadialApertures (pmConfig *config, const pmFPAview *view, const char *filerule, int entry) 7 10 { 8 11 bool status = true; 12 13 fprintf (stdout, "\n"); 14 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Radial Apertures ---"); 9 15 10 16 // select the appropriate recipe information … … 22 28 // loop over the available readouts 23 29 for (int i = 0; i < num; i++) { 24 if (!psphotRadialAperturesReadout (config, view, filerule, i, recipe )) {30 if (!psphotRadialAperturesReadout (config, view, filerule, i, recipe, entry)) { 25 31 psError (PSPHOT_ERR_CONFIG, false, "failed on measure extended source aperture-like parameters for %s entry %d", filerule, i); 26 32 return false; … … 32 38 // aperture-like measurements for extended sources 33 39 // flux in simple, circular apertures 34 bool psphotRadialAperturesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe) { 40 // 'entry' tells us which of the matched-PSF images we are working on (0 == unmatched image, also non-stack psphot) 41 bool psphotRadialAperturesReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, int entry) { 35 42 36 43 bool status; … … 62 69 return true; 63 70 } 71 72 // determine the number of allowed threads 73 int nThreads = psMetadataLookupS32(&status, config->arguments, "NTHREADS"); // Number of threads 74 if (!status) { 75 nThreads = 0; 76 } 77 78 // source analysis is done in S/N order (brightest first) 79 // XXX are we getting the objects out of order? does it matter? 80 sources = psArraySort (sources, pmSourceSortByFlux); 81 82 // XXX make this consistent with entry 0 == unmatched 83 int nEntry = 1; 84 psVector *fwhmValues = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES"); 85 if (fwhmValues) { 86 psAssert (entry < fwhmValues->n, "inconsistent matched-PSF entry"); 87 nEntry = fwhmValues->n; 88 } 89 if (entry > 0) { 90 psLogMsg ("psphot", PS_LOG_DETAIL, "Radial Apertures for matched image %s : PSF FWHM = %f pixels\n", file->name, fwhmValues->data.F32[entry]); 91 } else { 92 psLogMsg ("psphot", PS_LOG_DETAIL, "Radial Apertures for unmatched image %s\n", file->name); 93 } 94 95 // option to limit analysis to a specific region 96 char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION"); 97 psRegion *AnalysisRegion = psRegionAlloc(0,0,0,0); 98 *AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region)); 99 if (psRegionIsNaN (*AnalysisRegion)) psAbort("analysis region mis-defined"); 100 101 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) 102 int Cx = 1, Cy = 1; 103 psphotChooseCellSizes (&Cx, &Cy, readout, nThreads); 104 105 psArray *cellGroups = psphotAssignSources (Cx, Cy, sources); 106 107 for (int i = 0; i < cellGroups->n; i++) { 108 109 psArray *cells = cellGroups->data[i]; 110 111 for (int j = 0; j < cells->n; j++) { 112 113 // allocate a job -- if threads are not defined, this just runs the job 114 psThreadJob *job = psThreadJobAlloc ("PSPHOT_RADIAL_APERTURES"); 115 116 psArrayAdd(job->args, 1, readout); 117 psArrayAdd(job->args, 1, cells->data[j]); // sources 118 psArrayAdd(job->args, 1, AnalysisRegion); 119 psArrayAdd(job->args, 1, recipe); 120 121 PS_ARRAY_ADD_SCALAR(job->args, entry, PS_TYPE_S32); 122 PS_ARRAY_ADD_SCALAR(job->args, nEntry, PS_TYPE_S32); 123 124 PS_ARRAY_ADD_SCALAR(job->args, 0, PS_TYPE_S32); // this is used as a return value for Nradial 125 126 // set this to 0 to run without threading 127 # if (1) 128 if (!psThreadJobAddPending(job)) { 129 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 130 psFree(AnalysisRegion); 131 return false; 132 } 133 # else 134 if (!psphotRadialApertures_Threaded(job)) { 135 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 136 psFree(AnalysisRegion); 137 return false; 138 } 139 psScalar *scalar = NULL; 140 scalar = job->args->data[6]; 141 Nradial += scalar->data.S32; 142 psFree(job); 143 # endif 144 } 145 146 // wait for the threads to finish and manage results 147 if (!psThreadPoolWait (false)) { 148 psError(PS_ERR_UNKNOWN, false, "Unable to guess model."); 149 psFree(AnalysisRegion); 150 return false; 151 } 152 153 // we have only supplied one type of job, so we can assume the types here 154 psThreadJob *job = NULL; 155 while ((job = psThreadJobGetDone()) != NULL) { 156 if (job->args->n < 1) { 157 fprintf (stderr, "error with job\n"); 158 } else { 159 psScalar *scalar = NULL; 160 scalar = job->args->data[6]; 161 Nradial += scalar->data.S32; 162 } 163 psFree(job); 164 } 165 } 166 psFree (cellGroups); 167 psFree(AnalysisRegion); 168 169 psLogMsg ("psphot", PS_LOG_WARN, "radial source apertures: %f sec for %d objects\n", psTimerMark ("psphot.radial"), Nradial); 170 return true; 171 } 172 173 bool psphotRadialApertures_Threaded (psThreadJob *job) { 174 175 bool status; 176 int Nradial = 0; 177 178 // arguments: readout, sources, models, region, psfSize, maskVal, markVal 179 pmReadout *readout = job->args->data[0]; 180 psArray *sources = job->args->data[1]; 181 psRegion *region = job->args->data[2]; 182 psMetadata *recipe = job->args->data[3]; 183 184 int entry = PS_SCALAR_VALUE(job->args->data[4],S32); // which psf-matched image are we working on? (0 == unmatched) 185 int nEntry = PS_SCALAR_VALUE(job->args->data[5],S32); // total number of psf-matched images + 1 unmatched 64 186 65 187 // radMax stores the upper bounds of the annuli … … 68 190 psAssert (radMax, "annular bins (RADIAL.ANNULAR.BINS.UPPER) are not defined in the recipe"); 69 191 psAssert (radMax->n, "no valid annular bins (RADIAL.ANNULAR.BINS.UPPER) are define"); 70 float outerRadius = radMax->data.F32[radMax->n - 1];71 192 72 193 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) … … 77 198 float SN_LIM = psMetadataLookupF32 (&status, recipe, "RADIAL_APERTURES_SN_LIM"); 78 199 79 // source analysis is done in S/N order (brightest first) 80 // XXX are we getting the objects out of order? does it matter? 81 sources = psArraySort (sources, pmSourceSortByFlux); 82 83 // option to limit analysis to a specific region 84 char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION"); 85 psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region)); 86 if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined"); 200 float outerRadius = radMax->data.F32[radMax->n - 1]; 87 201 88 202 // choose the sources of interest … … 104 218 105 219 // limit selection by analysis region 106 if (source->peak->x < AnalysisRegion.x0) continue;107 if (source->peak->y < AnalysisRegion.y0) continue;108 if (source->peak->x > AnalysisRegion.x1) continue;109 if (source->peak->y > AnalysisRegion.y1) continue;220 if (source->peak->x < region->x0) continue; 221 if (source->peak->y < region->y0) continue; 222 if (source->peak->x > region->x1) continue; 223 if (source->peak->y > region->y1) continue; 110 224 111 225 // allocate pmSourceExtendedParameters, if not already defined 112 if (!source->radialAper) { 113 source->radialAper = psArrayAlloc(1); 226 // XXX check that nPSFsizes is consistent with targets 227 if (source->parent) { 228 if (!source->parent->radialAper) { 229 source->parent->radialAper = psArrayAlloc(nEntry); 230 } 231 } else { 232 if (!source->radialAper) { 233 source->radialAper = psArrayAlloc(nEntry); 234 } 114 235 } 115 236 … … 131 252 pmSourceRedefinePixels (source, readout, source->peak->xf, source->peak->yf, outerRadius + 2); 132 253 133 if (!psphotRadialApertureSource (source, recipe, maskVal, radMax, 0)) {254 if (!psphotRadialApertureSource (source, recipe, maskVal, radMax, entry)) { 134 255 psTrace ("psphot", 5, "failed to extract radial profile for source at %7.1f, %7.1f", source->moments->Mx, source->moments->My); 135 256 } else { … … 145 266 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 146 267 } 147 148 psLogMsg ("psphot", PS_LOG_INFO, "radial source apertures: %f sec for %d objects\n", psTimerMark ("psphot.radial"), Nradial); 268 psScalar *scalar = job->args->data[6]; 269 scalar->data.S32 = Nradial; 270 149 271 return true; 150 272 } -
trunk/psphot/src/psphotRadialAperturesByObject.c
r31154 r32348 162 162 // re-subtract the object, leave local sky 163 163 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 164 165 // psLogMsg("psphot", PS_LOG_INFO, "radial apertures for %d", index);166 // psphotVisualShowImage(readout);167 164 } 168 165 } -
trunk/psphot/src/psphotRadialProfile.c
r31154 r32348 39 39 // convert the isophotal radius vs angle measurements to an elliptical contour 40 40 if (!psphotEllipticalContour (source)) { 41 psLogMsg ("psphot", 3, "failed to measure elliptical contour");41 // psLogMsg ("psphot", 3, "failed to measure elliptical contour"); 42 42 return false; 43 43 } -
trunk/psphot/src/psphotRadiusChecks.c
r31452 r32348 142 142 } 143 143 144 # define MIN_WINDOW 5.0 145 # define SCALE1 5.0 146 # define SCALE2 12.0 147 148 // call this function whenever you (re)-define the EXT model 149 // XXX this function does not shrink the window 150 bool psphotSetRadiusMoments (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal) { 151 152 psAssert (source, "source not defined??"); 153 psAssert (source->moments, "moments not defined??"); 154 155 *fitRadius = SCALE1 * source->moments->Mrf; 156 *fitRadius = PS_MIN (PS_MAX(*fitRadius, MIN_WINDOW), EXT_FIT_MAX_RADIUS); 157 158 *windowRadius = SCALE2 * source->moments->Mrf; 159 *windowRadius = PS_MIN (PS_MAX(*windowRadius, 2.5*MIN_WINDOW), 2.5*EXT_FIT_MAX_RADIUS); 160 161 // redefine the pixels if needed 162 pmSourceRedefinePixels (source, readout, source->peak->xf, source->peak->yf, *windowRadius); 163 164 // set the mask to flag the excluded pixels 165 psImageKeepCircle (source->maskObj, source->peak->xf, source->peak->yf, *fitRadius, "OR", markVal); 166 167 return true; 168 } 169 # undef SCALE1 170 # undef SCALE2 171 # undef MIN_WINDOW 172 173 # define MIN_WINDOW 5.0 174 # define SCALE1 5.0 175 # define PAD_WINDOW 3.0 176 177 // call this function whenever you (re)-define the EXT model 178 // XXX alternate function to set exactly the desired window size 179 bool psphotSetRadiusMomentsExact (float *fitRadius, float *windowRadius, pmReadout *readout, pmSource *source, psImageMaskType markVal) { 180 181 psRegion newRegion; 182 183 psAssert (source, "source not defined??"); 184 psAssert (source->moments, "moments not defined??"); 185 186 *fitRadius = SCALE1 * source->moments->Mrf; 187 *fitRadius = PS_MIN (PS_MAX(*fitRadius, MIN_WINDOW), EXT_FIT_MAX_RADIUS); 188 189 *windowRadius = *fitRadius + PAD_WINDOW; 190 191 // check to see if new region is completely contained within old region 192 newRegion = psRegionForSquare (source->peak->xf, source->peak->yf, *windowRadius); 193 newRegion = psRegionForImage (readout->image, newRegion); 194 195 // redefine the pixels to match 196 pmSourceRedefinePixelsByRegion (source, readout, newRegion); 197 198 // set the mask to flag the excluded pixels 199 psImageKeepCircle (source->maskObj, source->peak->xf, source->peak->yf, *fitRadius, "OR", markVal); 200 201 return true; 202 } 203 144 204 // call this function whenever you (re)-define the EXT model 145 205 bool psphotSetRadiusFootprint (float *radius, pmReadout *readout, pmSource *source, psImageMaskType markVal, float factor) { … … 181 241 } 182 242 243 // call this function whenever you (re)-define the EXT model 244 bool psphotMaskFootprint (pmReadout *readout, pmSource *source, psImageMaskType markVal) { 245 246 psAssert (source, "source not defined??"); 247 psAssert (source->peak, "peak not defined??"); 248 249 pmPeak *peak = source->peak; 250 251 // set the radius based on the footprint: 252 if (!peak->footprint) return false; 253 pmFootprint *footprint = peak->footprint; 254 if (!footprint->spans) return false; 255 if (footprint->spans->n < 1) return false; 256 257 int Xo = source->maskObj->col0; 258 int Yo = source->maskObj->row0; 259 260 // mark all pixels 261 for (int j = 0; j < source->maskObj->numRows; j++) { 262 for (int i = 0; i < source->maskObj->numCols; i++) { 263 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[j][i] |= markVal; 264 } 265 } 266 267 psImageMaskType clearVal = PS_NOT_IMAGE_MASK(markVal); 268 269 for (int j = 0; j < footprint->spans->n; j++) { 270 pmSpan *span = footprint->spans->data[j]; 271 272 // mask the rows before and after each span 273 int minX = span->x0 - Xo - 2; 274 int maxX = span->x1 - Xo + 2; 275 int myY = span->y - Yo; 276 277 // unmark pixels inside the footprint 278 for (int i = minX; i <= maxX; i++) { 279 source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[myY][i] &= clearVal; 280 } 281 } 282 return true; 283 } 284 183 285 // alternative EXT radius based on model guess (for use without footprints) 184 286 bool psphotSetRadiusModel (pmModel *model, pmReadout *readout, pmSource *source, psImageMaskType markVal, bool deep) { -
trunk/psphot/src/psphotReadout.c
r31452 r32348 102 102 return psphotReadoutCleanup (config, view, filerule); 103 103 } 104 105 # if (0)106 // XXX test to mask outliers, not very helpful107 // mask the high values in the image (with MARK)108 if (!psphotMaskBackground (config, view, filerule)) {109 return psphotReadoutCleanup (config, view, filerule);110 }111 112 // generate a background model (median, smoothed image)113 if (!psphotModelBackground (config, view, filerule)) {114 return psphotReadoutCleanup (config, view, filerule);115 }116 # endif117 118 104 if (!psphotSubtractBackground (config, view, filerule)) { 119 105 return psphotReadoutCleanup (config, view, filerule); … … 137 123 } 138 124 139 // construct sources and measure basic stats (saved on detections->newSources) 125 // construct sources and measure moments and other basic stats (saved on detections->newSources) 126 // all sources use the auto-scaled window appropriate to a PSF, except for the saturated 127 // stars : these use a larger window (3x the basic window) 140 128 if (!psphotSourceStats (config, view, filerule, true)) { // pass 1 141 129 psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources"); … … 153 141 154 142 // mark blended peaks PS_SOURCE_BLEND (detections->newSources) 155 if (!psphotBasicDeblend (config, view, filerule)) { 143 // XXX I've deactivated this because it was preventing galaxies close to stars from being 144 // XXX fitted as an extended source. 145 if (false && !psphotBasicDeblend (config, view, filerule)) { 156 146 psError (PSPHOT_ERR_UNKNOWN, false, "failed on deblend analysis"); 157 147 return psphotReadoutCleanup (config, view, filerule); … … 200 190 psphotDumpChisqs (config, view, filerule); 201 191 202 // XXX re-measure the kron mags with models subtracted 203 psphotKronMasked(config, view, filerule); 192 // re-measure the kron mags with models subtracted. this pass uses a circular window of size PSF_MOMENTS_RADIUS (same window used to measure the psf-scale moments) 193 194 // but this is chosen above to be appropriate for the PSF objects (not galaxies) 195 // psphotKronMasked(config, view, filerule); 196 psphotKronIterate(config, view, filerule); 204 197 205 198 // identify CRs and extended sources (only unmeasured sources are measured) … … 240 233 psphotSubNoise (config, view, filerule); // pass 1 (detections->allSources) 241 234 242 // define new sources based on only the new peaks 235 // define new sources based on only the new peaks & measure moments 243 236 // NOTE: new sources are saved on detections->newSources 244 237 psphotSourceStats (config, view, filerule, false); // pass 2 (detections->newSources) … … 312 305 pass1finish: 313 306 314 // XXX re-measure the kron mags with models subtracted 315 psphotKronMasked(config, view, filerule); 307 // re-measure the kron mags with models subtracted 308 // psphotKronMasked(config, view, filerule); 309 psphotKronIterate(config, view, filerule); 316 310 317 311 // measure source size for the remaining sources … … 321 315 psphotExtendedSourceAnalysis (config, view, filerule); // pass 1 (detections->allSources) 322 316 psphotExtendedSourceFits (config, view, filerule); // pass 1 (detections->allSources) 323 psphotRadialApertures(config, view, filerule );317 psphotRadialApertures(config, view, filerule, 0); 324 318 325 319 finish: … … 359 353 } 360 354 355 psLogMsg ("psphot.readout", PS_LOG_WARN, "complete psphot readout : %f sec\n", psTimerMark ("psphotReadout")); 356 361 357 // create the exported-metadata and free local data 362 358 return psphotReadoutCleanup(config, view, filerule); -
trunk/psphot/src/psphotRoughClass.c
r31673 r32348 11 11 { 12 12 bool status = true; 13 14 fprintf (stdout, "\n"); 15 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Rough Class ---"); 13 16 14 17 // select the appropriate recipe information … … 128 131 psphotDumpMoments (recipe, sources); 129 132 130 psLogMsg ("psphot.roughclass", PS_LOG_ INFO, "rough classification: %f sec\n", psTimerMark ("psphot.rough"));133 psLogMsg ("psphot.roughclass", PS_LOG_WARN, "rough classification: %f sec\n", psTimerMark ("psphot.rough")); 131 134 132 135 psphotVisualPlotMoments (recipe, readout->analysis, sources); -
trunk/psphot/src/psphotSetThreads.c
r31452 r32348 30 30 psFree(task); 31 31 32 task = psThreadTaskAlloc("PSPHOT_KRON_ITERATE", 7); 33 task->function = &psphotKronIterate_Threaded; 34 psThreadTaskAdd(task); 35 psFree(task); 36 32 37 task = psThreadTaskAlloc("PSPHOT_BLEND_FIT", 10); 33 38 task->function = &psphotBlendFit_Threaded; … … 40 45 psFree(task); 41 46 47 task = psThreadTaskAlloc("PSPHOT_EXTENDED_ANALYSIS", 8); 48 task->function = &psphotExtendedSourceAnalysis_Threaded; 49 psThreadTaskAdd(task); 50 psFree(task); 51 52 task = psThreadTaskAlloc("PSPHOT_RADIAL_APERTURES", 7); 53 task->function = &psphotRadialApertures_Threaded; 54 psThreadTaskAdd(task); 55 psFree(task); 56 42 57 return true; 43 58 } -
trunk/psphot/src/psphotSourceFits.c
r31452 r32348 211 211 bool psphotFitBlob (pmReadout *readout, pmSource *source, psArray *newSources, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal) { 212 212 213 float radius;213 float fitRadius, windowRadius; 214 214 bool okEXT, okDBL; 215 215 pmModel *ONE = NULL; … … 217 217 pmModel *EXT = NULL; 218 218 psArray *DBL = NULL; 219 pmMoments psfMoments;219 // pmMoments psfMoments; 220 220 221 221 // skip the source if we don't think it is extended … … 225 225 if (source->type == PM_SOURCE_TYPE_SATURATED) return false; 226 226 227 # define TEST_X -420.0 228 # define TEST_Y 300.0 229 230 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 231 fprintf (stderr, "test galaxy\n"); 232 } 233 234 # undef TEST_X 235 # undef TEST_Y 236 227 237 // set the radius based on the footprint (also sets the mask pixels) 228 if (!psphotSetRadiusFootprint(&radius, readout, source, markVal, 1.0)) return false; 229 230 // XXX note that this changes the source moments that are published... 231 // XXX all published moments should use the same measurement 232 // recalculate the source moments using the larger extended-source moments radius 233 // at this stage, skip Gaussian windowing, and do not clip pixels by S/N 234 // this uses the footprint to judge both radius and aperture? 235 // XXX save the psf-based moments for output 236 psfMoments = *source->moments; 237 if (!pmSourceMoments (source, radius, 0.0, 0.5, 0.0, maskVal)) { 238 *source->moments = psfMoments; 239 return false; 240 } 238 if (!psphotSetRadiusMoments(&fitRadius, &windowRadius, readout, source, markVal)) return false; 239 // fprintf (stderr, "rad: %6.1f %6.1f | %5.2f %5.2f %5.2f ", source->peak->xf, source->peak->yf, source->moments->Mrf, fitRadius, windowRadius); 241 240 242 241 psTrace ("psphot", 5, "trying blob...\n"); … … 263 262 ONE = DBL->data[0]; 264 263 if (ONE) { 265 if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");264 psAssert (isfinite(ONE->params->data.F32[PM_PAR_I0]), "nan in fit"); 266 265 chiDBL = ONE->chisqNorm; // save chisq for double-star/galaxy comparison 267 ONE->fitRadius = radius;266 ONE->fitRadius = fitRadius; 268 267 } 269 268 … … 271 270 ONE = DBL->data[1]; 272 271 if (ONE) { 273 if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");274 ONE->fitRadius = radius;272 psAssert (isfinite(ONE->params->data.F32[PM_PAR_I0]), "nan in fit"); 273 ONE->fitRadius = fitRadius; 275 274 } 276 275 } … … 284 283 okEXT = psphotEvalEXT (tmpSrc, EXT); 285 284 chiEXT = EXT ? EXT->chisqNorm : NAN; 285 EXT->fitRadius = fitRadius; 286 286 } 287 287 … … 294 294 295 295 if (okEXT && okDBL) { 296 psTrace ("psphot", 5, "blob chisq: %f vs %f\n", chiEXT, chiDBL);297 296 // XXX EAM : a bogus bias: need to examine this better 298 297 if (3*chiEXT > chiDBL) goto keepDBL; … … 303 302 if (!okEXT && okDBL) goto keepDBL; 304 303 304 psTrace ("psphot", 4, "both failed: blob chisq: %f vs %f for %f,%f\n", chiEXT, chiDBL, source->peak->xf, source->peak->yf); 305 305 306 // both models failed; reject them both 306 307 // XXX -- change type flags to psf in this case, and make sure we subtract it? 307 308 // reset the psf moments 308 *source->moments = psfMoments;309 // XXX *source->moments = psfMoments; 309 310 310 311 psFree (EXT); … … 313 314 314 315 keepEXT: 316 psTrace ("psphot", 4, "goto EXT : blob chisq: %f vs %f for %f,%f\n", chiEXT, chiDBL, source->peak->xf, source->peak->yf); 315 317 // sub EXT 316 318 psFree (DBL); … … 338 340 339 341 // reset the psf moments 340 *source->moments = psfMoments;342 // XXX *source->moments = psfMoments; 341 343 return true; 342 344 343 345 keepDBL: 346 psTrace ("psphot", 4, "goto DBL : blob chisq: %f vs %f for %f,%f\n", chiEXT, chiDBL, source->peak->xf, source->peak->yf); 344 347 // sub DLB 345 348 psFree (EXT); … … 372 375 psLogMsg ("psphot", 1, "PAR %d : %f +/- %f\n", i, source->modelPSF->params->data.F32[i], source->modelPSF->dparams->data.F32[i]); 373 376 } 374 psphotVisualShowResidualImage (readout, false);375 377 } 376 378 # endif 377 378 // reset the (original) psf moments379 *source->moments = psfMoments;380 *newSrc->moments = psfMoments;381 379 382 380 psArrayAdd (newSources, 100, newSrc); … … 386 384 387 385 escape: 388 // reset the psf moments389 *source->moments = psfMoments;390 386 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); 391 387 psFree (tmpSrc); … … 476 472 // for sersic models, use a grid search to choose an index, then float the params there 477 473 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { 478 // for the test fits, use a somewhat smaller radius479 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);480 474 psphotFitSersicIndex (model, readout, source, fitOptions, maskVal, markVal); 481 }482 483 if (!psphotSetRadiusModel (model, readout, source, markVal, true)) {484 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 1.0);485 475 } 486 476 … … 494 484 pmSourceFitModel (source, model, &options, maskVal); 495 485 // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix); 496 497 486 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); 487 498 488 return (model); 499 489 } 490 491 # define TIMING 0 500 492 501 493 pmModel *psphotFitPCM (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { … … 517 509 return NULL; 518 510 } 511 512 # define TEST_X -540.0 513 # define TEST_Y 540.0 514 515 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 516 psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 5); 517 } 518 519 float t1, t2, t4, t5; 520 if (TIMING) { psTimerStart ("psphotFitPCM"); } 519 521 520 522 pmPCMdata *pcm = pmPCMinit (source, &options, model, maskVal, psfSize); … … 524 526 return model; 525 527 } 526 527 // use the source moments, etc to guess basic model parameters 528 if (!pmSourceModelGuessPCM (pcm, source, maskVal, markVal)) { 529 psFree (pcm); 530 model->flags |= PM_MODEL_STATUS_BADARGS; 531 return model; 532 } 533 534 // for sersic models, use a grid search to choose an index, then float the params there 528 if (TIMING) { t1 = psTimerMark ("psphotFitPCM"); } 529 530 // get the guess for sersic models 535 531 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { 536 // for the test fits, use a somewhat smaller radius 537 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5); 538 539 if (!psphotFitSersicIndexPCM (pcm, readout, source, fitOptions, maskVal, markVal, psfSize)) { 532 // use the source moments, etc to guess basic model parameters 533 if (!psphotSersicModelClassGuessPCM (pcm, source)) { 540 534 psFree (pcm); 541 535 model->flags |= PM_MODEL_STATUS_BADARGS; 542 536 return model; 543 537 } 544 } 545 546 if (!psphotSetRadiusModel (model, readout, source, markVal, true)) { 547 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 1.0); 548 } 538 } else { 539 // use the source moments, etc to guess basic model parameters 540 if (!pmSourceModelGuessPCM (pcm, source, maskVal, markVal)) { 541 psFree (pcm); 542 model->flags |= PM_MODEL_STATUS_BADARGS; 543 return model; 544 } 545 } 546 547 if (TIMING) { t2 = psTimerMark ("psphotFitPCM"); } 549 548 550 549 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { … … 555 554 // update the pcm elements if we have changed the circumstance (options.mode or source->pixels) 556 555 pmPCMupdate(pcm, source, &options, model); 556 if (TIMING) { t4 = psTimerMark ("psphotFitPCM"); } 557 557 558 558 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5); 559 559 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 560 // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix); 560 if (TIMING) { t5 = psTimerMark ("psphotFitPCM"); } 561 562 if (TIMING) { 563 int nPixBig = source->pixels->numCols * source->pixels->numRows; 564 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); 565 } 566 567 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 568 psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 0); 569 } 561 570 562 571 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); … … 566 575 } 567 576 577 # undef TEST_X 578 # undef TEST_Y 579 568 580 // note that these should be 1/2n of the standard sersic index 569 float indexGuess[] = {0.5, 0.33, 0.25, 0.167, 0.125, 0.083}; 570 # define N_INDEX_GUESS 6 581 // float indexGuess[] = {0.8, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0}; 582 // float indexGuess[] = {0.5, 0.33, 0.25, 0.167, 0.125, 0.083}; 583 float indexGuess[] = {1.0, 2.0, 3.0, 4.0}; 584 # define N_INDEX_GUESS 4 571 585 572 586 // A sersic model is very sensitive to the index. attempt to find the index first by grid search in just the index … … 586 600 float chiSquare[N_INDEX_GUESS]; 587 601 602 # define TEST_X -540.0 603 # define TEST_Y 540.0 604 605 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 606 psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 5); 607 } 608 588 609 for (int i = 0; i < N_INDEX_GUESS; i++) { 589 model->params->data.F32[PM_PAR_7] = indexGuess[i];610 model->params->data.F32[PM_PAR_7] = 0.5/indexGuess[i]; 590 611 591 612 if (!model->modelGuess(model, source)) { … … 594 615 } 595 616 596 // each time we change the model guess, we need to adjust the radius597 // XXX this did not work : we do not need such a large radius -- just uses moments-based radius598 if (false && !psphotSetRadiusModel (model, readout, source, markVal, false)) {599 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);600 }601 602 617 pmSourceFitModel (source, model, &options, maskVal); 603 // fprintf (stderr, " chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix);618 // fprintf (stderr, "index: %f, chisq: %f, nIter: %d, radius: %f, npix: %d\n", indexGuess[i], model->chisqNorm, model->nIter, model->fitRadius, model->nPix); 604 619 605 620 chiSquare[i] = model->chisqNorm; … … 616 631 assert (iMin >= 0); 617 632 633 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 634 psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 0); 635 } 636 618 637 model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it 619 model->params->data.F32[PM_PAR_7] = indexGuess[iMin];638 model->params->data.F32[PM_PAR_7] = 0.5/indexGuess[iMin]; 620 639 model->modelGuess(model, source); 621 622 // each time we change the model guess, we need to adjust the radius623 // if (!psphotSetRadiusModel (model, readout, source, markVal, true)) {624 // psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal);625 // }626 640 627 641 return true; … … 648 662 float xMin = NAN; 649 663 float chiSquare[N_INDEX_GUESS]; 664 665 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 666 psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 5); 667 } 650 668 651 669 for (int i = 0; i < N_INDEX_GUESS; i++) { … … 657 675 } 658 676 659 // each time we change the model guess, we need to adjust the radius660 // XXX this did not work : we do not need such a large radius -- just uses moments-based radius661 if (false && !psphotSetRadiusModel (model, readout, source, markVal, false)) {662 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5);663 }664 665 677 # if (0) 678 // this block is to test the relative speed of straight and PCM fits 666 679 pmSourceFitModel (source, model, &options, maskVal); 667 680 # else … … 669 682 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 670 683 # endif 684 fprintf (stderr, "index: %f, chisq: %f, nIter: %d, radius: %f, npix: %d\n", indexGuess[i], model->chisqNorm, model->nIter, model->fitRadius, model->nPix); 671 685 // fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix); 672 686 … … 684 698 assert (iMin >= 0); 685 699 700 if ((fabs(source->peak->xf - TEST_X) < 5) && (fabs(source->peak->yf - TEST_Y) < 5)) { 701 psTraceSetLevel("psModules.objects.pmPCM_MinimizeChisq", 0); 702 } 703 686 704 model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it 687 705 model->params->data.F32[PM_PAR_7] = indexGuess[iMin]; -
trunk/psphot/src/psphotSourceMatch.c
r31154 r32348 48 48 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS"); 49 49 psAssert (detections, "missing detections?"); 50 psAssert (detections->newSources, "new sources not defined?"); 51 psAssert (!detections->allSources, "all sources already defined?"); 52 53 // XXX TEST: 54 if (detections->newSources) { 55 psphotMatchSourcesToObjects(objects, detections->newSources, RADIUS); 56 } 50 psAssert (detections->allSources, "all sources not defined?"); 51 52 psphotMatchSourcesToObjects(objects, detections->allSources, RADIUS); 57 53 58 54 return true; … … 261 257 peak->assigned = true; 262 258 pmPhotObjAddSource(obj, source); 263 psArrayAdd (detections-> newSources, 100, source);259 psArrayAdd (detections->allSources, 100, source); 264 260 psFree (source); 265 261 } -
trunk/psphot/src/psphotSourceSize.c
r31452 r32348 45 45 bool status = true; 46 46 47 fprintf (stdout, "\n"); 48 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Source Size ---"); 49 47 50 // select the appropriate recipe information 48 51 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); … … 209 212 pmSourceMagnitudes (source, psf, photMode, maskVal, markVal, source->apRadius); 210 213 211 float kMag = -2.5*log10(source->moments->KronFlux );214 float kMag = -2.5*log10(source->moments->KronFluxPSF); 212 215 float dMag = source->psfMag - kMag; 213 216 … … 334 337 psF32 Mxy = source->moments->Mxy; 335 338 336 float KronMag = -2.5*log10(source->moments->KronFlux );339 float KronMag = -2.5*log10(source->moments->KronFluxPSF); 337 340 338 341 float Mminor = 0.5*(Mxx + Myy) - 0.5*sqrt(PS_SQR(Mxx - Myy) + 4.0*PS_SQR(Mxy)); … … 509 512 pmSourceSub (source, PM_MODEL_OP_FULL, options->maskVal); 510 513 511 float kMag = -2.5*log10(source->moments->KronFlux );514 float kMag = -2.5*log10(source->moments->KronFluxPSF); 512 515 float dMag = source->psfMag - kMag; 513 516 -
trunk/psphot/src/psphotSourceStats.c
r31673 r32348 9 9 { 10 10 bool status = true; 11 12 fprintf (stdout, "\n"); 13 psLogMsg ("psphot", PS_LOG_INFO, "--- psphot Source Stats ---"); 11 14 12 15 // select the appropriate recipe information … … 239 242 psFree (cellGroups); 240 243 241 psLogMsg ("psphot", PS_LOG_ INFO, "%ld sources, %d moments, %d faint, %d failed: %f sec\n", sources->n, Nmoments, Nfaint, Nfail, psTimerMark ("psphot.stats"));244 psLogMsg ("psphot", PS_LOG_WARN, "%ld sources, %d moments, %d faint, %d failed: %f sec\n", sources->n, Nmoments, Nfaint, Nfail, psTimerMark ("psphot.stats")); 242 245 243 246 psphotVisualShowMoments (sources); … … 554 557 // determine the PSF parameters from the source moment values 555 558 pmPSFClump psfClump = pmSourcePSFClump (NULL, NULL, sources, PSF_SN_LIM, PSF_CLUMP_GRID_SCALE, MOMENTS_SX_MAX, MOMENTS_SY_MAX, MOMENTS_SX_MIN, MOMENTS_SY_MIN, MOMENTS_AR_MAX); 556 psLogMsg ("psphot", 3, " radius%.1f, nStars: %d of %d in clump, nSigma: %5.2f, X, Y: %f, %f (%f, %f)\n", sigma[i], psfClump.nStars, psfClump.nTotal, psfClump.nSigma, psfClump.X, psfClump.Y, sqrt(psfClump.X) / sigma[i], sqrt(psfClump.Y) / sigma[i]);559 psLogMsg ("psphot", 3, "sigma guess (pix) %.1f, nStars: %d of %d in clump, nSigma: %5.2f, X, Y: %f, %f (%f, %f)\n", sigma[i], psfClump.nStars, psfClump.nTotal, psfClump.nSigma, psfClump.X, psfClump.Y, sqrt(psfClump.X) / sigma[i], sqrt(psfClump.Y) / sigma[i]); 557 560 558 561 Rmin[i] = pmSourceMinKronRadius(sources, PSF_SN_LIM); -
trunk/psphot/src/psphotStackImageLoop.c
r31154 r32348 52 52 psMemDump("load"); 53 53 54 // PSF matching54 // Generate the 1st PSF-matched image set (larger target PSFs are generated by smoothing this image) 55 55 if (!psphotStackMatchPSFs (config, view)) { 56 56 psError(psErrorCodeLast(), false, "failure in psphotStackMatchPSFs for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout); -
trunk/psphot/src/psphotStackMatchPSFs.c
r31154 r32348 25 25 } 26 26 27 // loop over the available readouts (ignore chisq image)27 // loop over the available readouts 28 28 for (int i = 0; i < num; i++) { 29 // set up the PSF-matching parameters describing the input images 29 30 if (!psphotStackMatchPSFsPrepare (config, view, options, i)) { 30 31 psError (PSPHOT_ERR_CONFIG, false, "failed to set PSF matching options for entry %d", i); … … 33 34 } 34 35 35 // Generate target PSF36 // XXX convolve == false might not be valid at the moment 36 37 if (options->convolve) { 37 options->psf = psphotStackPSF(config, options->numCols, options->numRows, options->psfs, options->inputMask); 38 if (!options->psf) { 38 // Determine the 1st target PSF (either AUTO or defined by PSPHOT.STACK.TARGET.PSF.FWHM) 39 // NOTE: this also set the full list of target FWHMs (options->targetSeeing) 40 if (!psphotStackPSF(config, options)) { 39 41 psError(psErrorCodeLast(), false, "Unable to determine output PSF."); 40 42 return false; 41 43 } 42 psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "PSF.TARGET", PS_DATA_UNKNOWN, "Target PSF for stack", options->psf);43 options->targetSeeing = pmPSFtoFWHM(options->psf, 0.5 * options->numCols, 0.5 * options->numRows); // FWHM for target44 psLogMsg("psphotStack", PS_LOG_INFO, "Target seeing FWHM: %f\n", options->targetSeeing);45 46 // XXX is this needed to supply the psf to psphot??47 // pmChip *outChip = pmFPAfileThisChip(config->files, view, "PPSTACK.TARGET.PSF"); // Output chip48 // psMetadataAddPtr(outChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN, "Target PSF", options->psf);49 // outChip->data_exists = true;50 44 } 51 45 … … 63 57 64 58 // convolve the image to match desired PSF 59 // XXX is this code consistent with 'convolve' = false? 65 60 bool psphotStackMatchPSFsReadout (pmConfig *config, const pmFPAview *view, psphotStackOptions *options, int index) { 66 61 … … 109 104 saveMatchData(readoutOut, options, index); 110 105 } 111 rescaleData(readoutOut, config, options, index); 106 107 // renormalize the stack variances to have sigma = 1.0 108 if (!psphotStackRenormaliseVariance(config, readoutOut)) { 109 psError(psErrorCodeLast(), false, "Unable to renormalise variance."); 110 return false; 111 } 112 112 113 113 // save the output fwhm values in the readout->analysis. we may have / will have multiple output PSF sizes, 114 114 // so we save this in a vector. if the vector is not yet defined, create it 115 bool mdok = false; 116 psVector *fwhmValues = psMetadataLookupVector(&mdok, readoutOut->analysis, "STACK.PSF.FWHM.VALUES"); 117 if (!fwhmValues) { 118 fwhmValues = psVectorAllocEmpty(10, PS_TYPE_F32); 119 psMetadataAddVector(readoutOut->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues); 120 psFree(fwhmValues); // drops the extra copy 115 // NOTE: fwhmValues as defined here has 1 + nMatched PSF : 0 == unmatched 116 psVector *fwhmValues = psVectorAllocEmpty(10, PS_TYPE_F32); 117 psVectorAppend(fwhmValues, NAN); // XXX this corresponds to the unmatched image set 118 for (int i = 0; i < options->targetSeeing->n; i++) { 119 psVectorAppend(fwhmValues, options->targetSeeing->data.F32[i]); 121 120 } 122 psVectorAppend(fwhmValues, options->targetSeeing); 121 psMetadataAddVector(readoutSrc->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues); 122 psMetadataAddVector(readoutOut->analysis, PS_LIST_TAIL, "STACK.PSF.FWHM.VALUES", PS_META_REPLACE, "PSF sizes", fwhmValues); 123 psFree(fwhmValues); // drops the extra copy 123 124 124 125 return true; -
trunk/psphot/src/psphotStackMatchPSFsNext.c
r30624 r32348 1 1 # include "psphotInternal.h" 2 3 // NOTE : element 0 of fwhmValues if the unmatched image, 4 5 int psphotStackMatchPSFsEntries (pmConfig *config, const pmFPAview *view, const char *filerule) { 6 7 int nRadialEntries = 0; 8 9 // find the currently selected readout 10 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, 0); // File of interest 11 psAssert (file, "missing file?"); 12 13 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 14 psAssert (readout, "missing readout?"); 15 16 bool status = false; 17 psVector *fwhmValues = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES"); 18 if (!fwhmValues) { 19 return 1; 20 } 21 22 nRadialEntries = fwhmValues->n; 23 return nRadialEntries; 24 } 2 25 3 26 // smooth the input image to match the next target PSF … … 5 28 // and that the smoothing can use a 1D Gaussian kernel of width sqrt(TARGET^2 - CURRENT^2) 6 29 // each subsequent call 7 bool psphotStackMatchPSFsNext( bool *smoothAgain,pmConfig *config, const pmFPAview *view, const char *filerule, int lastSize)30 bool psphotStackMatchPSFsNext(pmConfig *config, const pmFPAview *view, const char *filerule, int lastSize) 8 31 { 9 bool status = true;10 11 // select the appropriate recipe information12 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);13 psAssert (recipe, "missing recipe?");14 15 psVector *fwhmValues = psMetadataLookupVector(&status, recipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); // Magnitude offsets16 if (!status) {17 // must not be a vector, only one value requested18 *smoothAgain = false;19 return true;20 }21 22 if (lastSize + 1 >= fwhmValues->n) {23 // all done with target FWHM values24 *smoothAgain = false;25 return true;26 }27 28 32 int num = psphotFileruleCount(config, filerule); 29 33 … … 33 37 // loop over the available readouts 34 38 for (int i = 0; i < num; i++) { 35 if (!psphotStackMatchPSFsNextReadout (config, view, filerule, i, recipe, fwhmValues,lastSize)) {36 psError (PSPHOT_ERR_CONFIG, false, "failed to smooth image %s (%d) to target PSF %f", filerule, i, fwhmValues->data.F32[lastSize+1]);39 if (!psphotStackMatchPSFsNextReadout (config, view, filerule, i, lastSize)) { 40 psError (PSPHOT_ERR_CONFIG, false, "failed to smooth image %s (%d) to target PSF", filerule, i); 37 41 psImageConvolveSetThreads(oldThreads); 38 42 return false; … … 44 48 } 45 49 46 bool psphotStackMatchPSFsNextReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, psMetadata *recipe, psVector *fwhmValues,int lastSize) {50 bool psphotStackMatchPSFsNextReadout (pmConfig *config, const pmFPAview *view, const char *filerule, int index, int lastSize) { 47 51 48 52 bool status = false; … … 58 62 psphotVisualShowImage(readout); 59 63 64 // select the appropriate recipe information 65 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 66 psAssert (recipe, "missing recipe?"); 67 60 68 // user-defined masks to test for good/bad pixels (build from recipe list if not yet set) 61 69 psImageMaskType maskVal = psMetadataLookupImageMask(&status, recipe, "MASK.PSPHOT"); // Mask value for bad pixels … … 66 74 psWarning("PEAKS_MIN_GAUSS is not set in recipe; using default value"); 67 75 minGauss = 0.5; 76 } 77 78 psVector *fwhmValues = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES"); 79 psAssert (fwhmValues, "need target PSFs"); 80 81 if (lastSize + 1 >= fwhmValues->n) { 82 return true; 68 83 } 69 84 … … 128 143 // psMetadataAddF32(readout->analysis, PS_LIST_TAIL, "SIGNIFICANCE_SCALE_FACTOR", PS_META_REPLACE, "Signicance scale factor", factor); 129 144 130 // save the output fwhm values in the readout->analysis. we may have / will have multiple output PSF sizes,131 // so we save this in a vector. if the vector is not yet defined, create it132 133 psVector *fwhmValuesOut = psMetadataLookupVector(&status, readout->analysis, "STACK.PSF.FWHM.VALUES");134 psAssert(fwhmValuesOut, "should already exist..");135 psVectorAppend(fwhmValuesOut, targetFWHM);136 137 145 // do not generate a PSF if we already were supplied one 138 146 pmPSF *psfOld = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF"); -
trunk/psphot/src/psphotStackMatchPSFsPrepare.c
r28013 r32348 4 4 bool determineSeeing (pmPSF *psf, psphotStackOptions *options, int index); 5 5 6 // set up the stacking parameters6 // set up the PSF-matching parameters describing the input images 7 7 bool psphotStackMatchPSFsPrepare (pmConfig *config, const pmFPAview *view, psphotStackOptions *options, int index) { 8 8 -
trunk/psphot/src/psphotStackMatchPSFsUtils.c
r31154 r32348 2 2 # define ARRAY_BUFFER 16 // Number to add to array at a time 3 3 4 // XXX better name 5 bool readImage(psImage **target, // Target for image 6 const char *name, // Name of FITS file 7 const pmConfig *config // Configuration 8 ) 9 { 10 psString resolved = pmConfigConvertFilename(name, config, false, false); // Resolved filename 11 psFits *fits = psFitsOpen(resolved, "r"); 12 psFree(resolved); 13 if (!fits) { 14 psError(PSPHOT_ERR_IO, false, "Unable to open previously produced image: %s", name); 15 return false; 16 } 17 psImage *image = psFitsReadImage(fits, psRegionSet(0,0,0,0), 0); // Image of interest 18 if (!image) { 19 psError(PSPHOT_ERR_IO, false, "Unable to read previously produced image: %s", name); 20 psFitsClose(fits); 21 return false; 22 } 23 psFitsClose(fits); 24 25 psFree(*target); 26 *target = image; 27 28 return true; 29 } 4 psVector *SetOptWidths (bool *optimum, psMetadata *recipe); 5 pmReadout *makeFakeReadout(pmConfig *config, pmReadout *raw, psArray *sources, pmPSF *psf, psImageMaskType maskVal, int fullSize); 6 bool saveMatchData (pmReadout *readout, psphotStackOptions *options, int index); 7 bool matchKernel(pmConfig *config, pmReadout *cnv, pmReadout *raw, psphotStackOptions *options, int index); 8 bool dumpImageDiff(pmReadout *readoutConv, pmReadout *readoutFake, pmReadout *readoutRef, int index, char *rootname); 9 bool dumpImage(pmReadout *readoutOut, pmReadout *readoutRef, int index, char *rootname); 30 10 31 11 // Get coordinates from a source … … 148 128 149 129 // Renormalise a readout's variance map 150 bool stackRenormaliseReadout(const pmConfig *config, // Configuration151 pmReadout *readout // Readout to renormalise130 bool psphotStackRenormaliseVariance(const pmConfig *config, // Configuration 131 pmReadout *readout // Readout to renormalise 152 132 ) 153 133 { … … 180 160 return pmReadoutVarianceRenormalise(readout, maskBad, num, minValid, maxValid); 181 161 } 182 183 // This is a hack to use the temporary convolved images and kernel generated previously.184 // This makes the 'matching' operation much faster, allowing debugging of the stack process easier.185 // It implicitly assumes the output root name is the same between invocations.186 187 # if (0)188 bool loadKernel (pmConfig *config, pmReadout *readoutCnv, psphotStackOptions *options, int index) {189 190 // Read the convolution kernel from the saved file191 pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PPSTACK.CONV.KERNEL", index);192 psAssert(file, "Require file");193 194 pmFPAview *view = pmFPAviewAlloc(0); // View to readout of interest195 view->chip = view->cell = view->readout = 0;196 psString filename = pmFPAfileNameFromRule(file->filerule, file, view); // Filename of interest197 198 // Read convolution kernel data199 psString resolved = pmConfigConvertFilename(filename, config, false, false); // Resolved filename200 psFree(filename);201 psFits *fits = psFitsOpen(resolved, "r"); // FITS file for subtraction kernel202 psFree(resolved);203 if (!fits || !pmReadoutReadSubtractionKernels(readoutCnv, fits)) {204 psError(PSPHOT_ERR_IO, false, "Unable to read previously produced kernel");205 psFitsClose(fits);206 return false;207 }208 psFitsClose(fits);209 210 // read the convolved pixels (image, mask, variance) -- names are pre-defined211 if (!readImage(&readoutCnv->image, options->convImages->data[index], config) ||212 !readImage(&readoutCnv->mask, options->convMasks->data[index], config) ||213 !readImage(&readoutCnv->variance, options->convVariances->data[index], config)) {214 psError(PSPHOT_ERR_IO, false, "Unable to read previously produced image.");215 return false;216 }217 218 // XXX ??? not sure what is happening here -- consult Paul219 psRegion *region = psMetadataLookupPtr(NULL, readoutCnv->analysis, PM_SUBTRACTION_ANALYSIS_REGION); // Convolution region220 pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, readoutCnv->analysis, PM_SUBTRACTION_ANALYSIS_KERNEL);221 222 pmSubtractionAnalysis(readoutCnv->analysis, NULL, kernels, region, readoutCnv->image->numCols, readoutCnv->image->numRows);223 224 psKernel *kernel = pmSubtractionKernel(kernels, 0.0, 0.0, false); // Convolution kernel225 226 // update the covariance matrix227 // XXX why is this needed if we have correctly read the saved data?228 bool oldThreads = psImageCovarianceSetThreads(true); // Old thread setting229 psKernel *covar = psImageCovarianceCalculate(kernel, readoutCnv->covariance); // Covariance matrix230 psImageCovarianceSetThreads(oldThreads);231 psFree(readoutCnv->covariance);232 readoutCnv->covariance = covar;233 psFree(kernel);234 return true;235 }236 # endif237 162 238 163 bool dumpImage(pmReadout *readoutOut, pmReadout *readoutRef, int index, char *rootname) { … … 362 287 widthsCopy = psVectorCopy(NULL, widths, PS_TYPE_F32); // Copy of kernel widths 363 288 364 // we need to register the FWHM values for use downstream365 pmSubtractionSetFWHMs(options->targetSeeing , options->inputSeeing->data.F32[index]);289 // we need to register the FWHM values for use by pmSubtraction code 290 pmSubtractionSetFWHMs(options->targetSeeing->data.F32[0], options->inputSeeing->data.F32[index]); 366 291 367 292 pmSubtractionParamScaleOptions(scale, scaleRef, scaleMin, scaleMax); … … 469 394 } 470 395 471 // Kernel normalisation for convolved readout472 bool renormKernel(pmReadout *readout, psphotStackOptions *options, int index) {473 474 double sum = 0.0; // Sum of chi^2475 int num = 0; // Number of measurements of chi^2476 psString regex = NULL; // Regular expression477 psStringAppend(®ex, "^%s$", PM_SUBTRACTION_ANALYSIS_NORM);478 psMetadataIterator *iter = psMetadataIteratorAlloc(readout->analysis, PS_LIST_HEAD, regex);479 psFree(regex);480 psMetadataItem *item = NULL;// Item from iteration481 while ((item = psMetadataGetAndIncrement(iter))) {482 assert(item->type == PS_TYPE_F32);483 float norm = item->data.F32; // Normalisation484 sum += norm;485 num++;486 }487 psFree(iter);488 float conv = sum/num; // Mean normalisation from convolution489 float stars = powf(10.0, -0.4 * options->norm->data.F32[index]); // Normalisation from stars490 float renorm = stars / conv; // Renormalisation to apply491 psLogMsg("psphotStack", PS_LOG_INFO, "Renormalising image %d by %f (kernel: %f, stars: %f)\n", index, renorm, conv, stars);492 493 psBinaryOp(readout->image, readout->image, "*", psScalarAlloc(renorm, PS_TYPE_F32));494 psBinaryOp(readout->variance, readout->variance, "*", psScalarAlloc(PS_SQR(renorm), PS_TYPE_F32));495 return true;496 }497 498 // adjust scaling for readout (remove background, ..., determine weighting)499 bool rescaleData(pmReadout *readout, pmConfig *config, psphotStackOptions *options, int index) {500 501 psMetadata *stackRecipe = psMetadataLookupMetadata(NULL, config->recipes, "PPSTACK"); // ppStack recipe502 psAssert(stackRecipe, "We've thrown an error on this before.");503 504 // Look up appropriate values from the ppSub recipe505 psMetadata *subRecipe = psMetadataLookupMetadata(NULL, config->recipes, "PPSUB"); // PPSUB recipe506 psAssert(subRecipe, "recipe missing");507 508 psString maskValStr = psMetadataLookupStr(NULL, subRecipe, "MASK.VAL"); // Name of bits to mask going in509 psString maskBadStr = psMetadataLookupStr(NULL, stackRecipe, "MASK.BAD"); // Name of bits to mask for bad510 511 psImageMaskType maskVal = pmConfigMaskGet(maskValStr, config); // Bits to mask going in to pmSubtractionMatch512 psImageMaskType maskBad = pmConfigMaskGet(maskBadStr, config); // Bits to mask for bad pixels513 514 // Ensure the background value is zero515 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background516 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator517 518 // XXX why is this in config->arguments and not recipe?519 if (!psMetadataLookupBool(NULL, config->arguments, "PPSTACK.SKIP.BG.SUB")) {520 if (!psImageBackground(bg, NULL, readout->image, readout->mask, maskVal | maskBad, rng)) {521 psAbort("Can't measure background for image.");522 // XXX we used to clear error: why is this acceptable? psErrorClear();523 }524 525 float value = psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN);526 float stdev = psStatsGetValue(bg, PS_STAT_ROBUST_STDEV);527 528 psLogMsg("psphotStack", PS_LOG_INFO, "Correcting convolved image background by %lf (+/- %lf)", value, stdev);529 psBinaryOp(readout->image, readout->image, "-", psScalarAlloc(value, PS_TYPE_F32));530 }531 532 if (!stackRenormaliseReadout(config, readout)) {533 psFree(rng);534 psFree(bg);535 return false;536 }537 538 // Measure the variance level for the weighting539 if (psMetadataLookupBool(NULL, stackRecipe, "WEIGHTS")) {540 if (!psImageBackground(bg, NULL, readout->variance, readout->mask, maskVal | maskBad, rng)) {541 psError(PSPHOT_ERR_DATA, false, "Can't measure mean variance for image.");542 psFree(rng);543 psFree(bg);544 return false;545 }546 options->weightings->data.F32[index] = 1.0 / (psStatsGetValue(bg, PS_STAT_ROBUST_MEDIAN) * psImageCovarianceFactor(readout->covariance));547 } else {548 options->weightings->data.F32[index] = 1.0;549 }550 psLogMsg("psphotStack", PS_LOG_INFO, "Weighting for image %d is %f\n", index, options->weightings->data.F32[index]);551 552 psFree(rng);553 psFree(bg);554 return true;555 }556 557 396 # define NOISE_FRACTION 0.01 // Set minimum flux to this fraction of noise 558 397 # define SOURCE_MASK (PM_SOURCE_MODE_FAIL | PM_SOURCE_MODE_DEFECT | PM_SOURCE_MODE_SATURATED | PM_SOURCE_MODE_CR_LIMIT | PM_SOURCE_MODE_EXT_LIMIT) // Mask to apply to input sources -
trunk/psphot/src/psphotStackObjects.c
r28013 r32348 47 47 return true; 48 48 } 49 50 // mark good vs bad objects 51 bool psphotStackObjectsSelectForAnalysis (pmConfig *config, const pmFPAview *view, const char *filerule, psArray *objects) { 52 53 bool status = false; 54 55 // find the currently selected readout 56 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filerule, 0); // use the 0-index image to represent the image area 57 psAssert (file, "missing file?"); 58 59 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa); 60 psAssert (readout, "missing readout?"); 61 62 // select the appropriate recipe information 63 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 64 psAssert (recipe, "missing recipe?"); 65 66 // option to limit analysis to a specific region 67 char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION"); 68 psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region)); 69 if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined"); 70 71 // S/N limit to perform full non-linear fits 72 float SN_LIM = psMetadataLookupF32 (&status, recipe, "EXTENDED_SOURCE_SN_LIM"); 73 74 bool doPetroStars = psMetadataLookupBool (&status, recipe, "PETROSIAN_FOR_STARS"); 75 76 for (int i = 0; i < objects->n; i++) { 77 pmPhotObj *object = objects->data[i]; 78 if (!object) continue; 79 if (!object->sources) continue; 80 81 // we check each source for an object and keep the object if any source is valid 82 83 bool keepObject = false; 84 for (int j = 0; j < object->sources->n; j++) { 85 86 pmSource *source = object->sources->data[j]; 87 if (!source) continue; 88 if (!source->peak) continue; 89 90 // skip PSF-like and non-astronomical objects 91 if (source->type == PM_SOURCE_TYPE_DEFECT) continue; 92 if (source->type == PM_SOURCE_TYPE_SATURATED) continue; 93 if (source->mode & PM_SOURCE_MODE_DEFECT) continue; 94 if (source->mode & PM_SOURCE_MODE_SATSTAR) continue; 95 96 // optionally allow non-extended objects to get petrosians as well 97 if (!doPetroStars) { 98 if (!(source->mode & PM_SOURCE_MODE_EXT_LIMIT)) continue; 99 if (source->type == PM_SOURCE_TYPE_STAR) continue; 100 } 101 102 // limit selection to some SN limit 103 // assert (source->peak); // how can a source not have a peak? 104 // limit selection to some SN limit 105 bool skipSource = false; 106 if (source->mode & PM_SOURCE_MODE_EXT_LIMIT) { 107 skipSource = (source->moments->KronFlux < SN_LIM * source->moments->KronFluxErr); 108 } else { 109 skipSource = (sqrt(source->peak->detValue) < SN_LIM); 110 } 111 if (skipSource) continue; 112 113 // limit selection by analysis region (this automatically apply 114 if (source->peak->x < AnalysisRegion.x0) continue; 115 if (source->peak->y < AnalysisRegion.y0) continue; 116 if (source->peak->x > AnalysisRegion.x1) continue; 117 if (source->peak->y > AnalysisRegion.y1) continue; 118 119 keepObject = true; 120 } 121 122 for (int j = 0; j < object->sources->n; j++) { 123 pmSource *source = object->sources->data[j]; 124 if (!source) continue; 125 if (!source->peak) continue; 126 127 // we have to set a bit in either case to tell psphotExtendedSourceAnalysis to 128 // avoid the single-detection tests 129 130 if (keepObject) { 131 source->tmpFlags |= PM_SOURCE_TMPF_STACK_KEEP; 132 source->tmpFlags &= ~PM_SOURCE_TMPF_STACK_SKIP; 133 } else { 134 source->tmpFlags |= PM_SOURCE_TMPF_STACK_SKIP; 135 source->tmpFlags &= ~PM_SOURCE_TMPF_STACK_KEEP; 136 } 137 } 138 } 139 140 psLogMsg ("psphot", PS_LOG_INFO, "marked good vs bad objects\n"); 141 return true; 142 } -
trunk/psphot/src/psphotStackOptions.c
r28160 r32348 19 19 psFree (options->norm); 20 20 psFree (options->matchChi2); 21 psFree (options-> weightings);21 psFree (options->targetSeeing); 22 22 23 23 return; … … 36 36 options->convolve = false; 37 37 options->convolveSource = PSPHOT_CNV_SRC_NONE; 38 options->targetSeeing = N AN;38 options->targetSeeing = NULL; 39 39 40 40 options->psfs = psArrayAlloc(num); … … 47 47 options->norm = psVectorAlloc(num, PS_TYPE_F32); 48 48 options->matchChi2 = psVectorAlloc(num, PS_TYPE_F32); // chi^2 for stamps when matching 49 options->weightings = psVectorAlloc(num, PS_TYPE_F32); // Combination weightings for images (1/noise^2)50 49 51 50 psVectorInit(options->inputMask, 0); … … 53 52 psVectorInit(options->norm, NAN); 54 53 psVectorInit(options->matchChi2, NAN); 55 psVectorInit(options->weightings, NAN);56 54 57 55 return options; -
trunk/psphot/src/psphotStackPSF.c
r31154 r32348 1 1 # include "psphotInternal.h" 2 2 3 pmPSF *psphotStackPSF(const pmConfig *config, int numCols, int numRows, const psArray *psfs, const psVector *inputMask) 4 { 3 // determine the 1st target PSF (either AUTO or defined by PSPHOT.STACK.TARGET.PSF.FWHM) 4 bool psphotStackPSF(const pmConfig *config, psphotStackOptions *options) { 5 5 6 bool mdok = false; 6 pmPSF *psf = NULL; 7 8 int numCols = options->numCols; 9 int numRows = options->numRows; 10 psArray *psfs = options->psfs; 11 psVector *inputMask = options->inputMask; 7 12 8 13 // Get the recipe values … … 17 22 18 23 char *psfModel = psMetadataLookupStr(NULL, recipe, "PSF.MODEL"); // Model for PSF 24 25 options->targetSeeing = psVectorAllocEmpty(4, PS_TYPE_F32); 19 26 20 27 if (autoPSF) { … … 38 45 39 46 // Solve for the target PSF 40 psf = pmPSFEnvelope(numCols, numRows, psfs, psfInstances, psfRadius, psfModel, psfOrder, psfOrder, maskVal);41 if (! psf) {47 options->psf = pmPSFEnvelope(numCols, numRows, psfs, psfInstances, psfRadius, psfModel, psfOrder, psfOrder, maskVal); 48 if (!options->psf) { 42 49 psError(PSPHOT_ERR_PSF, false, "Unable to determine output PSF."); 43 return NULL;50 return false; 44 51 } 45 52 46 } else { 47 48 // externally-defined PSF 49 // XXX need to test for compatibility of target with inputs 50 51 float targetFWHM = psMetadataLookupF32 (&mdok, psphotRecipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); 52 if (!mdok) { 53 psVector *fwhmValues = psMetadataLookupVector(&mdok, psphotRecipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); // Magnitude offsets 54 psAssert (mdok, "missing psphot recipe value PSPHOT.STACK.TARGET.PSF.FWHM"); 55 targetFWHM = fwhmValues->data.F32[0]; 56 } 57 58 // measured scale factors (fwhm = Sxx * 2.35 * scaleFactor / sqrt(2.0)) 59 // GAUSS : 1.000 60 // PGAUSS : 1.006 61 // QGAUSS : 1.151 62 // RGAUSS : 0.883 63 // PS1_V1 : 1.134 64 65 float scaleFactor = NAN; 66 if (!strcmp(psfModel, "PS_MODEL_GAUSS")) { 67 scaleFactor = 1.000; 68 } 69 if (!strcmp(psfModel, "PS_MODEL_PGAUSS")) { 70 scaleFactor = 1.0006; 71 } 72 if (!strcmp(psfModel, "PS_MODEL_QGAUSS")) { 73 scaleFactor = 1.151; 74 } 75 if (!strcmp(psfModel, "PS_MODEL_RGAUSS")) { 76 scaleFactor = 0.883; 77 } 78 if (!strcmp(psfModel, "PS_MODEL_PS1_V1")) { 79 scaleFactor = 1.134; 80 } 81 psAssert (isfinite(scaleFactor), "invalid model for PSF"); 82 83 float Sxx = sqrt(2.0)*targetFWHM / 2.35 / scaleFactor; 84 85 // XXX probably should make the model type (and par 7) optional from recipe 86 // psf = pmPSFBuildSimple(psfModel, Sxx, Sxx, 0.0, 1.0); 87 psf = pmPSFBuildSimple(psfModel, Sxx, Sxx, 0.0, 0.2); 88 if (!psf) { 89 psError(PSPHOT_ERR_PSF, false, "Unable to build dummy PSF."); 90 return NULL; 91 } 53 psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "PSF.TARGET", PS_DATA_UNKNOWN, "Target PSF for stack", options->psf); 54 float targetSeeing = pmPSFtoFWHM(options->psf, 0.5 * options->numCols, 0.5 * options->numRows); // FWHM for target 55 psVectorAppend(options->targetSeeing, targetSeeing); 56 psLogMsg("psphotStack", PS_LOG_INFO, "Target seeing FWHM (auto-scaled): %f\n", targetSeeing); 57 return true; 92 58 } 93 59 94 return psf; 60 // externally-defined PSF 61 // XXX need to test for compatibility of target with inputs 62 63 // is a single target FWHM specified, or a set of values? set up the vector options->targetSeeing and the local 1st value 64 float targetSeeing = psMetadataLookupF32 (&mdok, psphotRecipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); 65 if (!mdok) { 66 psVector *fwhmValues = psMetadataLookupVector(&mdok, psphotRecipe, "PSPHOT.STACK.TARGET.PSF.FWHM"); // Magnitude offsets 67 psAssert (mdok, "missing psphot recipe value PSPHOT.STACK.TARGET.PSF.FWHM"); 68 for (int i = 0; i < fwhmValues->n; i++) { 69 psVectorAppend(options->targetSeeing, fwhmValues->data.F32[i]); 70 } 71 targetSeeing = fwhmValues->data.F32[0]; 72 } else { 73 psVectorAppend(options->targetSeeing, targetSeeing); 74 } 75 76 // measured scale factors (fwhm = Sxx * 2.35 * scaleFactor / sqrt(2.0)) 77 // GAUSS : 1.000 78 // PGAUSS : 1.006 79 // QGAUSS : 1.151 80 // RGAUSS : 0.883 81 // PS1_V1 : 1.134 82 83 float scaleFactor = NAN; 84 if (!strcmp(psfModel, "PS_MODEL_GAUSS")) { 85 scaleFactor = 1.000; 86 } 87 if (!strcmp(psfModel, "PS_MODEL_PGAUSS")) { 88 scaleFactor = 1.0006; 89 } 90 if (!strcmp(psfModel, "PS_MODEL_QGAUSS")) { 91 scaleFactor = 1.151; 92 } 93 if (!strcmp(psfModel, "PS_MODEL_RGAUSS")) { 94 scaleFactor = 0.883; 95 } 96 if (!strcmp(psfModel, "PS_MODEL_PS1_V1")) { 97 scaleFactor = 1.134; 98 } 99 psAssert (isfinite(scaleFactor), "invalid model for PSF"); 100 101 float Sxx = sqrt(2.0)*targetSeeing / 2.35 / scaleFactor; 102 103 // XXX probably should make the model type (and par 7) optional from recipe 104 // psf = pmPSFBuildSimple(psfModel, Sxx, Sxx, 0.0, 1.0); 105 options->psf = pmPSFBuildSimple(psfModel, Sxx, Sxx, 0.0, 0.2); 106 if (!options->psf) { 107 psError(PSPHOT_ERR_PSF, false, "Unable to build dummy PSF."); 108 return false; 109 } 110 111 psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "PSF.TARGET", PS_DATA_UNKNOWN, "Target PSF for stack", options->psf); 112 psLogMsg("psphotStack", PS_LOG_INFO, "Target seeing FWHM (1 of %ld): %f\n", options->targetSeeing->n, targetSeeing); 113 return true; 95 114 } -
trunk/psphot/src/psphotStackReadout.c
r31154 r32348 44 44 bool psphotStackReadout (pmConfig *config, const pmFPAview *view) { 45 45 46 // measure the total elapsed time in psphotReadout. dtime is the elapsed time used jointly 47 // by the multiple threads, not the total time used by all threads. 46 48 psTimerStart ("psphotReadout"); 47 49 … … 56 58 // optional break-point for processing 57 59 char *breakPt = psMetadataLookupStr (NULL, recipe, "BREAK_POINT"); 58 PS_ASSERT_PTR_NON_NULL (breakPt, false); 59 60 // XXX or do I set OUT to be a pmFPAfile pointing at the input of interest? 60 psAssert (breakPt, "configuration error: set BREAK_POINT"); 61 62 // we have 3 relevant files: RAW (unconvolved), CNV (convolved stack), OUT (psf-matched stack) 63 // select which image (RAW or CNV) is used for analysis (RAW always used for detection) 61 64 bool useRaw = psMetadataLookupBool (NULL, recipe, "PSPHOT.STACK.USE.RAW"); 62 65 char *STACK_SRC = useRaw ? STACK_RAW : STACK_CNV; 63 char *STACK_DET = STACK_RAW; // XXX optionally allow this to be CNV? 64 65 // we have 3 relevant files: RAW, CNV, OUT 66 char *STACK_DET = STACK_RAW; 66 67 67 68 // set the photcode for each image … … 71 72 } 72 73 73 // Generate the mask and weight images 74 // XXX this should be done before we perform the convolutions 74 // Generate the mask and weight images (if not supplied) and set mask bits 75 75 if (!psphotSetMaskAndVariance (config, view, STACK_DET)) { 76 76 return psphotReadoutCleanup (config, view, STACK_SRC); … … 80 80 } 81 81 82 // XXX I think this is not defined correctly for an array of images. 83 // XXX I probably need to subtract the model (same model?) for both RAW and OUT. 84 // XXX But, probably not a problem in practice since the stacks are constructed with 0.0 mean level. 85 82 86 // generate a background model (median, smoothed image) 83 // XXX I think this is not defined correctly for an array of images.84 // XXX probably need to subtract the model (same model?) for both RAW and OUT85 87 if (!psphotModelBackground (config, view, STACK_DET)) { 86 88 return psphotReadoutCleanup (config, view, STACK_SRC); … … 93 95 } 94 96 97 // also make the chisq detection image 95 98 if (!psphotStackChisqImage(config, view, STACK_DET, STACK_SRC)) { 96 99 psError (PSPHOT_ERR_UNKNOWN, false, "failure to generate chisq image"); … … 109 112 } 110 113 111 // copy the detections from DET to SRC114 // if DET and SRC are different images, copy the detections from DET to SRC 112 115 if (strcmp(STACK_SRC, STACK_DET)) { 113 116 if (!psphotCopySources (config, view, STACK_SRC, STACK_DET)) { … … 122 125 return psphotReadoutCleanup (config, view, STACK_SRC); 123 126 } 124 125 if (!strcasecmp (breakPt, "TEST1")) { 126 return psphotReadoutCleanup (config, view, STACK_SRC); 127 } 128 127 if (!strcasecmp (breakPt, "PEAKS")) { 128 return psphotReadoutCleanup (config, view, STACK_SRC); 129 } 129 130 psMemDump("sourcestats"); 130 131 131 // generate the objects (object unify the sources from the different images) 132 // classify sources based on moments, brightness 133 // only run this on detections from the input images, not chisq image 134 if (!psphotRoughClass (config, view, STACK_SRC)) { 135 psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough classifications"); 136 return psphotReadoutCleanup (config, view, STACK_SRC); 137 } 138 139 // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources) 140 // only run this on detections from the input images, not chisq image 141 if (!psphotImageQuality (config, view, STACK_SRC)) { // pass 1 142 psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality"); 143 return psphotReadoutCleanup (config, view, STACK_SRC); 144 } 145 if (!strcasecmp (breakPt, "MOMENTS")) { 146 return psphotReadoutCleanup (config, view, STACK_SRC); 147 } 148 149 // use bright stellar objects to measure PSF 150 if (!psphotChoosePSF (config, view, STACK_SRC, true)) { // pass 1 151 psLogMsg ("psphot", 3, "failure to construct a psf model"); 152 return psphotReadoutCleanup (config, view, STACK_SRC); 153 } 154 if (!strcasecmp (breakPt, "PSFMODEL")) { 155 return psphotReadoutCleanup (config, view, STACK_SRC); 156 } 157 158 // construct an initial model for each object, set the radius to fitRadius, set circular fit mask 159 psphotGuessModels (config, view, STACK_SRC); 160 161 // merge the newly selected sources into the existing list 162 // NOTE: merge OLD and NEW 163 psphotMergeSources (config, view, STACK_SRC); 164 165 // linear PSF fit to source peaks, subtract the models from the image (in PSF mask) 166 // XXX why do this as a stack operation? 167 // psphotFitSourcesLinearStack (config, objects, false); 168 psphotFitSourcesLinear (config, view, STACK_SRC, false); 169 psphotStackVisualFilerule(config, view, STACK_SRC); 170 171 // re-measure the kron mags with models subtracted. this pass starts with a circular 172 // window of size PSF_MOMENTS_RADIUS (same window used to measure the psf-scale moments) 173 // but iterates to an appropriately larger size 174 psphotKronIterate(config, view, STACK_SRC); 175 176 // identify CRs and extended sources 177 psphotSourceSize (config, view, STACK_SRC, true); 178 179 // non-linear PSF and EXT fit to brighter sources 180 // replace model flux, adjust mask as needed, fit, subtract the models (full stamp) 181 psphotBlendFit (config, view, STACK_SRC); // pass 1 (detections->allSources) 182 183 // replace all sources 184 psphotReplaceAllSources (config, view, STACK_SRC); // pass 1 (detections->allSources) 185 186 // linear fit to include all sources (subtract again) 187 // NOTE : apply to ALL sources (extended + psf) 188 psphotFitSourcesLinear (config, view, STACK_SRC, true); // pass 2 (detections->allSources) 189 190 // if we only do one pass, skip to extended source analysis 191 if (!strcasecmp (breakPt, "PASS1")) goto pass1finish; 192 193 // NOTE: possibly re-measure background model here with objects subtracted / or masked 194 195 // NOTE: this block performs the 2nd pass low-significance PSF detection stage 196 { 197 // add noise for subtracted objects 198 psphotAddNoise (config, view, STACK_DET); // pass 1 (detections->allSources) 199 200 // find fainter sources 201 // NOTE: finds new peaks and new footprints, OLD and FULL set are saved on detections 202 psphotFindDetections (config, view, STACK_DET, false); // pass 2 (detections->peaks, detections->footprints) 203 204 // remove noise for subtracted objects (ie, return to normal noise level) 205 // NOTE: this needs to operate only on the OLD sources 206 psphotSubNoise (config, view, STACK_DET); // pass 1 (detections->allSources) 207 208 // if DET and SRC are different images, copy the detections from DET to SRC 209 if (strcmp(STACK_SRC, STACK_DET)) { 210 // XXX how does this handle 1st vs 2nd pass sources? 211 if (!psphotCopySources (config, view, STACK_SRC, STACK_DET)) { 212 psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis"); 213 return psphotReadoutCleanup (config, view, STACK_SRC); 214 } 215 } 216 217 // define new sources based on only the new peaks & measure moments 218 // NOTE: new sources are saved on detections->newSources 219 psphotSourceStats (config, view, STACK_SRC, false); // pass 2 (detections->newSources) 220 221 // set source type 222 // NOTE: apply only to detections->newSources 223 if (!psphotRoughClass (config, view, STACK_SRC)) { // pass 2 (detections->newSources) 224 psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image"); 225 return psphotReadoutCleanup (config, view, STACK_SRC); 226 } 227 228 // create full input models, set the radius to fitRadius, set circular fit mask 229 // NOTE: apply only to detections->newSources 230 psphotGuessModels (config, view, STACK_SRC); // pass 2 (detections->newSources) 231 232 // replace all sources so fit below applies to all at once 233 // NOTE: apply only to OLD sources (which have been subtracted) 234 psphotReplaceAllSources (config, view, STACK_SRC); // pass 2 235 236 // merge the newly selected sources into the existing list 237 // NOTE: merge OLD and NEW 238 // XXX check on free of sources... 239 psphotMergeSources (config, view, STACK_SRC); // (detections->newSources + detections->allSources -> detections->allSources) 240 241 // NOTE: apply to ALL sources 242 psphotFitSourcesLinear (config, view, STACK_SRC, true); // pass 3 (detections->allSources) 243 } 244 245 pass1finish: 246 247 // re-measure the kron mags with models subtracted 248 // psphotKronMasked(config, view, STACK_SRC); 249 psphotKronIterate(config, view, STACK_SRC); 250 251 // measure source size for the remaining sources 252 // NOTE: applies only to NEW (unmeasured) sources 253 psphotSourceSize (config, view, STACK_SRC, false); // pass 2 (detections->allSources) 254 255 psMemDump("psfstats"); 256 257 // generate the objects (objects unify the sources from the different images) 132 258 // XXX this could just match the detections for the chisq image, and not bother measuring the 133 259 // source stats in that case... 134 260 psArray *objects = psphotMatchSources (config, view, STACK_SRC); 135 136 261 psMemDump("matchsources"); 137 262 138 if (!strcasecmp (breakPt, "TEST2")) {139 psFree(objects);140 return psphotReadoutCleanup (config, view, STACK_SRC);141 }142 143 // construct sources for the newly-generated sources (from other images)144 if (!psphotSourceStats (config, view, STACK_SRC, false)) { // pass 1145 psFree(objects);146 psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources");147 return psphotReadoutCleanup (config, view, STACK_SRC);148 }149 150 psMemDump("sourcestats");151 152 // find blended neighbors of very saturated stars (detections->newSources)153 // if (!psphotDeblendSatstars (config, view)) {154 // psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis");155 // return psphotReadoutCleanup (config, view, STACK_SRC);156 // }157 158 // mark blended peaks PS_SOURCE_BLEND (detections->newSources)159 // if (!psphotBasicDeblend (config, view)) {160 // psError (PSPHOT_ERR_UNKNOWN, false, "failed on deblend analysis");161 // return psphotReadoutCleanup (config, view, STACK_SRC);162 // }163 164 // classify sources based on moments, brightness165 // only run this on detections from the input images, not chisq image166 if (!psphotRoughClass (config, view, STACK_SRC)) {167 psFree(objects);168 psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough classifications");169 return psphotReadoutCleanup (config, view, STACK_SRC);170 }171 // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources)172 // only run this on detections from the input images, not chisq image173 if (!psphotImageQuality (config, view, STACK_SRC)) { // pass 1174 psFree(objects);175 psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality");176 return psphotReadoutCleanup (config, view, STACK_SRC);177 }178 if (!strcasecmp (breakPt, "MOMENTS")) {179 psFree(objects);180 return psphotReadoutCleanup (config, view, STACK_SRC);181 }182 183 // use bright stellar objects to measure PSF if we were supplied a PSF for any input file,184 // this step is skipped185 if (!psphotChoosePSF (config, view, STACK_SRC, true)) { // pass 1186 psFree(objects);187 psLogMsg ("psphot", 3, "failure to construct a psf model");188 return psphotReadoutCleanup (config, view, STACK_SRC);189 }190 if (!strcasecmp (breakPt, "PSFMODEL")) {191 psFree(objects);192 return psphotReadoutCleanup (config, view, STACK_SRC);193 }194 195 // construct an initial model for each object, set the radius to fitRadius, set circular fit mask196 psphotGuessModels (config, view, STACK_SRC);197 198 // merge the newly selected sources into the existing list199 // NOTE: merge OLD and NEW200 psphotMergeSources (config, view, STACK_SRC);201 202 // linear PSF fit to source peaks, subtract the models from the image (in PSF mask)203 psphotFitSourcesLinearStack (config, objects, FALSE);204 psphotStackVisualFilerule(config, view, STACK_SRC);205 206 // identify CRs and extended sources207 psphotSourceSize (config, view, STACK_SRC, TRUE);208 209 // XXX do we want to do a preliminary (unconvolved) model fit here, and then210 // do a second detection pass? (like standard psphot)211 212 // measure aperture photometry corrections213 if (!psphotApResid (config, view, STACK_SRC)) {214 psFree (objects);215 psLogMsg ("psphot", 3, "failed on psphotApResid");216 return psphotReadoutCleanup (config, view, STACK_SRC);217 }218 219 psMemDump("psfstats");220 221 263 psphotStackObjectsUnifyPosition (objects); 222 264 265 psphotStackObjectsSelectForAnalysis (config, view, STACK_SRC, objects); 266 223 267 // measure elliptical apertures, petrosians (objects sorted by S/N) 224 psphotExtendedSourceAnalysisByObject (config, objects, view, STACK_SRC); // pass 1 (detections->allSources) 268 // psphotExtendedSourceAnalysisByObject (config, objects, view, STACK_SRC); // pass 1 (detections->allSources) 269 psphotExtendedSourceAnalysis (config, view, STACK_SRC); // pass 1 (detections->allSources) 225 270 226 271 // measure non-linear extended source models (exponential, deVaucouleur, Sersic) (sources sorted by S/N) 227 272 psphotExtendedSourceFits (config, view, STACK_SRC); // pass 1 (detections->allSources) 228 229 // calculate source magnitudes230 psphotMagnitudes(config, view, STACK_SRC);231 273 232 274 // create source children for the OUT filerule (for radial aperture photometry) … … 238 280 } 239 281 282 // measure circular, radial apertures (objects sorted by S/N) 283 // XXX can we just use psphotRadialApertures 284 // XXX make sure the headers are consistent with this (which PSF convolutions, ie mark 'none') 285 // psphotRadialAperturesByObject (config, objectsRadial, view, STACK_SRC, nMatchedPSF); 286 psphotRadialApertures (config, view, STACK_SRC, 0); // XXX entry 0 == unmatched? 240 287 psMemDump("extmeas"); 241 288 242 bool smoothAgain = true; 243 for (int nMatchedPSF = 0; smoothAgain; nMatchedPSF++) { 289 int nRadialEntries = psphotStackMatchPSFsEntries(config, view, STACK_OUT); 290 291 for (int entry = 1; entry < nRadialEntries; entry++) { 292 // NOTE: entry 0 is the unmatched image set 244 293 245 294 // re-measure the PSF for the smoothed image (using entries in 'allSources') … … 253 302 254 303 // measure circular, radial apertures (objects sorted by S/N) 255 psphotRadialAperturesByObject (config, objectsRadial, view, STACK_OUT, nMatchedPSF); 304 // entry 0 == unmatched? pass entry + 1? 305 psphotRadialApertures (config, view, STACK_OUT, entry); 256 306 257 307 // replace the flux in the image so it is returned to its original state … … 259 309 260 310 // smooth to the next FWHM, or set 'smoothAgain' to false if no more 261 psphotStackMatchPSFsNext( &smoothAgain, config, view, STACK_OUT, nMatchedPSF);311 psphotStackMatchPSFsNext(config, view, STACK_OUT, entry); 262 312 psMemDump("matched"); 263 313 } 264 314 265 if (0 && !psphotEfficiency(config, view, STACK_OUT)) { 315 // measure aperture photometry corrections 316 if (!psphotApResid (config, view, STACK_SRC)) { 317 psFree (objects); 318 psLogMsg ("psphot", 3, "failed on psphotApResid"); 319 return psphotReadoutCleanup (config, view, STACK_SRC); 320 } 321 322 // calculate source magnitudes 323 psphotMagnitudes(config, view, STACK_SRC); 324 325 if (0 && !psphotEfficiency(config, view, STACK_DET)) { 266 326 psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources"); 267 327 psErrorClear(); -
trunk/psphot/src/psphotSubtractBackground.c
r31154 r32348 103 103 psphotSaveImage (NULL, image, name); 104 104 } 105 psLogMsg ("psphot", PS_LOG_ INFO, "subtracted background model: %f sec\n", psTimerMark ("psphot.background"));105 psLogMsg ("psphot", PS_LOG_WARN, "subtracted background model: %f sec\n", psTimerMark ("psphot.background")); 106 106 107 107 // the pmReadout selected in this function are all view on entries in config->files
Note:
See TracChangeset
for help on using the changeset viewer.
