- Timestamp:
- Jul 29, 2010, 2:36:33 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.
