Changeset 13407
- Timestamp:
- May 17, 2007, 3:35:34 AM (19 years ago)
- File:
-
- 1 edited
-
trunk/psphot/src/psphotMakeResiduals.c (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/psphotMakeResiduals.c
r13196 r13407 1 1 # include "psphotInternal.h" 2 # define ZERO_ORDER 03 2 4 3 bool psphotMakeResiduals (psArray *sources, psMetadata *recipe, pmPSF *psf) { … … 12 11 if (!psMetadataLookupBool(&status, recipe, "PSF.RESIDUALS")) return true; 13 12 13 int SPATIAL_ORDER = psMetadataLookupS32(&status, recipe, "PSF.RESIDUALS.SPATIAL_ORDER"); 14 #if 0 // True when PSF.RESIDUALS.SPATIAL_ORDER's in default recipe 15 PS_ASSERT (status, false); 16 #else 17 if (!status) { 18 SPATIAL_ORDER = 1; // i.e. linear 19 } 20 #endif 21 if (SPATIAL_ORDER != 0 && SPATIAL_ORDER != 1) { 22 psError(PSPHOT_ERR_CONFIG, true, "PSF.RESIDUALS.SPATIAL_ORDER must be 0 or 1 (not %d)", 23 SPATIAL_ORDER); 24 return false; 25 } 26 14 27 int xBin = psMetadataLookupS32(&status, recipe, "PSF.RESIDUALS.XBIN"); 15 28 PS_ASSERT (status, false); 29 psErrorClear(); PS_ASSERT (xBin != 0, false); 16 30 17 31 int yBin = psMetadataLookupS32(&status, recipe, "PSF.RESIDUALS.YBIN"); 18 32 PS_ASSERT (status, false); 33 psErrorClear(); PS_ASSERT (yBin != 0, false); 19 34 20 35 float nSigma = psMetadataLookupF32(&status, recipe, "PSF.RESIDUALS.NSIGMA"); … … 122 137 psStats *fluxStatsDef = psStatsAlloc (statOption | PS_STAT_SAMPLE_STDEV); 123 138 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++) { 139 psImage *A = psImageAlloc(3, 3, PS_TYPE_F64); // Least-squares matrix 140 psVector *B = psVectorAlloc(3, PS_TYPE_F64); // Least-squares vector 141 142 // Solve MODEL = R + x R_x + y R_y in pixel-by-pixel a least-squares sense 143 // (If SPATIAL_ORDER == 0, just solve MODEL = R) 144 for (int oy = 0; resid != NULL && oy < resid->Ro->numRows; oy++) { 128 145 for (int ox = 0; ox < resid->Ro->numCols; ox++) { 129 146 … … 148 165 *fluxClip = *fluxClipDef; 149 166 psVectorStats (fluxClip, fluxes, NULL, fmasks, 0xff); 167 psErrorClear(); // clear (ignore) any outstanding errors 150 168 151 169 // mark input pixels which are more than N sigma from the median … … 161 179 } 162 180 163 // measure the desired statistic on the unclipped pixels 164 *fluxStats = *fluxStatsDef; 165 psVectorStats (fluxStats, fluxes, NULL, fmasks, 0xff); 166 167 resid->Ro->data.F32[oy][ox] = psStatsGetValue (fluxStats, statOption); 168 resid->weight->data.F32[oy][ox] = fluxStats->sampleStdev; 169 170 // clear (ignore) any outstanding errors 171 psErrorClear(); 172 } 173 } 174 psLogMsg ("psphot.pspsf", PS_LOG_INFO, "generated 0-th order residuals for %ld objects: %f sec\n", input->n, psTimerMark ("residuals")); 175 176 # else 177 178 psImage *A = psImageAlloc(3, 3, PS_TYPE_F64); // Least-squares matrix 179 psVector *B = psVectorAlloc(3, PS_TYPE_F64); // Least-squares vector 180 181 // build (x,y)*(DATA - MODEL - Ro) pixel-by-pixel 182 for (int oy = 0; oy < resid->Ro->numRows; oy++) { 183 for (int ox = 0; ox < resid->Ro->numCols; ox++) { 184 185 // build the vector of data values for this output pixel 186 // XXX this is identical to the pass above: we could cache the results for speed 187 for (int i = 0; i < input->n; i++) { 188 189 psImageInterpolateOptions *interp = input->data[i]; 181 if (SPATIAL_ORDER == 0) { 182 // measure the desired statistic on the unclipped pixels 183 *fluxStats = *fluxStatsDef; 184 psVectorStats (fluxStats, fluxes, NULL, fmasks, 0xff); 190 185 191 // fractional image position 192 float ix = (ox + 0.5 - resid->xCenter) / (float) xBin + xC->data.F32[i] - interp->image->col0; 193 float iy = (oy + 0.5 - resid->yCenter) / (float) yBin + yC->data.F32[i] - interp->image->row0; 194 195 mflux = 0; 196 psImageInterpolate (&flux, &dflux, &mflux, ix, iy, interp); 197 fluxes->data.F32[i] = flux; 198 dfluxes->data.F32[i] = dflux; 199 fmasks->data.U8[i] = mflux; 200 // fprintf (stderr, "%f %f : %f %f (%d)\n", ix, iy, flux, dflux, fmasks->data.U8[i]); 186 resid->Ro->data.F32[oy][ox] = psStatsGetValue (fluxStats, statOption); 187 //resid->weight->data.F32[oy][ox] = fluxStats->sampleStdev; 188 } else { 189 assert (SPATIAL_ORDER == 1); 190 psImageInit(A, 0.0); 191 psVectorInit(B, 0.0); 192 for (int i = 0; i < fluxes->n; i++) { 193 if (fmasks->data.U8[i]) continue; 194 B->data.F64[0] += fluxes->data.F32[i]/dfluxes->data.F32[i]; 195 B->data.F64[1] += fluxes->data.F32[i]*xC->data.F32[i]/dfluxes->data.F32[i]; 196 B->data.F64[2] += fluxes->data.F32[i]*yC->data.F32[i]/dfluxes->data.F32[i]; 197 198 A->data.F64[0][0] += 1.0/dfluxes->data.F32[i]; 199 A->data.F64[1][0] += xC->data.F32[i]/dfluxes->data.F32[i]; 200 A->data.F64[2][0] += yC->data.F32[i]/dfluxes->data.F32[i]; 201 202 A->data.F64[1][1] += PS_SQR(xC->data.F32[i])/dfluxes->data.F32[i]; 203 A->data.F64[2][2] += PS_SQR(yC->data.F32[i])/dfluxes->data.F32[i]; 204 A->data.F64[1][2] += xC->data.F32[i]*yC->data.F32[i]/dfluxes->data.F32[i]; 205 } 206 207 A->data.F64[0][1] = A->data.F64[1][0]; 208 A->data.F64[0][2] = A->data.F64[2][0]; 209 A->data.F64[2][1] = A->data.F64[1][2]; 210 211 if (!psMatrixGJSolve(A, B)) { 212 psError(PSPHOT_ERR_PSF, false, "Singular matrix solving for (r,x) = (%d,%d)'s residuals", 213 oy, ox); 214 psFree(resid); resid = NULL; 215 break; 216 } 217 218 resid->Ro->data.F32[oy][ox] = B->data.F64[0]; 219 resid->Rx->data.F32[oy][ox] = B->data.F64[1]; 220 resid->Ry->data.F32[oy][ox] = B->data.F64[2]; 201 221 } 202 203 // measure the robust median to determine a baseline reference value204 *fluxClip = *fluxClipDef;205 psVectorStats (fluxClip, fluxes, NULL, fmasks, 0xff);206 psErrorClear(); // clear (ignore) any outstanding errors207 208 // mark input pixels which are more than N sigma from the median209 for (int i = 0; i < fluxes->n; i++) {210 float delta = fluxes->data.F32[i] - fluxClip->robustMedian;211 float sigma = sqrt (dfluxes->data.F32[i]);212 float swing = fabs(delta) / sigma;213 214 // make this a user option215 if (swing > nSigma) {216 fmasks->data.U8[i] = 1;217 }218 }219 220 psImageInit(A, 0.0);221 psVectorInit(B, 0.0);222 for (int i = 0; i < fluxes->n; i++) {223 if (fmasks->data.U8[i]) continue;224 B->data.F64[0] += fluxes->data.F32[i]/dfluxes->data.F32[i];225 B->data.F64[1] += fluxes->data.F32[i]*xC->data.F32[i]/dfluxes->data.F32[i];226 B->data.F64[2] += fluxes->data.F32[i]*yC->data.F32[i]/dfluxes->data.F32[i];227 228 A->data.F64[0][0] += 1.0/dfluxes->data.F32[i];229 A->data.F64[1][0] += xC->data.F32[i]/dfluxes->data.F32[i];230 A->data.F64[2][0] += yC->data.F32[i]/dfluxes->data.F32[i];231 232 A->data.F64[1][1] += PS_SQR(xC->data.F32[i])/dfluxes->data.F32[i];233 A->data.F64[2][2] += PS_SQR(yC->data.F32[i])/dfluxes->data.F32[i];234 A->data.F64[1][2] += xC->data.F32[i]*yC->data.F32[i]/dfluxes->data.F32[i];235 }236 237 A->data.F64[0][1] = A->data.F64[1][0];238 A->data.F64[0][2] = A->data.F64[2][0];239 A->data.F64[2][1] = A->data.F64[1][2];240 psMatrixGJSolve(A, B);241 242 resid->Ro->data.F32[oy][ox] = B->data.F64[0];243 resid->Rx->data.F32[oy][ox] = B->data.F64[1];244 resid->Ry->data.F32[oy][ox] = B->data.F64[2];245 222 } 246 223 } … … 248 225 psFree (A); 249 226 psFree (B); 250 251 # endif252 227 253 228 psLogMsg ("psphot.pspsf", PS_LOG_INFO, "generate residuals for %ld objects: %f sec\n", input->n, psTimerMark ("residuals")); … … 266 241 psFree (fluxClipDef); 267 242 268 if ( psTraceGetLevel("psphot") > 5) {243 if (resid != NULL && psTraceGetLevel("psphot") > 5) { 269 244 psphotSaveImage (NULL, resid->Ro, "resid.ro.fits"); 270 245 psphotSaveImage (NULL, resid->Rx, "resid.rx.fits"); … … 275 250 276 251 psf->residuals = resid; 277 return true;252 return (resid != NULL) ? true : false; 278 253 }
Note:
See TracChangeset
for help on using the changeset viewer.
