- Timestamp:
- May 3, 2010, 8:50:52 AM (16 years ago)
- Location:
- branches/simtest_nebulous_branches
- Files:
-
- 4 edited
-
. (modified) (1 prop)
-
psphot (modified) (1 prop)
-
psphot/src (modified) (1 prop)
-
psphot/src/psphotFitSourcesLinearStack.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/simtest_nebulous_branches
- Property svn:mergeinfo changed
-
branches/simtest_nebulous_branches/psphot
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psphot merged eligible /branches/eam_branches/stackphot.20100406/psphot 27622-27655 /branches/pap_delete/psphot 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/simtest_nebulous_branches/psphot/src
- Property svn:ignore
-
old new 18 18 psphotVersionDefinitions.h 19 19 psphotMomentsStudy 20 psphotPetrosianStudy 21 psphotForced 22 psphotMakePSF 23 psphotStack
-
- Property svn:ignore
-
branches/simtest_nebulous_branches/psphot/src/psphotFitSourcesLinearStack.c
r24584 r27840 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 // fit flux (and optionally sky model) to all reasonable sources 4 // with the linear fitting process. sources must have an associated 5 // model with selected pixels, and the fit radius must be defined 5 # define COVAR_FACTOR 1.0 6 6 7 // given the set of sources, each of which points to the pixels in the 8 // science image, we construct a set of simulated sources with their own pixels. 9 // these are used to determine the simultaneous linear fit of fluxes. 10 // the analysis is performed wrt the simulated pixel values 11 12 static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, psImageMaskType markVal); 13 14 bool psphotFitSourcesLinear (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, bool final) { 7 bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final) { 15 8 16 9 bool status; 17 float x;18 float y;19 10 float f; 20 // float r; 11 12 // select the appropriate recipe information 13 psMetadata *recipe = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE); 14 assert (recipe); 21 15 22 16 psTimerStart ("psphot.linear"); … … 33 27 maskVal |= markVal; 34 28 35 // source analysis is done in spatial order 36 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); 37 32 38 33 // storage array for fitSources 39 psArray *fitSources = psArrayAllocEmpty ( sources->n);34 psArray *fitSources = psArrayAllocEmpty (objects->n); 40 35 41 bool CONSTANT_PHOTOMETRIC_WEIGHTS = 42 psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS"); 43 if (!status) { 44 psAbort("You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS"); 45 } 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"); 38 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); 46 42 47 43 // select the sources which will be used for the fitting analysis 48 for (int i = 0; i < sources->n; i++) { 49 pmSource *source = sources->data[i]; 44 for (int i = 0; i < objects->n; i++) { 45 pmPhotObj *object = objects->data[i]; 46 if (!object) continue; 47 if (!object->sources) continue; 50 48 51 // turn this bit off and turn it on again if we pass this test52 source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT;49 // XXX check an element of the group to see if we should use it 50 // if (!object->flags & PM_PHOT_OBJ_BAD) continue; 53 51 54 // skip non-astronomical objects (very likely defects) 55 if (source->type == PM_SOURCE_TYPE_DEFECT) continue;56 if (source->type == PM_SOURCE_TYPE_SATURATED) continue;52 for (int j = 0; j < object->sources->n; j++) { 53 pmSource *source = object->sources->data[j]; 54 if (!source) continue; 57 55 58 // do not include CRs in the full ensemble fit 59 if (source->mode & PM_SOURCE_MODE_CR_LIMIT) continue;56 // turn this bit off and turn it on again if we keep this source 57 source->mode &= ~PM_SOURCE_MODE_LINEAR_FIT; 60 58 61 if (final) { 62 if (source->tmpFlags & PM_SOURCE_TMPF_SUBTRACTED) continue; 63 } else { 64 if (source->mode & PM_SOURCE_MODE_BLEND) continue; 65 } 59 // generate model for sources without, or skip if we can't 60 if (!source->modelFlux) { 61 if (!pmSourceCacheModel (source, maskVal)) continue; 62 } 66 63 67 // generate model for sources without, or skip if we can't 68 if (!source->modelFlux) { 69 if (!pmSourceCacheModel (source, maskVal)) continue; 70 } 71 72 source->mode |= PM_SOURCE_MODE_LINEAR_FIT; 73 psArrayAdd (fitSources, 100, source); 64 source->mode |= PM_SOURCE_MODE_LINEAR_FIT; 65 psArrayAdd (fitSources, 100, source); 66 } 74 67 } 75 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); 76 69 77 70 if (fitSources->n == 0) { … … 83 76 psVector *errors = psVectorAlloc (fitSources->n, PS_TYPE_F32); 84 77 85 // create the border matrix (includes the sparse matrix) 86 // for just sky: 1 row; for x,y terms: 3 rows 78 // create the sparse matrix 87 79 psSparse *sparse = psSparseAlloc (fitSources->n, 100); 88 psSparseBorder *border = psSparseBorderAlloc (sparse, 1);89 80 90 81 // fill out the sparse matrix elements and border elements (B) … … 95 86 96 87 // diagonal elements of the sparse matrix (auto-cross-product) 97 f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS );88 f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR); 98 89 psSparseMatrixElement (sparse, i, i, f); 99 90 100 91 // the formal error depends on the weighting scheme 101 92 if (CONSTANT_PHOTOMETRIC_WEIGHTS) { 102 float var = pmSourceModelDotModel (SRCi, SRCi, false );93 float var = pmSourceModelDotModel (SRCi, SRCi, false, COVAR_FACTOR); 103 94 errors->data.F32[i] = 1.0 / sqrt(var); 104 95 } else { … … 106 97 } 107 98 108 109 99 // find the image x model value 110 f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS );100 f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR); 111 101 psSparseVectorElement (sparse, i, f); 112 113 f = pmSourceModelWeight (SRCi, 0, CONSTANT_PHOTOMETRIC_WEIGHTS);114 psSparseBorderElementB (border, i, 0, f);115 102 116 103 // loop over all other stars following this one … … 118 105 pmSource *SRCj = fitSources->data[j]; 119 106 107 // we only need to generate dot terms for source on the same image 108 if (SRCj->imageID != SRCi->imageID) { continue; } 109 120 110 // skip over disjoint source images, break after last possible overlap 121 if (SRC i->pixels->row0 + SRCi->pixels->numRows < SRCj->pixels->row0) break;122 if (SRC j->pixels->row0 + SRCj->pixels->numRows < SRCi->pixels->row0) continue;123 if (SRC i->pixels->col0 + SRCi->pixels->numCols < SRCj->pixels->col0) continue;124 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)] 125 115 126 116 // got an overlap; calculate cross-product and add to output array 127 f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS );117 f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR); 128 118 psSparseMatrixElement (sparse, j, i, f); 129 119 } … … 133 123 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); 134 124 135 // set the sky, sky_x, sky_y components of border matrix136 SetBorderMatrixElements (border, readout, fitSources, CONSTANT_PHOTOMETRIC_WEIGHTS, SKY_FIT_ORDER, markVal);137 138 125 psSparseConstraint constraint; 139 126 constraint.paramMin = 0.0; … … 142 129 143 130 // solve for normalization terms (need include local sky?) 144 psVector *norm = psSparseSolve (NULL, constraint, sparse, 5);145 131 psVector *norm = NULL; 132 norm = psSparseSolve (NULL, constraint, sparse, 5); 146 133 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "solve matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); 147 148 // XXXX **** philosophical question:149 // we measure bright objects in three passes: 1) linear fit; 2) non-linear fit; 3) linear fit:150 // should retain the chisq and errors from the intermediate non-linear fit?151 // the non-linear fit provides better values for the position errors, and for152 // extended sources, the shape errors153 134 154 135 // adjust I0 for fitSources and subtract … … 164 145 model->params->data.F32[PM_PAR_I0] = norm->data.F32[i]; 165 146 model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i]; 166 // XXX is the value of 'errors' modified by the sky fit?167 147 168 148 // subtract object 169 149 pmSourceSub (source, PM_MODEL_OP_FULL, maskVal); 170 source->tmpFlags |= PM_SOURCE_TMPF_SUBTRACTED;171 150 } 172 151 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "sub models: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); 173 152 174 153 // measure chisq for each source 175 for (int i = 0; final && (i < fitSources->n); i++) { 154 // for (int i = 0; final && (i < fitSources->n); i++) { 155 for (int i = 0; i < fitSources->n; i++) { 176 156 pmSource *source = fitSources->data[i]; 177 157 if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) continue; 178 158 pmModel *model = pmSourceGetModel (NULL, source); 179 pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal );159 pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal, COVAR_FACTOR); 180 160 } 181 161 psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "get chisqs: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem); … … 186 166 psFree (norm); 187 167 psFree (errors); 188 psFree (border);189 168 190 169 psLogMsg ("psphot.ensemble", PS_LOG_INFO, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear")); 191 192 psphotVisualShowResidualImage (readout);193 psphotVisualShowFlags (sources);194 170 195 171 return true; 196 172 } 197 173 198 // Calculate the weight terms for the sky fit component of the matrix. This function operates 199 // on the pixels which correspond to all of the sources of interest. These elements fill in 200 // the border matrix components in the sparse matrix equation. 201 static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, psImageMaskType markVal) { 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; 202 179 203 // generate the image-wide weight terms 204 // turn on MARK for all image pixels 205 psRegion fullArray = psRegionSet (0, 0, 0, 0); 206 fullArray = psRegionForImage (readout->mask, fullArray); 207 psImageMaskRegion (readout->mask, fullArray, "OR", markVal); 180 psF32 fA = objA->x; 181 psF32 fB = objB->x; 208 182 209 // turn off MARK for all object pixels 210 for (int i = 0; i < sources->n; i++) { 211 pmSource *source = sources->data[i]; 212 pmModel *model = pmSourceGetModel (NULL, source); 213 if (model == NULL) continue; 214 float x = model->params->data.F32[PM_PAR_XPOS]; 215 float y = model->params->data.F32[PM_PAR_YPOS]; 216 psImageMaskCircle (source->maskView, x, y, model->radiusFit, "AND", PS_NOT_IMAGE_MASK(markVal)); 217 } 218 219 // accumulate the image statistics from the masked regions 220 psF32 **image = readout->image->data.F32; 221 psF32 **variance = readout->variance->data.F32; 222 psImageMaskType **mask = readout->mask->data.PS_TYPE_IMAGE_MASK_DATA; 223 224 double w, x, y, x2, xy, y2, xc, yc, wt, f, fo, fx, fy; 225 w = x = y = x2 = xy = y2 = fo = fx = fy = 0; 226 227 int col0 = readout->image->col0; 228 int row0 = readout->image->row0; 229 230 for (int j = 0; j < readout->image->numRows; j++) { 231 for (int i = 0; i < readout->image->numCols; i++) { 232 if (mask[j][i]) continue; 233 if (constant_weights) { 234 wt = 1.0; 235 } else { 236 wt = variance[j][i]; 237 } 238 f = image[j][i]; 239 w += 1/wt; 240 fo += f/wt; 241 } 242 } 243 244 // turn off MARK for all image pixels 245 psImageMaskRegion (readout->mask, fullArray, "AND", PS_NOT_IMAGE_MASK(markVal)); 246 247 // set the Border T elements 248 psSparseBorderElementG (border, 0, fo); 249 psSparseBorderElementT (border, 0, 0, w); 250 251 return true; 183 psF32 diff = fA - fB; 184 if (diff > FLT_EPSILON) return (+1); 185 if (diff < FLT_EPSILON) return (-1); 186 return (0); 252 187 }
Note:
See TracChangeset
for help on using the changeset viewer.
