Changeset 5980 for trunk/psphot/src/psphotApResid.c
- Timestamp:
- Jan 13, 2006, 8:24:10 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/psphot/src/psphotApResid.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/psphotApResid.c
r5952 r5980 1 1 # include "psphot.h" 2 2 3 bool psphotApResid (psArray *sources, psMetadata *config, pmPSF *psf) { 3 psPolynomial4D *psVectorChiClipFitPolynomial4D( 4 psPolynomial4D *poly, 5 psStats *stats, 6 const psVector *mask, 7 psMaskType maskValue, 8 const psVector *f, 9 const psVector *fErr, 10 const psVector *x, 11 const psVector *y, 12 const psVector *z, 13 const psVector *t) 14 { 15 PS_ASSERT_POLY_NON_NULL(poly, NULL); 16 PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, NULL); 17 PS_ASSERT_PTR_NON_NULL(stats, NULL); 18 PS_ASSERT_VECTOR_NON_NULL(f, NULL); 19 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL); 20 if (mask != NULL) { 21 PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL); 22 PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL); 23 } 24 PS_ASSERT_VECTOR_NON_NULL(x, NULL); 25 PS_ASSERT_VECTORS_SIZE_EQUAL(f, x, NULL); 26 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(x, NULL); 27 PS_ASSERT_VECTOR_NON_NULL(y, NULL); 28 PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL); 29 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(y, NULL); 30 PS_ASSERT_VECTOR_NON_NULL(z, NULL); 31 PS_ASSERT_VECTORS_SIZE_EQUAL(f, z, NULL); 32 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(z, NULL); 33 PS_ASSERT_VECTOR_NON_NULL(t, NULL); 34 PS_ASSERT_VECTORS_SIZE_EQUAL(f, t, NULL); 35 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(t, NULL); 36 PS_ASSERT_VECTOR_NON_NULL(fErr, NULL); 37 PS_ASSERT_VECTORS_SIZE_EQUAL(fErr, mask, NULL); 38 PS_ASSERT_VECTOR_TYPE_F32_OR_F64(fErr, NULL); 39 40 // clipping range defined by min and max and/or clipSigma 41 float minClipSigma; 42 float maxClipSigma; 43 if (isfinite(stats->max)) { 44 maxClipSigma = +fabs(stats->max); 45 } else { 46 maxClipSigma = +fabs(stats->clipSigma); 47 } 48 if (isfinite(stats->min)) { 49 minClipSigma = -fabs(stats->min); 50 } else { 51 minClipSigma = -fabs(stats->clipSigma); 52 } 53 psVector *fit = NULL; 54 psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64); 55 56 // eventual expansion: user supplies one of various stats option pairs, 57 // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to 58 // evaluate the clipping sigma 59 // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used 60 stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 61 62 for (int N = 0; N < stats->clipIter; N++) { 63 int Nkeep = 0; 64 65 poly = psVectorFitPolynomial4D (poly, mask, maskValue, f, fErr, x, y, z, t); 66 fit = psPolynomial4DEvalVector (poly, x, y, z, t); 67 resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit); 68 69 stats = psVectorStats (stats, resid, NULL, mask, maskValue); 70 psTrace (".psphot.VectorClipFit", 5, "resid stats: %f +/- %f\n", stats->sampleMedian, stats->sampleStdev); 71 72 // set mask if pts are not valid 73 // we are masking out any point which is out of range 74 // recovery is not allowed with this scheme 75 for (int i = 0; i < resid->n; i++) { 76 if ((mask != NULL) && (mask->data.U8[i] & maskValue)) { 77 continue; 78 } 79 float sigma = hypot (psVectorGet (fErr, i), stats->sampleStdev); 80 if (resid->data.F64[i] - stats->sampleMedian > sigma*maxClipSigma) { 81 if (mask != NULL) { 82 mask->data.U8[i] |= 0x01; 83 } 84 continue; 85 } 86 if (resid->data.F64[i] - stats->sampleMedian < sigma*minClipSigma) { 87 if (mask != NULL) { 88 mask->data.U8[i] |= 0x01; 89 } 90 continue; 91 } 92 Nkeep ++; 93 } 94 95 psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n", 96 Nkeep, x->n); 97 98 stats->clippedNvalues = Nkeep; 99 psFree (fit); 100 } 101 // Free local temporary variables 102 psFree (resid); 103 104 if (poly == NULL) { 105 psError(PS_ERR_UNKNOWN, true, "Could not fit a polynomial to the data. Returning NULL.\n"); 106 return(NULL); 107 } 108 return(poly); 109 } 110 111 // measure the aperture residual statistics 112 bool psphotApResid (eamReadout *imdata, psArray *sources, psMetadata *config, pmPSF *psf) { 4 113 5 114 int Npsf; … … 8 117 pmSource *source; 9 118 10 // XXX EAM : check that PSF_FIT_RADIUS < SKY_OUTER_RADIUS11 float RADIUS = psMetadataLookupF32 (&status, config, "PSF_FIT_RADIUS");12 13 119 psTimerStart ("psphot"); 14 120 15 // XXX EAM : drop this if we know the list is sorted 16 sources = psArraySort (sources, psphotSortBySN); 17 121 // measure the aperture loss as a function of radius for PSF 122 float REF_RADIUS = psMetadataLookupF32 (&status, config, "PSF_REF_RADIUS"); 123 psf->growth = pmGrowthCurveAlloc (3.0, REF_RADIUS, 0.1); 124 psphotGrowthCurve (imdata, psf); 125 18 126 psVector *mask = psVectorAlloc (300, PS_TYPE_U8); 19 127 psVector *xPos = psVectorAlloc (300, PS_TYPE_F64); 20 128 psVector *yPos = psVectorAlloc (300, PS_TYPE_F64); 21 psVector *rflux = psVectorAlloc (300, PS_TYPE_F64); 129 psVector *flux = psVectorAlloc (300, PS_TYPE_F64); 130 psVector *r2rflux = psVectorAlloc (300, PS_TYPE_F64); 22 131 psVector *apResid = psVectorAlloc (300, PS_TYPE_F64); 23 mask->n = xPos->n = yPos->n = rflux->n = apResid->n = 0; 132 psVector *dMag = psVectorAlloc (300, PS_TYPE_F64); 133 mask->n = xPos->n = yPos->n = flux->n = r2rflux->n = apResid->n = dMag->n = 0; 24 134 Npsf = 0; 25 135 26 // select the NNN brightest, non-saturated sources, or just select PSFSTARs?27 for (int i = 0; (i < sources->n) && (Npsf < 300); i++) {136 // select all good PM_SOURCE_STAR entries 137 for (int i = 0; i < sources->n; i++) { 28 138 source = sources->data[i]; 29 139 … … 34 144 if (source->mode & PM_SOURCE_POOR) continue; 35 145 36 // get magnitudes, uncorrected for (x, y, rflux)37 model = pmSourceMagnitudes (source, NULL, RADIUS);146 // get uncorrected magnitudes in scaled apertures 147 model = pmSourceMagnitudes (source, NULL, 0); 38 148 if (model == NULL) continue; 39 149 … … 41 151 xPos->data.F64[Npsf] = model->params->data.F32[2]; 42 152 yPos->data.F64[Npsf] = model->params->data.F32[3]; 43 rflux->data.F64[Npsf] = pow(10.0, 0.4*source->fitMag); 44 apResid->data.F64[Npsf] = source->apMag - source->fitMag; 45 46 psVectorExtend (mask, 100, 1); 47 psVectorExtend (xPos, 100, 1); 48 psVectorExtend (yPos, 100, 1); 49 psVectorExtend (rflux, 100, 1); 153 154 flux->data.F64[Npsf] = pow(10.0, -0.4*source->fitMag); 155 r2rflux->data.F64[Npsf] = PS_SQR(model->radius) / flux->data.F64[Npsf]; 156 157 apResid->data.F64[Npsf] = source->apMag + pmGrowthCurveCorrect (psf->growth, model->radius) - source->fitMag ; 158 159 // XXX sanity clip? 160 // XXX need to see if all data were tossed? 161 // XXX need to subtract median? 162 if (fabs(apResid->data.F64[Npsf]) > 0.2) continue; 163 164 dMag->data.F64[Npsf] = model->dparams->data.F32[1] / model->params->data.F32[1]; 165 166 psVectorExtend (mask, 100, 1); 167 psVectorExtend (xPos, 100, 1); 168 psVectorExtend (yPos, 100, 1); 169 psVectorExtend (flux, 100, 1); 170 psVectorExtend (r2rflux, 100, 1); 171 psVectorExtend (dMag, 100, 1); 50 172 psVectorExtend (apResid, 100, 1); 51 173 Npsf ++; 52 174 } 53 psLogMsg ("psphot.apresid", 4, "measure aperture residuals : %f sec\n", psTimerMark ("psphot")); 175 psLogMsg ("psphot.apresid", 4, "measure aperture residuals : %f sec for %d objects\n", psTimerMark ("psphot"), Npsf); 176 177 // APTREND options : NONE SKYBIAS XY_LIN XY_QUAD SKY_XY_LIN FULL 178 char *ApTrendOption = psMetadataLookupPtr (&status, config, "APTREND"); 179 if (!status) ApTrendOption = psStringCopy ("SKYBIAS"); 54 180 55 181 // 3hi/1lo sigma clipping on the rflux vs metric fit 56 182 psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); 57 stats->min = 1.0;183 stats->min = 3.0; 58 184 stats->max = 3.0; 59 stats->clipIter = 3; 60 61 // first clip out objects which are too far from the median 62 stats->clipIter = 1; 63 maskToConstant (psf->ApTrend); 64 psf->ApTrend = psVectorClipFitPolynomial3D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, NULL, xPos, yPos, rflux); 65 66 // next, fit just SkyBias and clip out objects which are too far from the median 67 stats->clipIter = 2; 68 maskToSkyBias (psf->ApTrend); 69 psf->ApTrend = psVectorClipFitPolynomial3D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, NULL, xPos, yPos, rflux); 70 71 // finally, fit x, y, SkyBias and clip out objects which are too far from the median 72 stats->clipIter = 2; 73 maskToDefault (psf->ApTrend); 74 psf->ApTrend = psVectorClipFitPolynomial3D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, NULL, xPos, yPos, rflux); 75 76 // linear clipped fit of apResid to rflux, xPos, yPos 77 # if (0) 78 psf->ApTrend = psVectorClipFitPolynomial3D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, NULL, xPos, yPos, rflux); 79 psf->skyBias = psf->ApTrend->coeff[0][0][1] / (M_PI * PS_SQR(RADIUS)); 80 psf->ApResid = psf->ApTrend->coeff[0][0][0]; 81 psf->dApResid = stats->sampleStdev; 82 psf->ApTrend->coeff[0][0][1] = 0; 83 # endif 185 186 // constant only 187 if (!strcasecmp (ApTrendOption, "CONSTANT")) { 188 stats->clipIter = 2; 189 pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT); 190 psf->ApTrend = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 191 192 stats->clipIter = 3; 193 pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT); 194 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 195 } 196 197 // constant and skybias only 198 if (!strcasecmp (ApTrendOption, "SKYBIAS")) { 199 // first clip out objects which are too far from the median 200 stats->clipIter = 2; 201 pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT); 202 psf->ApTrend = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 203 204 // apply the fit 205 stats->clipIter = 3; 206 pmPSF_MaskApTrend (psf, PM_PSF_SKYBIAS); 207 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 208 } 209 210 if (!strcasecmp (ApTrendOption, "SKYSAT")) { 211 // first clip out objects which are too far from the median 212 stats->clipIter = 2; 213 pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT); 214 psf->ApTrend = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 215 216 // apply the fit 217 stats->clipIter = 2; 218 pmPSF_MaskApTrend (psf, PM_PSF_SKYBIAS); 219 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 220 221 // apply the fit 222 stats->clipIter = 3; 223 pmPSF_MaskApTrend (psf, PM_PSF_SKYSAT); 224 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 225 } 226 227 // constant and linear X,Y only 228 if (!strcasecmp (ApTrendOption, "XY_LIN")) { 229 // first clip out objects which are too far from the median 230 stats->clipIter = 2; 231 pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT); 232 psf->ApTrend = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 233 234 // apply the fit 235 stats->clipIter = 3; 236 pmPSF_MaskApTrend (psf, PM_PSF_XY_LIN); 237 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 238 } 239 240 // constant and quadratic X,Y only 241 if (!strcasecmp (ApTrendOption, "XY_QUAD")) { 242 // first clip out objects which are too far from the median 243 stats->clipIter = 2; 244 pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT); 245 psf->ApTrend = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 246 247 // apply the fit 248 stats->clipIter = 3; 249 pmPSF_MaskApTrend (psf, PM_PSF_XY_QUAD); 250 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 251 } 252 253 // constant and sky, linear X,Y only 254 if (!strcasecmp (ApTrendOption, "SKY_XY_LIN")) { 255 // first clip out objects which are too far from the median 256 stats->clipIter = 2; 257 pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT); 258 psf->ApTrend = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 259 260 // apply the fit 261 stats->clipIter = 3; 262 pmPSF_MaskApTrend (psf, PM_PSF_SKY_XY_LIN); 263 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 264 } 265 266 // constant and sky, linear X,Y only 267 if (!strcasecmp (ApTrendOption, "SKYSAT_XY_LIN")) { 268 // first clip out objects which are too far from the median 269 stats->clipIter = 2; 270 pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT); 271 psf->ApTrend = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 272 273 // apply the fit 274 stats->clipIter = 3; 275 pmPSF_MaskApTrend (psf, PM_PSF_SKYBIAS); 276 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 277 278 // apply the fit 279 stats->clipIter = 3; 280 pmPSF_MaskApTrend (psf, PM_PSF_SKYSAT_XY_LIN); 281 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 282 } 283 284 if (!strcasecmp (ApTrendOption, "ALL")) { 285 // first clip out objects which are too far from the median 286 stats->clipIter = 2; 287 pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT); 288 psf->ApTrend = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 289 290 // fit just SkyBias and clip out objects which are too far from the median 291 stats->clipIter = 2; 292 pmPSF_MaskApTrend (psf, PM_PSF_SKYBIAS); 293 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 294 295 // finally, fit x, y, SkyBias and clip out objects which are too far from the median 296 stats->clipIter = 3; 297 pmPSF_MaskApTrend (psf, PM_PSF_ALL); 298 psf->ApTrend = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux); 299 } 300 301 # if (1) 302 psPolynomial4D *poly = psf->ApTrend; 303 for (int nt = 0; nt <= poly->nT; nt++) { 304 for (int nz = 0; nz <= poly->nZ; nz++) { 305 for (int ny = 0; ny <= poly->nY; ny++) { 306 for (int nx = 0; nx <= poly->nX; nx++) { 307 if (poly->mask[nx][ny][nz][nt]) continue; 308 fprintf (stderr, "%d %d %d %d : %22.15g\n", nx, ny, nz, nt, poly->coeff[nx][ny][nz][nt]); 309 } 310 } 311 } 312 } 313 # endif 314 315 // construct the fitted values and the residuals 316 psVector *fit = psPolynomial4DEvalVector (psf->ApTrend, xPos, yPos, r2rflux, flux); 317 psVector *resid = (psVector *) psBinaryOp (NULL, (void *) apResid, "-", (void *) fit); 318 319 # if (0) 320 FILE *fout = fopen ("resid.dat", "w"); 321 for (int i = 0; i < resid->n; i++) { 322 fprintf (fout, "%d %f %f %f %f %f %f %f %f %d\n", 323 i, 324 (float) psVectorGet(xPos, i), (float) psVectorGet(yPos, i), (float) psVectorGet(r2rflux, i), (float) psVectorGet(flux, i), 325 (float) psVectorGet(apResid, i), (float) psVectorGet(fit, i), (float) psVectorGet(resid, i), (float) psVectorGet(dMag, i), 326 mask->data.U8[i]); 327 } 328 fclose (fout); 329 # endif 330 331 // measure scatter for sources with dMag < 0.01 (S/N = 100) 332 psStats *residStats = psStatsAlloc (PS_STAT_SAMPLE_STDEV); 333 for (int i = 0; i < dMag->n; i++) { 334 if (dMag->data.F64[i] > 0.01) { 335 mask->data.U8[i] |= 0x02; 336 } 337 } 338 residStats = psVectorStats (residStats, resid, NULL, mask, 0x03); 339 340 // apply ApTrend results 341 psf->skyBias = psf->ApTrend->coeff[0][0][1][0]; 342 psf->skySat = psf->ApTrend->coeff[0][0][0][1]; 343 psf->ApResid = psf->ApTrend->coeff[0][0][0][0]; 344 psf->dApResid = residStats->sampleStdev; 345 psf->ApTrend->coeff[0][0][1][0] = 0; 346 psf->ApTrend->coeff[0][0][0][1] = 0; 347 psf->nApResid = residStats->clippedNvalues; 84 348 85 349 /* … … 89 353 */ 90 354 91 # if (0)92 psPolynomial3D *poly = psf->ApTrend;93 for (int nz = 0; nz <= poly->nZ; nz++) {94 for (int ny = 0; ny <= poly->nY; ny++) {95 for (int nx = 0; nx <= poly->nX; nx++) {96 fprintf (stderr, "%d %d %d : %22.15g\n", nx, ny, nz, poly->coeff[nx][ny][nz]);97 }98 }99 }100 # endif101 102 355 psLogMsg ("psphot.apresid", 3, "measure full-frame aperture residual: %f sec\n", psTimerMark ("psphot")); 103 356 psLogMsg ("psphot.apresid", 4, "aperture residual: %f +/- %f : %f bias\n", psf->ApResid, psf->dApResid, psf->skyBias); 104 105 psFree (stats); 106 psFree (mask); 107 psFree (rflux); 108 psFree (apResid); 357 psLogMsg ("psphot.apresid", 4, "apresid trends: %f %f %f %f %f\n", 358 1e3*psf->ApTrend->coeff[1][0][0][0], 359 1e6*psf->ApTrend->coeff[2][0][0][0], 360 1e6*psf->ApTrend->coeff[1][1][0][0], 361 1e3*psf->ApTrend->coeff[0][1][0][0], 362 1e6*psf->ApTrend->coeff[0][2][0][0]); 363 364 // psFree (stats); 365 // psFree (mask); 366 // psFree (rflux); 367 // psFree (apResid); 109 368 110 369 return true; 111 370 } 371
Note:
See TracChangeset
for help on using the changeset viewer.
