Changeset 6481 for trunk/psphot/src/psphotEnsemblePSF.c
- Timestamp:
- Feb 23, 2006, 6:16:11 PM (20 years ago)
- File:
-
- 1 edited
-
trunk/psphot/src/psphotEnsemblePSF.c (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/psphotEnsemblePSF.c
r6427 r6481 1 1 # include "psphot.h" 2 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight); 2 3 3 4 // 2006.02.07 : no leaks! 4 5 // fit all reasonable sources with the linear PSF model 5 bool psphotEnsemblePSF (pmReadout *readout, psMetadata *config, psArray *sources, pmPSF *psf ) {6 bool psphotEnsemblePSF (pmReadout *readout, psMetadata *config, psArray *sources, pmPSF *psf, bool final) { 6 7 7 8 bool status; … … 9 10 float y; 10 11 float f; 12 float r; 13 14 // psRegion allArray = psRegionSet (0, 0, 0, 0); 11 15 12 16 psTimerStart ("psphot"); … … 29 33 30 34 // option to limit analysis to a specific region 31 bool UseAnalysisRegion = false;32 psRegion AnalysisRegion = {0, 0, 0, 0};33 35 char *region = psMetadataLookupStr (&status, config, "ANALYSIS_REGION"); 34 if (status) { 35 UseAnalysisRegion = true; 36 AnalysisRegion = psRegionFromString (region); 37 psLogMsg ("psphotEnsemblePSF", 4, "using region %f,%f - %f,%f\n", 38 AnalysisRegion.x0, AnalysisRegion.y0, 39 AnalysisRegion.x1, AnalysisRegion.y1); 40 } 36 psRegion AnalysisRegion = psRegionFromString (region); 37 AnalysisRegion = psRegionForImage (readout->image, AnalysisRegion); 38 // psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region)); 39 if (psRegionIsNaN (AnalysisRegion)) psAbort ("psphot", "analysis region mis-defined"); 41 40 42 41 for (int i = 0; i < sources->n; i++) { … … 45 44 // skip non-astronomical objects (very likely defects) 46 45 // XXX EAM : should we try these anyway? 47 if (inSource->mode & PM_SOURCE_BLEND) continue;48 46 if (inSource->type == PM_SOURCE_DEFECT) continue; 49 47 if (inSource->type == PM_SOURCE_SATURATED) continue; 50 51 if (UseAnalysisRegion) { 52 if (inSource->moments->x < AnalysisRegion.x0) continue; 53 if (inSource->moments->y < AnalysisRegion.y0) continue; 54 if (inSource->moments->x > AnalysisRegion.x1) continue; 55 if (inSource->moments->y > AnalysisRegion.y1) continue; 56 } 48 if (final) { 49 if (inSource->mode & PM_SOURCE_SUBTRACTED) continue; 50 } else { 51 if (inSource->mode & PM_SOURCE_BLEND) continue; 52 } 53 54 if (inSource->moments->x < AnalysisRegion.x0) continue; 55 if (inSource->moments->y < AnalysisRegion.y0) continue; 56 if (inSource->moments->x > AnalysisRegion.x1) continue; 57 if (inSource->moments->y > AnalysisRegion.y1) continue; 57 58 58 59 pmSource *otSource = pmSourceAlloc (); … … 73 74 // peak-up on peak (for non-sat objects) 74 75 75 int ix = inSource->peak->x; 76 int iy = inSource->peak->y; 76 // ix,iy must land on inSource->pixels 77 int ix = PS_MAX (inSource->pixels->col0 + 1, PS_MIN (inSource->pixels->col0 + inSource->pixels->numCols - 2, inSource->peak->x)); 78 int iy = PS_MAX (inSource->pixels->row0 + 1, PS_MIN (inSource->pixels->row0 + inSource->pixels->numRows - 2, inSource->peak->y)); 77 79 78 80 psPolynomial2D *bicube = psImageBicubeFit (inSource->pixels, ix, iy); … … 104 106 otSource->mask = psImageCopy (NULL, inSource->mask, PS_TYPE_U8); 105 107 otSource->pixels = psImageCopy (NULL, inSource->pixels, PS_TYPE_F32); 108 otSource->weight = psImageCopy (NULL, inSource->weight, PS_TYPE_F32); 106 109 107 110 // build the model image … … 117 120 psImageKeepCircle (mask, x, y, model->radius, "OR", PSPHOT_MASK_MARKED); 118 121 pmSourceAddModel (flux, mask, model, false, false); 122 123 // calculate nDOF (nPix - 1) 124 // int Nmaskpix = psImageCountPixelMask (mask, allArray, PSPHOT_MASK_SATURATED); 125 // model->nDOF = mask->numCols*mask->numRows - Nmaskpix - 1; 119 126 120 127 // save source in list … … 128 135 // fill out the sparse matrix 129 136 psSparse *sparse = psSparseAlloc (models->n, 100); 137 psVector *weight = psVectorAlloc (models->n, PS_TYPE_F32); 130 138 for (int i = 0; i < models->n; i++) { 131 139 int N = index->data.U32[i]; … … 133 141 pmSource *Mi = models->data[i]; 134 142 135 // diagonal element (auto-cross-product) 136 f = pmSourceCrossProduct (Mi, Mi); 137 psSparseMatrixElement (sparse, i, i, f); 143 // scale by diagonal element (auto-cross-product) 144 r = pmSourceCrossProduct (Mi, Mi); 145 weight->data.F32[i] = r; 146 147 psSparseMatrixElement (sparse, i, i, 1.0); 138 148 139 149 // find the image x model value 140 150 f = pmSourceCrossProduct (Fi, Mi); 141 psSparseVectorElement (sparse, i, f );151 psSparseVectorElement (sparse, i, f / r); 142 152 143 153 // loop over all other stars following this one … … 153 163 // got an overlap; calculate cross-product and add to output array 154 164 f = pmSourceCrossProduct (Mi, Mj); 155 psSparseMatrixElement (sparse, j, i, f );165 psSparseMatrixElement (sparse, j, i, f / r); 156 166 } 157 167 } 158 168 psLogMsg ("psphot.emsemble", 4, "built matrix: %f (%d elements)\n", psTimerMark ("psphot"), sparse->Nelem); 169 170 psSparseConstraint constraint; 171 constraint.paramMin = 0; 172 constraint.paramMax = 1e8; 173 constraint.paramDelta = 1e8; 159 174 160 175 // solve for normalization terms (need include local sky?) 161 176 psSparseResort (sparse); 162 psVector *norm = psSparseSolve (NULL, sparse, 3);177 psVector *norm = psSparseSolve (NULL, constraint, sparse, 3); 163 178 164 179 // adjust models, set sources and subtract … … 168 183 pmSource *Mi = models->data[i]; 169 184 185 // if we already have a PSF model, free it. 186 psFree (Fi->modelPSF); 187 170 188 // need to increment counter so we can free models here and sources above 171 189 Fi->modelPSF = psMemCopy (Mi->modelPSF); … … 173 191 // assign linearly-fitted normalization 174 192 Fi->modelPSF->params->data.F32[1] = norm->data.F32[i]; 193 Fi->modelPSF->dparams->data.F32[1] = sqrt(sqrt(2) * norm->data.F32[i] / (sparse->Bfj->data.F32[i] * weight->data.F32[i])); 194 // XXX EAM : this factor of sqrt(2) makes the errors consistent, but I don't understand it 175 195 176 196 // subtract object 177 197 pmSourceSubModel (Fi->pixels, Fi->mask, Fi->modelPSF, false, false); 178 198 Fi->mode |= PM_SOURCE_SUBTRACTED; 179 Fi->mode |= PM_SOURCE_TEMPSUB; 180 } 199 if (!final) Fi->mode |= PM_SOURCE_TEMPSUB; 200 } 201 202 // measure chisq for each source 203 for (int i = 0; final && (i < models->n); i++) { 204 int N = index->data.U32[i]; 205 pmSource *Fi = sources->data[N]; 206 pmModel *model = Fi->modelPSF; 207 208 x = model->params->data.F32[2]; 209 y = model->params->data.F32[3]; 210 211 psImageKeepCircle (Fi->mask, x, y, model->radius, "OR", PSPHOT_MASK_MARKED); 212 pmSourceChisq (model, Fi->pixels, Fi->mask, Fi->weight); 213 psImageKeepCircle (Fi->mask, x, y, model->radius, "AND", ~PSPHOT_MASK_MARKED); 214 } 215 181 216 psFree (index); 182 217 psFree (sparse); 183 218 psFree (models); 184 219 psFree (norm); 220 psFree (weight); 185 221 186 222 psLogMsg ("psphot.emsemble", 3, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot")); 187 223 return true; 188 224 } 225 226 bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight) { 227 228 double dC = 0.0; 229 int Npix = 0; 230 for (int j = 0; j < image->numRows; j++) { 231 for (int i = 0; i < image->numCols; i++) { 232 if (mask->data.U8[j][i]) continue; 233 if (weight->data.F32[j][i] <= 0) continue; 234 dC += PS_SQR (image->data.F32[j][i]) / weight->data.F32[j][i]; 235 Npix ++; 236 } 237 } 238 model->nDOF = Npix - 1; 239 model->chisq = dC; 240 241 return (true); 242 }
Note:
See TracChangeset
for help on using the changeset viewer.
