IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 6, 2011, 1:34:52 PM (15 years ago)
Author:
eugene
Message:

fix the mags of input stars and galaxies (prove we inserted the amount of flux we expected); realistic galaxy luminosity function

File:
1 edited

Legend:

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

    r31157 r32350  
    1111    if (!galaxyFake) return true;
    1212
    13     float galaxyLum       = psMetadataLookupF32(&mdok, recipe, "GALAXY.LUM"); // Galaxy luminosity func slope
    14     float galaxyMag       = psMetadataLookupF32(&mdok, recipe, "GALAXY.MAG"); // Galaxy brightest magnitude
     13    float galaxyAlpha     = psMetadataLookupF32(&mdok, recipe, "GALAXY.LUM"); // Galaxy luminosity func slope
     14    float brightMag       = psMetadataLookupF32(&mdok, recipe, "GALAXY.MAG"); // Galaxy brightest magnitude
    1515    float galaxyDensity   = psMetadataLookupF32(&mdok, recipe, "GALAXY.DENSITY"); // Density of fakes
    1616
     
    2020    bool galaxyGridRandom = psMetadataLookupBool(&mdok, recipe, "GALAXY.GRID.RANDOM"); // Density of fakes
    2121    float galaxyGridPeak  = psMetadataLookupF32 (&mdok, recipe, "GALAXY.GRID.PEAK"); // peak flux of fakes
     22    float galaxyGridMag   = psMetadataLookupF32 (&mdok, recipe, "GALAXY.GRID.MAG"); // peak flux of fakes
    2223   
     24    float galaxyGridXoff  = psMetadataLookupF32 (&mdok, recipe, "GALAXY.GRID.XOFF"); // centroid offset
     25    float galaxyGridYoff  = psMetadataLookupF32 (&mdok, recipe, "GALAXY.GRID.YOFF"); // centroid offset
     26
    2327    float galaxyRmajorMax = psMetadataLookupF32(&mdok, recipe, "GALAXY.RMAJOR.MAX"); // Density of fakes
    2428    float galaxyRmajorMin = psMetadataLookupF32(&mdok, recipe, "GALAXY.RMAJOR.MIN"); // Density of fakes
     
    3539    float galaxyIndexMax  = psMetadataLookupF32(&mdok, recipe, "GALAXY.INDEX.MAX"); // Density of fakes
    3640
    37     float darkRate        = psMetadataLookupF32(&mdok, recipe, "DARK.RATE"); // Dark rate
     41    // float darkRate     = psMetadataLookupF32(&mdok, recipe, "DARK.RATE"); // Dark rate
    3842    float expTime         = psMetadataLookupF32(&mdok, recipe, "EXPTIME"); // Exposure time
    3943    float zp              = psMetadataLookupF32(&mdok, recipe, "ZEROPOINT"); // Photometric zero point
    40     float seeing          = psMetadataLookupF32(&mdok, recipe, "SEEING"); // Seeing sigma (pix)
     44    // float seeing       = psMetadataLookupF32(&mdok, recipe, "SEEING"); // Seeing sigma (pix)
    4145    float scale           = psMetadataLookupF32(&mdok, recipe, "PIXEL.SCALE") * M_PI / 3600.0 / 180.0; // Plate scale (radians/pixel)
    4246    float skyRate         = psMetadataLookupF32(&mdok, recipe, "SKY.RATE"); // Sky rate
     
    4448        float skyMags = psMetadataLookupF32(&mdok, recipe, "SKY.MAGS");  assert (mdok);
    4549        skyRate = scale * scale * ppSimMagToFlux (skyMags, zp);
     50    }
     51
     52    // determine the galaxy model
     53    char *modelName = psMetadataLookupStr(&mdok, recipe, "GALAXY.MODEL"); // galaxy model name
     54    pmModelType type = pmModelClassGetType (modelName);
     55    if (type == -1) {
     56        psError (PS_ERR_UNKNOWN, false, "invalid model name");
     57        return false;
    4658    }
    4759
     
    6476    // Grabbing read noise from the recipe rather than the cell, which is a potential danger, but it
    6577    // shouldn't be too bad.
    66     float readnoise = psMetadataLookupF32(&mdok, recipe, "READNOISE"); // Default read noise
    67     if (!mdok) {
    68         psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find READNOISE in recipe.");
    69         psFree(bounds);
    70         return false;
    71     }
    72 
    73     // Peak fluxes: faintest and brightest levels for random galaxy
    74     float faint = 0.1 * 10.0 * sqrt(2.0*M_PI) * seeing * sqrtf(PS_SQR(readnoise) + (darkRate + skyRate) * expTime);
    75     float bright = powf(10.0, -0.4 * (galaxyMag - zp)) / sqrt(2.0*M_PI) / seeing * expTime;
    76     if (bright < faint) {
    77         psLogMsg("ppSim", PS_LOG_INFO,
    78                  "Image noise is above brightest random galaxy --- no random galaxy added.");
     78    // float readnoise = psMetadataLookupF32(&mdok, recipe, "READNOISE"); // Default read noise
     79    // if (!mdok) {
     80    //  psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find READNOISE in recipe.");
     81    //  psFree(bounds);
     82    //  return false;
     83    // }
     84
     85    // faintest and brightest magnitudes for random galaxies
     86    // float brightFlux = ppSimMagToFlux (brightMag, zp) * expTime;
     87    float faintMag = brightMag + 5.0;
     88    if (brightMag > faintMag) {
     89        psLogMsg("ppSim", PS_LOG_INFO, "Image noise is above brightest random galaxy --- no random galaxy added.");
    7990        return true;
    8091    }
    8192
    8293    // Normalisation, set by the specified stellar density at the specified bright magnitude
    83     float norm = galaxyDensity * xSize * ySize * PS_SQR(scale * 180.0 / M_PI) /
    84         powf(bright, galaxyLum);
     94    float refSum = galaxyDensity * xSize * ySize * PS_SQR(scale * 180.0 / M_PI);
     95    float normLum =  refSum / (galaxyAlpha * logf(10.0) * powf(10.0, (galaxyAlpha * brightMag)));
     96    float normScale = normLum * galaxyAlpha * logf(10.0);
    8597
    8698    // Total number of galaxy down to the faint flux end
    87     long num = expf(logf(norm) + galaxyLum * logf(faint)) + 0.5;
     99    long nTotal = 0;
     100    if (galaxyAlpha < 0.1) {
     101        nTotal = 100;
     102    } else {
     103        nTotal = normScale * powf (10.0, (galaxyAlpha * faintMag));
     104    }
    88105
    89106    if (galaxyGrid) {
    90         num = (int)(xSize / galaxyGridDX) * (int)(ySize / galaxyGridDY);
     107        fprintf (stderr, "galaxy grid inst mag: %f\n", galaxyGridMag - zp - 2.5*log10(expTime));
     108        nTotal = (int)(xSize / galaxyGridDX) * (int)(ySize / galaxyGridDY);
    91109   
    92         psLogMsg("ppSim", PS_LOG_INFO, "Adding grid of %ld galaxies\n", num);
     110        psLogMsg("ppSim", PS_LOG_INFO, "Adding grid of %ld galaxies\n", nTotal);
    93111
    94112        float galaxyIndexSlope = (galaxyIndexMax - galaxyIndexMin);
     
    98116
    99117        int i = 0;
    100         float refNorm = 1.0;
    101         float ourNorm = 1.0;
     118        // float refNorm = 1.0;
     119        // float ourNorm = 1.0;
    102120
    103121        for (long iy = 0.5*galaxyGridDY; iy < ySize; iy += galaxyGridDY) {
     
    106124
    107125                // make fpa center of distribution
    108                 galaxy->x    = ix;
    109                 galaxy->y    = iy;
    110                 galaxy->peak = galaxyGridPeak;
     126                // center the galaxy peak on the center of a pixel
     127                galaxy->x    = ix + 0.5 + galaxyGridXoff;
     128                galaxy->y    = iy + 0.5 + galaxyGridYoff;
     129
     130                float galaxyGridFlux = expTime * powf(10.0, -0.4 * (galaxyGridMag - zp));
    111131
    112132                // galaxyIndex from user should be for function of this form: exp(-r^(1/n))
     
    115135                float rndValue;
    116136
    117                 rndValue = galaxyGridRandom ? drand48() : i / (float) num;
     137                rndValue = galaxyGridRandom ? drand48() : i / (float) nTotal;
    118138                float index = (galaxyIndexMin  + rndValue * galaxyIndexSlope);
    119139                galaxy->index = 0.5/index; // factor of 0.5 because the Sersic model creates exp(-z^n), not exp(-r^n)
    120140
    121                 rndValue = galaxyGridRandom ? drand48() : i / (float) num;
     141                rndValue = galaxyGridRandom ? drand48() : i / (float) nTotal;
    122142                float scale = (galaxyRmajorMin + rndValue * galaxyRmajorSlope);
    123143
    124                 // for a sersic model,
    125                 float bn = 1.9992*index - 0.3271;
    126                 float fR = 1.0 / (sqrt(2.0) * pow (bn, index));
    127                 float Io = exp(bn);
    128 
    129144                galaxy->Rmaj  = scale;
    130145
    131                 rndValue = galaxyGridRandom ? drand48() : i / (float) num;
     146                rndValue = galaxyGridRandom ? drand48() : i / (float) nTotal;
    132147                galaxy->Rmin  = (galaxyARatioMin + rndValue * galaxyARatioSlope) * galaxy->Rmaj;
    133148
    134                 rndValue = galaxyGridRandom ? drand48() : i / (float) num;
     149                rndValue = galaxyGridRandom ? drand48() : i / (float) nTotal;
    135150                galaxy->theta = (galaxyThetaMin  + rndValue * galaxyThetaSlope);
    136151               
    137                 if (i == 0) {
    138                     refNorm = Io*scale*scale;
    139                 }
    140                 ourNorm = refNorm / (Io*scale*scale);
    141                 galaxy->peak *= ourNorm;
    142 
    143                 if (0) {
    144                     fprintf (stderr, "Rmaj: %f, scale: %f, index: %f, bn: %f, Ro: %f, Io: %f, theta: %f\n", galaxy->Rmaj, scale, index, bn, fR, Io, galaxy->theta);
     152                bool sersicType = false;
     153                sersicType |= (type == pmModelClassGetType ("PS_MODEL_SERSIC"));
     154                sersicType |= (type == pmModelClassGetType ("PS_MODEL_EXP"));
     155                sersicType |= (type == pmModelClassGetType ("PS_MODEL_DEV"));
     156                if (sersicType) {
     157                    if (type == pmModelClassGetType ("PS_MODEL_DEV")) index = 4.0;
     158                    if (type == pmModelClassGetType ("PS_MODEL_EXP")) index = 1.0;
     159                       
     160                    // for a sersic model,
     161                    float bn = 1.9992*index - 0.3271;
     162                    float Io = exp(bn);
     163                   
     164                    // the integral of a Sersic has an analytical form as follows:
     165                    float logGamma = lgamma(2.0*index);
     166                    float bnFactor = pow(bn, 2.0*index);
     167                    float norm = 2.0 * M_PI * PS_SQR(galaxy->Rmaj) * index * Io * exp(logGamma) / bnFactor;
     168                   
     169                    // XXX probably should limit the allowed thinness of a galaxy
     170                    galaxy->peak = galaxyGridFlux / norm / (galaxy->Rmin / galaxy->Rmaj);
     171                } else {
     172                    galaxy->peak = galaxyGridPeak;
    145173                }
     174
     175                // if (0) {
     176                //     fprintf (stderr, "Rmaj: %f, scale: %f, index: %f, bn: %f, Ro: %f, Io: %f, theta: %f\n", galaxy->Rmaj, scale, index, bn, fR, Io, galaxy->theta);
     177                // }
    146178
    147179                psArrayAdd (galaxies, 100, galaxy);
     
    151183    } else {   
    152184
     185        fprintf (stderr, "galaxy ref inst mag: %f\n", brightMag - zp - 2.5*log10(expTime));
    153186        float galaxyIndexSlope = (galaxyIndexMax - galaxyIndexMin);
    154187        float galaxyThetaSlope = (galaxyThetaMax - galaxyThetaMin);
     
    156189        float galaxyRmajorSlope = (galaxyRmajorMax - galaxyRmajorMin);
    157190
    158         psLogMsg("ppSim", PS_LOG_INFO, "Adding %ld galaxies down to %f mag\n", num,
    159                  -2.5 * log10(faint * sqrt(2.0*M_PI) * seeing / expTime) + zp);
    160 
    161         for (long i = 0; i < num; i++) {
     191        psLogMsg("ppSim", PS_LOG_INFO, "Adding %ld galaxies down to %f mag\n", nTotal, faintMag);
     192
     193        for (long i = 0; i < nTotal; i++) {
    162194            ppSimGalaxy *galaxy = ppSimGalaxyAlloc ();
    163195
     
    170202
    171203            float scale = (psRandomUniform(rng) * galaxyRmajorSlope + galaxyRmajorMin);
    172 
    173             // for a sersic model,
    174             float bn = 1.9992*index - 0.3271;
    175             float fR = 1.0 / (sqrt(2.0) * pow (bn, index));
    176             float Io = exp(bn);
    177 
    178204            galaxy->Rmaj  = scale;
    179 
    180205            galaxy->Rmin  = (PS_SQR(psRandomUniform(rng)) * galaxyARatioSlope + galaxyARatioMin) * galaxy->Rmaj;
    181 
    182206            galaxy->theta = (psRandomUniform(rng) * galaxyThetaSlope  + galaxyThetaMin);
    183207
    184             // the flux is only approximately correct (scaling of the peak is wrong)
    185             // elsewhere (ppSimInsertGalaxies.c) we calculate the true galaxy flux
    186             galaxy->flux = expf((logf(i + 1) - logf(norm)) / galaxyLum); // Peak flux
    187             galaxy->peak = galaxy->flux / (2.0*M_PI*PS_SQR(seeing));
    188 
    189             if (0) {
    190               fprintf (stderr, "Rmaj: %f, scale: %f, index: %f, bn: %f, Ro: %f, Io: %f\n", galaxy->Rmaj, scale, index, bn, fR, Io);
     208            bool sersicType = false;
     209            sersicType |= (type == pmModelClassGetType ("PS_MODEL_SERSIC"));
     210            sersicType |= (type == pmModelClassGetType ("PS_MODEL_EXP"));
     211            sersicType |= (type == pmModelClassGetType ("PS_MODEL_DEV"));
     212            if (sersicType) {
     213                if (type == pmModelClassGetType ("PS_MODEL_DEV")) index = 4.0;
     214                if (type == pmModelClassGetType ("PS_MODEL_EXP")) index = 1.0;
     215               
     216                // for a sersic model,
     217                float bn = 1.9992*index - 0.3271;
     218                float Io = exp(bn);
     219               
     220                // the integral of a Sersic has an analytical form as follows:
     221                float logGamma = lgamma(2.0*index);
     222                float bnFactor = pow(bn, 2.0*index);
     223                float norm = 2.0 * M_PI * PS_SQR(galaxy->Rmaj) * index * Io * exp(logGamma) / bnFactor;
     224                   
     225                // XXX probably should limit the allowed thinness of a galaxy
     226                float galaxyMag =  PS_MIN (faintMag, PS_MAX (brightMag, (log10((i + 1.0) / normScale) / galaxyAlpha)));
     227
     228                galaxy->flux = ppSimMagToFlux (galaxyMag, zp) * expTime;
     229                galaxy->peak = galaxy->flux / norm / (galaxy->Rmin / galaxy->Rmaj);
     230            }
     231
     232            if (1) {
     233                fprintf (stderr, "Rmaj: %f, Rmin: %f, theta: %f, scale: %f, index: %f, peak: %f, mag: %f\n", galaxy->Rmaj, galaxy->Rmin, galaxy->theta*180.0/M_PI, scale, index, galaxy->peak, -2.5*log10(galaxy->flux));
    191234            }
    192235
Note: See TracChangeset for help on using the changeset viewer.