Changeset 12907
- Timestamp:
- Apr 18, 2007, 12:49:57 PM (19 years ago)
- File:
-
- 1 edited
-
trunk/ppSim/src/ppSimLoop.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ppSim/src/ppSimLoop.c
r12873 r12907 208 208 float peak, // Peak flux of star 209 209 float noise, // Rough noise estimate 210 float seeing, // Seeing for star210 float seeing, // Seeing for star 211 211 const psImage *correction // Exposure correction as a function of position 212 212 ) … … 247 247 psError(PS_ERR_UNKNOWN, false, "Unable to determine bounds of FPA"); 248 248 return PS_EXIT_CONFIG_ERROR; 249 }250 251 psVector *ra = psMetadataLookupPtr(NULL, config->arguments, "CATALOG.RA"); // Star RAs252 psVector *dec = psMetadataLookupPtr(NULL, config->arguments, "CATALOG.DEC"); // Star Declinations253 psVector *mag = psMetadataLookupPtr(NULL, config->arguments, "CATALOG.MAG"); // Star magnitudes254 float seeing = psMetadataLookupF32(NULL, config->arguments, "SEEING"); // Seeing sigma (pix)255 float scale = psMetadataLookupF32(NULL, config->arguments, "SCALE"); // Plate scale (arcsec/pixel)256 scale *= M_PI / 3600.0 / 180.0; // Convert to radians/pixel257 float zp = psMetadataLookupF32(NULL, config->arguments, "ZEROPOINT"); // Photometric zero point258 259 if (ra && dec && mag) {260 // Convert star ra,dec to pixels from FPA centre261 float ra0 = psMetadataLookupF32(NULL, config->arguments, "RA"); // Boresight RA (radians)262 float dec0 = psMetadataLookupF32(NULL, config->arguments, "DEC"); // Boresight Dec (radians)263 float pa = psMetadataLookupF32(NULL, config->arguments, "PA"); // Position angle (radians)264 265 // Conversion loop266 for (long i = 0; i < ra->n; i++) {267 float div = sin(dec->data.F32[i]) * sin(dec0) +268 cos(dec->data.F32[i]) * cos(dec0) * cos(ra->data.F32[i] - ra0); // Divisor269 270 // Convert to x,y position on tangent plane, in pixels271 float xi = cos(dec->data.F32[i]) * sin(ra->data.F32[i] - ra0) / div / scale;272 float eta = (sin(dec->data.F32[i]) * cos(dec0) -273 cos(dec->data.F32[i]) * sin(dec0) * cos(ra->data.F32[i] - ra0)) / div / scale;274 275 // Apply rotation276 ra->data.F32[i] = cos(pa) * xi - sin(pa) * eta;277 dec->data.F32[i] = sin(pa) * xi + cos(pa) * eta;278 ra->data.F32[i] = xi;279 dec->data.F32[i] = eta;280 281 // Convert magnitude to peak flux282 mag->data.F32[i] = powf(10.0, -0.4 * (mag->data.F32[i] - zp)) / sqrt(2.0*M_PI) / seeing;283 }284 249 } 285 250 … … 301 266 302 267 psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSIM_RECIPE); // Recipe 303 304 268 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Random number generator 269 270 psVector *ra = psMetadataLookupPtr(NULL, config->arguments, "CATALOG.RA"); // Star RAs 271 psVector *dec = psMetadataLookupPtr(NULL, config->arguments, "CATALOG.DEC"); // Star Declinations 272 psVector *mag = psMetadataLookupPtr(NULL, config->arguments, "CATALOG.MAG"); // Star magnitudes 273 float seeing = psMetadataLookupF32(NULL, config->arguments, "SEEING"); // Seeing sigma (pix) 274 float scale = psMetadataLookupF32(NULL, config->arguments, "SCALE"); // Plate scale (arcsec/pixel) 275 scale *= M_PI / 3600.0 / 180.0; // Convert to radians/pixel 276 float zp = psMetadataLookupF32(NULL, config->arguments, "ZEROPOINT"); // Photometric zero point 277 278 // Add catalogue stars 279 if (type == PPSIM_TYPE_OBJECT && ra && dec && mag) { 280 // Convert star ra,dec to pixels from FPA centre 281 float ra0 = psMetadataLookupF32(NULL, config->arguments, "RA"); // Boresight RA (radians) 282 float dec0 = psMetadataLookupF32(NULL, config->arguments, "DEC"); // Boresight Dec (radians) 283 float pa = psMetadataLookupF32(NULL, config->arguments, "PA"); // Position angle (radians) 284 285 // Conversion loop 286 for (long i = 0; i < ra->n; i++) { 287 float div = sin(dec->data.F32[i]) * sin(dec0) + 288 cos(dec->data.F32[i]) * cos(dec0) * cos(ra->data.F32[i] - ra0); // Divisor 289 290 // Convert to x,y position on tangent plane, in pixels 291 float xi = cos(dec->data.F32[i]) * sin(ra->data.F32[i] - ra0) / div / scale; 292 float eta = (sin(dec->data.F32[i]) * cos(dec0) - 293 cos(dec->data.F32[i]) * sin(dec0) * cos(ra->data.F32[i] - ra0)) / div / scale; 294 295 // Apply rotation 296 ra->data.F32[i] = cos(pa) * xi - sin(pa) * eta; 297 dec->data.F32[i] = sin(pa) * xi + cos(pa) * eta; 298 299 // Convert magnitude to peak flux 300 mag->data.F32[i] = powf(10.0, -0.4 * (mag->data.F32[i] - zp)) / sqrt(2.0*M_PI) / seeing * expTime; 301 } 302 303 psMetadataAddF64(fpa->concepts, PS_LIST_TAIL, "FPA.RA", PS_META_REPLACE, "Right ascension", ra0); 304 psMetadataAddF64(fpa->concepts, PS_LIST_TAIL, "FPA.DEC", PS_META_REPLACE, "Declination", dec0); 305 } 306 307 // Add random stars 308 if (type == PPSIM_TYPE_OBJECT && starsDensity > 0) { 309 310 // Grabbing read noise from the recipe rather than the cell, which is a potential danger, but it 311 // shouldn't be too bad. 312 float readnoise = psMetadataLookupF32(&mdok, recipe, "READNOISE"); // Default read noise 313 if (!mdok) { 314 psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find READNOISE in recipe."); 315 psFree(bounds); 316 psFree(rng); 317 return PS_EXIT_CONFIG_ERROR; 318 } 319 320 // Peak fluxes: faintest and brightest levels for random stars 321 float faint = 0.1 * 10.0 * sqrtf(PS_SQR(readnoise) + (darkRate + skyRate) * expTime); 322 float bright = powf(10.0, -0.4 * (starsMag - zp)) / sqrt(2.0*M_PI) / seeing * expTime; 323 if (bright < faint) { 324 psLogMsg("ppSim", PS_LOG_INFO, 325 "Image noise is above brightest random star --- no random stars added."); 326 } else { 327 // Size of focal plane 328 int xSize = bounds->x1 - bounds->x0; 329 int ySize = bounds->y1 - bounds->y0; 330 331 // Normalisation, set by the specified stellar density at the specified bright magnitude 332 float norm = starsDensity * xSize * ySize * PS_SQR(scale * 180.0 / M_PI) / 333 powf(bright, starsLum); 334 335 // Total number of stars down to the faint flux end 336 long num = expf(logf(norm) + starsLum * logf(faint)) + 0.5; 337 338 psLogMsg("ppSim", PS_LOG_INFO, "Adding %ld stars down to %f mag\n", num, 339 -2.5 * LOG10(faint * sqrt(2.0*M_PI) * seeing / expTime) + zp); 340 341 // Extend the vectors 342 long oldSize; // Old size of ra, dec, mag vectors 343 if (ra && dec && mag) { 344 oldSize = ra->n; 345 ra = psVectorRealloc(ra, oldSize + num); 346 dec = psVectorRealloc(dec, oldSize + num); 347 mag = psVectorRealloc(mag, oldSize + num); 348 ra->n = dec->n = mag->n = oldSize + num; 349 } else { 350 oldSize = 0; 351 ra = psVectorAlloc(num, PS_TYPE_F32); 352 dec = psVectorAlloc(num, PS_TYPE_F32); 353 mag = psVectorAlloc(num, PS_TYPE_F32); 354 } 355 356 for (long i = 0; i < num; i++) { 357 ra->data.F32[oldSize + i] = (psRandomUniform(rng) - 0.5) * xSize ; // x position 358 dec->data.F32[oldSize + i] = (psRandomUniform(rng) - 0.5) * ySize; // y position 359 mag->data.F32[oldSize + i] = expf((logf(i + 1) - logf(norm)) / starsLum); // Peak flux 360 } 361 } 362 } 363 305 364 pmFPAview *view = pmFPAviewAlloc(0);// View for iterating over FPA 306 365 307 // Update concepts366 // Update FPA concepts 308 367 const char *typeStr; // Exposure type String 309 368 switch (type) { … … 334 393 x0Chip -= 0.5 * (bounds->x1 - bounds->x0); 335 394 y0Chip -= 0.5 * (bounds->y1 - bounds->y0); 336 337 #if 0338 // Add random stars339 if (type == PPSIM_TYPE_OBJECT && starsDensity > 0) {340 // Peak fluxes: faintest and brightest levels for random stars341 float faint = roughNoise;342 float bright = powf(10.0, -0.4 * (starsMag - zp)) / sqrt(2.0*M_PI) / seeing * expTime;343 if (bright < faint) {344 psLogMsg("ppSim", PS_LOG_INFO,345 "Image noise is above brightest random star --- no random stars added.");346 } else {347 // Normalisation, set by the specified stellar density at the specified bright348 // magnitude349 float norm = starsDensity * numCols * numRows * PS_SQR(scale * 180.0 / M_PI) /350 powf(bright, starsLum);351 352 // Total number of stars down to the faint flux end353 long num = expf(logf(norm) + starsLum * logf(faint)) + 0.5;354 355 printf("Adding %ld stars to %f\n", num, faint);356 357 for (long j = 0; j < num; j++) {358 float flux = expf((logf(j + 1) - logf(norm)) / starsLum); // Flux of star359 360 // TO DO: put stars on chips, rather than cells, so they can overlap cell361 // boundaries362 363 // Position on cell364 float x = psRandomUniform(rng) * numCols;365 float y = psRandomUniform(rng) * numRows;366 star(signal, variance, x, y, flux, roughNoise, seeing, expCorr);367 }368 }369 }370 #endif371 395 372 396 pmCell *cell; // Cell from chip … … 529 553 } 530 554 531 // Rough noise estimate, appropriate for entire cell 532 float roughNoise = sqrtf(PS_SQR(readnoise) + (darkRate + skyRate) * expTime); 533 534 535 // XXX Not sure I've got the scaling right on the peak flux: it's multiplied by the expTime 536 // here, and the exposure up above. 537 538 // Add specified (catalogue) stars 555 // Add stars 539 556 if (type == PPSIM_TYPE_OBJECT && ra && dec && mag) { 557 // Rough noise estimate, appropriate for entire cell 558 float roughNoise = sqrtf(PS_SQR(readnoise) + (darkRate + skyRate) * expTime); 559 540 560 for (long j = 0; j < ra->n; j++) { 541 // Position on the cell 561 // Position on the cell and peak flux 542 562 float x = fpa2cell(ra->data.F32[j], x0Cell, xParityCell, x0Chip, xParityChip); 543 563 float y = fpa2cell(dec->data.F32[j], y0Cell, yParityCell, y0Chip, yParityChip); 544 star(signal, variance, x, y, mag->data.F32[j] * expTime,545 roughNoise, seeing, expCorr);564 float flux = mag->data.F32[j]; 565 star(signal, variance, x, y, flux, roughNoise, seeing, expCorr); 546 566 } 547 567 } 548 549 // Add random stars550 if (type == PPSIM_TYPE_OBJECT && starsDensity > 0) {551 // Peak fluxes: faintest and brightest levels for random stars552 float faint = roughNoise;553 float bright = powf(10.0, -0.4 * (starsMag - zp)) / sqrt(2.0*M_PI) / seeing * expTime;554 if (bright < faint) {555 psLogMsg("ppSim", PS_LOG_INFO,556 "Image noise is above brightest random star --- no random stars added.");557 } else {558 // Normalisation, set by the specified stellar density at the specified bright559 // magnitude560 float norm = starsDensity * numCols * numRows * PS_SQR(scale * 180.0 / M_PI) /561 powf(bright, starsLum);562 563 // Total number of stars down to the faint flux end564 long num = expf(logf(norm) + starsLum * logf(faint)) + 0.5;565 566 printf("Adding %ld stars to %f\n", num, faint);567 568 for (long j = 0; j < num; j++) {569 float flux = expf((logf(j + 1) - logf(norm)) / starsLum); // Flux of star570 571 // TO DO: put stars on chips, rather than cells, so they can overlap cell572 // boundaries573 574 // Position on cell575 float x = psRandomUniform(rng) * numCols;576 float y = psRandomUniform(rng) * numRows;577 star(signal, variance, x, y, flux, roughNoise, seeing, expCorr);578 }579 }580 }581 582 568 readout->image = addNoise(signal, variance, rng, gain); 583 569 saturate(readout->image, saturation);
Note:
See TracChangeset
for help on using the changeset viewer.
