Changeset 12948
- Timestamp:
- Apr 20, 2007, 2:18:15 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_02_branch/psphot/src/psphotMakeResiduals.c
r12933 r12948 1 1 # include "psphotInternal.h" 2 # define ZERO_ORDER 0 2 3 3 4 bool psphotMakeResiduals (psArray *sources, psMetadata *recipe, pmPSF *psf) { … … 9 10 psTimerStart ("residuals"); 10 11 12 if (!psMetadataLookupBool(&status, recipe, "PSF.RESIDUALS")) return true; 13 11 14 int xBin = psMetadataLookupS32(&status, recipe, "PSF.RESIDUALS.XBIN"); 12 15 PS_ASSERT (status, false); … … 14 17 int yBin = psMetadataLookupS32(&status, recipe, "PSF.RESIDUALS.YBIN"); 15 18 PS_ASSERT (status, false); 19 20 float nSigma = psMetadataLookupF32(&status, recipe, "PSF.RESIDUALS.NSIGMA"); 21 PS_ASSERT (status, false); 22 23 char *modeString = psMetadataLookupStr(&status, recipe, "PSF.RESIDUALS.INTERPOLATION"); 24 PS_ASSERT (status, false); 25 26 psImageInterpolateMode mode = psImageInterpolateModeFromString (modeString); 27 if (mode == PS_INTERPOLATE_NONE) { 28 psError(PSPHOT_ERR_CONFIG, false, "invalid interpolation in psphot.config"); 29 return false; 30 } 31 32 char *statString = psMetadataLookupStr(&status, recipe, "PSF.RESIDUALS.STATISTIC"); 33 PS_ASSERT (status, false); 34 35 psStatsOptions statOption = psStatsOptionFromString (statString); 36 if (!statOption) { 37 psError(PSPHOT_ERR_CONFIG, false, "invalid residual statistic in psphot.config"); 38 return false; 39 } 16 40 17 41 // user parameters: … … 40 64 psVector *yC = psVectorAllocEmpty (100, PS_TYPE_F32); 41 65 66 // build (DATA - MODEL) [an image] for each psf star 42 67 psArray *input = psArrayAllocEmpty (100); 43 68 for (int i = 0; i < sources->n; i++) { … … 55 80 psImage *mask = psImageCopy (NULL, source->mask, PS_TYPE_U8); 56 81 pmModelSub (image, mask, model, false, false); 57 psFree (mask);58 82 59 83 // re-normalize image and weight … … 62 86 psBinaryOp (weight, weight, "/", psScalarAlloc(Io*Io, PS_TYPE_F32)); 63 87 64 psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(65 PS_INTERPOLATE_BILINEAR,66 image, weight, NULL, 0, 0.0, 0.0, 1, 0, 0.0);88 // we will interpolate the image and weight - include the mask or not? 89 // XXX consider better values for the mask bits 90 psImageInterpolateOptions *interp = psImageInterpolateOptionsAlloc(mode, image, weight, NULL, 0xff, 0.0, 0.0, 1, 2, 0.0); 67 91 psArrayAdd (input, 100, interp); 68 92 … … 77 101 78 102 // free up the excess references 103 psFree (mask); 79 104 psFree (image); 80 105 psFree (weight); … … 89 114 psVector *fmasks = psVectorAlloc (input->n, PS_TYPE_U8); 90 115 116 // statistic to use to determine baseline for clipping 91 117 psStats *fluxClip = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 92 118 psStats *fluxClipDef = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); 93 psStats *fluxStats = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); 94 psStats *fluxStatsDef = psStatsAlloc (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV); 95 96 // build the residual image pixel-by-pixel 97 for (int oy = 0; oy < resid->image->numRows; oy++) { 119 // statistic to use to determine output flux 120 // XXX make API to convert statOption for MEAN/MEDIAN in to corresponding STDEV? 121 psStats *fluxStats = psStatsAlloc (statOption | PS_STAT_SAMPLE_STDEV); 122 psStats *fluxStatsDef = psStatsAlloc (statOption | PS_STAT_SAMPLE_STDEV); 123 124 // this section builds just the 0th order term Ro 125 # if (ZERO_ORDER) 126 // build Ro = DATA - MODEL (rebinned image) pixel-by-pixel 127 for (int oy = 0; oy < resid->Ro->numRows; oy++) { 98 128 fprintf (stderr, "."); 99 for (int ox = 0; ox < resid-> image->numCols; ox++) {129 for (int ox = 0; ox < resid->Ro->numCols; ox++) { 100 130 131 // build the vector of data values for this output pixel 101 132 for (int i = 0; i < input->n; i++) { 102 133 … … 104 135 105 136 // fractional image position 106 float ix = (ox - resid->xCenter) / (float) xBin + xC->data.F32[i] - interp->image->col0;107 float iy = (oy - resid->yCenter) / (float) yBin + yC->data.F32[i] - interp->image->row0;137 float ix = (ox + 0.5 - resid->xCenter) / (float) xBin + xC->data.F32[i] - interp->image->col0; 138 float iy = (oy + 0.5 - resid->yCenter) / (float) yBin + yC->data.F32[i] - interp->image->row0; 108 139 109 140 mflux = 0; … … 115 146 } 116 147 148 // measure the robust median to determine a baseline reference value 117 149 *fluxClip = *fluxClipDef; 118 150 psVectorStats (fluxClip, fluxes, NULL, fmasks, 0xff); 119 psErrorClear();120 151 121 152 // mark input pixels which are more than N sigma from the median … … 123 154 float delta = fluxes->data.F32[i] - fluxClip->robustMedian; 124 155 float sigma = sqrt (dfluxes->data.F32[i]); 125 126 156 float swing = fabs(delta) / sigma; 127 157 128 158 // make this a user option 129 if (swing > 3.0) {159 if (swing > nSigma) { 130 160 fmasks->data.U8[i] = 1; 131 161 } 132 162 } 133 163 164 // measure the desired statistic on the unclipped pixels 134 165 *fluxStats = *fluxStatsDef; 135 166 psVectorStats (fluxStats, fluxes, NULL, fmasks, 0xff); 167 168 resid->Ro->data.F32[oy][ox] = psStatsGetValue (fluxStats, statOption); 169 resid->weight->data.F32[oy][ox] = fluxStats->sampleStdev; 170 171 // clear (ignore) any outstanding errors 136 172 psErrorClear(); 137 138 resid->image->data.F32[oy][ox] = fluxStats->sampleMean;139 resid->weight->data.F32[oy][ox] = fluxStats->sampleStdev;140 173 } 141 174 } 142 143 psphotSaveImage (NULL, resid->image, "resid.im.fits"); 144 psphotSaveImage (NULL, resid->weight, "resid.wt.fits"); 145 psphotSaveImage (NULL, resid->mask, "resid.mk.fits"); 146 147 psLogMsg ("psphot.pspsf", PS_LOG_INFO, "generate residuals for %ld objects: %f sec\n", input->n, psTimerMark ("residuals")); 175 psLogMsg ("psphot.pspsf", PS_LOG_INFO, "generated 0-th order residuals for %ld objects: %f sec\n", input->n, psTimerMark ("residuals")); 176 177 # else 178 179 psImage *A = psImageAlloc(3, 3, PS_TYPE_F64); // Least-squares matrix 180 psVector *B = psVectorAlloc(3, PS_TYPE_F64); // Least-squares vector 181 182 // build (x,y)*(DATA - MODEL - Ro) pixel-by-pixel 183 for (int oy = 0; oy < resid->Ro->numRows; oy++) { 184 fprintf (stderr, "."); 185 for (int ox = 0; ox < resid->Ro->numCols; ox++) { 186 187 // build the vector of data values for this output pixel 188 // XXX this is identical to the pass above: we could cache the results for speed 189 for (int i = 0; i < input->n; i++) { 190 191 psImageInterpolateOptions *interp = input->data[i]; 192 193 // fractional image position 194 float ix = (ox + 0.5 - resid->xCenter) / (float) xBin + xC->data.F32[i] - interp->image->col0; 195 float iy = (oy + 0.5 - resid->yCenter) / (float) yBin + yC->data.F32[i] - interp->image->row0; 196 197 mflux = 0; 198 psImageInterpolate (&flux, &dflux, &mflux, ix, iy, interp); 199 fluxes->data.F32[i] = flux; 200 dfluxes->data.F32[i] = dflux; 201 fmasks->data.U8[i] = mflux; 202 // fprintf (stderr, "%f %f : %f %f (%d)\n", ix, iy, flux, dflux, fmasks->data.U8[i]); 203 } 204 205 // measure the robust median to determine a baseline reference value 206 *fluxClip = *fluxClipDef; 207 psVectorStats (fluxClip, fluxes, NULL, fmasks, 0xff); 208 psErrorClear(); // clear (ignore) any outstanding errors 209 210 // mark input pixels which are more than N sigma from the median 211 for (int i = 0; i < fluxes->n; i++) { 212 float delta = fluxes->data.F32[i] - fluxClip->robustMedian; 213 float sigma = sqrt (dfluxes->data.F32[i]); 214 float swing = fabs(delta) / sigma; 215 216 // make this a user option 217 if (swing > nSigma) { 218 fmasks->data.U8[i] = 1; 219 } 220 } 221 222 psImageInit(A, 0.0); 223 psVectorInit(B, 0.0); 224 for (int i = 0; i < fluxes->n; i++) { 225 if (fmasks->data.U8[i]) continue; 226 B->data.F64[0] += fluxes->data.F32[i]/dfluxes->data.F32[i]; 227 B->data.F64[1] += fluxes->data.F32[i]*xC->data.F32[i]/dfluxes->data.F32[i]; 228 B->data.F64[2] += fluxes->data.F32[i]*yC->data.F32[i]/dfluxes->data.F32[i]; 229 230 A->data.F64[0][0] += 1.0/dfluxes->data.F32[i]; 231 A->data.F64[1][0] += xC->data.F32[i]/dfluxes->data.F32[i]; 232 A->data.F64[2][0] += yC->data.F32[i]/dfluxes->data.F32[i]; 233 234 A->data.F64[1][1] += PS_SQR(xC->data.F32[i])/dfluxes->data.F32[i]; 235 A->data.F64[2][2] += PS_SQR(yC->data.F32[i])/dfluxes->data.F32[i]; 236 A->data.F64[1][2] += xC->data.F32[i]*yC->data.F32[i]/dfluxes->data.F32[i]; 237 } 238 239 A->data.F64[0][1] = A->data.F64[1][0]; 240 A->data.F64[0][2] = A->data.F64[2][0]; 241 A->data.F64[2][1] = A->data.F64[1][2]; 242 psMatrixGJSolve(A, B); 243 244 resid->Ro->data.F32[oy][ox] = B->data.F64[0]; 245 resid->Rx->data.F32[oy][ox] = B->data.F64[1]; 246 resid->Ry->data.F32[oy][ox] = B->data.F64[2]; 247 } 248 } 249 250 psFree (A); 251 psFree (B); 252 253 # endif 148 254 149 255 psFree (xC); … … 160 266 psFree (fluxClipDef); 161 267 268 psphotSaveImage (NULL, resid->Ro, "resid.ro.fits"); 269 psphotSaveImage (NULL, resid->Rx, "resid.rx.fits"); 270 psphotSaveImage (NULL, resid->Ry, "resid.ry.fits"); 271 psphotSaveImage (NULL, resid->weight, "resid.wt.fits"); 272 psphotSaveImage (NULL, resid->mask, "resid.mk.fits"); 273 274 psLogMsg ("psphot.pspsf", PS_LOG_INFO, "generate residuals for %ld objects: %f sec\n", input->n, psTimerMark ("residuals")); 275 162 276 psf->residuals = resid; 163 277 return true;
Note:
See TracChangeset
for help on using the changeset viewer.
