Changeset 28782
- Timestamp:
- Jul 29, 2010, 2:36:33 PM (16 years ago)
- Location:
- branches/eam_branches/ipp-20100621/psphot/src
- Files:
-
- 7 edited
-
psphot.h (modified) (3 diffs)
-
psphotAddNoise.c (modified) (4 diffs)
-
psphotBlendFit.c (modified) (1 diff)
-
psphotExtendedSourceFits.c (modified) (3 diffs)
-
psphotGuessModels.c (modified) (1 diff)
-
psphotRadiusChecks.c (modified) (9 diffs)
-
psphotSourceFits.c (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20100621/psphot/src/psphot.h
r28702 r28782 180 180 181 181 // functions to set the correct source pixels 182 bool psphotInitRadiusPSF(const psMetadata *recipe, const psMetadata *analysis, const pmModelType type); 182 bool psphotInitRadiusPSF (psMetadata *recipe, pmReadout *readout); 183 bool psphotInitRadiusEXT (psMetadata *recipe, pmReadout *readout); 183 184 184 185 bool psphotCheckRadiusPSF (pmReadout *readout, pmSource *source, pmModel *model, psImageMaskType markVal); 185 186 bool psphotCheckRadiusPSFBlend (pmReadout *readout, pmSource *source, pmModel *model, psImageMaskType markVal, float dR); 186 bool psphotInitRadiusEXT (psMetadata *recipe, pmModelType type); 187 bool psphotCheckRadiusEXT (pmReadout *readout, pmSource *source, pmModel *model, psImageMaskType markVal); 188 float psphotSetRadiusEXT (pmReadout *readout, pmSource *source, psImageMaskType markVal); 187 bool psphotSetRadiusFootprint (float *radius, pmReadout *readout, pmSource *source, psImageMaskType markVal, float factor); 188 bool psphotSetRadiusModel (pmModel *model, pmReadout *readout, pmSource *source, psImageMaskType markVal, bool deep); 189 189 190 190 bool psphotDumpMoments (psMetadata *recipe, psArray *sources); … … 202 202 // functions to support the source fitting process 203 203 bool psphotInitLimitsPSF (psMetadata *recipe, pmReadout *readout); 204 bool psphotInitLimitsEXT (psMetadata *recipe );204 bool psphotInitLimitsEXT (psMetadata *recipe, pmReadout *readout); 205 205 bool psphotFitBlend (pmReadout *readout, pmSource *source, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal); 206 206 bool psphotFitBlob (pmReadout *readout, pmSource *source, psArray *sources, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal); … … 426 426 bool psphotStackObjectsUnifyPosition (psArray *objects); 427 427 428 bool psphotFitSersicIndexPCM (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 428 bool psphotFitSersicIndex (pmModel *model, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal); 429 430 bool psphotFitSersicIndexPCM (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 429 431 pmModel *psphotFitPCM (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal, int psfSize); 430 432 -
branches/eam_branches/ipp-20100621/psphot/src/psphotAddNoise.c
r28013 r28782 34 34 35 35 bool status = false; 36 psEllipseShape oldshape;37 psEllipseShape newshape;38 psEllipseAxes axes;39 36 40 37 // find the currently selected readout … … 78 75 } 79 76 77 psphotSaveImage (NULL, readout->variance, "test.var0.fits"); 78 80 79 // loop over all source 81 80 for (int i = 0; i < sources->n; i++) { … … 86 85 if (!(source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED)) continue; 87 86 88 // select appropriate model 89 pmModel *model = pmSourceGetModel (NULL, source); 90 if (model == NULL) continue; // model must be defined 91 92 if (add) { 93 psTrace ("psphot", 4, "adding noise for object at %f,%f\n", model->params->data.F32[PM_PAR_XPOS], model->params->data.F32[PM_PAR_YPOS]); 94 } else { 95 psTrace ("psphot", 4, "remove noise for object at %f,%f\n", model->params->data.F32[PM_PAR_XPOS], model->params->data.F32[PM_PAR_YPOS]); 96 } 97 98 psF32 *PAR = model->params->data.F32; 99 100 // save original values 101 float oldI0 = PAR[PM_PAR_I0]; 102 oldshape.sx = PAR[PM_PAR_SXX]; 103 oldshape.sy = PAR[PM_PAR_SYY]; 104 oldshape.sxy = PAR[PM_PAR_SXY]; 105 106 // XXX can this be done more intelligently? 107 if (oldI0 == 0.0) continue; 108 if (!isfinite(oldI0)) continue; 109 110 // increase size and height of source 111 axes = psEllipseShapeToAxes (oldshape, 20.0); 112 axes.major *= SIZE; 113 axes.minor *= SIZE; 114 newshape = psEllipseAxesToShape (axes); 115 PAR[PM_PAR_I0] = FACTOR*oldI0; 116 PAR[PM_PAR_SXX] = newshape.sx; 117 PAR[PM_PAR_SYY] = newshape.sy; 118 PAR[PM_PAR_SXY] = newshape.sxy; 119 120 // XXX if we use pmSourceOp, the size (and possibly Io) will not be respected 121 pmSourceOp (source, PM_MODEL_OP_FULL | PM_MODEL_OP_NOISE, add, maskVal, 0, 0); 122 123 // restore original values 124 PAR[PM_PAR_I0] = oldI0; 125 PAR[PM_PAR_SXX] = oldshape.sx; 126 PAR[PM_PAR_SYY] = oldshape.sy; 127 PAR[PM_PAR_SXY] = oldshape.sxy; 87 pmSourceNoiseOp (source, PM_MODEL_OP_FULL | PM_MODEL_OP_NOISE, FACTOR, SIZE, add, maskVal, 0, 0); 128 88 } 129 89 if (add) { … … 132 92 psLogMsg ("psphot.noise", PS_LOG_INFO, "sub noise for %ld objects: %f sec\n", sources->n, psTimerMark ("psphot.noise")); 133 93 } 94 95 psphotSaveImage (NULL, readout->variance, "test.var1.fits"); 134 96 return true; 135 97 } -
branches/eam_branches/ipp-20100621/psphot/src/psphotBlendFit.c
r28657 r28782 90 90 91 91 psphotInitLimitsPSF (recipe, readout); 92 psphotInitLimitsEXT (recipe );93 psphotInitRadiusPSF (recipe, readout ->analysis, psf->type);92 psphotInitLimitsEXT (recipe, readout); 93 psphotInitRadiusPSF (recipe, readout); 94 94 95 95 // starts the timer, sets up the array of fitSets -
branches/eam_branches/ipp-20100621/psphot/src/psphotExtendedSourceFits.c
r28687 r28782 39 39 int NplainPass = 0; 40 40 bool savePics = false; 41 float radius; 41 42 42 43 // find the currently selected readout … … 164 165 Next ++; 165 166 167 // set the radius based on the footprint (also sets the mask pixels) 168 if (!psphotSetRadiusFootprint(&radius, readout, source, markVal, 1.0)) return false; 169 170 // XXX note that this changes the source moments that are published... 171 // recalculate the source moments using the larger extended-source moments radius 172 // at this stage, skip Gaussian windowing, and do not clip pixels by S/N 173 // this uses the footprint to judge both radius and aperture? 174 // XXX save the psf-based moments for output 175 if (!pmSourceMoments (source, radius, 0.0, 0.0, maskVal)) { 176 // subtract the best fit from the object, leave local sky 177 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 178 // XXX raise an error of some kind 179 continue; 180 } 181 166 182 // save the modelFlux here in case we need to subtract it (for failure) 167 183 psImage *modelFluxStart = psMemIncrRefCounter (source->modelFlux); … … 242 258 243 259 // test for fit quality / result 260 modelFit->fitRadius = radius; 244 261 psArrayAdd (source->modelFits, 4, modelFit); 245 262 -
branches/eam_branches/ipp-20100621/psphot/src/psphotGuessModels.c
r28405 r28782 80 80 81 81 // setup the PSF fit radius details 82 psphotInitRadiusPSF (recipe, readout ->analysis, psf->type);82 psphotInitRadiusPSF (recipe, readout); 83 83 84 84 // choose Cx, Cy (see psphotThreadTools.c for overview of the concepts) -
branches/eam_branches/ipp-20100621/psphot/src/psphotRadiusChecks.c
r28440 r28782 8 8 // and a per-object radius is calculated) 9 9 10 bool psphotInitRadiusPSF( const psMetadata *recipe, const psMetadata *analysis, const pmModelType type) {10 bool psphotInitRadiusPSF(psMetadata *recipe, pmReadout *readout) { 11 11 12 12 bool status = true; … … 15 15 PSF_FIT_PADDING = psMetadataLookupF32(&status, recipe, "PSF_FIT_PADDING"); 16 16 17 PSF_FIT_RADIUS = psMetadataLookupF32(&status, analysis, "PSF_FIT_RADIUS");17 PSF_FIT_RADIUS = psMetadataLookupF32(&status, readout->analysis, "PSF_FIT_RADIUS"); 18 18 if (!status) { 19 19 PSF_FIT_RADIUS = psMetadataLookupF32(&status, recipe, "PSF_FIT_RADIUS"); 20 20 } 21 21 22 PSF_APERTURE = psMetadataLookupF32(&status, analysis, "PSF_APERTURE");22 PSF_APERTURE = psMetadataLookupF32(&status, readout->analysis, "PSF_APERTURE"); 23 23 if (!status) { 24 24 PSF_APERTURE = psMetadataLookupF32(&status, recipe, "PSF_APERTURE"); … … 28 28 29 29 if (PSF_FIT_RADIUS == 0.0) { 30 float gaussSigma = psMetadataLookupF32(&status, analysis, "MOMENTS_GAUSS_SIGMA");30 float gaussSigma = psMetadataLookupF32(&status, readout->analysis, "MOMENTS_GAUSS_SIGMA"); 31 31 if (!status) { 32 32 gaussSigma = psMetadataLookupF32(&status, recipe, "MOMENTS_GAUSS_SIGMA"); … … 37 37 38 38 if (PSF_APERTURE == 0.0) { 39 float gaussSigma = psMetadataLookupF32(&status, analysis, "MOMENTS_GAUSS_SIGMA");39 float gaussSigma = psMetadataLookupF32(&status, readout->analysis, "MOMENTS_GAUSS_SIGMA"); 40 40 if (!status) { 41 41 gaussSigma = psMetadataLookupF32(&status, recipe, "MOMENTS_GAUSS_SIGMA"); … … 122 122 } 123 123 124 static float EXT_FIT_SKY_SIG; 124 125 static float EXT_FIT_NSIGMA; 125 126 static float EXT_FIT_PADDING; 126 127 static float EXT_FIT_MAX_RADIUS; 127 128 128 bool psphotInitRadiusEXT (psMetadata *recipe, pm ModelType type) {129 bool psphotInitRadiusEXT (psMetadata *recipe, pmReadout *readout) { 129 130 130 131 bool status; … … 134 135 EXT_FIT_MAX_RADIUS = psMetadataLookupF32 (&status, recipe, "EXT_FIT_MAX_RADIUS"); 135 136 137 float skyMean = psMetadataLookupF32 (&status, readout->analysis, "SKY_MEAN"); 138 float skyStdev = psMetadataLookupF32 (&status, readout->analysis, "SKY_STDEV"); 139 140 fprintf (stderr, "sky: %f +/- %f\n", skyMean, skyStdev); 141 142 EXT_FIT_SKY_SIG = skyStdev; 143 136 144 return true; 137 145 } 138 146 139 147 // call this function whenever you (re)-define the EXT model 140 float psphotSetRadiusEXT (pmReadout *readout, pmSource *source, psImageMaskType markVal) {148 bool psphotSetRadiusFootprint (float *radius, pmReadout *readout, pmSource *source, psImageMaskType markVal, float factor) { 141 149 142 150 psAssert (source, "source not defined??"); … … 146 154 147 155 // set the radius based on the footprint: 148 if (!peak->footprint) goto escape;156 if (!peak->footprint) return false; 149 157 pmFootprint *footprint = peak->footprint; 150 if (!footprint->spans) goto escape;151 if (footprint->spans->n < 1) goto escape;158 if (!footprint->spans) return false; 159 if (footprint->spans->n < 1) return false; 152 160 153 161 // find the max radius 154 float ra dius = 0.0;162 float rawRadius = 0.0; 155 163 for (int j = 0; j < footprint->spans->n; j++) { 156 164 pmSpan *span = footprint->spans->data[j]; … … 160 168 float dX1 = span->x1 - peak->xf; 161 169 162 radius = PS_MAX (radius, hypot(dY, dX0)); 163 radius = PS_MAX (radius, hypot(dY, dX1)); 164 } 165 166 radius += EXT_FIT_PADDING; 167 if (isnan(radius)) psAbort("error in radius"); 168 169 radius = PS_MIN (radius, EXT_FIT_MAX_RADIUS); 170 rawRadius = PS_MAX (rawRadius, hypot(dY, dX0)); 171 rawRadius = PS_MAX (rawRadius, hypot(dY, dX1)); 172 } 173 if (isnan(rawRadius)) return false; 174 rawRadius = PS_MIN (factor*rawRadius + EXT_FIT_PADDING, EXT_FIT_MAX_RADIUS); 170 175 171 176 // redefine the pixels if needed 172 pmSourceRedefinePixels (source, readout, peak->xf, peak->yf, radius); 173 174 // set the mask to flag the excluded pixels 175 psImageKeepCircle (source->maskObj, peak->xf, peak->yf, radius, "OR", markVal); 176 return radius; 177 178 escape: 179 return NAN; 180 // bool result = psphotCheckRadiusEXT (readout, source, model, markVal); 181 // return result; 177 pmSourceRedefinePixels (source, readout, peak->xf, peak->yf, rawRadius); 178 179 // set the mask to flag the excluded pixels 180 psImageKeepCircle (source->maskObj, peak->xf, peak->yf, rawRadius, "OR", markVal); 181 182 *radius = rawRadius; 183 return true; 182 184 } 183 185 184 186 // alternative EXT radius based on model guess (for use without footprints) 185 bool psphotCheckRadiusEXT (pmReadout *readout, pmSource *source, pmModel *model, psImageMaskType markVal) { 186 187 psAbort ("do not use this function"); 187 bool psphotSetRadiusModel (pmModel *model, pmReadout *readout, pmSource *source, psImageMaskType markVal, bool deep) { 188 188 189 189 psF32 *PAR = model->params->data.F32; … … 193 193 194 194 // set the fit radius based on the object flux limit and the model 195 float rawRadius = model->modelRadius (model->params, EXT_FIT_NSIGMA*moments->dSky); 196 197 model->fitRadius = rawRadius + EXT_FIT_PADDING; 198 if (isnan(model->fitRadius)) psAbort("error in radius"); 195 float flux = deep ? EXT_FIT_NSIGMA*EXT_FIT_SKY_SIG : 0.1 * model->params->data.F32[PM_PAR_I0]; 196 197 float rawRadius = model->modelRadius (model->params, flux); 198 if (isnan(rawRadius)) return false; 199 200 rawRadius = PS_MIN (rawRadius + EXT_FIT_PADDING, EXT_FIT_MAX_RADIUS); 201 model->fitRadius = rawRadius; 199 202 200 203 // redefine the pixels if needed 201 bool status =pmSourceRedefinePixels (source, readout, PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], model->fitRadius);204 pmSourceRedefinePixels (source, readout, PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], model->fitRadius); 202 205 203 206 // set the mask to flag the excluded pixels 204 207 psImageKeepCircle (source->maskObj, PAR[PM_PAR_XPOS], PAR[PM_PAR_YPOS], model->fitRadius, "OR", markVal); 205 return status;206 } 208 return true; 209 } -
branches/eam_branches/ipp-20100621/psphot/src/psphotSourceFits.c
r28702 r28782 1 1 # include "psphotInternal.h" 2 bool psphotFitSersicIndex (pmSource *source, pmModel *model, pmSourceFitOptions *fitOptions, psImageMaskType maskVal);3 2 4 3 // given a source with an existing modelPSF, attempt a full PSF fit, subtract if successful … … 19 18 20 19 psLogMsg ("psphot.pspsf", PS_LOG_INFO, "fitted %5d psf, %5d blend, %5d ext, %5d dbl : %6.2f sec\n", 21 NfitPSF, NfitBlend, NfitEXT, NfitDBL, psTimerMark ("psphot.fits"));20 NfitPSF, NfitBlend, NfitEXT, NfitDBL, psTimerMark ("psphot.fits")); 22 21 return true; 23 22 } … … 205 204 } 206 205 206 // save a local, static copy of the EXT model type so we don't have to lookup for each object 207 207 static pmModelType modelTypeEXT; 208 208 209 bool psphotInitLimitsEXT (psMetadata *recipe ) {209 bool psphotInitLimitsEXT (psMetadata *recipe, pmReadout *readout) { 210 210 211 211 bool status; … … 214 214 char *modelNameEXT = psMetadataLookupStr (&status, recipe, "EXT_MODEL"); 215 215 modelTypeEXT = pmModelClassGetType (modelNameEXT); 216 psphotInitRadiusEXT (recipe, modelTypeEXT); 216 217 psphotInitRadiusEXT (recipe, readout); 217 218 218 219 return true; … … 221 222 bool psphotFitBlob (pmReadout *readout, pmSource *source, psArray *newSources, pmPSF *psf, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal) { 222 223 224 float radius; 223 225 bool okEXT, okDBL; 224 226 float chiEXT, chiDBL; … … 230 232 231 233 // skip the source if we don't think it is extended 234 // XXX are these robust, or do we have better info from the source-size analysis?? 232 235 if (source->type == PM_SOURCE_TYPE_UNKNOWN) return false; 233 236 if (source->type == PM_SOURCE_TYPE_DEFECT) return false; … … 235 238 236 239 // set the radius based on the footprint (also sets the mask pixels) 237 float radius = psphotSetRadiusEXT (readout, source, markVal);240 if (!psphotSetRadiusFootprint(&radius, readout, source, markVal, 1.0)) return false; 238 241 239 242 // XXX note that this changes the source moments that are published... 243 // XXX all published moments should use the same measurement 240 244 // recalculate the source moments using the larger extended-source moments radius 241 245 // at this stage, skip Gaussian windowing, and do not clip pixels by S/N 242 246 // this uses the footprint to judge both radius and aperture? 247 // XXX save the psf-based moments for output 243 248 if (!pmSourceMoments (source, radius, 0.0, 0.0, maskVal)) return false; 244 249 … … 250 255 // this temporary source is used as a place-holder by the psphotEval functions below 251 256 tmpSrc = pmSourceAlloc (); 252 253 // XXX need to handle failures better here 254 EXT = psphotFitEXT (readout, source, fitOptions, modelTypeEXT, maskVal, markVal); 255 if (!EXT) goto escape; 256 if (!isfinite(EXT->params->data.F32[PM_PAR_I0])) goto escape; 257 258 okEXT = psphotEvalEXT (tmpSrc, EXT); 259 chiEXT = EXT ? EXT->chisq / EXT->nDOF : NAN; 260 261 // DBL will always be defined, but DBL->data[n] might not 262 DBL = psphotFitDBL (readout, source, fitOptions, maskVal, markVal); 263 if (!DBL) goto escape; 264 if (!DBL->n) goto escape; 265 266 okDBL = psphotEvalDBL (tmpSrc, DBL->data[0]); 267 okDBL &= psphotEvalDBL (tmpSrc, DBL->data[1]); 268 // XXX should I keep / save the flags set in the eval functions? 257 { 258 // DBL will always be defined, but DBL->data[n] might not 259 DBL = psphotFitDBL (readout, source, fitOptions, maskVal, markVal); 260 if (!DBL) goto escape; 261 if (!DBL->n) goto escape; 262 263 okDBL = psphotEvalDBL (tmpSrc, DBL->data[0]); 264 okDBL &= psphotEvalDBL (tmpSrc, DBL->data[1]); 265 // XXX should I keep / save the flags set in the eval functions? 266 267 // correct first model chisqs for flux trend 268 chiDBL = NAN; 269 ONE = DBL->data[0]; 270 if (ONE) { 271 if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit"); 272 chiTrend = psPolynomial1DEval (psf->ChiTrend, ONE->params->data.F32[1]); 273 ONE->chisqNorm = ONE->chisq / chiTrend; 274 chiDBL = ONE->chisq / ONE->nDOF; // save chisq for double-star/galaxy comparison 275 ONE->fitRadius = radius; 276 } 277 278 // correct second model chisqs for flux trend 279 ONE = DBL->data[1]; 280 if (ONE) { 281 if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit"); 282 chiTrend = psPolynomial1DEval (psf->ChiTrend, ONE->params->data.F32[1]); 283 ONE->chisqNorm = ONE->chisq / chiTrend; 284 ONE->fitRadius = radius; 285 } 286 } 287 288 { 289 // XXX need to handle failures better here 290 EXT = psphotFitEXT (readout, source, fitOptions, modelTypeEXT, maskVal, markVal); 291 if (!EXT) goto escape; 292 if (!isfinite(EXT->params->data.F32[PM_PAR_I0])) goto escape; 293 294 okEXT = psphotEvalEXT (tmpSrc, EXT); 295 chiEXT = EXT ? EXT->chisq / EXT->nDOF : NAN; 296 } 269 297 270 298 // clear the circular mask 271 299 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); 272 273 // correct first model chisqs for flux trend274 chiDBL = NAN;275 ONE = DBL->data[0];276 if (ONE) {277 if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");278 chiTrend = psPolynomial1DEval (psf->ChiTrend, ONE->params->data.F32[1]);279 ONE->chisqNorm = ONE->chisq / chiTrend;280 chiDBL = ONE->chisq / ONE->nDOF; // save chisq for double-star/galaxy comparison281 }282 283 // correct second model chisqs for flux trend284 ONE = DBL->data[1];285 if (ONE) {286 if (!isfinite(ONE->params->data.F32[PM_PAR_I0])) psAbort("nan in fit");287 chiTrend = psPolynomial1DEval (psf->ChiTrend, ONE->params->data.F32[1]);288 ONE->chisqNorm = ONE->chisq / chiTrend;289 }290 300 291 301 psFree (tmpSrc); … … 314 324 315 325 // save new model 326 // XXX save the correct radius... 316 327 source->modelEXT = EXT; 317 source->modelEXT->fitRadius = radius;318 328 source->type = PM_SOURCE_TYPE_EXTENDED; 319 329 source->mode |= PM_SOURCE_MODE_EXTMODEL; … … 343 353 source->modelPSF = psMemIncrRefCounter (DBL->data[0]); 344 354 source->mode |= PM_SOURCE_MODE_PAIR; 345 source->modelPSF->fitRadius = radius;346 355 347 356 // copy most data from the primary source (modelEXT, blends stay NULL) 348 357 pmSource *newSrc = pmSourceCopyData (source); 349 358 newSrc->modelPSF = psMemIncrRefCounter (DBL->data[1]); 350 newSrc->modelPSF->fitRadius = radius;351 359 352 360 // build cached models and subtract … … 452 460 maskVal |= markVal; 453 461 454 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);455 456 462 // use the source moments, etc to guess basic model parameters 457 pmModel * EXT= pmSourceModelGuess (source, modelType);458 if (! EXT) {463 pmModel *model = pmSourceModelGuess (source, modelType); 464 if (!model) { 459 465 psTrace ("psphot", 5, "failed to generate a model for source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy); 460 466 return NULL; … … 463 469 // for sersic models, use a grid search to choose an index, then float the params there 464 470 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { 465 psphotFitSersicIndex (source, EXT, fitOptions, maskVal); 471 // for the test fits, use a somewhat smaller radius 472 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5); 473 psphotFitSersicIndex (model, readout, source, fitOptions, maskVal, markVal); 474 } 475 476 if (!psphotSetRadiusModel (model, readout, source, markVal, true)) { 477 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 1.0); 466 478 } 467 479 … … 471 483 options.mode = PM_SOURCE_FIT_EXT; 472 484 } 473 pmSourceFitModel (source, EXT, &options, maskVal); 485 486 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5); 487 pmSourceFitModel (source, model, &options, maskVal); 488 fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix); 474 489 475 490 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); 476 return ( EXT);491 return (model); 477 492 } 478 493 479 494 pmModel *psphotFitPCM (pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, pmModelType modelType, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 495 496 if ((source->moments->Mxx < 1e-3) || (source->moments->Myy < 1e-3)) { 497 psTrace ("psphot", 5, "problem source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy); 498 } 499 500 pmSourceFitOptions options = *fitOptions; 501 502 NfitPCM ++; 503 504 // maskVal is used to test for rejected pixels, and must include markVal 505 maskVal |= markVal; 480 506 481 507 // allocate the model … … 484 510 return NULL; 485 511 } 486 487 pmSourceFitOptions options = *fitOptions;488 489 if ((source->moments->Mxx < 1e-3) || (source->moments->Myy < 1e-3)) {490 psTrace ("psphot", 5, "problem source: moments: %f %f\n", source->moments->Mxx, source->moments->Myy);491 }492 493 float radius = psphotSetRadiusEXT (readout, source, markVal);494 495 // XXX note that this changes the source moments that are published...496 // recalculate the source moments using the larger extended-source moments radius497 // at this stage, skip Gaussian windowing, and do not clip pixels by S/N498 // this uses the footprint to judge both radius and aperture?499 if (!pmSourceMoments (source, radius, 0.0, 0.0, maskVal)) {500 // XXX set some mask bit/501 model->flags |= PM_MODEL_STATUS_BADARGS;502 return model;503 }504 505 NfitPCM ++;506 507 // maskVal is used to test for rejected pixels, and must include markVal508 maskVal |= markVal;509 510 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5);511 512 512 513 pmPCMdata *pcm = pmPCMinit (source, &options, model, maskVal, psfSize); … … 518 519 519 520 // use the source moments, etc to guess basic model parameters 520 pmSourceModelGuessPCM (pcm, source, maskVal, markVal); 521 if (!pmSourceModelGuessPCM (pcm, source, maskVal, markVal)) { 522 psFree (pcm); 523 model->flags |= PM_MODEL_STATUS_BADARGS; 524 return model; 525 } 521 526 522 527 // for sersic models, use a grid search to choose an index, then float the params there 523 528 if (modelType == pmModelClassGetType("PS_MODEL_SERSIC")) { 524 psphotFitSersicIndexPCM (pcm, source, fitOptions, maskVal, markVal, psfSize); 529 // for the test fits, use a somewhat smaller radius 530 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5); 531 if (!psphotFitSersicIndexPCM (pcm, readout, source, fitOptions, maskVal, markVal, psfSize)) { 532 model->flags |= PM_MODEL_STATUS_BADARGS; 533 return model; 534 } 535 } 536 537 if (!psphotSetRadiusModel (model, readout, source, markVal, true)) { 538 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 1.0); 525 539 } 526 540 … … 530 544 options.mode = PM_SOURCE_FIT_EXT; 531 545 } 546 547 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 5); 532 548 pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 549 fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix); 533 550 534 551 // psTraceSetLevel("psLib.math.psMinimizeLMChi2", 0); … … 544 561 // A sersic model is very sensitive to the index. attempt to find the index first by grid search in just the index 545 562 // for a sersic model, attempt to fit just the index and normalization with a modest number of iterations 546 bool psphotFitSersicIndex (pm Source *source, pmModel *model, pmSourceFitOptions *fitOptions, psImageMaskType maskVal) {563 bool psphotFitSersicIndex (pmModel *model, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal) { 547 564 548 565 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); … … 552 569 // fit EXT (not PSF) model (set/unset the pixel mask) 553 570 options.mode = PM_SOURCE_FIT_NO_INDEX; 554 options.nIter = 3;571 options.nIter = 4; 555 572 556 573 int iMin = -1; … … 561 578 model->params->data.F32[PM_PAR_7] = indexGuess[i]; 562 579 563 model->modelGuess(model, source); 580 if (!model->modelGuess(model, source)) { 581 model->flags |= PM_MODEL_STATUS_BADARGS; 582 return false; 583 } 584 585 // each time we change the model guess, we need to adjust the radius 586 // XXX this did not work : we do not need such a large radius -- just uses moments-based radius 587 if (false && !psphotSetRadiusModel (model, readout, source, markVal, false)) { 588 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5); 589 } 590 564 591 pmSourceFitModel (source, model, &options, maskVal); 592 fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix); 593 594 chiSquare[i] = model->chisqNorm; 595 if (i == 0) { 596 xMin = chiSquare[i]; 597 iMin = i; 598 } else { 599 if (chiSquare[i] < xMin) { 600 xMin = chiSquare[i]; 601 iMin = i; 602 } 603 } 604 } 605 assert (iMin >= 0); 606 607 model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it 608 model->params->data.F32[PM_PAR_7] = indexGuess[iMin]; 609 model->modelGuess(model, source); 610 611 // each time we change the model guess, we need to adjust the radius 612 // if (!psphotSetRadiusModel (model, readout, source, markVal, true)) { 613 // psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal); 614 // } 615 616 return true; 617 } 618 619 // A sersic model is very sensitive to the index. attempt to find the index first by grid search in just the index 620 // for a sersic model, attempt to fit just the index and normalization with a modest number of iterations 621 bool psphotFitSersicIndexPCM (pmPCMdata *pcm, pmReadout *readout, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) { 622 623 pmModel *model = pcm->modelConv; 624 625 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC")); 626 627 pmSourceFitOptions options = *fitOptions; 628 629 // fit EXT (not PSF) model (set/unset the pixel mask) 630 options.mode = PM_SOURCE_FIT_NO_INDEX; 631 options.nIter = 4; 632 633 int iMin = -1; 634 float xMin = NAN; 635 float chiSquare[N_INDEX_GUESS]; 636 637 for (int i = 0; i < N_INDEX_GUESS; i++) { 638 model->params->data.F32[PM_PAR_7] = indexGuess[i]; 639 640 if (!model->modelGuess(model, source)) { 641 model->flags |= PM_MODEL_STATUS_BADARGS; 642 return false; 643 } 644 645 // each time we change the model guess, we need to adjust the radius 646 // XXX this did not work : we do not need such a large radius -- just uses moments-based radius 647 if (false && !psphotSetRadiusModel (model, readout, source, markVal, false)) { 648 psphotSetRadiusFootprint(&model->fitRadius, readout, source, markVal, 0.5); 649 } 650 651 pmSourceFitModel (source, model, &options, maskVal); 652 fprintf (stderr, "chisq: %f, nIter: %d, radius: %f, npix: %d\n", model->chisqNorm, model->nIter, model->fitRadius, model->nPix); 653 654 // pmSourceModelGuessPCM(pcm, source, maskVal, markVal); 655 // pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize); 565 656 566 657 chiSquare[i] = model->chisq; … … 575 666 } 576 667 } 577 578 model->flags = PM_MODEL_STATUS_NONE; // do not attempt to handle failures here, let the next iteration deal with it579 model->params->data.F32[PM_PAR_7] = indexGuess[iMin];580 model->modelGuess(model, source);581 582 return true;583 }584 585 // A sersic model is very sensitive to the index. attempt to find the index first by grid search in just the index586 // for a sersic model, attempt to fit just the index and normalization with a modest number of iterations587 bool psphotFitSersicIndexPCM (pmPCMdata *pcm, pmSource *source, pmSourceFitOptions *fitOptions, psImageMaskType maskVal, psImageMaskType markVal, int psfSize) {588 589 pmModel *model = pcm->modelConv;590 591 assert (model->type == pmModelClassGetType("PS_MODEL_SERSIC"));592 593 pmSourceFitOptions options = *fitOptions;594 595 // fit EXT (not PSF) model (set/unset the pixel mask)596 options.mode = PM_SOURCE_FIT_NO_INDEX;597 options.nIter = 3;598 599 int iMin = -1;600 float xMin = NAN;601 float chiSquare[N_INDEX_GUESS];602 603 for (int i = 0; i < N_INDEX_GUESS; i++) {604 model->params->data.F32[PM_PAR_7] = indexGuess[i];605 606 model->modelGuess(model, source);607 pmSourceFitModel (source, model, &options, maskVal);608 609 // pmSourceModelGuessPCM(pcm, source, maskVal, markVal);610 // pmSourceFitPCM (pcm, source, &options, maskVal, markVal, psfSize);611 612 chiSquare[i] = model->chisq;613 if (i == 0) {614 xMin = chiSquare[i];615 iMin = i;616 } else {617 if (chiSquare[i] < xMin) {618 xMin = chiSquare[i];619 iMin = i;620 }621 }622 }623 624 668 assert (iMin >= 0); 625 669
Note:
See TracChangeset
for help on using the changeset viewer.
