Changeset 4115
- Timestamp:
- Jun 4, 2005, 5:22:13 PM (21 years ago)
- Location:
- trunk/psphot
- Files:
-
- 4 added
- 11 edited
-
doc/notes.txt (added)
-
doc/psphot.txt (modified) (1 diff)
-
src/apply_psf_model.c (modified) (3 diffs)
-
src/by_SN.c (added)
-
src/choose_psf_model.c (modified) (1 diff)
-
src/find_peaks.c (modified) (2 diffs)
-
src/image_stats.c (modified) (1 diff)
-
src/mark_psf_source.c (added)
-
src/psPolynomials.c (modified) (8 diffs)
-
src/psphot.c (modified) (2 diffs)
-
src/psphot.h (modified) (1 diff)
-
src/pspsf.c (modified) (8 diffs)
-
src/subtract_psf_source.c (added)
-
src/subtract_psf_sources.c (modified) (1 diff)
-
src/test_psf_scatter.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/doc/psphot.txt
r4114 r4115 1 1 2 2005.04.12 : Notes on psphot 2 psphot is a stand-alone program which implements the Pan-STARRS IPP 3 object detection and analysis functions for using with individual 4 images. 3 5 4 - psPeak, psSource, etc: should be pmPeak, pmSource, etc5 - pmCullPeaks: should be pmCullImagePeaks6 7 - does pmSourceMoments need an image argument?8 9 - psLibInit / p_psTimeInit10 11 we should not have to know about astronomy time concepts (ie, have a12 timeConfig file) in order to use the time functions for basic work.13 This means having a PS_TIME_UNIX which just works with the UNIX14 clock and avoids all initialization issues.15 16 - psImageStats is much too slow for basic median17 - this function does a complete sort on all pixel values. we need18 to use the histogram method (spec a different type of median)19 20 - psImageStats, ROBUST_MEDIAN fails21 - there are errors in psVectorStats for ROBUST MEAN, STDEV (& median?)22 * this is ill-defined. revise the ADD: too sensitive to the23 binning, smoothing scales24 25 - pmFindImagePeaks is not finding any peaks:26 typo in interior row section: see bug 35927 after this fix: PASS28 29 * p_psGetRowVectorFromImage : PASS30 * psGetRowVectorFromImage : PASS31 - both have about the same time (~15 us +/- 5us) for 2048 pix on alala32 33 * pmFindVectorPeaks : PASS (returned row data in data.U32)34 35 - # include <string.h> : needed in psMetadata.c36 37 * MyListAddPeak / pmPeakAlloc are inconsistent wrt col,row vs x,y38 39 - why does psMetadataItemAllocV allocate a string of length40 MAX_STRING_LENGTH for the comment, then use strncpy?41 42 should be:43 44 // set metadata item comment45 if (comment == NULL) {46 // Per SDRS, null isn't allowed, must use "" instead47 metadataItem->comment = psStringCopy ("");48 } else {49 metadataItem->comment = psStringCopy (comment);50 }51 52 psMetadataAdd -> psMetadataAddItem is all confused:53 - we end up with two psMetadataItemAlloc calls, when only one should54 be used55 - psMetadataItemAlloc was doing the wrong thing if the incoming data56 was NULL57 - I think the logic in this block is wrong as well.58 59 * I fixed this in psMetadata.c60 61 2005.04.14 :62 63 - psImageStats is still much too slow64 65 - pmObjects : changed to using psArray to carry peaks / sources,66 rather than psList67 68 - added function pmPeaksSubset to replace pmCullPeaks69 70 - pmSourceLocalSky: added min/max fncs to force subimage to stay in71 image72 73 - Sx, Sy can go negative: have forced limit to 0,074 75 - pmSourceRoughClass: implemented sigmaX, sigmaY search for stellar76 clump (uses pmComparePeakDescend)77 78 - the search ignores the 0,0 pixel79 80 - pmSourceRoughClass uses all detected peaks. allow an exclusion81 for peak > max, peak < min?82 83 - need to push clump stats on the metadata84 85 - the source classes are assigned so they are mutually exclusive86 87 - change PS_SOURCE_OTHER to STAR?88 89 - pmSourceSetPixelCircle:90 91 - name should be pmSourceSetPixelsCircle (geometry could be an92 option...)93 94 - I cleaned the defined region to match the convensions of95 pmSourceLocalSky96 97 - truncate and force subimage to lie on image98 99 - CheckRadius2 seems like an inefficient coding100 101 - valid pixels have mask value of 1 (inverse of other funcs)102 103 - pmSourceFitModel:104 105 - num iterations is much too large106 107 -108 109 mrq:110 111 - allocate alpha, beta arrays112 - mrq2dcof (pars, alpha, beta)113 - make guess pars', alpha', beta'114 - mrq2dcof (pars', alpha', beta')115 - if (chisq < old chisq), keep new guess116 117 118 2005.04.19:119 120 - psMinimizeLMChi2 has some serious problems. I re-wrote it starting121 from the mrqmin example in ohana. after a variety little bugs, it122 seems to work quite well. the program 'modeltest.c' runs two123 different gaussians through psMinimizeLMChi2, and gets the right124 answer quite quickly. The first pass at the implementation had a125 variety of problems. to avoid any worry about errors in the126 psMatrix code, I implemented psGaussJordan, basing the code on the127 elixir gaussj.c code. this worked fine, and let me find the errors128 elsewhere in the code. the LUD version now works just the same as129 the GaussJ version.130 131 132 2005.04.21133 134 - psMinimizeLMChi2 does an excellent job now in most cases. I am able135 to run pmSourceFitModel on the PSF stars quite well. I added in the136 (nearly) correct errors (actually, just using sqrt(N), limiting to137 N>=1). I see one problem object, which is quite faint, and does not138 converge well: I get very large values for x,y, Sx, Sy, etc. I need139 to think about constraining these fits from running way off scale.140 141 fit: 0.123879 sec for 277 stars (gauss)142 fit: 0.155940 sec for 277 stars (pgauss) (!)143 fit: 0.153292 sec for 277 stars144 (0.5 msec per star) -
trunk/psphot/src/apply_psf_model.c
r4114 r4115 22 22 keep = psRegionForImage (keep, image, keep); 23 23 24 // set the object surfact-brightness limit for fitted pixels 24 float shapeNsigma = psMetadataLookupF32 (&status, config, "PSF_SHAPE_NSIGMA"); 25 float snFaint = psMetadataLookupF32 (&status, config, "FAINT_SN_LIM"); 26 27 // set the object surface-brightness limit for fitted pixels 25 28 float FLUX_LIMIT = FIT_NSIGMA * sky->sampleStdev; 26 29 psLogMsg ("psphot.apply_psf_model", 3, "fitting pixels with at least %f object counts\n", FLUX_LIMIT); … … 31 34 for (int i = 0; i < sources->n; i++) { 32 35 psSource *source = sources->data[i]; 36 37 // skip the existing PSF stars 38 // XXX drop this -- refit? 33 39 if (source->modelPSF != NULL) continue; 34 40 … … 55 61 pmSourceMaskSaturated (source, SATURATE); 56 62 57 // fit as PSF, not FLT ( drop poor fits)63 // fit as PSF, not FLT (skip poor fits) 58 64 if (!pmSourceFitModel (source, model, true)) continue; 59 65 source->modelPSF = model; 60 66 Niter += model[0].nIter; 61 67 Nfit ++; 68 69 mark_psf_source (source); 70 subtract_psf_source (source); 62 71 } 63 72 psLogMsg ("psphot", 3, "fit PSF models: %f sec for %d objects (%d total iterations)\n", psTimerMark ("psphot"), Nfit, Niter); -
trunk/psphot/src/choose_psf_model.c
r4114 r4115 68 68 for (int i = 0; i < test->sources->n; i++) { 69 69 psSource *source = test->sources->data[i]; 70 source->modelPSF = test->modelPSF->data[i]; 70 // drop masked sources from PSFSTAR list 71 if (test->mask->data.U8[i]) { 72 source->type = PS_SOURCE_OTHER; 73 // XXX is this the right type to go to? 74 } else { 75 source->modelPSF = test->modelPSF->data[i]; 76 } 71 77 } 72 78 return (test->psf); -
trunk/psphot/src/find_peaks.c
r4114 r4115 9 9 10 10 // smooth the image 11 // should we also subtract a super-binned image? (as an option )11 // should we also subtract a super-binned image? (as an option?) 12 12 13 13 psTimerStart ("psphot"); … … 24 24 25 25 psLogMsg ("psphot", 4, "smooth: %f sec\n", psTimerMark ("psphot")); 26 27 26 28 27 // find the peaks in the smoothed image -
trunk/psphot/src/image_stats.c
r4114 r4115 13 13 // pass on the stats 14 14 { 15 bool status = false; 15 bool status = false; 16 int Npixels = image->numRows*image->numCols; 17 int Nsubset = PS_MIN (Npixels, psMetadataLookupF32 (&status, config, "NSUBSET")); 18 psVector *subset = psVectorAlloc (Nsubset, PS_TYPE_F32); 16 19 psRandom *rnd = psRandomAlloc (PS_RANDOM_TAUS, 0); 17 int Nsubset = psMetadataLookupF32 (&status, config, "NSUBSET");18 double fSubset = (double) Nsubset / (image->numRows*image->numCols);19 psVector *subset = psVectorAlloc (Nsubset, PS_TYPE_F32);20 20 21 subset->n = 0; 22 for (int i = 0; i < image->numRows; i++) { 23 for (int j = 0; j < image->numCols; j++) { 24 double frnd = psRandomUniform (rnd); 25 if ((fSubset < 1.0) && (fSubset < frnd)) continue; 26 subset->data.F32[subset->n] = image->data.F32[j][i]; 27 subset->n ++; 28 if (subset->n == Nsubset) goto got_subset; 29 } 21 // choose Nsubset points between 0 and Nx*Ny, convert to coords 22 Npixels = image->numRows*image->numCols; 23 for (int i = 0; i < Nsubset; i++) { 24 double frnd = psRandomUniform (rnd); 25 int pixel = Npixels * frnd; 26 int ix = pixel / image->numCols; 27 int iy = pixel % image->numCols; 28 subset->data.F32[i] = image->data.F32[iy][ix]; 30 29 } 31 30 32 got_subset:33 31 // this should use ROBUST not SAMPLE median 34 32 // robust median is broken in pslib (0.5) -
trunk/psphot/src/psPolynomials.c
r4114 r4115 191 191 // XXX EAM : test version of 1d fitting 192 192 psPolynomial1D* VectorFitPolynomial1DOrd_EAM(psPolynomial1D* myPoly, 193 const psVector* x, 194 const psVector* y, 195 const psVector* yErr) 193 psVector *mask, 194 const psVector *x, 195 const psVector *y, 196 const psVector *yErr) 196 197 { 197 198 // I think this is 1 dimension down … … 232 233 // Build the B and A data structs. 233 234 for (int k = 0; k < x->n; k++) { 235 if ((mask != NULL) && mask->U8[k]) continue; 234 236 xSums = BuildSums1D(xSums, x->data.F64[k], nTerm); 235 237 … … 291 293 // XXX EAM : test version of 2d fitting 292 294 psPolynomial2D* VectorFitPolynomial2DOrd_EAM(psPolynomial2D* myPoly, 293 const psVector* x, 294 const psVector* y, 295 const psVector* z, 296 const psVector* zErr) 295 psVector* mask, 296 const psVector* x, 297 const psVector* y, 298 const psVector* z, 299 const psVector* zErr) 297 300 { 298 301 // I think this is 1 dimension down … … 322 325 // Build the B and A data structs. 323 326 for (int k = 0; k < x->n; k++) { 327 if ((mask != NULL) && mask->data.U8[i]) continue; 324 328 Sums = BuildSums2D(Sums, x->data.F64[k], y->data.F64[k], nXterm, nYterm); 325 329 … … 391 395 } 392 396 393 psPolynomial2D* RobustFit2D (psPolynomial2D* poly,397 psPolynomial2D* RobustFit2D_nomask(psPolynomial2D* poly, 394 398 const psVector* x, 395 399 const psVector* y, … … 413 417 for (int N = 0; N < 3; N++) { 414 418 // XXX EAM : this would be better defined with an element mask 415 poly = VectorFitPolynomial2DOrd_EAM (poly, X, Y, Z, dZ);419 poly = VectorFitPolynomial2DOrd_EAM (poly, NULL, X, Y, Z, dZ); 416 420 zFit = Polynomial2DEvalVectorD (poly, x, y); 417 421 zResid = (psVector *) psBinaryOp (NULL, (void *) z, "-", (void *) zFit); … … 424 428 int n = 0; 425 429 for (int i = 0; i < zResid->n; i++) { 426 if (fabs(zResid->data.F64[i] - stats->clippedMean) > 3*stats->clippedStdev) continue; 430 if (fabs(zResid->data.F64[i] - stats->clippedMean) > 3*stats->clippedStdev) { 431 continue; 432 } 427 433 X->data.F64[n] = x->data.F64[i]; 428 434 Y->data.F64[n] = y->data.F64[i]; … … 435 441 Z->n = n; 436 442 dZ->n = n; 443 } 444 return (poly); 445 } 446 447 // XXX EAM : be careful here with F32 vs F64 vectors 448 psPolynomial2D* RobustFit2D(psPolynomial2D* poly, 449 psVector* mask, 450 const psVector* x, 451 const psVector* y, 452 const psVector* z, 453 const psVector* dz) 454 { 455 psVector *zFit = NULL; 456 psVector *zResid = NULL; 457 psStats *stats = NULL; 458 459 for (int N = 0; N < 3; N++) { 460 poly = VectorFitPolynomial2DOrd_EAM (poly, mask, x, y, z, dz); 461 zFit = Polynomial2DEvalVectorD (poly, x, y); 462 zResid = (psVector *) psBinaryOp (NULL, (void *) z, "-", (void *) zFit); 463 464 stats = psStatsAlloc (PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV); 465 stats = psVectorStats (stats, zResid, NULL, mask, 1); 466 psTrace (".psphot.RobustFit", 4, "residual stats for robust fit: %g +/- %g (%d pts)\n", 467 stats->clippedMean, stats->clippedStdev, stats->clippedNvalues); 468 469 // set mask if pts are not valid 470 int n = 0; 471 for (int i = 0; i < zResid->n; i++) { 472 if (fabs(zResid->data.F64[i] - stats->clippedMean) > 3*stats->clippedStdev) { 473 mask->data.U8[i] = 1; 474 continue; 475 } else { 476 mask->data.U8[i] = 0; 477 } 478 n++; 479 } 437 480 } 438 481 return (poly); -
trunk/psphot/src/psphot.c
r4114 r4115 24 24 peaks = find_peaks (image, config, sky); 25 25 26 // construct sources and measure basic stats 26 27 sources = source_moments (image, config, peaks); 28 29 // source analysis is done in S/N order (brightest first) 30 sources = psArraySort (sources, by_SN); 27 31 28 32 // use stellar objects SN > PSF_SN_LIM … … 35 39 // XXX it has some problems 36 40 // test_psf_scatter (sources); 37 38 // identify PSF-like objects (< PSF_SHAPE_NSIGMA from dSx,dSy model)39 // SN <= FAINT_SN_LIM : FAINTSTAR40 // SN > FAINT_SN_LIM : BRIGHTSTAR41 mark_psf_sources (sources, config);42 43 // subtract BRIGHTSTAR, PSFSTAR, SATSTAR44 subtract_psf_sources (sources);45 41 46 42 // fit_galaxies (image, config, sources); -
trunk/psphot/src/psphot.h
r4114 r4115 13 13 psArray *modelFLT; // model fits, floating parameters 14 14 psArray *modelPSF; // model fits, PSF parameters 15 psVector *mask; 15 16 psVector *metric; 16 17 psStats *metricStats; -
trunk/psphot/src/pspsf.c
r4114 r4115 36 36 test->metricStats = NULL; 37 37 test->metric = psVectorAlloc (sources->n, PS_TYPE_F64); 38 test->mask = psVectorAlloc (sources->n, PS_TYPE_U8); 38 39 39 40 for (int i = 0; i < test->modelFLT->n; i++) { 40 41 test->modelFLT->data[i] = NULL; 41 42 test->modelPSF->data[i] = NULL; 43 test->mask->data.U8[i] = 0; 42 44 } 43 45 return (test); … … 57 59 psModel *model = pmSourceModelGuess (source, test->modelType); 58 60 59 // fit model as FLT, not PSF (skip poor fits) 60 if (!pmSourceFitModel (source, model, false)) continue; 61 // fit model as FLT, not PSF (mask & skip poor fits) 62 if (!pmSourceFitModel (source, model, false)) { 63 test->mask->data.U8[i] = 1; 64 continue; 65 } 61 66 test->modelFLT->data[i] = model; 62 67 Nflt ++; … … 66 71 67 72 // stage 2: construct a psf (pmPSF) from this collection of model fits 68 pmPSFFromModels (test->psf, test->modelFLT );73 pmPSFFromModels (test->psf, test->modelFLT, test->mask); 69 74 70 75 // stage 3: refit with fixed shape parameters … … 73 78 psSource *source = test->sources->data[i]; 74 79 psModel *modelFLT = test->modelFLT->data[i]; 75 if (modelFLT == NULL) continue; 80 81 // masked for: bad model fit, outlier in parameters 82 if (test->mask->data.U8[i]) continue; 83 if (modelFLT == NULL) { 84 psLogMsg ("psphot.psftest", 2, "programming error: missing model not masked\n"); 85 continue; 86 } 76 87 psModel *modelPSF = psModelFromPSF (modelFLT, test->psf); // set shape for this model 77 88 78 89 // fit model as PSF, not FLT (skip poor fits) 79 if (!pmSourceFitModel (source, modelPSF, true)) continue; 90 if (!pmSourceFitModel (source, modelPSF, true)) { 91 test->mask->data.U8[i] = 1; 92 continue; 93 } 80 94 test->modelPSF->data[i] = modelPSF; 81 95 Npsf ++; … … 92 106 float fitSum = 0; 93 107 108 // is this metricMask redundant with test->mask ? 94 109 metricMask->data.U8[i] = 1; 95 110 test->metric->data.F64[i] = 0; 96 111 112 if (test->mask->data.U8[i]) continue; 113 97 114 psModel *model = test->modelPSF->data[i]; 98 if (model == NULL) continue; 115 if (model == NULL) { 116 psLogMsg ("psphot.psftest", 2, "programming error: missing model not masked\n"); 117 continue; 118 } 99 119 100 120 psImage *image = ((psSource *)test->sources->data[i])->pixels; 101 121 psImage *mask = ((psSource *)test->sources->data[i])->mask; 102 122 123 // this metric is Ap-Fit 103 124 float sky = model->params->data.F32[0]; 104 105 125 for (int ix = 0; ix < image->numCols; ix++) { 106 126 for (int iy = 0; iy < image->numRows; iy++) { … … 110 130 } 111 131 } 112 // this metric is Ap-Fit113 132 // fprintf (stderr, "%d %f %f %f\n", i, obsSum, fitSum, test->metric->data.F64[i]); 133 // keep the good metrics 114 134 if ((fitSum > 0) && (obsSum > 0)) { 115 135 metricMask->data.U8[i] = 0; 116 136 test->metric->data.F64[i] = -2.5*log10(obsSum/fitSum); 117 } 137 } else { 138 test->mask->data.U8[i] = 1; 139 } 118 140 } 119 141 … … 128 150 // input: an array of psModels, pre-allocated psf 129 151 // some of the array entries may be NULL, ignore them 130 bool pmPSFFromModels (pmPSF *psf, psArray *models ) {152 bool pmPSFFromModels (pmPSF *psf, psArray *models, psVector *mask) { 131 153 132 154 int n; 133 155 134 // construct the x and yvectors from the collection of objects135 // count the number of valid model measurements156 // construct the fit vectors from the collection of objects 157 // use the mask to ignore missing fits 136 158 psVector *x = psVectorAlloc (models->n, PS_TYPE_F64); 137 159 psVector *y = psVectorAlloc (models->n, PS_TYPE_F64); 138 n = 0; 160 psVector *z = psVectorAlloc (models->n, PS_TYPE_F64); 161 psVector *dz = psVectorAlloc (models->n, PS_TYPE_F64); 162 139 163 for (int i = 0; i < models->n; i++) { 140 164 psModel *model = models->data[i]; … … 142 166 143 167 // XXX EAM : this is fragile: x and y must be stored consistently at 2,3 144 x->data.F64[n] = model->params->data.F32[2]; 145 y->data.F64[n] = model->params->data.F32[3]; 146 n++; 147 } 148 x->n = y->n = n; 168 x->data.F64[i] = model->params->data.F32[2]; 169 y->data.F64[i] = model->params->data.F32[3]; 170 } 149 171 150 172 // we are doing a robust fit. after each pass, we drop points which are 151 // more deviant than three sigma. 152 psVector *z = psVectorAlloc (x->n, PS_TYPE_F64);153 psVector *dz = psVectorAlloc (x->n, PS_TYPE_F64); 173 // more deviant than three sigma. 174 // mask is currently updated for each pass. this is inconsistent 175 154 176 for (int i = 0; i < psf->params->n; i++) { 155 n = 0;156 177 for (int j = 0; j < models->n; j++) { 157 178 psModel *model = models->data[j]; 158 179 if (model == NULL) continue; 159 z->data.F64[n] = model->params->data.F32[i + 4]; 160 dz->data.F64[n] = 1; 161 n++; 180 z->data.F64[j] = model->params->data.F32[i + 4]; 181 dz->data.F64[j] = 1; 162 182 // XXX EAM : need to use actual errors? 163 183 // XXX EAM : this is fragile: psf(Nparams) = model(Nparams) - 4 164 184 } 165 if (n != x->n) psAbort ("pmPSFFromModels", "programming error: mismatched number of NULL models\n"); 166 z->n = n; 167 dz->n = n; 168 169 psf->params->data[i] = RobustFit2D (psf->params->data[i], x, y, z, dz); 185 // if (n != x->n) psAbort ("pmPSFFromModels", "programming error: mismatched number of NULL models\n"); 186 187 psf->params->data[i] = RobustFit2D (psf->params->data[i], mask, x, y, z, dz); 170 188 // psPolynomial2DDump (psf->params->data[i]); 171 189 } -
trunk/psphot/src/subtract_psf_sources.c
r4114 r4115 6 6 bool subtract_psf_sources (psArray *sources) 7 7 { 8 9 sources = psArraySort (sources, by_SN); 10 8 11 for (int i = 0; i < sources->n; i++) { 9 12 float sky; -
trunk/psphot/src/test_psf_scatter.c
r4114 r4115 71 71 72 72 psPolynomial1D *dsxLine = psPolynomial1DAlloc (2, PS_POLYNOMIAL_ORD); 73 psVectorFitPolynomial1D (dsxLine, snBin, dsxBin, NULL);73 psVectorFitPolynomial1D (dsxLine, NULL, snBin, dsxBin, NULL); 74 74 psPolynomial1D *dsyLine = psPolynomial1DAlloc (2, PS_POLYNOMIAL_ORD); 75 psVectorFitPolynomial1D (dsyLine, snBin, dsyBin, NULL);75 psVectorFitPolynomial1D (dsyLine, NULL, snBin, dsyBin, NULL); 76 76 // these should have a slope of 1.0 77 77 psPolynomial1DDump (dsxLine);
Note:
See TracChangeset
for help on using the changeset viewer.
