Changeset 25476
- Timestamp:
- Sep 21, 2009, 8:37:01 PM (17 years ago)
- Location:
- branches/eam_branches/20090715/psModules/src
- Files:
-
- 2 added
- 9 edited
- 1 moved
-
extras/pmVisual.c (modified) (1 diff)
-
objects/Makefile.am (modified) (1 diff)
-
objects/pmPSF.h (modified) (2 diffs)
-
objects/pmPSFtry.c (modified) (4 diffs)
-
objects/pmPSFtry.h (modified) (4 diffs)
-
objects/pmPSFtryFitEXT.c (modified) (2 diffs)
-
objects/pmPSFtryFitPSF.c (modified) (2 diffs)
-
objects/pmPSFtryMakePSF.c (moved) (moved from branches/eam_branches/20090715/psModules/src/objects/pmPSFFromPSFtry.c ) (6 diffs, 1 prop)
-
objects/pmPSFtryMetric.c (added)
-
objects/pmPSFtryModel.c (added)
-
objects/pmSourceVisual.c (modified) (2 diffs)
-
objects/pmSourceVisual.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/20090715/psModules/src/extras/pmVisual.c
r23989 r25476 22 22 #include "pmSubtractionStamps.h" 23 23 #include "pmTrend2D.h" 24 #include "pmPSF.h" 25 #include "pmPSFtry.h" 24 26 #include "pmFPAExtent.h" 25 27 -
branches/eam_branches/20090715/psModules/src/objects/Makefile.am
r25407 r25476 50 50 pmPSF_IO.c \ 51 51 pmPSFtry.c \ 52 pmPSFtryModel.c \ 53 pmPSFtryFitEXT.c \ 54 pmPSFtryMakePSF.c \ 55 pmPSFtryFitPSF.c \ 56 pmPSFtryMetric.c \ 52 57 pmTrend2D.c \ 53 58 pmGrowthCurveGenerate.c \ -
branches/eam_branches/20090715/psModules/src/objects/pmPSF.h
r24206 r25476 38 38 * 39 39 */ 40 typedef struct 41 { 40 typedef struct { 42 41 pmModelType type; ///< PSF Model in use 43 42 psArray *params; ///< Model parameters (psPolynomial2D) … … 65 64 pmGrowthCurve *growth; ///< apMag vs Radius 66 65 pmResiduals *residuals; ///< normalized residual image (no spatial variation) 67 } 68 pmPSF; 66 } pmPSF; 69 67 70 68 typedef struct { -
branches/eam_branches/20090715/psModules/src/objects/pmPSFtry.c
r25455 r25476 63 63 psMemSetDeallocator(test, (psFreeFunc) pmPSFtryFree); 64 64 65 test->psf = pmPSFAlloc (options);65 test->psf = NULL; 66 66 test->metric = psVectorAlloc (sources->n, PS_TYPE_F32); 67 67 test->metricErr = psVectorAlloc (sources->n, PS_TYPE_F32); … … 87 87 PS_ASSERT_PTR(ptr, false); 88 88 return ( psMemGetDeallocator(ptr) == (psFreeFunc) pmPSFtryFree); 89 }90 91 92 // build a pmPSFtry for the given model:93 // - fit each source with the free-floating model94 // - construct the pmPSF from the collection of models95 // - fit each source with the PSF-parameter models96 // - measure the pmPSF quality metric (dApResid)97 98 // sources used in for pmPSFtry may be masked by the analysis99 // mask values indicate the reason the source was rejected:100 101 // generate a pmPSFtry with a copy of the test PSF sources102 pmPSFtry *pmPSFtryModel (const psArray *sources, const char *modelName, pmPSFOptions *options, psImageMaskType maskVal, psImageMaskType markVal)103 {104 bool status;105 int Next = 0;106 int Npsf = 0;107 108 // validate the requested model name109 options->type = pmModelClassGetType (modelName);110 if (options->type == -1) {111 psError (PS_ERR_UNKNOWN, true, "invalid model name %s", modelName);112 return NULL;113 }114 115 pmPSFtry *psfTry = pmPSFtryAlloc (sources, options);116 if (psfTry == NULL) {117 psError (PS_ERR_UNKNOWN, false, "failed to allocate psf model");118 return NULL;119 }120 121 // maskVal is used to test for rejected pixels, and must include markVal122 maskVal |= markVal;123 124 // stage 1: fit an EXT model to all candidates PSF sources -- this is independent of the modeled 2D variations in the PSF125 if (!pmPSFtryFitEXT(psfTry, options, maskVal, markVal)) {126 psError(PS_ERR_UNKNOWN, false, "failed to fit EXT models to sources for psf model");127 psFree(psfTry);128 return NULL;129 }130 131 for (int i = 0; i < Norder; i++) {132 // stage 2: construct a psf (pmPSF) from this collection of model fits, including the 2D variation133 if (!pmPSFFromPSFtry (psfTry, Nx, Ny)) {134 psError(PS_ERR_UNKNOWN, false, "failed to construct a psf model from collection of sources");135 psFree(psfTry);136 return NULL;137 }138 139 // stage 3: refit with fixed shape parameters, measure pmPSFtryMetric140 if (!pmPSFtryFitPSF (psfTry, Nx, Ny)) {141 psError(PS_ERR_UNKNOWN, false, "failed to construct a psf model from collection of sources");142 psFree(psfTry);143 return NULL;144 }145 }146 // XXXXX this is probably not used any more. Are the chisq of the fits so bad? can we147 // fix them by softening the errors on the brightest pixels?148 149 // measure the chi-square trend as a function of flux (PAR[PM_PAR_I0])150 // this should be linear for Poisson errors and quadratic for constant sky errors151 psVector *flux = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);152 psVector *chisq = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);153 psVector *mask = psVectorAlloc (psfTry->sources->n, PS_TYPE_VECTOR_MASK);154 155 // generate the x and y vectors, and mask missing models156 for (int i = 0; i < psfTry->sources->n; i++) {157 pmSource *source = psfTry->sources->data[i];158 if (source->modelPSF == NULL) {159 flux->data.F32[i] = 0.0;160 chisq->data.F32[i] = 0.0;161 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0xff;162 } else {163 flux->data.F32[i] = source->modelPSF->params->data.F32[PM_PAR_I0];164 chisq->data.F32[i] = source->modelPSF->chisq / source->modelPSF->nDOF;165 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = 0;166 }167 }168 169 // use 3hi/3lo sigma clipping on the chisq fit170 psStats *stats = options->stats;171 172 // linear clipped fit of chisq trend vs flux173 if (options->chiFluxTrend) {174 bool result = psVectorClipFitPolynomial1D(psfTry->psf->ChiTrend, options->stats,175 mask, 0xff, chisq, NULL, flux);176 psStatsOptions meanStat = psStatsMeanOption(options->stats->options); // Statistic for mean177 psStatsOptions stdevStat = psStatsStdevOption(options->stats->options); // Statistic for stdev178 179 psLogMsg ("pmPSFtry", 4, "chisq vs flux fit: %f +/- %f\n",180 psStatsGetValue(stats, meanStat), psStatsGetValue(stats, stdevStat));181 182 psFree(flux);183 psFree(mask);184 psFree(chisq);185 186 if (!result) {187 psError(PS_ERR_UNKNOWN, false, "Failed to fit psf->ChiTrend");188 psFree(psfTry);189 return NULL;190 }191 }192 193 for (int i = 0; i < psfTry->psf->ChiTrend->nX + 1; i++) {194 psLogMsg ("pmPSFtry", 4, "chisq vs flux fit term %d: %f +/- %f\n", i,195 psfTry->psf->ChiTrend->coeff[i]*pow(10000, i),196 psfTry->psf->ChiTrend->coeffErr[i]*pow(10000,i));197 }198 199 // XXX this function wants aperture radius for pmSourcePhotometry200 if (!pmPSFtryMetric (psfTry, options)) {201 psError(PS_ERR_UNKNOWN, false, "Attempt to fit PSF with model %s failed.", modelName);202 psFree (psfTry);203 return NULL;204 }205 206 psLogMsg ("psphot.pspsf", 3, "try model %s, ap-fit: %f +/- %f : sky bias: %f\n",207 modelName, psfTry->psf->ApResid, psfTry->psf->dApResid, psfTry->psf->skyBias);208 209 return (psfTry);210 }211 212 bool pmPSFtryMetric (pmPSFtry *psfTry, pmPSFOptions *options)213 {214 PS_ASSERT_PTR_NON_NULL(psfTry, false);215 PS_ASSERT_PTR_NON_NULL(options, false);216 PS_ASSERT_PTR_NON_NULL(psfTry->sources, false);217 218 float RADIUS = options->radius;219 220 // the measured (aperture - fit) magnitudes (dA == psfTry->metric)221 // depend on both the true ap-fit (dAo) and the bias in the sky measurement:222 // dA = dAo + dsky/flux223 // where flux is the flux of the star224 // we fit this trend to find the infinite flux aperture correction (dAo),225 // the nominal sky bias (dsky), and the error on dAo226 // the values of dA are contaminated by stars with close neighbors in the aperture227 // we use an outlier rejection to avoid this bias228 229 // r2rflux = radius^2 * ten(0.4*fitMag);230 psVector *r2rflux = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);231 232 for (int i = 0; i < psfTry->sources->n; i++) {233 if (psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PSFTRY_MASK_ALL)234 continue;235 r2rflux->data.F32[i] = PS_SQR(RADIUS) * pow(10.0, 0.4*psfTry->fitMag->data.F32[i]);236 }237 238 // XXX test dump of aperture residual data239 if (psTraceGetLevel("psModules.objects") >= 5) {240 FILE *f = fopen ("apresid.dat", "w");241 for (int i = 0; i < psfTry->sources->n; i++) {242 int keep = (psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PSFTRY_MASK_ALL);243 244 pmSource *source = psfTry->sources->data[i];245 float x = source->peak->x;246 float y = source->peak->y;247 248 fprintf (f, "%d %d, %f %f %f %f %f %f \n",249 i, keep, x, y,250 psfTry->fitMag->data.F32[i],251 r2rflux->data.F32[i],252 psfTry->metric->data.F32[i],253 psfTry->metricErr->data.F32[i]);254 }255 fclose (f);256 }257 258 // This analysis of the apResid statistics is only approximate. The fitted magnitudes259 // measured at this point (in the PSF fit) use Poisson errors, and are thus biased as a260 // function of magnitude. We re-measure the apResid statistics later in psphot using the261 // linear, constant-error fitting. Do not reject outliers with excessive vigor here.262 263 // fit ApTrend only to r2rflux, ignore x,y,flux variations for now264 // linear clipped fit of ApResid to r2rflux265 psPolynomial1D *poly = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 1);266 poly->coeffMask[1] = PS_POLY_MASK_SET; // fit only a constant offset (no SKYBIAS)267 268 // XXX replace this with a psVectorStats call? since we are not fitting the trend269 bool result = psVectorClipFitPolynomial1D(poly, options->stats, psfTry->mask, PSFTRY_MASK_ALL,270 psfTry->metric, psfTry->metricErr, r2rflux);271 if (!result) {272 psError(PS_ERR_UNKNOWN, false, "Failed to fit clipped poly");273 274 psFree(poly);275 psFree(r2rflux);276 277 return false;278 }279 psStatsOptions stdevStat = psStatsStdevOption(options->stats->options); // Statistic for stdev280 psLogMsg ("pmPSFtryMetric", 4, "apresid: %f +/- %f; from statistics of %ld psf stars\n", poly->coeff[0],281 psStatsGetValue(options->stats, stdevStat), psfTry->sources->n);282 283 float dSys = psVectorSystematicError (psfTry->metric, psfTry->metricErr, 0.1);284 fprintf (stderr, "systematic error: %f\n", dSys);285 286 int n = 0;287 psVector *bright = psVectorAllocEmpty (psfTry->metric->n, PS_TYPE_F32);288 psVector *brightErr = psVectorAllocEmpty (psfTry->metric->n, PS_TYPE_F32);289 for (int i = 0; i < psfTry->metric->n; i++) {290 if (!isfinite(psfTry->metric->data.F32[i])) continue;291 if (!isfinite(psfTry->metricErr->data.F32[i])) continue;292 if (psfTry->metricErr->data.F32[i] <= 0.0) continue;293 if (psfTry->metricErr->data.F32[i] > 0.005) continue;294 bright->data.F32[n] = psfTry->metric->data.F32[i];295 brightErr->data.F32[n] = psfTry->metricErr->data.F32[i];296 n++;297 }298 bright->n = brightErr->n = n;299 300 float dSysBright = psVectorSystematicError (bright, brightErr, 0.1);301 fprintf (stderr, "bright systematic error: %f\n", dSysBright);302 psFree(bright);303 psFree(brightErr);304 305 // XXX test dump of fitted model (dump when tracing?)306 if (psTraceGetLevel("psModules.objects") >= 4) {307 FILE *f = fopen ("resid.dat", "w");308 psVector *apfit = psPolynomial1DEvalVector (poly, r2rflux);309 for (int i = 0; i < psfTry->sources->n; i++) {310 int keep = (psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PSFTRY_MASK_ALL);311 312 pmSource *source = psfTry->sources->data[i];313 float x = source->peak->x;314 float y = source->peak->y;315 316 fprintf (f, "%d %d, %f %f %f %f %f %f %f\n",317 i, keep, x, y,318 psfTry->fitMag->data.F32[i],319 r2rflux->data.F32[i],320 psfTry->metric->data.F32[i],321 psfTry->metricErr->data.F32[i],322 apfit->data.F32[i]);323 }324 fclose (f);325 psFree (apfit);326 }327 328 // XXX drop the skyBias value, or include above??329 psfTry->psf->skyBias = poly->coeff[1];330 psfTry->psf->ApResid = poly->coeff[0];331 psfTry->psf->dApResid = psStatsGetValue(options->stats, stdevStat);332 333 psFree (r2rflux);334 psFree (poly);335 336 return true;337 }338 339 /*340 (aprMag' - fitMag) = rflux*skyBias + ApTrend(x,y)341 (aprMag - rflux*skyBias) - fitMag = ApTrend(x,y)342 (aprMag - rflux*skyBias) = fitMag + ApTrend(x,y)343 */344 345 bool pmPSFFitShapeParams (pmPSF *psf, psArray *sources, psVector *x, psVector *y, psVector *srcMask) {346 347 // we are doing a robust fit. after each pass, we drop points which are more deviant than348 // three sigma. mask is currently updated for each pass.349 350 // The shape parameters (SXX, SXY, SYY) are strongly coupled. We have to handle them very351 // carefully. First, we convert them to the Ellipse Polarization terms (E0, E1, E2) for352 // each source and fit this set of parameters. These values are less tightly coupled, but353 // are still inter-related. The fitted values do a good job of constraining the major axis354 // and the position angle, but the minor axis is weakly measured. When we apply the PSF355 // model to construct a source model, we convert the fitted values of E0,E1,E2 to the shape356 // parameters, with the constraint that the minor axis must be greater than a minimum357 // threshold.358 359 // XXX re-read the sextractor manual on handling 'infinitely thin' sources...360 361 // convert the measured source shape paramters to polarization terms362 psVector *e0 = psVectorAlloc (sources->n, PS_TYPE_F32);363 psVector *e1 = psVectorAlloc (sources->n, PS_TYPE_F32);364 psVector *e2 = psVectorAlloc (sources->n, PS_TYPE_F32);365 psVector *mag = psVectorAlloc (sources->n, PS_TYPE_F32);366 367 for (int i = 0; i < sources->n; i++) {368 // skip any masked sources (failed to fit one of the model steps or get a magnitude)369 if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue;370 371 pmSource *source = sources->data[i];372 assert (source->modelEXT); // all unmasked sources should have modelEXT373 374 psEllipsePol pol = pmPSF_ModelToFit (source->modelEXT->params->data.F32);375 376 e0->data.F32[i] = pol.e0;377 e1->data.F32[i] = pol.e1;378 e2->data.F32[i] = pol.e2;379 380 float flux = source->modelEXT->params->data.F32[PM_PAR_I0];381 mag->data.F32[i] = (flux > 0.0) ? -2.5*log(flux) : -100.0;382 }383 384 if (psf->psfTrendMode == PM_TREND_MAP) {385 float scatterTotal = 0.0;386 float scatterTotalMin = FLT_MAX;387 int entryMin = -1;388 389 psVector *dz = NULL;390 psVector *mask = psVectorAlloc (sources->n, PS_TYPE_VECTOR_MASK);391 392 // check the fit residuals and increase Nx,Ny until the error is minimized393 // pmPSFParamTrend increases the number along the longer of x or y394 for (int i = 1; i <= PS_MAX (psf->trendNx, psf->trendNy); i++) {395 396 // copy srcMask to mask (we do not want the mask values set in pmPSFFitShapeParamsMap to be sticky)397 for (int i = 0; i < mask->n; i++) {398 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i];399 }400 if (!pmPSFFitShapeParamsMap (psf, i, &scatterTotal, mask, x, y, mag, e0, e1, e2, dz)) {401 break;402 }403 404 // store the resulting scatterTotal values and the scales, redo the best405 if (scatterTotal < scatterTotalMin) {406 scatterTotalMin = scatterTotal;407 entryMin = i;408 }409 }410 if (entryMin == -1) {411 psError (PS_ERR_UNKNOWN, false, "failed to find image map for shape params");412 return false;413 }414 415 // copy srcMask to mask (we do not want the mask values set in pmPSFFitShapeParamsMap to be sticky)416 for (int i = 0; i < mask->n; i++) {417 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i];418 }419 if (!pmPSFFitShapeParamsMap (psf, entryMin, &scatterTotal, mask, x, y, mag, e0, e1, e2, dz)) {420 psAbort ("failed pmPSFFitShapeParamsMap on second pass?");421 }422 423 pmTrend2D *trend = psf->params->data[PM_PAR_E0];424 psf->trendNx = trend->map->map->numCols;425 psf->trendNy = trend->map->map->numRows;426 427 // copy mask back to srcMask428 for (int i = 0; i < mask->n; i++) {429 srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = mask->data.PS_TYPE_VECTOR_MASK_DATA[i];430 }431 432 psFree (mask);433 psFree (dz);434 } else {435 436 // XXX iterate Nx, Ny based on scatter?437 // XXX we force the x & y order to be the same438 // modify the order to correspond to the actual number of matched stars:439 int order = PS_MAX (psf->trendNx, psf->trendNy);440 if ((sources->n < 15) && (order >= 3)) order = 2;441 if ((sources->n < 11) && (order >= 2)) order = 1;442 if ((sources->n < 8) && (order >= 1)) order = 0;443 if ((sources->n < 3)) {444 psError (PS_ERR_UNKNOWN, true, "failed to fit polynomial to shape params");445 return false;446 }447 psf->trendNx = order;448 psf->trendNy = order;449 450 // we run 'clipIter' cycles clipping in each of x and y, with only one iteration each.451 // This way, the parameters masked by one of the fits will be applied to the others452 for (int i = 0; i < psf->psfTrendStats->clipIter; i++) {453 454 psStatsOptions meanOption = psStatsMeanOption(psf->psfTrendStats->options);455 psStatsOptions stdevOption = psStatsStdevOption(psf->psfTrendStats->options);456 457 pmTrend2D *trend = NULL;458 float mean, stdev;459 460 // XXX we are using the same stats structure on each pass: do we need to re-init it?461 bool status = true;462 463 trend = psf->params->data[PM_PAR_E0];464 status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e0, NULL);465 mean = psStatsGetValue (trend->stats, meanOption);466 stdev = psStatsGetValue (trend->stats, stdevOption);467 psTrace ("psModules.objects", 4, "clipped E0 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e0->n);468 pmSourceVisualPSFModelResid (trend, x, y, e0, srcMask);469 470 trend = psf->params->data[PM_PAR_E1];471 status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e1, NULL);472 mean = psStatsGetValue (trend->stats, meanOption);473 stdev = psStatsGetValue (trend->stats, stdevOption);474 psTrace ("psModules.objects", 4, "clipped E1 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e1->n);475 pmSourceVisualPSFModelResid (trend, x, y, e1, srcMask);476 477 trend = psf->params->data[PM_PAR_E2];478 status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e2, NULL);479 mean = psStatsGetValue (trend->stats, meanOption);480 stdev = psStatsGetValue (trend->stats, stdevOption);481 psTrace ("psModules.objects", 4, "clipped E2 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e2->n);482 pmSourceVisualPSFModelResid (trend, x, y, e2, srcMask);483 484 if (!status) {485 psError (PS_ERR_UNKNOWN, true, "failed to fit polynomial to shape params");486 return false;487 }488 }489 }490 491 // test dump of the psf parameters492 if (psTraceGetLevel("psModules.objects") >= 4) {493 FILE *f = fopen ("pol.dat", "w");494 fprintf (f, "# x y : e0obs e1obs e2obs : e0fit e1fit e2fit : mask\n");495 for (int i = 0; i < e0->n; i++) {496 fprintf (f, "%f %f : %f %f %f : %f %f %f : %d\n",497 x->data.F32[i], y->data.F32[i],498 e0->data.F32[i], e1->data.F32[i], e2->data.F32[i],499 pmTrend2DEval (psf->params->data[PM_PAR_E0], x->data.F32[i], y->data.F32[i]),500 pmTrend2DEval (psf->params->data[PM_PAR_E1], x->data.F32[i], y->data.F32[i]),501 pmTrend2DEval (psf->params->data[PM_PAR_E2], x->data.F32[i], y->data.F32[i]),502 srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]);503 }504 fclose (f);505 }506 507 psFree (e0);508 psFree (e1);509 psFree (e2);510 psFree (mag);511 return true;512 }513 514 // fit the shape variations as a psImageMap for the given scale factor515 bool pmPSFFitShapeParamsMap (pmPSF *psf, int scale, float *scatterTotal, psVector *mask, psVector *x, psVector *y, psVector *mag, psVector *e0obs, psVector *e1obs, psVector *e2obs, psVector *dz) {516 517 int Nx, Ny;518 519 // set the map scale to match the aspect ratio : for a scale of 1, we guarantee520 // that we have a single cell521 if (psf->fieldNx > psf->fieldNy) {522 Nx = scale;523 float AR = psf->fieldNy / (float) psf->fieldNx;524 Ny = (int) (Nx * AR + 0.5);525 Ny = PS_MAX (1, Ny);526 } else {527 Ny = scale;528 float AR = psf->fieldNx / (float) psf->fieldNy;529 Nx = (int) (Ny * AR + 0.5);530 Nx = PS_MAX (1, Nx);531 }532 533 // do we have enough sources for this fine of a grid?534 if (x->n < 10*Nx*Ny) {535 return false;536 }537 538 // XXX check this against the exising type539 pmTrend2DMode psfTrendMode = PM_TREND_MAP;540 541 psImageBinning *binning = psImageBinningAlloc();542 binning->nXruff = Nx;543 binning->nYruff = Ny;544 binning->nXfine = psf->fieldNx;545 binning->nYfine = psf->fieldNy;546 psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER);547 psImageBinningSetSkipByOffset (binning, psf->fieldXo, psf->fieldYo);548 549 psFree (psf->params->data[PM_PAR_E0]);550 psFree (psf->params->data[PM_PAR_E1]);551 psFree (psf->params->data[PM_PAR_E2]);552 553 int nIter = psf->psfTrendStats->clipIter;554 psf->psfTrendStats->clipIter = 1;555 psf->params->data[PM_PAR_E0] = pmTrend2DNoImageAlloc (psfTrendMode, binning, psf->psfTrendStats);556 psf->params->data[PM_PAR_E1] = pmTrend2DNoImageAlloc (psfTrendMode, binning, psf->psfTrendStats);557 psf->params->data[PM_PAR_E2] = pmTrend2DNoImageAlloc (psfTrendMode, binning, psf->psfTrendStats);558 psFree (binning);559 560 // if the map is 1x1 (a single value), we measure the resulting ensemble scatter561 562 // if the map is more finely sampled, divide the values into two sets: measure the fit from563 // one set and the scatter from the other set.564 psVector *x_fit = NULL;565 psVector *y_fit = NULL;566 psVector *x_tst = NULL;567 psVector *y_tst = NULL;568 569 psVector *e0obs_fit = NULL;570 psVector *e1obs_fit = NULL;571 psVector *e2obs_fit = NULL;572 psVector *e0obs_tst = NULL;573 psVector *e1obs_tst = NULL;574 psVector *e2obs_tst = NULL;575 576 if (scale == 1) {577 x_fit = psMemIncrRefCounter (x);578 y_fit = psMemIncrRefCounter (y);579 x_tst = psMemIncrRefCounter (x);580 y_tst = psMemIncrRefCounter (y);581 e0obs_fit = psMemIncrRefCounter (e0obs);582 e1obs_fit = psMemIncrRefCounter (e1obs);583 e2obs_fit = psMemIncrRefCounter (e2obs);584 e0obs_tst = psMemIncrRefCounter (e0obs);585 e1obs_tst = psMemIncrRefCounter (e1obs);586 e2obs_tst = psMemIncrRefCounter (e2obs);587 } else {588 x_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);589 y_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);590 x_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);591 y_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);592 e0obs_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);593 e1obs_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);594 e2obs_fit = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);595 e0obs_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);596 e1obs_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);597 e2obs_tst = psVectorAlloc (e0obs->n/2, PS_TYPE_F32);598 for (int i = 0; i < e0obs_fit->n; i++) {599 // e0obs->n == 8 or 9:600 // i = 0, 1, 2, 3 : 2i+0 = 0, 2, 4, 6601 // i = 0, 1, 2, 3 : 2i+1 = 1, 3, 5, 7602 x_fit->data.F32[i] = x->data.F32[2*i+0];603 x_tst->data.F32[i] = x->data.F32[2*i+1];604 y_fit->data.F32[i] = y->data.F32[2*i+0];605 y_tst->data.F32[i] = y->data.F32[2*i+1];606 607 e0obs_fit->data.F32[i] = e0obs->data.F32[2*i+0];608 e0obs_tst->data.F32[i] = e0obs->data.F32[2*i+1];609 e1obs_fit->data.F32[i] = e1obs->data.F32[2*i+0];610 e1obs_tst->data.F32[i] = e1obs->data.F32[2*i+1];611 e2obs_fit->data.F32[i] = e2obs->data.F32[2*i+0];612 e2obs_tst->data.F32[i] = e2obs->data.F32[2*i+1];613 }614 }615 616 // the mask marks the values not used to calculate the ApTrend617 psVector *fitMask = psVectorAlloc (x_fit->n, PS_TYPE_VECTOR_MASK);618 // copy mask values to fitMask as a starting point619 for (int i = 0; i < fitMask->n; i++) {620 fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i] = mask->data.PS_TYPE_VECTOR_MASK_DATA[i];621 }622 623 // we run 'clipIter' cycles clipping in each of x and y, with only one iteration each.624 // This way, the parameters masked by one of the fits will be applied to the others625 for (int i = 0; i < nIter; i++) {626 // XXX we are using the same stats structure on each pass: do we need to re-init it?627 psStatsOptions meanOption = psStatsMeanOption(psf->psfTrendStats->options);628 psStatsOptions stdevOption = psStatsStdevOption(psf->psfTrendStats->options);629 630 pmTrend2D *trend = NULL;631 float mean, stdev;632 633 // XXX we are using the same stats structure on each pass: do we need to re-init it?634 bool status = true;635 636 trend = psf->params->data[PM_PAR_E0];637 status &= pmTrend2DFit (trend, fitMask, 0xff, x_fit, y_fit, e0obs_fit, NULL);638 mean = psStatsGetValue (trend->stats, meanOption);639 stdev = psStatsGetValue (trend->stats, stdevOption);640 psTrace ("psModules.objects", 4, "clipped E0 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e0obs_fit->n);641 // pmTrend2DPrintMap (trend);642 psImageMapCleanup (trend->map);643 // pmTrend2DPrintMap (trend);644 pmSourceVisualPSFModelResid (trend, x, y, e0obs, mask);645 646 trend = psf->params->data[PM_PAR_E1];647 status &= pmTrend2DFit (trend, fitMask, 0xff, x_fit, y_fit, e1obs_fit, NULL);648 mean = psStatsGetValue (trend->stats, meanOption);649 stdev = psStatsGetValue (trend->stats, stdevOption);650 psTrace ("psModules.objects", 4, "clipped E1 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e1obs_fit->n);651 // pmTrend2DPrintMap (trend);652 psImageMapCleanup (trend->map);653 // pmTrend2DPrintMap (trend);654 pmSourceVisualPSFModelResid (trend, x, y, e1obs, mask);655 656 trend = psf->params->data[PM_PAR_E2];657 status &= pmTrend2DFit (trend, fitMask, 0xff, x_fit, y_fit, e2obs_fit, NULL);658 mean = psStatsGetValue (trend->stats, meanOption);659 stdev = psStatsGetValue (trend->stats, stdevOption);660 psTrace ("psModules.objects", 4, "clipped E2 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e2obs->n);661 // pmTrend2DPrintMap (trend);662 psImageMapCleanup (trend->map);663 // pmTrend2DPrintMap (trend);664 pmSourceVisualPSFModelResid (trend, x, y, e2obs, mask);665 }666 psf->psfTrendStats->clipIter = nIter; // restore default setting667 668 // construct the fitted values and the residuals669 psVector *e0fit = pmTrend2DEvalVector (psf->params->data[PM_PAR_E0], fitMask, 0xff, x_tst, y_tst);670 psVector *e1fit = pmTrend2DEvalVector (psf->params->data[PM_PAR_E1], fitMask, 0xff, x_tst, y_tst);671 psVector *e2fit = pmTrend2DEvalVector (psf->params->data[PM_PAR_E2], fitMask, 0xff, x_tst, y_tst);672 673 psVector *e0res = (psVector *) psBinaryOp (NULL, (void *) e0obs_tst, "-", (void *) e0fit);674 psVector *e1res = (psVector *) psBinaryOp (NULL, (void *) e1obs_tst, "-", (void *) e1fit);675 psVector *e2res = (psVector *) psBinaryOp (NULL, (void *) e2obs_tst, "-", (void *) e2fit);676 677 // measure scatter for the unfitted points678 // psTraceSetLevel ("psLib.math.vectorSampleStdev", 10);679 // psTraceSetLevel ("psLib.math.vectorClippedStats", 10);680 pmPSFShapeParamsScatter (scatterTotal, e0res, e1res, e2res, fitMask, 0xff, psStatsStdevOption(psf->psfTrendStats->options));681 // psTraceSetLevel ("psLib.math.vectorSampleStdev", 0);682 // psTraceSetLevel ("psLib.math.vectorClippedStats", 0);683 684 psLogMsg ("psphot.psftry", PS_LOG_INFO, "result of %d x %d grid\n", Nx, Ny);685 psLogMsg ("psphot.psftry", PS_LOG_INFO, "systematic scatter: %f\n", *scatterTotal);686 687 psFree (x_fit);688 psFree (y_fit);689 psFree (x_tst);690 psFree (y_tst);691 692 psFree (e0obs_fit);693 psFree (e1obs_fit);694 psFree (e2obs_fit);695 psFree (e0obs_tst);696 psFree (e1obs_tst);697 psFree (e2obs_tst);698 699 psFree (e0fit);700 psFree (e1fit);701 psFree (e2fit);702 703 psFree (e0res);704 psFree (e1res);705 psFree (e2res);706 707 // XXX copy fitMask values back to mask708 for (int i = 0; i < fitMask->n; i++) {709 mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = fitMask->data.PS_TYPE_VECTOR_MASK_DATA[i];710 }711 psFree (fitMask);712 713 return true;714 }715 716 // calculate the scatter of the parameters717 bool pmPSFShapeParamsScatter(float *scatterTotal, psVector *e0res, psVector *e1res, psVector *e2res, psVector *mask, psVectorMaskType maskValue, psStatsOptions stdevOpt)718 {719 720 // psStats *stats = psStatsAlloc(stdevOpt);721 psStats *stats = psStatsAlloc(PS_STAT_CLIPPED_STDEV);722 723 // calculate the root-mean-square of E0, E1, E2724 float dEsquare = 0.0;725 psStatsInit (stats);726 if (!psVectorStats (stats, e0res, NULL, mask, maskValue)) {727 psError(PS_ERR_UNKNOWN, false, "failure to measure stats");728 return false;729 }730 dEsquare += PS_SQR(psStatsGetValue(stats, stdevOpt));731 732 psStatsInit (stats);733 if (!psVectorStats (stats, e1res, NULL, mask, maskValue)) {734 psError(PS_ERR_UNKNOWN, false, "failure to measure stats");735 return false;736 }737 dEsquare += PS_SQR(psStatsGetValue(stats, stdevOpt));738 739 psStatsInit (stats);740 if (!psVectorStats (stats, e2res, NULL, mask, maskValue)) {741 psError(PS_ERR_UNKNOWN, false, "failure to measure stats");742 return false;743 }744 dEsquare += PS_SQR(psStatsGetValue(stats, stdevOpt));745 746 *scatterTotal = sqrtf(dEsquare);747 748 psFree(stats);749 return true;750 }751 752 // calculate the minimum scatter of the parameters753 bool pmPSFShapeParamsErrors(float *errorFloor, psVector *mag, psVector *e0res, psVector *e1res,754 psVector *e2res, psVector *mask, int nGroup, psStatsOptions stdevOpt)755 {756 757 psStats *statsS = psStatsAlloc(stdevOpt);758 759 // measure the trend in bins with 10 values each; if < 10 total, use them all760 int nBin = PS_MAX (mag->n / nGroup, 1);761 762 // use mag to group parameters in sequence763 psVector *index = psVectorSortIndex (NULL, mag);764 765 // subset vectors for mag and dap values within the given range766 psVector *dE0subset = psVectorAllocEmpty (nGroup, PS_TYPE_F32);767 psVector *dE1subset = psVectorAllocEmpty (nGroup, PS_TYPE_F32);768 psVector *dE2subset = psVectorAllocEmpty (nGroup, PS_TYPE_F32);769 psVector *mkSubset = psVectorAllocEmpty (nGroup, PS_TYPE_VECTOR_MASK);770 771 int n = 0;772 float min = INFINITY; // Minimum error773 for (int i = 0; i < nBin; i++) {774 int j;775 int nValid = 0;776 for (j = 0; (j < nGroup) && (n < mag->n); j++, n++) {777 int N = index->data.U32[n];778 dE0subset->data.F32[j] = e0res->data.F32[N];779 dE1subset->data.F32[j] = e1res->data.F32[N];780 dE2subset->data.F32[j] = e2res->data.F32[N];781 782 mkSubset->data.PS_TYPE_VECTOR_MASK_DATA[j] = mask->data.PS_TYPE_VECTOR_MASK_DATA[N];783 if (!mask->data.PS_TYPE_VECTOR_MASK_DATA[N]) nValid ++;784 }785 if (nValid < 3) continue;786 787 dE0subset->n = j;788 dE1subset->n = j;789 dE2subset->n = j;790 mkSubset->n = j;791 792 // calculate the root-mean-square of E0, E1, E2793 float dEsquare = 0.0;794 psStatsInit (statsS);795 if (!psVectorStats (statsS, dE0subset, NULL, mkSubset, 0xff)) {796 }797 dEsquare += PS_SQR(psStatsGetValue(statsS, stdevOpt));798 799 psStatsInit (statsS);800 if (!psVectorStats (statsS, dE1subset, NULL, mkSubset, 0xff)) {801 psError(PS_ERR_UNKNOWN, false, "failure to measure stats");802 return false;803 }804 dEsquare += PS_SQR(psStatsGetValue(statsS, stdevOpt));805 806 psStatsInit (statsS);807 if (!psVectorStats (statsS, dE2subset, NULL, mkSubset, 0xff)) {808 psError(PS_ERR_UNKNOWN, false, "failure to measure stats");809 return false;810 }811 dEsquare += PS_SQR(psStatsGetValue(statsS, stdevOpt));812 813 if (isfinite(dEsquare)) {814 float err = sqrtf(dEsquare);815 if (err < min) {816 min = err;817 }818 }819 }820 *errorFloor = min;821 822 psFree (dE0subset);823 psFree (dE1subset);824 psFree (dE2subset);825 psFree (mkSubset);826 827 psFree(index);828 829 psFree(statsS);830 831 return true;832 89 } 833 90 … … 886 143 if (mask->data.PS_TYPE_VECTOR_MASK_DATA[n]) continue; 887 144 res2mean += PS_SQR(residuals->data.F32[n]); 888 ChiSq += PS_SQR(residuals->data.F32[n] /errors->data.F32[n]);145 ChiSq += PS_SQR(residuals->data.F32[n]) / PS_SQR(errors->data.F32[n]); 889 146 nPts += 1.0; 890 147 } … … 914 171 float dS = (ChiSq - 1.0) / dRdS; 915 172 S2guess += dS; 173 S2guess = PS_MAX(0.0, S2guess); 916 174 917 175 psLogMsg ("psModules", 3, "ChiSquare: %f, dS: %f, S2 guess: %f\n", ChiSq, dS, S2guess); -
branches/eam_branches/20090715/psModules/src/objects/pmPSFtry.h
r25353 r25476 89 89 * 90 90 */ 91 pmPSFtry *pmPSFtryModel (const psArray *sources, const char *modelName, pmPSFOptions *options, psImageMaskType maskVal, psImageMaskType mark); 91 pmPSFtry *pmPSFtryModel ( 92 const psArray *sources, ///< PSF sources to use in the pmPSF model analysis 93 const char *modelName, ///< human-readable name of desired model 94 pmPSFOptions *options, 95 psImageMaskType maskVal, 96 psImageMaskType mark 97 ); 98 99 /** fit EXT models to all possible psf sources */ 100 bool pmPSFtryFitEXT (pmPSFtry *psfTry, pmPSFOptions *options, psImageMaskType maskVal, psImageMaskType markVal); 101 102 bool pmPSFtryMakePSF (pmPSFtry *psfTry); 103 104 bool pmPSFtryFitPSF (pmPSFtry *psfTry, pmPSFOptions *options, psImageMaskType maskVal, psImageMaskType markVal); 92 105 93 106 /** pmPSFtryMetric() … … 97 110 * 98 111 */ 99 bool pmPSFtryMetric( 100 pmPSFtry *psfTry, ///< Add comment. 101 pmPSFOptions *options ///< PSF fitting options 102 ); 112 bool pmPSFtryMetric(pmPSFtry *psfTry); 103 113 104 114 /** pmPSFtryMetric_Alt() … … 112 122 float RADIUS ///< Add comment. 113 123 ); 124 125 bool pmPSFFitShapeParams (pmPSF *psf, psArray *sources, psVector *x, psVector *y, psVector *srcMask); 126 127 float psVectorSystematicError (psVector *residuals, psVector *errors, float clipFraction); 128 129 /// @} 130 # endif 114 131 115 132 /** … … 125 142 * 126 143 */ 127 bool pmPSFFromPSFtry (pmPSFtry *psfTry);128 144 129 bool pmPSFFitShapeParams (pmPSF *psf, psArray *sources, psVector *x, psVector *y, psVector *srcMask);130 bool pmPSFFitShapeParamsMap (pmPSF *psf, int scale, float *scatterTotal, psVector *mask, psVector *x, psVector *y, psVector *mag, psVector *e0obs, psVector *e1obs, psVector *e2obs, psVector *dz);131 bool pmPSFShapeParamsScatter(float *scatterTotal, psVector *e0res, psVector *e1res, psVector *e2res, psVector *mask, psVectorMaskType maskValue, psStatsOptions stdevOpt);132 bool pmPSFShapeParamsErrors (float *errorFloor, psVector *mag, psVector *e0res, psVector *e1res, psVector *e2res, psVector *mask, int nGroup, psStatsOptions stdevOpt);133 134 float psVectorSystematicError (psVector *residuals, psVector *errors, float clipFraction);135 136 /// @}137 # endif -
branches/eam_branches/20090715/psModules/src/objects/pmPSFtryFitEXT.c
r25455 r25476 61 61 } 62 62 63 source->modelEXT = pmSourceModelGuess (source, psfTry->psf->type);63 source->modelEXT = pmSourceModelGuess (source, options->type); 64 64 if (source->modelEXT == NULL) { 65 65 psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL; … … 86 86 Next ++; 87 87 } 88 psLogMsg ("psphot.psftry", PS_LOG_MINUTIA, "fit ext: %f sec for %d of %ld sources\n", psTimerMark ("psf.fit"), Next, sources->n);89 psTrace ("psModules.object", 3, "keeping %d of %ld PSF candidates (EXT)\n", Next, sources->n);88 psLogMsg ("psphot.psftry", PS_LOG_MINUTIA, "fit ext: %f sec for %d of %ld sources\n", psTimerMark ("psf.fit"), Next, psfTry->sources->n); 89 psTrace ("psModules.object", 3, "keeping %d of %ld PSF candidates (EXT)\n", Next, psfTry->sources->n); 90 90 91 91 if (Next == 0) { -
branches/eam_branches/20090715/psModules/src/objects/pmPSFtryFitPSF.c
r25455 r25476 39 39 // stage 3: Refit with fixed shape parameters. This function uses the LMM fitting, but could 40 40 // be re-written to use the simultaneous linear fitting (see psphotFitSourcesLinear.c) 41 bool pmPSFtryFitPSF (pmPSFtry *psfTry) { 41 bool pmPSFtryFitPSF (pmPSFtry *psfTry, pmPSFOptions *options, psImageMaskType maskVal, psImageMaskType markVal) { 42 43 bool status; 42 44 43 45 psTimerStart ("psf.fit"); 46 47 // maskVal is used to test for rejected pixels, and must include markVal 48 maskVal |= markVal; 49 50 int Npsf = 0; 44 51 for (int i = 0; i < psfTry->sources->n; i++) { 45 52 … … 98 105 psfTry->psf->nPSFstars = Npsf; 99 106 100 psLogMsg ("psphot.psftry", PS_LOG_MINUTIA, "fit psf: %f sec for %d of %ld sources\n", psTimerMark ("psf.fit"), Npsf, sources->n);101 psTrace ("psModules.object", 3, "keeping %d of %ld PSF candidates (PSF)\n", Npsf, sources->n);107 psLogMsg ("psphot.psftry", PS_LOG_MINUTIA, "fit psf: %f sec for %d of %ld sources\n", psTimerMark ("psf.fit"), Npsf, psfTry->sources->n); 108 psTrace ("psModules.object", 3, "keeping %d of %ld PSF candidates (PSF)\n", Npsf, psfTry->sources->n); 102 109 103 110 if (Npsf == 0) { 104 111 psError(PS_ERR_UNKNOWN, false, "No sources with good PSF fits after model is built."); 105 psFree(psfTry); 106 return NULL; 112 return false; 107 113 } 108 114 115 return true; 116 } -
branches/eam_branches/20090715/psModules/src/objects/pmPSFtryMakePSF.c
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/czw_branch/cleanup/psModules/src/objects/pmPSFFromPSFtry.c 24713-25285 /branches/eam_branches/20090522/psModules/src/objects/pmPSFFromPSFtry.c 24238-24573 /branches/pap/psModules/src/objects/pmPSFFromPSFtry.c 25238-25382 /branches/pap_mops/psModules/src/objects/pmPSFFromPSFtry.c 25137-25255 /trunk/psModules/src/objects/pmPSFFromPSFtry.c 24799-25395
r25455 r25476 1 1 /** @file pmPSFtry.c 2 * 3 * XXX: need description of file purpose 2 * @brief generate a pmPSF from a collection of EXT measurments of likely PSF stars. 4 3 * 5 4 * @author EAM, IfA … … 44 43 Note: some of the array entries may be NULL (failed fits); ignore them. 45 44 *****************************************************************************/ 46 bool pmPSF FromPSFtry (pmPSFtry *psfTry, int Nx, int Ny)45 bool pmPSFtryMakePSF (pmPSFtry *psfTry) 47 46 { 48 47 PS_ASSERT_PTR_NON_NULL(psfTry, false); … … 50 49 51 50 pmPSF *psf = psfTry->psf; 51 psVector *srcMask = psfTry->mask; 52 52 53 53 // construct the fit vectors from the collection of objects 54 54 psVector *x = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32); 55 55 psVector *y = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32); 56 psVector *z = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);57 56 58 57 // construct the x,y terms 59 58 for (int i = 0; i < psfTry->sources->n; i++) { 59 if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue; 60 60 61 pmSource *source = psfTry->sources->data[i]; 61 if (source->modelEXT == NULL) 62 continue; 62 assert (source->modelEXT); // all unmasked sources should have modelEXT 63 63 64 64 x->data.F32[i] = source->modelEXT->params->data.F32[PM_PAR_XPOS]; … … 66 66 } 67 67 68 if (!pmPSFFitShapeParams (psf, psfTry->sources, x, y, psfTry->mask)) { 68 // fit the shape parameters (SXX, SYY, SXY) as a function of position 69 if (!pmPSFFitShapeParams (psf, psfTry->sources, x, y, srcMask)) { 69 70 psFree(x); 70 71 psFree(y); 71 psFree(z);72 72 return false; 73 73 } 74 74 75 // skip the unfitted parameters (X, Y, Io, Sky) and the shape parameters (SXX, SYY, SXY) 76 // apply the values of Nx, Ny determined above for E0,E1,E2 to the remaining parameters 75 // vector to store the other parameter values 76 psVector *z = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32); 77 78 // skip the unfitted parameters (X, Y, Io, Sky) and the shape parameters (SXX, SYY, SXY); 79 // fit the remaining parameters. 77 80 for (int i = 0; i < psf->params->n; i++) { 78 81 switch (i) { … … 91 94 // select the per-object fitted data for this parameter 92 95 for (int j = 0; j < psfTry->sources->n; j++) { 96 // skip any masked sources (failed to fit one of the model steps or get a magnitude) 97 if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue; 98 93 99 pmSource *source = psfTry->sources->data[j]; 94 if (source->modelEXT == NULL) continue; 100 assert (source->modelEXT); // all unmasked sources should have modelEXT 101 95 102 z->data.F32[j] = source->modelEXT->params->data.F32[i]; 96 103 } 97 98 psImageBinning *binning = psImageBinningAlloc();99 binning->nXruff = psf->trendNx;100 binning->nYruff = psf->trendNy;101 binning->nXfine = psf->fieldNx;102 binning->nYfine = psf->fieldNy;103 104 if (psf->psfTrendMode == PM_TREND_MAP) {105 psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER);106 psImageBinningSetSkipByOffset (binning, psf->fieldXo, psf->fieldYo);107 }108 109 // free existing trend, re-alloc110 psFree (psf->params->data[i]);111 psf->params->data[i] = pmTrend2DNoImageAlloc (psf->psfTrendMode, binning, psf->psfTrendStats);112 psFree (binning);113 104 114 105 // fit the collection of measured parameters to the PSF 2D model 115 106 // the mask is carried from previous steps and updated with this operation 116 107 // the weight is either the flux error or NULL, depending on 'psf->poissonErrorParams' 117 if (!pmTrend2DFit (psf->params->data[i], psfTry->mask, 0xff, x, y, z, NULL)) {108 if (!pmTrend2DFit (psf->params->data[i], srcMask, 0xff, x, y, z, NULL)) { 118 109 psError(PS_ERR_UNKNOWN, false, "failed to build psf model for parameter %d", i); 119 110 psFree(x); … … 154 145 } 155 146 147 // fit the shape parameters using the supplied order (pmPSF->trendNx,trendNy) 148 bool pmPSFFitShapeParams (pmPSF *psf, psArray *sources, psVector *x, psVector *y, psVector *srcMask) { 149 150 // we are doing a robust fit. after each pass, we drop points which are more deviant than 151 // three sigma. the source mask (srcMask) is updated for each pass. 152 153 // The shape parameters (SXX, SXY, SYY) are strongly coupled. We have to handle them very 154 // carefully. First, we convert them to the Ellipse Polarization terms (E0, E1, E2) for 155 // each source and fit this set of parameters. These values are less tightly coupled, but 156 // are still inter-related. The fitted values do a good job of constraining the major axis 157 // and the position angle, but the minor axis is weakly measured. When we apply the PSF 158 // model to construct a source model, we convert the fitted values of E0,E1,E2 to the shape 159 // parameters, with the constraint that the minor axis must be greater than a minimum 160 // threshold. 161 162 // XXX re-read the sextractor manual on handling 'infinitely thin' sources... 163 164 // storage vectors for the polarization terms & mags 165 psVector *e0 = psVectorAlloc (sources->n, PS_TYPE_F32); 166 psVector *e1 = psVectorAlloc (sources->n, PS_TYPE_F32); 167 psVector *e2 = psVectorAlloc (sources->n, PS_TYPE_F32); 168 169 // convert the measured source shape paramters to polarization terms 170 for (int i = 0; i < sources->n; i++) { 171 // skip any masked sources (failed to fit one of the model steps or get a magnitude) 172 if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue; 173 174 pmSource *source = sources->data[i]; 175 assert (source->modelEXT); // all unmasked sources should have modelEXT 176 177 psEllipsePol pol = pmPSF_ModelToFit (source->modelEXT->params->data.F32); 178 179 e0->data.F32[i] = pol.e0; 180 e1->data.F32[i] = pol.e1; 181 e2->data.F32[i] = pol.e2; 182 } 183 184 // we run 'clipIter' cycles clipping in each of x and y, with only one iteration each. 185 // This way, the parameters masked by one of the fits will be applied to the others 186 for (int i = 0; i < psf->psfTrendStats->clipIter; i++) { 187 // XXX we are using the same stats structure on each pass: do we need to re-init it? 188 // XXX we hardwire this to SAMPLE stats above (psphotChoosePSF.c), hardwire here instead? 189 psStatsOptions meanOption = psStatsMeanOption(psf->psfTrendStats->options); 190 psStatsOptions stdevOption = psStatsStdevOption(psf->psfTrendStats->options); 191 192 pmTrend2D *trend = NULL; 193 float mean, stdev; 194 195 // XXX we are using the same stats structure on each pass: do we need to re-init it? 196 bool status = true; 197 198 trend = psf->params->data[PM_PAR_E0]; 199 trend->stats->clipIter = 1; // in allocation, this value is set to the value of nIter, but we should use 1 here 200 status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e0, NULL); 201 mean = psStatsGetValue (trend->stats, meanOption); 202 stdev = psStatsGetValue (trend->stats, stdevOption); 203 psTrace ("psModules.objects", 4, "clipped E0 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e0->n); 204 if (psf->psfTrendMode == PM_TREND_MAP) psImageMapCleanup (trend->map); 205 // pmSourceVisualPSFModelResid (trend, x, y, e0, srcMask); 206 207 trend = psf->params->data[PM_PAR_E1]; 208 trend->stats->clipIter = 1; // in allocation, this value is set to the value of nIter, but we should use 1 here 209 status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e1, NULL); 210 mean = psStatsGetValue (trend->stats, meanOption); 211 stdev = psStatsGetValue (trend->stats, stdevOption); 212 psTrace ("psModules.objects", 4, "clipped E1 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e1->n); 213 if (psf->psfTrendMode == PM_TREND_MAP) psImageMapCleanup (trend->map); 214 // pmSourceVisualPSFModelResid (trend, x, y, e1, srcMask); 215 216 trend = psf->params->data[PM_PAR_E2]; 217 trend->stats->clipIter = 1; // in allocation, this value is set to the value of nIter, but we should use 1 here 218 status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e2, NULL); 219 mean = psStatsGetValue (trend->stats, meanOption); 220 stdev = psStatsGetValue (trend->stats, stdevOption); 221 psTrace ("psModules.objects", 4, "clipped E2 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e2->n); 222 if (psf->psfTrendMode == PM_TREND_MAP) psImageMapCleanup (trend->map); 223 // pmSourceVisualPSFModelResid (trend, x, y, e2, srcMask); 224 225 if (!status) { 226 psError (PS_ERR_UNKNOWN, true, "failed to fit PSF shape params"); 227 return false; 228 } 229 } 230 231 // test dump of the psf parameters 232 if (psTraceGetLevel("psModules.objects") >= 4) { 233 FILE *f = fopen ("pol.dat", "w"); 234 fprintf (f, "# x y : e0obs e1obs e2obs : e0fit e1fit e2fit : mask\n"); 235 for (int i = 0; i < e0->n; i++) { 236 fprintf (f, "%f %f : %f %f %f : %f %f %f : %d\n", 237 x->data.F32[i], y->data.F32[i], 238 e0->data.F32[i], e1->data.F32[i], e2->data.F32[i], 239 pmTrend2DEval (psf->params->data[PM_PAR_E0], x->data.F32[i], y->data.F32[i]), 240 pmTrend2DEval (psf->params->data[PM_PAR_E1], x->data.F32[i], y->data.F32[i]), 241 pmTrend2DEval (psf->params->data[PM_PAR_E2], x->data.F32[i], y->data.F32[i]), 242 srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]); 243 } 244 fclose (f); 245 } 246 247 psFree (e0); 248 psFree (e1); 249 psFree (e2); 250 return true; 251 } 252 -
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/eam_branches/20090715/psModules/src/objects/pmSourceVisual.c
r25268 r25476 5 5 #include <pslib.h> 6 6 #include "pmTrend2D.h" 7 #include "pmPSF.h" 8 #include "pmPSFtry.h" 7 9 #include "pmSourceVisual.h" 8 10 … … 27 29 bool pmSourcePlotPoints3D (int myKapa, Graphdata *graphdata, psVector *xn, psVector *yn, psVector *zn, float theta, float phi); 28 30 31 bool pmSourceVisualPlotPSFMetric (pmPSFtry *psfTry) { 32 33 Graphdata graphdata; 34 35 if (!pmVisualIsVisual()) return true; 36 37 if (kapa1 == -1) { 38 kapa1 = KapaOpenNamedSocket ("kapa", "pmSource:plots"); 39 if (kapa1 == -1) { 40 fprintf (stderr, "failure to open kapa; visual mode disabled\n"); 41 pmVisualSetVisual(false); 42 return false; 43 } 44 } 45 46 KapaClearPlots (kapa1); 47 KapaInitGraph (&graphdata); 48 49 psVector *x = psVectorAllocEmpty (psfTry->sources->n, PS_TYPE_F32); 50 psVector *y = psVectorAllocEmpty (psfTry->sources->n, PS_TYPE_F32); 51 psVector *dy = psVectorAllocEmpty(psfTry->sources->n, PS_TYPE_F32); 52 53 graphdata.xmin = +32.0; 54 graphdata.xmax = -32.0; 55 graphdata.ymin = +32.0; 56 graphdata.ymax = -32.0; 57 58 // construct the plot vectors 59 int n = 0; 60 for (int i = 0; i < psfTry->sources->n; i++) { 61 if (psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PSFTRY_MASK_ALL) continue; 62 x->data.F32[n] = psfTry->fitMag->data.F32[i]; 63 y->data.F32[n] = psfTry->metric->data.F32[i]; 64 dy->data.F32[n] = psfTry->metricErr->data.F32[i]; 65 graphdata.xmin = PS_MIN(graphdata.xmin, x->data.F32[n]); 66 graphdata.xmax = PS_MAX(graphdata.xmax, x->data.F32[n]); 67 graphdata.ymin = PS_MIN(graphdata.ymin, y->data.F32[n]); 68 graphdata.ymax = PS_MAX(graphdata.ymax, y->data.F32[n]); 69 n++; 70 } 71 x->n = y->n = dy->n = n; 72 73 float range; 74 range = graphdata.xmax - graphdata.xmin; 75 graphdata.xmax += 0.05*range; 76 graphdata.xmin -= 0.05*range; 77 range = graphdata.ymax - graphdata.ymin; 78 graphdata.ymax += 0.05*range; 79 graphdata.ymin -= 0.05*range; 80 81 KapaSetLimits (kapa1, &graphdata); 82 83 KapaSetFont (kapa1, "helvetica", 14); 84 KapaBox (kapa1, &graphdata); 85 KapaSendLabel (kapa1, "PSF Mag", KAPA_LABEL_XM); 86 KapaSendLabel (kapa1, "Ap Mag - PSF Mag", KAPA_LABEL_YM); 87 88 graphdata.color = KapaColorByName ("black"); 89 graphdata.ptype = 2; 90 graphdata.size = 0.5; 91 graphdata.style = 2; 92 graphdata.etype |= 0x01; 93 94 KapaPrepPlot (kapa1, n, &graphdata); 95 KapaPlotVector (kapa1, n, x->data.F32, "x"); 96 KapaPlotVector (kapa1, n, y->data.F32, "y"); 97 KapaPlotVector (kapa1, n, dy->data.F32, "dym"); 98 KapaPlotVector (kapa1, n, dy->data.F32, "dyp"); 99 100 psFree (x); 101 psFree (y); 102 psFree (dy); 103 104 // pause and wait for user input: 105 // continue, save (provide name), ?? 106 char key[10]; 107 fprintf (stdout, "[c]ontinue? "); 108 if (!fgets(key, 8, stdin)) { 109 psWarning("Unable to read option"); 110 } 111 return true; 112 } 29 113 30 114 bool pmSourceVisualPSFModelResid (pmTrend2D *trend, psVector *x, psVector *y, psVector *param, psVector *mask) { -
branches/eam_branches/20090715/psModules/src/objects/pmSourceVisual.h
r23242 r25476 18 18 19 19 bool pmSourceVisualPSFModelResid (pmTrend2D *trend, psVector *x, psVector *y, psVector *param, psVector *mask); 20 bool pmSourceVisualPlotPSFMetric (pmPSFtry *try); 20 21 21 22 /// @}
Note:
See TracChangeset
for help on using the changeset viewer.
