Changeset 27657 for trunk/psphot/src/psphotFitSourcesLinearStack.c
- Timestamp:
- Apr 11, 2010, 5:08:29 PM (16 years ago)
- Location:
- trunk/psphot
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot
-
Property svn:mergeinfo
set to
/branches/eam_branches/stackphot.20100406/psphot merged eligible
-
Property svn:mergeinfo
set to
-
trunk/psphot/src
- Property svn:ignore
-
old new 21 21 psphotForced 22 22 psphotMakePSF 23 psphotStack
-
- Property svn:ignore
-
trunk/psphot/src/psphotFitSourcesLinearStack.c
r27547 r27657 1 1 # include "psphotInternal.h" 2 // XXX need array of covar factors for each image 3 // XXX define the 'good' / 'bad' flags? 2 4 3 // for now, let's store the detections on the readout->analysis for each readout 4 bool psphotFitSourcesLinearStack (pmConfig *config, const pmFPAview *view, bool final) 5 { 6 bool status = true; 5 # define COVAR_FACTOR 1.0 7 6 8 int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM"); 9 psAssert (status, "programming error: must define PSPHOT.INPUT.NUM"); 10 11 // loop over the available readouts 12 for (int i = 0; i < num; i++) { 13 if (!psphotFitSourcesLinearReadoutStack (config, view, "PSPHOT.INPUT", i, final)) { 14 psError (PSPHOT_ERR_CONFIG, false, "failed to fit sources (linear) for PSPHOT.INPUT entry %d", i); 15 return false; 16 } 17 } 18 return true; 19 } 20 21 bool psphotFitSourcesLinearReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, bool final) { 7 bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final) { 22 8 23 9 bool status; 24 float x;25 float y;26 10 float f; 27 // float r;28 11 29 12 // select the appropriate recipe information 30 13 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 31 14 assert (recipe); 32 33 // find the currently selected readout34 pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest35 psAssert (file, "missing file?");36 37 pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);38 psAssert (readout, "missing readout?");39 40 pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");41 psAssert (detections, "missing detections?");42 43 psArray *sources = detections->allSources;44 psAssert (sources, "missing sources?");45 46 if (!sources->n) {47 psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping linear fit");48 return true;49 }50 51 pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");52 psAssert (sources, "missing psf?");53 15 54 16 psTimerStart ("psphot.linear"); … … 65 27 maskVal |= markVal; 66 28 67 // source analysis is done in spatial order 68 sources = psArraySort (sources, pmSourceSortByY); 29 // analysis is done in spatial order (to speed up overlap search) 30 // sort by first element in each source list 31 objects = psArraySort (objects, pmPhotObjSortByX); 69 32 70 33 // storage array for fitSources 71 psArray *fitSources = psArrayAllocEmpty ( sources->n);34 psArray *fitSources = psArrayAllocEmpty (objects->n); 72 35 73 // option to limit analysis to a specific region 74 char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION"); 75 psRegion AnalysisRegion = psRegionFromString (region); 76 AnalysisRegion = psRegionForImage (readout->image, AnalysisRegion); 77 if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined"); 36 bool CONSTANT_PHOTOMETRIC_WEIGHTS = psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS"); 37 psAssert (status, "You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS"); 78 38 79 bool CONSTANT_PHOTOMETRIC_WEIGHTS = 80 psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS"); 81 if (!status) { 82 psAbort("You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS"); 83 } 84 int SKY_FIT_ORDER = psMetadataLookupS32(&status, recipe, "SKY_FIT_ORDER"); 85 if (!status) { 86 SKY_FIT_ORDER = 0; 87 } 88 bool SKY_FIT_LINEAR = psMetadataLookupBool(&status, recipe, "SKY_FIT_LINEAR"); 89 if (!status) { 90 SKY_FIT_LINEAR = false; 91 } 92 93 // XXX test: choose a larger-than expected radius: 94 float covarFactor = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix 95 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "covariance factor: %f\n", covarFactor); 96 97 // XXX do not apply covarFactor for the moment... 98 // covarFactor = 1.0; 39 // XXX store a local static array of covar factors for each of the images (by image ID) 40 // float covarFactor = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix 41 // psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "covariance factor: %f\n", covarFactor); 99 42 100 43 // select the sources which will be used for the fitting analysis … … 104 47 if (!object->sources) continue; 105 48 106 // check an element of the group to see if we should use it107 if (!object->flags & PM_PHOT_OBJ_BAD) continue;49 // XXX check an element of the group to see if we should use it 50 // if (!object->flags & PM_PHOT_OBJ_BAD) continue; 108 51 109 52 for (int j = 0; j < object->sources->n; j++) { … … 123 66 } 124 67 } 125 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), sources->n);68 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), objects->n); 126 69 127 70 if (fitSources->n == 0) { … … 143 86 144 87 // diagonal elements of the sparse matrix (auto-cross-product) 145 f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor);88 f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR); 146 89 psSparseMatrixElement (sparse, i, i, f); 147 90 148 91 // the formal error depends on the weighting scheme 149 92 if (CONSTANT_PHOTOMETRIC_WEIGHTS) { 150 float var = pmSourceModelDotModel (SRCi, SRCi, false, covarFactor);93 float var = pmSourceModelDotModel (SRCi, SRCi, false, COVAR_FACTOR); 151 94 errors->data.F32[i] = 1.0 / sqrt(var); 152 95 } else { … … 155 98 156 99 // find the image x model value 157 f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor);100 f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR); 158 101 psSparseVectorElement (sparse, i, f); 159 102 … … 162 105 pmSource *SRCj = fitSources->data[j]; 163 106 164 // XXX I need to know if this source is on the same image as SRCi --165 if ( !sameImge) { continue; }107 // we only need to generate dot terms for source on the same image 108 if (SRCj->imageID != SRCi->imageID) { continue; } 166 109 167 110 // skip over disjoint source images, break after last possible overlap 168 if (SRC i->pixels->row0 + SRCi->pixels->numRows < SRCj->pixels->row0) break;169 if (SRC j->pixels->row0 + SRCj->pixels->numRows < SRCi->pixels->row0) continue;170 if (SRC i->pixels->col0 + SRCi->pixels->numCols < SRCj->pixels->col0) continue;171 if (SRC j->pixels->col0 + SRCj->pixels->numCols < SRCi->pixels->col0) continue;111 if (SRCj->pixels->row0 + SRCj->pixels->numRows < SRCi->pixels->row0) continue; // source(i) is above source(j) 112 if (SRCi->pixels->row0 + SRCi->pixels->numRows < SRCj->pixels->row0) continue; // source(i) is below source(j) 113 if (SRCj->pixels->col0 + SRCj->pixels->numCols < SRCi->pixels->col0) continue; // source(i) is right of source(j) 114 if (SRCi->pixels->col0 + SRCi->pixels->numCols < SRCj->pixels->col0) break; // source(i) is left of source(j) [no other source(j) can overlap source(i)] 172 115 173 116 // got an overlap; calculate cross-product and add to output array 174 f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor);117 f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR); 175 118 psSparseMatrixElement (sparse, j, i, f); 176 119 } … … 190 133 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "solve matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); 191 134 192 // XXXX **** philosophical question:193 // we measure bright objects in three passes: 1) linear fit; 2) non-linear fit; 3) linear fit:194 // should retain the chisq and errors from the intermediate non-linear fit?195 // the non-linear fit provides better values for the position errors, and for196 // extended sources, the shape errors197 198 135 // adjust I0 for fitSources and subtract 199 136 for (int i = 0; i < fitSources->n; i++) { … … 208 145 model->params->data.F32[PM_PAR_I0] = norm->data.F32[i]; 209 146 model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i]; 210 // XXX is the value of 'errors' modified by the sky fit?211 147 212 148 // subtract object … … 221 157 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) continue; 222 158 pmModel *model = pmSourceGetModel (NULL, source); 223 pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal, covarFactor);159 pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal, COVAR_FACTOR); 224 160 } 225 161 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "get chisqs: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); … … 229 165 psFree (fitSources); 230 166 psFree (norm); 231 psFree (skyfit);232 167 psFree (errors); 233 psFree (border);234 168 235 169 psLogMsg ("psphot.ensemble", PS_LOG_INFO, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear")); 236 237 psphotVisualShowResidualImage (readout);238 psphotVisualPlotChisq (sources);239 // psphotVisualShowFlags (sources);240 241 // We have to place this visualization here because the models are not realized until242 // psphotGuessModels or fitted until psphotFitSourcesLinear.243 psphotVisualShowPSFStars (recipe, psf, sources);244 170 245 171 return true; 246 172 } 247 173 248 // XXX do we need this? 249 // XXX disallow the simultaneous sky fit and remove this code... 174 // sort by X (ascending) 175 int pmPhotObjSortByX (const void **a, const void **b) 176 { 177 pmPhotObj *objA = *(pmPhotObj **)a; 178 pmPhotObj *objB = *(pmPhotObj **)b; 250 179 251 // Calculate the weight terms for the sky fit component of the matrix. This function operates 252 // on the pixels which correspond to all of the sources of interest. These elements fill in 253 // the border matrix components in the sparse matrix equation. 254 static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, int SKY_FIT_ORDER, psImageMaskType markVal) { 180 psF32 fA = objA->x; 181 psF32 fB = objB->x; 255 182 256 // generate the image-wide weight terms 257 // turn on MARK for all image pixels 258 psRegion fullArray = psRegionSet (0, 0, 0, 0); 259 fullArray = psRegionForImage (readout->mask, fullArray); 260 psImageMaskRegion (readout->mask, fullArray, "OR", markVal); 261 262 // turn off MARK for all object pixels 263 for (int i = 0; i < sources->n; i++) { 264 pmSource *source = sources->data[i]; 265 pmModel *model = pmSourceGetModel (NULL, source); 266 if (model == NULL) continue; 267 float x = model->params->data.F32[PM_PAR_XPOS]; 268 float y = model->params->data.F32[PM_PAR_YPOS]; 269 psImageMaskCircle (source->maskView, x, y, model->fitRadius, "AND", PS_NOT_IMAGE_MASK(markVal)); 270 } 271 272 // accumulate the image statistics from the masked regions 273 psF32 **image = readout->image->data.F32; 274 psF32 **variance = readout->variance->data.F32; 275 psImageMaskType **mask = readout->mask->data.PS_TYPE_IMAGE_MASK_DATA; 276 277 double w, x, y, x2, xy, y2, xc, yc, wt, f, fo, fx, fy; 278 w = x = y = x2 = xy = y2 = fo = fx = fy = 0; 279 280 int col0 = readout->image->col0; 281 int row0 = readout->image->row0; 282 283 for (int j = 0; j < readout->image->numRows; j++) { 284 for (int i = 0; i < readout->image->numCols; i++) { 285 if (mask[j][i]) continue; 286 if (constant_weights) { 287 wt = 1.0; 288 } else { 289 wt = variance[j][i]; 290 } 291 f = image[j][i]; 292 w += 1/wt; 293 fo += f/wt; 294 if (SKY_FIT_ORDER == 0) continue; 295 296 xc = i + col0; 297 yc = j + row0; 298 x += xc/wt; 299 y += yc/wt; 300 x2 += xc*xc/wt; 301 xy += xc*yc/wt; 302 y2 += yc*yc/wt; 303 fx += f*xc/wt; 304 fy += f*yc/wt; 305 } 306 } 307 308 // turn off MARK for all image pixels 309 psImageMaskRegion (readout->mask, fullArray, "AND", PS_NOT_IMAGE_MASK(markVal)); 310 311 // set the Border T elements 312 psSparseBorderElementG (border, 0, fo); 313 psSparseBorderElementT (border, 0, 0, w); 314 if (SKY_FIT_ORDER > 0) { 315 psSparseBorderElementG (border, 0, fx); 316 psSparseBorderElementG (border, 0, fy); 317 psSparseBorderElementT (border, 1, 0, x); 318 psSparseBorderElementT (border, 2, 0, y); 319 psSparseBorderElementT (border, 0, 1, x); 320 psSparseBorderElementT (border, 1, 1, x2); 321 psSparseBorderElementT (border, 2, 1, xy); 322 psSparseBorderElementT (border, 0, 2, y); 323 psSparseBorderElementT (border, 1, 2, xy); 324 psSparseBorderElementT (border, 2, 2, y2); 325 } 326 327 return true; 183 psF32 diff = fA - fB; 184 if (diff > FLT_EPSILON) return (+1); 185 if (diff < FLT_EPSILON) return (-1); 186 return (0); 328 187 }
Note:
See TracChangeset
for help on using the changeset viewer.
