Exemple #1
0
/***********************************************************************//**
 * @brief Sum effective area multiplied by livetime over zenith and
 *        (optionally) azimuth angles
 *
 * @param[in] dir True sky direction.
 * @param[in] energy True photon energy.
 * @param[in] aeff Effective area.
 *
 * Computes
 * \f[\sum_{\cos \theta, \phi} T_{\rm live}(\cos \theta, \phi) 
 *    A_{\rm eff}(\log E, \cos \theta, \phi)\f]
 * where
 * \f$T_{\rm live}(\cos \theta, \phi)\f$ is the livetime as a function of
 * the cosine of the zenith and the azimuth angle, and
 * \f$A_{\rm eff}(\log E, \cos \theta, \phi)\f$ is the effective area that
 * depends on
 * the log10 of the energy (in MeV),
 * the cosine of the zenith angle, and
 * the azimuth angle.
 * This method assumes that \f$T_{\rm live}(\cos \theta, \phi)\f$ is
 * stored as a set of maps in a 2D array with \f$\cos \theta\f$ being the
 * most rapidely varying parameter and with the first map starting at
 * index m_num_ctheta (the first m_num_ctheta maps are the livetime cube
 * maps without any \f$\phi\f$ dependence).
 ***************************************************************************/
double GLATLtCubeMap::operator()(const GSkyDir& dir, const GEnergy& energy,
                                 const GLATAeff& aeff) const
{
    // Get map index
    int pixel = m_map.dir2pix(dir);

    // Initialise sum
    double sum = 0.0;

    // Circumvent const correctness
    GLATAeff* fct = ((GLATAeff*)&aeff);

    // If livetime cube and response have phi dependence then sum over
    // zenith and azimuth. Note that the map index starts with m_num_ctheta
    // as the first m_num_ctheta maps correspond to an evaluation without
    // any phi-dependence.
    if (has_phi() && aeff.has_phi()) {
        for (int iphi = 0, i = m_num_ctheta; iphi < m_num_phi; ++iphi) {
            double p = phi(iphi);
            for (int itheta = 0; itheta < m_num_ctheta; ++itheta, ++i) {
                sum += m_map(pixel, i) * (*fct)(energy.log10MeV(), costheta(i), p);
            }
        }
    }

    // ... otherwise sum only over zenith angle
    else {
        for (int i = 0; i < m_num_ctheta; ++i) {
            sum += m_map(pixel, i) * (*fct)(energy.log10MeV(), costheta(i));
        }
    }

    // Return sum
    return sum;
}
Exemple #2
0
///< The function projects latitude-longitude environment map to SH basis up to lmax band
void ShProjectEnvironmentMap(float3 const* envmap, int width, int height, int lmax, float3* coeffs)
{
    // Resulting coefficients for RGB
    // std::vector<float3> coeffs(NumShTerms(lmax));
    // Temporary coefficients storage
    std::vector<float>  ylm(NumShTerms(lmax));

    // Precompute sin and cos for the sphere
    std::vector<float> sintheta(height);
    std::vector<float> costheta(height);
    std::vector<float> sinphi(width);
    std::vector<float> cosphi(width);

    float thetastep = PI / height;
    float phistep = 2.f * PI / width;
    float theta0 = PI / height / 2;
    float phi0 = 2.f * PI / width / 2;

    for (int i = 0; i < width; ++i)
    {
        sinphi[i] = std::sin(phi0 + i * phistep);
        cosphi[i] = std::cos(phi0 + i * phistep);
    }

    for (int i = 0; i < height; ++i)
    {
        sintheta[i] = std::sin(theta0 + i * thetastep);
        costheta[i] = std::cos(theta0 + i * thetastep);
    }

    // Iterate over the pixels calculating Riemann sum
    for (int phi = 0; phi < width; ++phi)
    {
        for (int theta = 0; theta < height; ++theta)
        {
            // Construct direction vector
            float3 w = normalize(float3(sintheta[theta] * cosphi[phi], costheta[theta], sintheta[theta] * sinphi[phi]));

            // Construct uv sample coordinates
            float2 uv = float2((float)phi / width, (float)theta / height);

            // Sample environment map
            int iu = (int)floor(uv.x * width);
            int iv = (int)floor(uv.y * height);

            float3 le = envmap[width * iv + iu];

            // Evaluate SH functions at w up to lmax band
            ShEvaluate(w, lmax, &ylm[0]);

            // Evaluate Riemann sum accouting for solid angle conversion (sin term)
            for (int i = 0; i < NumShTerms(lmax); ++i)
            {
                coeffs[i] += le * ylm[i] * sintheta[theta] * (PI / height) * (2.f * PI / width);
            }
        }
    }
}
Exemple #3
0
///< The function evaluates SH functions and dumps values to latitude-longitude map
void ShEvaluateAndDump(ImageIo& io, std::string const& filename,  int width, int height, int lmax, float3 const* coeffs)
{
    // Prepare image memory
    std::vector<float> imagedata(width * height * 3);

    // Allocate space for SH functions
    std::vector<float> ylm(NumShTerms(lmax));

    // Precalculate sin and cos terms 
    std::vector<float> sintheta(height);
    std::vector<float> costheta(height);
    std::vector<float> sinphi(width);
    std::vector<float> cosphi(width);

    float thetastep = PI / height;
    float phistep = 2.f*PI / width;
    float theta0 = PI / height / 2;
    float phi0= 2.f*PI / width / 2;

    for (int i = 0; i < width; ++i)
    {
        sinphi[i] = std::sin(phi0 + i * phistep);
        cosphi[i] = std::cos(phi0 + i * phistep);
    }

    for (int i = 0; i < height; ++i)
    {
        sintheta[i] = std::sin(theta0 + i * thetastep);
        costheta[i] = std::cos(theta0 + i * thetastep);
    }

    // Iterate thru image pixels
    for (int phi = 0; phi < width; ++phi)
    {
        for (int theta = 0; theta < height; ++theta)
        {
            // Calculate direction
            float3 w = normalize(float3(sintheta[theta] * cosphi[phi], costheta[theta], sintheta[theta] * sinphi[phi]));

            // Evaluate SH functions at w up to lmax band
            ShEvaluate(w, lmax, &ylm[0]);

            // Evaluate function injecting SH coeffs
            for (int i = 0; i < NumShTerms(lmax); ++i)
            {
                imagedata[theta * width * 3 + phi * 3] += ylm[i] * coeffs[i].x;
                imagedata[theta * width * 3 + phi * 3 + 1] += ylm[i] * coeffs[i].y;
                imagedata[theta * width * 3 + phi * 3 + 2] += ylm[i] * coeffs[i].z;
            }
        }
    }

    // Write image to file
    ImageIo::ImageDesc imgdesc(width, height, 3);
    io.Write(filename, imagedata, imgdesc);
}
Exemple #4
0
/***********************************************************************//**
 * @brief Sum function multiplied by livetime over zenith angle
 *
 * @param[in] dir Sky direction.
 * @param[in] fct Function to evaluate.
 *
 * Computes
 * \f[\sum_{\cos \theta} T_{\rm live}(\cos \theta) f(\cos \theta)\f]
 * where
 * \f$T_{\rm live}(\cos \theta)\f$ is the livetime as a function of the
 * cosine of the zenith angle, and
 * \f$f(\cos \theta)\f$ is a function that depends on the cosine of the
 * zenith angle.
 * This method assumes that \f$T_{\rm live}(\cos \theta)\f$ is stored as a
 * set of maps.
 ***************************************************************************/
double GLATLtCubeMap::operator()(const GSkyDir& dir, _ltcube_ctheta fct) const
{
    // Get map index
    int pixel = m_map.dir2pix(dir);

    // Initialise sum
    double sum = 0.0;

    // Loop over zenith angles
    for (int i = 0; i < m_num_ctheta; ++i) {
        sum += m_map(pixel, i) * (*fct)(costheta(i));
    }

    // Return sum
    return sum;
}
Exemple #5
0
/***********************************************************************//**
 * @brief Sum function multiplied by livetime over zenith and azimuth angles
 *
 * @param[in] dir Sky direction.
 * @param[in] fct Function to evaluate.
 *
 * Computes
 * \f[\sum_{\cos \theta, \phi} T_{\rm live}(\cos \theta, \phi) 
 *    f(\cos \theta, \phi)\f]
 * where
 * \f$T_{\rm live}(\cos \theta, \phi)\f$ is the livetime as a function of
 * the cosine of the zenith and of the azimuth angle, and
 * \f$f(\cos \theta, \phi)\f$ is a function that depends on the cosine of
 * the zenith angle and of the azimuth angle.
 * This method assumes that \f$T_{\rm live}(\cos \theta, \phi)\f$ is
 * stored as a set of maps in a 2D array with \f$\cos \theta\f$ being the
 * most rapidely varying parameter and with the first map starting at
 * index m_num_ctheta (the first m_num_ctheta maps are the livetime cube
 * maps without any \f$\phi\f$ dependence).
 ***************************************************************************/
double GLATLtCubeMap::operator()(const GSkyDir& dir, _ltcube_ctheta_phi fct) const
{
    // Get map index
    int pixel = m_map.dir2pix(dir);

    // Initialise sum
    double sum = 0.0;

    // Loop over azimuth and zenith angles. Note that the map index starts
    // with m_num_ctheta as the first m_num_ctheta maps correspond to an
    // evaluation without any phi-dependence.
    for (int iphi = 0, i = m_num_ctheta; iphi < m_num_phi; ++iphi) {
        double p = phi(iphi);
        for (int itheta = 0; itheta < m_num_ctheta; ++itheta, ++i) {
            sum += m_map(pixel, i) * (*fct)(costheta(itheta), p);
        }
    }

    // Return sum
    return sum;
}
Exemple #6
0
///< The function projects latitude-longitude environment map to SH basis up to lmax band
void ShProjectEnvironmentMap(TextureSystem const& texsys, std::string const& texture, int lmax, float3* coeffs)
{
    // Resulting coefficients for RGB
    // std::vector<float3> coeffs(NumShTerms(lmax));
    // Temporary coefficients storage
    std::vector<float>  ylm(NumShTerms(lmax));

    // Get texture width and height
    TextureSystem::TextureDesc texdesc;
    texsys.GetTextureInfo(texture, texdesc);

    // Precompute sin and cos for the sphere
    std::vector<float> sintheta(texdesc.height);
    std::vector<float> costheta(texdesc.height);
    std::vector<float> sinphi(texdesc.width);
    std::vector<float> cosphi(texdesc.width);

    float thetastep = PI / texdesc.height;
    float phistep = 2.f*PI / texdesc.width;
    float theta0 = PI / texdesc.height / 2;
    float phi0 = 2.f*PI / texdesc.width / 2;

    for (int i = 0; i < texdesc.width; ++i)
    {
        sinphi[i] = std::sin(phi0 + i * phistep);
        cosphi[i] = std::cos(phi0 + i * phistep);
    }

    for (int i = 0; i < texdesc.height; ++i)
    {
        sintheta[i] = std::sin(theta0 + i * thetastep);
        costheta[i] = std::cos(theta0 + i * thetastep);
    }

    // Iterate over the pixels calculating Riemann sum
    for (int phi = 0; phi < texdesc.width; ++phi)
    {
        for (int theta = 0; theta < texdesc.height; ++theta)
        {
            // Construct direction vector
            float3 w = normalize(float3(sintheta[theta] * cosphi[phi], costheta[theta], sintheta[theta] * sinphi[phi]));

            // Construct uv sample coordinates
            float2 uv = float2((float)phi / texdesc.width, (float)theta / texdesc.height);

            // Sample environment map
            TextureSystem::Options opts;
            opts.wrapmode = TextureSystem::Options::kRepeat;
            opts.filter= TextureSystem::Options::kPoint;
            float3 le = texsys.Sample(texture, uv, float2());

            // Evaluate SH functions at w up to lmax band
            ShEvaluate(w, lmax, &ylm[0]);

            // Evaluate Riemann sum accouting for solid angle conversion (sin term)
            for (int i = 0; i < NumShTerms(lmax); ++i)
            {
                coeffs[i] += le * ylm[i] * sintheta[theta] * (PI / texdesc.height) * (2.f * PI / texdesc.width);
            }
        }
    }
}