Changeset 31361 for branches/eam_branches/ipp-20110404/psModules/src/objects/pmGrowthCurveGenerate.c
- Timestamp:
- Apr 24, 2011, 10:09:38 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20110404/psModules/src/objects/pmGrowthCurveGenerate.c
r31327 r31361 50 50 51 51 #include "pmSourcePhotometry.h" 52 53 pmGrowthCurve *pmGrowthCurveForPosition (psImage *image, pmPSF *psf, bool ignore, psImageMaskType maskVal, psImageMaskType markVal, float xc, float yc); 52 #include "pmGrowthCurveGenerate.h" 54 53 55 54 /*****************************************************************************/ … … 226 225 return growth; 227 226 } 227 228 // we generate the growth curve for the center of the image with the specified psf model 229 bool pmGrowthCurveGenerateFromSources (pmReadout *readout, pmPSF *psf, psArray *sources, bool INTERPOLATE_AP, psImageMaskType maskVal, psImageMaskType markVal) 230 { 231 PS_ASSERT_PTR_NON_NULL(readout, false); 232 PS_ASSERT_PTR_NON_NULL(readout->image, false); 233 234 // maskVal is used to test for rejected pixels, and must include markVal 235 maskVal |= markVal; 236 237 pmSourcePhotometryMode photMode = INTERPOLATE_AP ? PM_SOURCE_PHOT_INTERP : 0; 238 239 // measure the growth curve for each PSF source and average them together 240 psArray *growths = psArrayAllocEmpty (100); 241 242 for (int i = 0; i < sources->n; i++) { 243 244 pmSource *source = sources->data[i]; 245 246 if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue; 247 248 pmGrowthCurve *growth = pmGrowthCurveForSource (source, psf, photMode, maskVal, markVal); 249 if (!growth) continue; 250 251 psArrayAdd (growths, 100, growth); 252 psFree (growth); 253 } 254 psAssert (growths->n, "cannot build growth curve (no valid PSF stars?)"); 255 256 # if (0) 257 FILE *f = fopen ("growth.dat", "w"); 258 assert (f); 259 260 for (int j = 0; j < psf->growth->radius->n; j++) { 261 262 fprintf (f, "%f : ", psf->growth->radius->data.F32[j]); 263 264 // XXX dump the growth curves: 265 for (int i = 0; i < growths->n; i++) { 266 267 pmGrowthCurve *growth = growths->data[i]; 268 if (!growth) continue; 269 270 fprintf (f, "%8.4f ", growth->apMag->data.F32[j]); 271 } 272 fprintf (f, "\n"); 273 } 274 fclose (f); 275 # endif 276 277 // just use a simple sample median to get the 'best' value from each growth curve... 278 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN); 279 280 psVector *values = psVectorAlloc (growths->n, PS_DATA_F32); 281 282 // loop over a range of source fluxes 283 // no need to interpolate since we have forced the object center 284 // to 0.5, 0.5 above 285 for (int i = 0; i < psf->growth->radius->n; i++) { 286 287 // median the values for each radial bin 288 values->n = 0; 289 for (int j = 0; j < growths->n; j++) { 290 pmGrowthCurve *growth = growths->data[j]; 291 if (!isfinite(growth->apMag->data.F32[i])) continue; 292 psVectorAppend (values, growth->apMag->data.F32[i] - growth->fitMag); 293 } 294 if (values->n == 0) { 295 psf->growth->apMag->data.F32[i] = NAN; 296 } else { 297 if (!psVectorStats (stats, values, NULL, NULL, 0)) { 298 psError(PS_ERR_UNKNOWN, false, "failure to measure stats"); 299 return false; 300 } 301 psf->growth->apMag->data.F32[i] = stats->sampleMedian; 302 } 303 } 304 305 psf->growth->fitMag = psf->growth->apMag->data.F32[psf->growth->radius->n-1]; 306 psf->growth->apRef = psVectorInterpolate (psf->growth->radius, psf->growth->apMag, psf->growth->refRadius); 307 psf->growth->apLoss = psf->growth->fitMag - psf->growth->apRef; 308 309 psLogMsg ("psphot.growth", 4, "GrowthCurve : apLoss : %f (fitMag - apMag @ ref : %f - %f)\n", psf->growth->apLoss, psf->growth->fitMag, psf->growth->apRef); 310 311 psFree (growths); 312 psFree (stats); 313 psFree (values); 314 315 return true; 316 } 317 318 pmGrowthCurve *pmGrowthCurveForSource (pmSource *source, pmPSF *psf, pmSourcePhotometryMode photMode, psImageMaskType maskVal, psImageMaskType markVal) { 319 320 float radius; 321 322 assert (psf->growth); 323 324 float minRadius = psf->growth->radius->data.F32[0]; 325 pmGrowthCurve *growth = pmGrowthCurveAlloc (minRadius, psf->growth->maxRadius, psf->growth->refRadius); 326 327 // measure the fitMag for this source (for normalization) 328 // pmSourcePhotometryModel (&fitMag, NULL, source->psfModel); 329 growth->fitMag = source->psfMag; 330 331 float xc = source->peak->xf; 332 float yc = source->peak->yf; 333 334 // Loop over the range of radii 335 for (int i = 0; i < growth->radius->n; i++) { 336 337 radius = growth->radius->data.F32[i]; 338 339 // mask the given aperture and measure the apMag 340 psImageKeepCircle (source->maskObj, xc, yc, radius, "OR", markVal); 341 342 if (!pmSourceMagnitudes (source, psf, photMode, maskVal, markVal, radius)) { 343 psFree (growth); 344 return NULL; 345 } 346 347 // if (!pmSourcePhotometryAper (NULL, &apMag, NULL, NULL, NULL, source->pixels, NULL, source->maskObj, maskVal)) { 348 // psFree (growth); 349 // return NULL; 350 // } 351 352 psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask 353 354 growth->apMag->data.F32[i] = source->apMag; 355 } 356 return growth; 357 } 358 359 # if (0) 360 // solve for the best growth and the offsets per star to minimize the scatter 361 362 // generate the per-star and per-radius sums 363 int Nradius = psf->growth->radius->n; 364 int Nstar = growths->n; 365 366 psVector *Mstar = psVectorAlloc (Nstar, PS_DATA_F32); 367 psVector *Mradius = psVectorAlloc (Nradius, PS_DATA_F32); 368 369 psVectorInit (Mstar, 0.0); 370 psVectorInit (Mradius, 0.0); 371 372 for (int i = 0; i < Nstar; i++) { 373 pmGrowthCurve *growth = growths->data[i]; 374 for (int j = 0; j < Nradius; j++) { 375 Mstar->data.F32[i] += growth->apMag->data.F32[j]; 376 Mradius->data.F32[j] += growth->apMag->data.F32[j]; 377 } 378 } 379 380 psImage *A = psImageAlloc(Nstar + Nradius, Nstar + Nradius, PS_DATA_F32); 381 psVector *B = psVectorAlloc(Nstar + Nradius, PS_DATA_F32); 382 383 psImageInit (A, 0.0); 384 psVectorInit (B, 0.0); 385 386 for (int i = 0; i < Nstar; i++) { 387 A->data.F32[i][i] = Nradius; 388 B->data.F32[i] = Mstar->data.F32[i]; 389 } 390 for (int i = 0; i < Nradius; i++) { 391 int j = i + Nstar; 392 A->data.F32[j][j] = Nstar; 393 B->data.F32[j] = Mradius->data.F32[i]; 394 } 395 396 if (!psMatrixGJSolve(A, B)) { 397 psAbort("GJ failure"); 398 } 399 400 for (int i = 0; i < Nradius; i++) { 401 psf->growth->apMag->data.F32[i] = B->data.F32[Nstar+i]; 402 } 403 404 // XXX this analysis produces a biased growth curve: points with small radius are more 405 // likely to err on the side of being too faint (bacause of mis-aligned aperture), while on 406 // the bright side the tend to be too bright (because of contaminating neighbors). Bright 407 // stars are less likely to be biased, 408 409 // XXX at this point, we could iterate and exclude some of the stars with low data quality 410 // XXX we could also weight the above by flux or something 411 412 # endif
Note:
See TracChangeset
for help on using the changeset viewer.
