Changeset 4582
- Timestamp:
- Jul 20, 2005, 4:19:11 AM (21 years ago)
- Location:
- trunk/psphot/src
- Files:
-
- 6 edited
-
LocalSky.c (modified) (1 diff)
-
apply_psf_model.c (modified) (1 diff)
-
basic_classes.c (modified) (1 diff)
-
fit_galaxies.c (modified) (3 diffs)
-
onesource.c (modified) (2 diffs)
-
psphot.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/LocalSky.c
r4375 r4582 58 58 } 59 59 60 # define PM_SOURCE_FIT_MODEL_NUM_ITERATIONS 15 61 # define PM_SOURCE_FIT_MODEL_TOLERANCE 0.1 62 bool pmSourceFitModel_EAM(psSource *source, 63 psModel *model, 64 const bool PSF, 65 float SOFT) 66 { 67 PS_PTR_CHECK_NULL(source, false); 68 PS_PTR_CHECK_NULL(source->moments, false); 69 PS_PTR_CHECK_NULL(source->peak, false); 70 PS_PTR_CHECK_NULL(source->pixels, false); 71 PS_PTR_CHECK_NULL(source->mask, false); 72 PS_PTR_CHECK_NULL(source->noise, false); 73 psBool fitStatus = true; 74 psBool onPic = true; 75 psBool rc = true; 76 psF32 Ro; 77 78 79 // XXX EAM : is it necessary for the mask & noise to exist? the 80 // tests below could be conditions (!NULL) 81 82 psModelFunc modelFunc = psModelFunc_GetFunction (model->type); 83 84 psVector *params = model->params; 85 psVector *dparams = model->dparams; 86 psVector *paramMask = NULL; 87 88 int nParams = PSF ? params->n - 4 : params->n; 89 psF32 Xo = params->data.F32[2]; 90 psF32 Yo = params->data.F32[3]; 91 92 // find the number of valid pixels 93 // XXX EAM : this loop and the loop below could just be one pass 94 // using the psArrayAdd and psVectorExtend functions 95 psS32 count = 0; 96 for (psS32 i = 0; i < source->pixels->numRows; i++) { 97 for (psS32 j = 0; j < source->pixels->numCols; j++) { 98 if (source->mask->data.U8[i][j] == 0) { 99 count++; 100 } 101 } 102 } 103 if (count < nParams + 1) { 104 psTrace (".pmObjects.pmSourceFitModel", 4, "insufficient valid pixels\n"); 105 return(false); 106 } 107 108 // construct the coordinate and value entries 109 psArray *x = psArrayAlloc(count); 110 psVector *y = psVectorAlloc(count, PS_TYPE_F32); 111 psVector *yErr = psVectorAlloc(count, PS_TYPE_F32); 112 psS32 tmpCnt = 0; 113 for (psS32 i = 0; i < source->pixels->numRows; i++) { 114 for (psS32 j = 0; j < source->pixels->numCols; j++) { 115 if (source->mask->data.U8[i][j] == 0) { 116 psVector *coord = psVectorAlloc(2, PS_TYPE_F32); 117 // XXX: Convert i/j to image space: 118 // XXX EAM: coord order is (x,y) == (col,row) 119 coord->data.F32[0] = (psF32) (j + source->pixels->col0); 120 coord->data.F32[1] = (psF32) (i + source->pixels->row0); 121 x->data[tmpCnt] = (psPtr *) coord; 122 y->data.F32[tmpCnt] = source->pixels->data.F32[i][j]; 123 124 // XXX just for test purposes, use the raw radius. a better 125 // choice is to ask what is the value of z and scale by that 126 Ro = hypot ((Xo - coord->data.F32[0]), (Yo - coord->data.F32[1])); 127 128 // XXX enhance the noise (doubled if R = 10 pix, etc. note the square) 129 yErr->data.F32[tmpCnt] = sqrt (source->noise->data.F32[i][j] * (1 + PS_SQR(Ro/SOFT))); 130 // XXX EAM : note the wasted effort: we carry dY^2, take sqrt(), then 131 // the minimization function calculates sq() 132 tmpCnt++; 133 } 134 } 135 } 136 137 psMinimization *myMin = psMinimizationAlloc(PM_SOURCE_FIT_MODEL_NUM_ITERATIONS, 138 PM_SOURCE_FIT_MODEL_TOLERANCE); 139 140 // PSF model only fits first 4 parameters, FLT model fits all 141 if (PSF) { 142 paramMask = psVectorAlloc (params->n, PS_TYPE_U8); 143 for (int i = 0; i < 4; i++) { 144 paramMask->data.U8[i] = 0; 145 } 146 for (int i = 4; i < paramMask->n; i++) { 147 paramMask->data.U8[i] = 1; 148 } 149 } 150 151 psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F64); 152 153 psTrace (".pmObjects.pmSourceFitModel", 5, "fitting function\n"); 154 fitStatus = psMinimizeLMChi2(myMin, covar, params, paramMask, x, y, yErr, modelFunc); 155 for (int i = 0; i < dparams->n; i++) { 156 if ((paramMask != NULL) && paramMask->data.U8[i]) continue; 157 dparams->data.F32[i] = sqrt(covar->data.F64[i][i]); 158 } 159 160 // XXX EAM: we need to do something (give an error?) if rc is false 161 // XXX EAM: psMinimizeLMChi2 does not check convergence 162 163 // XXX models can go insane: reject these 164 onPic &= (params->data.F32[2] >= source->pixels->col0); 165 onPic &= (params->data.F32[2] < source->pixels->col0 + source->pixels->numCols); 166 onPic &= (params->data.F32[3] >= source->pixels->row0); 167 onPic &= (params->data.F32[3] < source->pixels->row0 + source->pixels->numRows); 168 169 // XXX EAM: save the resulting chisq, nDOF, nIter 170 model->chisq = myMin->value; 171 model->nIter = myMin->iter; 172 model->nDOF = y->n - nParams; 173 174 // XXX EAM get the Gauss-Newton distance for fixed model parameters 175 if (paramMask != NULL) { 176 psVector *delta = psVectorAlloc (params->n, PS_TYPE_F64); 177 psMinimizeGaussNewtonDelta (delta, params, NULL, x, y, yErr, modelFunc); 178 for (int i = 0; i < dparams->n; i++) { 179 if (!paramMask->data.U8[i]) continue; 180 dparams->data.F32[i] = delta->data.F64[i]; 181 } 182 } 183 184 psFree(paramMask); 185 psFree(x); 186 psFree(y); 187 psFree(myMin); 188 189 rc = (onPic && fitStatus); 190 return(rc); 191 } 192 193 /****************************************************************************** 194 pmSourceMoments(source, radius): this function takes a subImage defined in the 195 psSource data structure, along with the peak location, and determines the 196 various moments associated with that peak. 197 198 Requires the following to have been created: 199 psSource 200 psSource->peak 201 psSource->pixels 202 203 XXX: The peak calculations are done in image coords, not subImage coords. 204 205 XXX: mask values? 206 *****************************************************************************/ 207 # define VALID_RADIUS(X,Y) (((R2) >= (PS_SQR(X) + PS_SQR(Y))) ? 1 : 0) 208 209 bool pmSourceMoments_EAM(psSource *source, 210 psF32 radius) 211 { 212 PS_PTR_CHECK_NULL(source, NULL); 213 PS_PTR_CHECK_NULL(source->peak, NULL); 214 PS_PTR_CHECK_NULL(source->pixels, NULL); 215 PS_PTR_CHECK_NULL(source->noise, NULL); 216 PS_FLOAT_COMPARE(0.0, radius, NULL); 217 218 // 219 // XXX: Verify the setting for sky if source->moments == NULL. 220 // 221 psF32 sky = 0.0; 222 if (source->moments == NULL) { 223 source->moments = pmMomentsAlloc(); 224 } else { 225 sky = source->moments->Sky; 226 } 227 228 // 229 // Sum = SUM (z - sky) 230 // X1 = SUM (x - xc)*(z - sky) 231 // X2 = SUM (x - xc)^2 * (z - sky) 232 // XY = SUM (x - xc)*(y - yc)*(z - sky) 233 // 234 psF32 peakPixel = -PS_MAX_F32; 235 psS32 numPixels = 0; 236 psF32 Sum = 0.0; 237 psF32 X1 = 0.0; 238 psF32 Y1 = 0.0; 239 psF32 X2 = 0.0; 240 psF32 Y2 = 0.0; 241 psF32 XY = 0.0; 242 psF32 x = 0; 243 psF32 y = 0; 244 psF32 R2 = PS_SQR(radius); 245 246 psF32 xPeak = source->peak->x; 247 psF32 yPeak = source->peak->y; 248 249 // XXX why do I get different results for these two methods of finding Sx? 250 // XXX Sx, Sy would be better measured if we clip pixels close to sky 251 // XXX Sx, Sy can still be imaginary, so we probably need to keep Sx^2? 252 // We loop through all pixels in this subimage (source->pixels), and for each 253 // pixel that is not masked, AND within the radius of the peak pixel, we 254 // proceed with the moments calculation. need to do two loops for a 255 // numerically stable result. first loop: get the sums. 256 // XXX EAM : mask == 0 is valid 257 258 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 259 for (psS32 col = 0; col < source->pixels->numCols ; col++) { 260 if ((source->mask != NULL) && (source->mask->data.U8[row][col])) continue; 261 262 psF32 xDiff = col + source->pixels->col0 - xPeak; 263 psF32 yDiff = row + source->pixels->row0 - yPeak; 264 265 if (!VALID_RADIUS(xDiff, yDiff)) continue; 266 267 psF32 pDiff = source->pixels->data.F32[row][col] - sky; 268 269 // XXX EAM : check for valid S/N in pixel 270 if (pDiff / sqrt(source->noise->data.F32[row][col]) < 1) continue; 271 272 Sum += pDiff; 273 X1 += xDiff * pDiff; 274 Y1 += yDiff * pDiff; 275 XY += xDiff * yDiff * pDiff; 276 277 X2 += PS_SQR(xDiff) * pDiff; 278 Y2 += PS_SQR(yDiff) * pDiff; 279 280 peakPixel = PS_MAX (source->pixels->data.F32[row][col], peakPixel); 281 numPixels++; 282 } 283 } 284 // XXX EAM - the limit is a bit arbitrary. make it user defined? 285 if ((numPixels < 3) || (Sum <= 0)) { 286 psTrace (".psModules.pmSourceMoments", 5, "no valid pixels for source\n"); 287 return (false); 288 } 289 290 psTrace (".psModules.pmSourceMoments", 5, 291 "sky: %f Sum: %f X1: %f Y1: %f X2: %f Y2: %f XY: %f Npix: %d\n", 292 sky, Sum, X1, Y1, X2, Y2, XY, numPixels); 293 294 // 295 // first moment X = X1/Sum + xc 296 // second moment X = sqrt (X2/Sum - (X1/Sum)^2) 297 // Sxy = XY / Sum 298 // 299 x = X1/Sum; 300 y = Y1/Sum; 301 if ((fabs(x) > radius) || (fabs(y) > radius)) { 302 psTrace (".psModules.pmSourceMoments", 5, 303 "large centroid swing; invalid peak %d, %d\n", 304 source->peak->x, source->peak->y); 305 return (false); 306 } 307 308 source->moments->x = x + xPeak; 309 source->moments->y = y + yPeak; 310 311 source->moments->Sxy = XY/Sum - x*y; 312 source->moments->Sum = Sum; 313 source->moments->Peak = peakPixel; 314 source->moments->nPixels = numPixels; 315 316 // XXX EAM : these values can be negative, so we need to limit the range 317 source->moments->Sx = sqrt(PS_MAX(X2/Sum - PS_SQR(x), 0)); 318 source->moments->Sy = sqrt(PS_MAX(Y2/Sum - PS_SQR(y), 0)); 319 320 psTrace (".psModules.pmSourceMoments", 4, 321 "sky: %f Sum: %f x: %f y: %f Sx: %f Sy: %f Sxy: %f\n", 322 sky, Sum, source->moments->x, source->moments->y, 323 source->moments->Sx, source->moments->Sy, source->moments->Sxy); 324 325 return(true); 326 } 327 -
trunk/psphot/src/apply_psf_model.c
r4574 r4582 21 21 float FIT_PADDING = psMetadataLookupF32 (&status, config, "FIT_PADDING"); 22 22 float shapeNsigma = psMetadataLookupF32 (&status, config, "PSF_SHAPE_NSIGMA"); 23 float snFaint = psMetadataLookupF32 (&status, config, "FAINT_SN_LIM");24 23 float OUTER = psMetadataLookupF32 (&status, config, "OUTER_RADIUS"); 25 24 -
trunk/psphot/src/basic_classes.c
r4574 r4582 11 11 // make this optional 12 12 // DumpMoments (sources, "moments.dat"); 13 return (true); 13 14 } -
trunk/psphot/src/fit_galaxies.c
r4574 r4582 14 14 15 15 float MOMENT_R = psMetadataLookupF32 (&status, config, "GAL_MOMENTS_RADIUS"); 16 float RADIUS = psMetadataLookupF32 (&status, config, "FIT_RADIUS");16 // float RADIUS = psMetadataLookupF32 (&status, config, "FIT_RADIUS"); 17 17 float snFaint = psMetadataLookupF32 (&status, config, "FAINT_SN_LIM"); 18 18 float OUTER = psMetadataLookupF32 (&status, config, "OUTER_RADIUS"); … … 22 22 float FLUX_LIMIT = FIT_NSIGMA * skyStats->sampleStdev; 23 23 24 psModelType modelType = psModelSetType ("PS_MODEL_ RGAUSS");24 psModelType modelType = psModelSetType ("PS_MODEL_SGAUSS"); 25 25 psModelRadius modelRadius = psModelRadius_GetFunction (modelType); 26 26 … … 34 34 35 35 // recalculate the source moments using the galaxy radius (larger) 36 status = pmSourceMoments (source, MOMENT_R); 36 status = pmSourceMoments_EAM (source, MOMENT_R); 37 if (!status) { 38 fprintf (stderr, "invalid moments, skipping\n"); 39 continue; 40 } 37 41 38 42 // use the source moments, etc to guess basic model parameters -
trunk/psphot/src/onesource.c
r4421 r4582 14 14 float MRAD = psMetadataLookupF32 (&status, config, "PSF_MOMENTS_RADIUS"); 15 15 float RADIUS = psMetadataLookupF32 (&status, config, "FIT_RADIUS"); 16 float SOFT = psMetadataLookupF32 (&status, config, "SOFT_RADIUS"); 16 17 17 18 psSource *source = pmSourceAlloc(); … … 26 27 27 28 psImageKeepCircle (source->mask, x, y, RADIUS, OR, 0x80); 28 status = pmSourceFitModel (source, model, false);29 status = pmSourceFitModel_EAM (source, model, false, SOFT); 29 30 30 31 pmSourcePhotometry (&fitMag, &obsMag, model, source->pixels, source->mask); -
trunk/psphot/src/psphot.h
r4574 r4582 67 67 bool DumpModelFits (psArray *models, char *filename); 68 68 bool DumpModelPSF (psArray *sources, char *filename); 69 bool DumpModelFLT (psArray *sources, char *filename); 70 bool DumpModelNULL (psArray *sources, char *filename); 69 71 bool DumpImage (psImage *image, char *filename); 72 bool DumpPSFTestData (pmPSF_Test *test, char *filename); 70 73 71 74 // psphot utilities … … 77 80 bool pmSourceDefinePixels(psSource *mySource, const psImageData *imdata, psF32 x, psF32 y, psF32 Radius); 78 81 bool pmSourceLocalSky_EAM (psSource *source, psStatsOptions statsOptions, psF32 Radius); 82 bool pmSourceFitModel_EAM(psSource *source, psModel *model, const bool PSF, float SOFT); 83 bool pmSourceMoments_EAM(psSource *source, psF32 radius); 79 84 80 85 // fitsource utilities
Note:
See TracChangeset
for help on using the changeset viewer.
