IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 12907


Ignore:
Timestamp:
Apr 18, 2007, 12:49:57 PM (19 years ago)
Author:
Paul Price
Message:

Putting random stars over the entire focal plane, so they're not cut
off by cell borders, etc.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppSim/src/ppSimLoop.c

    r12873 r12907  
    208208                 float peak,            // Peak flux of star
    209209                 float noise,           // Rough noise estimate
    210                  float seeing,           // Seeing for star
     210                 float seeing,          // Seeing for star
    211211                 const psImage *correction // Exposure correction as a function of position
    212212    )
     
    247247        psError(PS_ERR_UNKNOWN, false, "Unable to determine bounds of FPA");
    248248        return PS_EXIT_CONFIG_ERROR;
    249     }
    250 
    251     psVector *ra = psMetadataLookupPtr(NULL, config->arguments, "CATALOG.RA"); // Star RAs
    252     psVector *dec = psMetadataLookupPtr(NULL, config->arguments, "CATALOG.DEC"); // Star Declinations
    253     psVector *mag = psMetadataLookupPtr(NULL, config->arguments, "CATALOG.MAG"); // Star magnitudes
    254     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/pixel
    257     float zp = psMetadataLookupF32(NULL, config->arguments, "ZEROPOINT"); // Photometric zero point
    258 
    259     if (ra && dec && mag) {
    260         // Convert star ra,dec to pixels from FPA centre
    261         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 loop
    266         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); // Divisor
    269 
    270             // Convert to x,y position on tangent plane, in pixels
    271             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 rotation
    276             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 flux
    282             mag->data.F32[i] = powf(10.0, -0.4 * (mag->data.F32[i] - zp)) / sqrt(2.0*M_PI) / seeing;
    283         }
    284249    }
    285250
     
    301266
    302267    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSIM_RECIPE); // Recipe
    303 
    304268    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
    305364    pmFPAview *view = pmFPAviewAlloc(0);// View for iterating over FPA
    306365
    307     // Update concepts
     366    // Update FPA concepts
    308367    const char *typeStr;                // Exposure type String
    309368    switch (type) {
     
    334393        x0Chip -= 0.5 * (bounds->x1 - bounds->x0);
    335394        y0Chip -= 0.5 * (bounds->y1 - bounds->y0);
    336 
    337 #if 0
    338         // Add random stars
    339         if (type == PPSIM_TYPE_OBJECT && starsDensity > 0) {
    340             // Peak fluxes: faintest and brightest levels for random stars
    341             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 bright
    348                 // magnitude
    349                 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 end
    353                 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 star
    359 
    360                     // TO DO: put stars on chips, rather than cells, so they can overlap cell
    361                     // boundaries
    362 
    363                     // Position on cell
    364                     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 #endif
    371395
    372396        pmCell *cell;                   // Cell from chip
     
    529553                }
    530554
    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
    539556                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
    540560                    for (long j = 0; j < ra->n; j++) {
    541                         // Position on the cell
     561                        // Position on the cell and peak flux
    542562                        float x = fpa2cell(ra->data.F32[j], x0Cell, xParityCell, x0Chip, xParityChip);
    543563                        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);
    546566                    }
    547567                }
    548 
    549                 // Add random stars
    550                 if (type == PPSIM_TYPE_OBJECT && starsDensity > 0) {
    551                     // Peak fluxes: faintest and brightest levels for random stars
    552                     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 bright
    559                         // magnitude
    560                         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 end
    564                         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 star
    570 
    571                             // TO DO: put stars on chips, rather than cells, so they can overlap cell
    572                             // boundaries
    573 
    574                             // Position on cell
    575                             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 
    582568                readout->image = addNoise(signal, variance, rng, gain);
    583569                saturate(readout->image, saturation);
Note: See TracChangeset for help on using the changeset viewer.