Changeset 25278
- Timestamp:
- Sep 4, 2009, 6:08:08 PM (17 years ago)
- File:
-
- 1 edited
-
branches/pap/psphot/src/psphotFake.c (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/pap/psphot/src/psphotFake.c
r25265 r25278 1 1 # include "psphotInternal.h" 2 2 3 #define TESTING 4 5 6 #ifdef TESTING 7 #define MIN_FLUX 0.1 // Minimum flux for faint sources 8 #endif 3 #define MODEL_MASK (PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE | \ 4 PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models 9 5 10 6 … … 14 10 // non-Gaussian PSF) to the limiting flux in the un-smoothed original image. 15 11 static bool fakeLimit(float *magLim, // Limiting magntiude, to return 16 float *minFlux, // Minimum flux, to return12 int *radius, // Radius for fake sources 17 13 const pmReadout *ro, // Readout of interest 14 const pmPSF *psf, // Point-spread function 18 15 float thresh, // Threshold for source identification 19 float fwhmMajor, float fwhmMinor, // Size of PSF20 float smoothNsigma, // Smoothing limit21 psImageMaskType maskVal // Value to mask16 float smoothSigma, // Gaussian smoothing sigma 17 float smoothNsigma, // Smoothing limit 18 psImageMaskType maskVal // Value to mask 22 19 ) 23 20 { … … 25 22 PM_ASSERT_READOUT_VARIANCE(ro, false); 26 23 27 float smoothSigma = 0.5*(fwhmMajor + fwhmMinor) / (2.0*sqrtf(2.0*log(2.0)));28 24 psKernel *kernel = psImageSmoothKernel(smoothSigma, smoothNsigma); // Kernel used for smoothing 29 25 psKernel *newCovar = psImageCovarianceCalculate(kernel, ro->covariance); // Covariance matrix … … 45 41 psFree(stats); 46 42 43 // Need to normalise out difference between Gaussian and real PSF 44 pmModel *normModel = pmModelFromPSFforXY(psf, 0.5 * ro->variance->numCols, 45 0.5 * ro->variance->numRows, 1.0); // Model for normalisation 46 if (!normModel || (normModel->flags & MODEL_MASK)) { 47 psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to generate PSF model."); 48 psFree(normModel); 49 return false; 50 } 51 float norm = normModel->modelFlux(normModel->params); // Total flux for peak of 1.0 52 psFree(normModel); 53 47 54 if (magLim) { 48 *magLim = -2.5 * log10(thresh * sqrtf(meanVar * factor)); 49 } 50 if (minFlux) { 51 *minFlux = sqrtf(meanVar); 55 // The signal-to-noise of the smoothed image is: S/N ~ I_smooth / sqrt(variance * factor) 56 57 // since the variance factor tells us the variance in the smoothed image. Now, the trick is working 58 // out what the intensity in the smoothed image is, and how it is related to the flux. We are 59 // convolving Io G_* with G_PSF/2pi.w^2, where G_* is the approximately-Gaussian PSF of the star, 60 // G_PSF is the pretty-close-matching Gaussian of the convolution kernel, Io is the peak flux in the 61 // unsmoothed image, and w is the width of the Gaussian. Now, a normalised 2D Gaussian convolved 62 // with itself has a normalisation of 1/2pi(w^2+w^2) = 1/4pi.w^2. Therefore: 63 // I_smooth = Flux / 2*norm. 64 float peakLim = thresh * sqrtf(meanVar * factor); // Limiting peak value in smoothed image 65 float fluxLim = 2.0 * norm * peakLim; // Limiting flux in original 66 *magLim = -2.5 * log10f(fluxLim); 67 psTrace("psphot.fake", 1, "Limiting peak: %f\n", peakLim); 68 psTrace("psphot.fake", 1, "Limiting flux: %f\n", fluxLim); 69 psTrace("psphot.fake", 1, "Limiting mag: %f\n", *magLim); 70 } 71 if (radius) { 72 *radius = smoothSigma * smoothNsigma; 52 73 } 53 74 … … 62 83 int numSources, // Number of fake sources for each bin 63 84 float refMag, // Reference magnitude 64 float minFlux // Minimum flux level for fake image85 int radius // Radius for fake sources 65 86 ) 66 87 { … … 99 120 pmReadout *fakeRO = pmReadoutAlloc(NULL); // Fake readout 100 121 if (!pmReadoutFakeFromVectors(fakeRO, numCols, numRows, xAll, yAll, magAll, 101 NULL, NULL, psf, minFlux, 0, false, false)) {122 NULL, NULL, psf, NAN, radius, false, true)) { 102 123 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image"); 103 124 psFree(fakeRO); … … 130 151 131 152 // Collect recipe information 132 bool mdok; // Status of MD lookup133 153 float fwhmMajor = psMetadataLookupF32(NULL, recipe, "FWHM_MAJ"); // PSF size in x 134 154 float fwhmMinor = psMetadataLookupF32(NULL, recipe, "FWHM_MIN"); // PSF size in y … … 157 177 return NULL; 158 178 } 159 float minFluxFudge = psMetadataLookupF32(&mdok, recipe, "FAKE.MINFLUX"); // Fudge factor for minimum flux 160 if (!mdok) { 161 minFluxFudge = 1.0; 162 } 179 180 float smoothSigma = 0.5*(fwhmMajor + fwhmMinor) / (2.0*sqrtf(2.0*log(2.0))); // Gaussian smoothing sigma 163 181 164 182 psImageMaskType maskVal = psMetadataLookupImageMask(NULL, recipe, "MASK.PSPHOT"); // Value to mask … … 166 184 // remove all sources, adding noise for subtracted sources 167 185 psphotRemoveAllSources(realSources, recipe); 168 psphotAddNoise(readout, realSources, recipe);186 // psphotAddNoise(readout, realSources, recipe); 169 187 170 188 float magLim; // Guess at limiting magnitude 171 float minFlux; // Minimum flux for fake image172 if (!fakeLimit(&magLim, & minFlux, readout, thresh, fwhmMajor, fwhmMinor, smoothNsigma, maskVal)) {189 int radius; // Radius for fake sources 190 if (!fakeLimit(&magLim, &radius, readout, psf, thresh, smoothSigma, smoothNsigma, maskVal)) { 173 191 psError(PS_ERR_UNKNOWN, false, "Unable to determine limits for image"); 174 192 return false; 175 193 } 176 minFlux *= minFluxFudge;177 194 178 195 psImage *xFake = NULL, *yFake = NULL; // Coordinates of sources, each bin in a row 179 if (!fakeGenerate(&xFake, &yFake, readout, psf, magOffsets, numSources, magLim, minFlux)) {196 if (!fakeGenerate(&xFake, &yFake, readout, psf, magOffsets, numSources, magLim, radius)) { 180 197 psError(PS_ERR_UNKNOWN, false, "Unable to generate fake sources"); 181 198 psFree(xFake); … … 195 212 196 213 int numBins = magOffsets->n; // Number of bins 214 int numCols = readout->image->numCols, numRows = readout->image->numRows; // Size of image 197 215 psVector *frac = psVectorAlloc(numBins, PS_TYPE_F32); // Fraction of sources in each bin 198 216 for (int i = 0; i < numBins; i++) { 199 217 int numFound = 0; // Number found 200 218 for (int j = 0; j < numSources; j++) { 201 float x = xFake->data.F32[i][j], y = yFake->data.F32[i][j]; // Coordinates of interest 202 int xPix = x, yPix = y; // Pixel coordinates 219 // Coordinates of interest 220 float x = PS_MIN(xFake->data.F32[i][j] + 0.5, numCols - 1); 221 float y = PS_MIN(yFake->data.F32[i][j] + 0.5, numRows - 1); 222 int xPix = x, yPix = y; // Pixel coordinates 203 223 if (significance->data.F32[yPix][xPix] > thresh) { 204 224 numFound++;
Note:
See TracChangeset
for help on using the changeset viewer.
