Changeset 17557 for trunk/ppSim/src/ppSimMakeStars.c
- Timestamp:
- May 7, 2008, 10:55:21 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/ppSim/src/ppSimMakeStars.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppSim/src/ppSimMakeStars.c
r16498 r17557 1 1 # include "ppSim.h" 2 3 #define FAINT_FUDGE_FACTOR 0.4 // Fraction of the noise in a (boxcar) PSF for the faint limit4 5 2 6 3 bool ppSimMakeStars(psArray *stars, pmFPA *fpa, pmConfig *config, const psRandom *rng) { 7 4 8 bool mdok;5 bool status; 9 6 assert (stars); 10 7 11 psMetadata *recipe = psMetadataLookupMetadata(& mdok, config->recipes, PPSIM_RECIPE); // Recipe8 psMetadata *recipe = psMetadataLookupMetadata(&status, config->recipes, PPSIM_RECIPE); // Recipe 12 9 13 bool starsFake = psMetadataLookupBool(& mdok, recipe, "STARS.FAKE"); // Density of fakes10 bool starsFake = psMetadataLookupBool(&status, recipe, "STARS.FAKE"); // Density of fakes 14 11 if (!starsFake) return true; 15 12 16 float starsLum = psMetadataLookupF32(NULL, config->arguments, "STARS.LUM"); // Star luminosity func slope 17 float starsMag = psMetadataLookupF32(NULL, config->arguments, "STARS.MAG"); // Star brightest magnitude 18 float starsDensity = psMetadataLookupF32(NULL, config->arguments, "STARS.DENSITY"); // Density of fakes 13 bool starsReal = psMetadataLookupBool(&status, recipe, "STARS.REAL"); // were real stars generated? 14 bool matchDensity = psMetadataLookupBool(&status, recipe, "MATCH.DENSITY"); // match real star density? 19 15 20 float darkRate = psMetadataLookupF32(NULL, config->arguments, "DARK.RATE"); // Dark rate 21 float expTime = psMetadataLookupF32(NULL, config->arguments, "EXPTIME"); // Exposure time 16 float starsAlpha = psMetadataLookupF32(&status, recipe, "STARS.LUM"); // Star luminosity func slope 17 float starsDensity = psMetadataLookupF32(&status, recipe, "STARS.DENSITY"); // Density of fakes 18 float brightMag = psMetadataLookupF32(&status, recipe, "STARS.MAG"); // Star brightest magnitude 19 float nSigmaLim = psMetadataLookupF32(&status, recipe, "STARS.SIGMA.LIM"); // significance of faintest stars 22 20 23 float zp = psMetadataLookupF32(NULL, config->arguments, "ZEROPOINT"); // Photometric zero point 24 float seeing = psMetadataLookupF32(NULL, config->arguments, "SEEING"); // Seeing sigma (pix) 25 float scale = psMetadataLookupF32(NULL, config->arguments, "SCALE") * M_PI / 3600.0 / 180.0; // Plate scale (radians/pixel) 21 float darkRate = psMetadataLookupF32(&status, recipe, "DARK.RATE"); // Dark rate 22 float expTime = psMetadataLookupF32(&status, recipe, "EXPTIME"); // Exposure time 23 float zp = psMetadataLookupF32(&status, recipe, "ZEROPOINT"); // Photometric zero point 24 float seeing = psMetadataLookupF32(&status, recipe, "SEEING"); // Seeing SIGMA (pixels) 25 float scale = psMetadataLookupF32(&status, recipe, "SCALE") * M_PI / 3600.0 / 180.0; // Plate scale (radians/pixel) 26 26 27 float skyRate = psMetadataLookupF32(& mdok, config->arguments, "SKY.RATE"); // Sky rate27 float skyRate = psMetadataLookupF32(&status, recipe, "SKY.RATE"); // Sky rate 28 28 if (isnan(skyRate)) { 29 float skyMags = psMetadataLookupF32(& mdok, config->arguments, "SKY.MAGS"); assert (mdok);30 skyRate = scale * scale * p ow (10.0, -0.4*(skyMags - zp));29 float skyMags = psMetadataLookupF32(&status, recipe, "SKY.MAGS"); assert (status); 30 skyRate = scale * scale * ppSimMagToFlux (skyMags, zp); 31 31 } 32 33 if (starsDensity <= 0) return true;34 32 35 33 // Size of FPA … … 40 38 psFree(bounds); 41 39 40 // choose reference magnitude & density to set normalization 41 float refMag = 0; 42 float refSum = 0; 43 if (starsReal && matchDensity) { 44 refMag = psMetadataLookupF32(&status, fpa->concepts, "STARS.REAL.MAG.PEAK"); // Star brightest magnitude 45 refSum = psMetadataLookupF32(&status, fpa->concepts, "STARS.REAL.SUM.PEAK"); // Star brightest magnitude 46 assert (status); 47 } else { 48 refMag = brightMag; 49 refSum = starsDensity * xSize * ySize * PS_SQR(scale * 180.0 / M_PI); 50 } 51 psTrace("ppSim", 6, "refMag: %f, refSum: %f\n", refMag, refSum); 52 53 if (refSum <= 0) return true; 54 42 55 // Grabbing read noise from the recipe rather than the cell, which is a potential danger, but it 43 56 // shouldn't be too bad. 44 float readnoise = psMetadataLookupF32(& mdok, recipe, "READNOISE"); // Default read noise45 if (! mdok) {57 float readnoise = psMetadataLookupF32(&status, recipe, "READNOISE"); // Default read noise 58 if (!status) { 46 59 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find READNOISE in recipe."); 47 60 psFree(bounds); … … 50 63 51 64 // Faintest and brightest (integrated) fluxes (actually fluence, since integrated) for random stars 52 float faint = FAINT_FUDGE_FACTOR * sqrtf(PS_SQR(readnoise) + (darkRate + skyRate) * expTime) * 53 (2.0 * sqrt(2.0 * log(2.0)) * seeing); // Faint limit is related to the noise in a (boxcar) PSF 54 float bright = powf(10.0, -0.4 * (starsMag - zp)) * expTime; // Bright limit is specified by user as mag 55 psTrace("ppSim", 6, "Faint limit: %f\n", faint); 56 psTrace("ppSim", 6, "Bright limit: %f\n", bright); 57 if (bright < faint) { 65 66 // faint limit is set by detection limit, in turn set by sky noise 67 float skySigma = sqrtf(PS_SQR(readnoise) + (darkRate + skyRate) * expTime); 68 float skyNoise = ppSimStarSkyNoise (skySigma, seeing); 69 70 // total flux of faintest star: 71 float faintCounts = nSigmaLim * skyNoise; 72 float faintMag = ppSimFluxToMag ((faintCounts / expTime), zp); 73 74 float brightCounts = ppSimMagToFlux (brightMag, zp) * expTime; // Bright limit is specified by user as mag 75 76 psTrace("ppSim", 6, "Faint limit: %f counts = %f mags\n", faintCounts, faintMag); 77 psTrace("ppSim", 6, "Bright limit: %f counts = %f mags\n", brightCounts, brightMag); 78 if (brightCounts < faintCounts) { 58 79 psLogMsg("ppSim", PS_LOG_INFO, 59 80 "Image noise is above brightest random star --- no random stars added."); … … 61 82 } 62 83 63 // Normalisation, set by the specified stellar density at the specified bright magnitude 64 float norm = starsDensity * xSize * ySize * PS_SQR(scale * 180.0 / M_PI) / 65 powf(bright, starsLum); 84 // given log_10 (dN / dmag) = alpha mag + beta 85 // or dN / dmag = No 10^(alpha mag), then: 86 // N(m < Mo) = alpha * No * log(10.0) * 10^(alpha*Mo) 87 88 // XXX this needs to handle the case of a flat distribution for efficiency testing 89 90 // Normalization, set by the specified stellar density at the specified bright magnitude 91 float norm = refSum / (starsAlpha * logf(10.0) * powf(10.0, (starsAlpha * refMag))); 92 float normScale = norm * starsAlpha * logf(10.0); 66 93 67 94 // Total number of stars down to the faint flux end 68 long n um = expf(logf(norm) + starsLum * logf(faint)) + 0.5;95 long nTotal = normScale * powf (10.0, (starsAlpha * faintMag)); 69 96 70 psLogMsg("ppSim", PS_LOG_INFO, "Adding %ld stars down to %f mag\n", 71 num, -2.5 * log10(faint / expTime) + zp); 97 psLogMsg("ppSim", PS_LOG_INFO, "Adding %ld stars down to %f mag\n", nTotal, faintMag); 72 98 73 99 long oldSize = stars->n; 74 psArrayRealloc (stars, stars->n + n um);100 psArrayRealloc (stars, stars->n + nTotal); 75 101 76 for (long i = 0; i < n um; i++) {102 for (long i = 0; i < nTotal; i++) { 77 103 ppSimStar *star = ppSimStarAlloc (); 78 104 … … 81 107 star->y = psRandomUniform(rng) * ySize; // y position 82 108 83 star->flux = expf((logf(i + 1) - logf(norm)) / starsLum); // Peak flux 84 star->peak = star->flux / (2.0*M_PI*PS_SQR(seeing)); 109 // XXX this needs to respect the bright limit 110 float starMag = log10((i + 1.0) / normScale) / starsAlpha; 111 112 star->flux = ppSimMagToFlux (starMag, zp) * expTime; 113 star->peak = ppSimStarFluxToPeak (star->flux, seeing); 85 114 86 115 stars->data[oldSize + i] = star; 87 116 } 88 stars->n = oldSize + n um;117 stars->n = oldSize + nTotal; 89 118 90 119 return true;
Note:
See TracChangeset
for help on using the changeset viewer.
