#ifndef __JPHYSICS__JRADIATIONFUNCTION__ #define __JPHYSICS__JRADIATIONFUNCTION__ #include "JTools/JFunction1D_t.hh" #include "JTools/JFunctionalMap_t.hh" #include "JTools/JMultiFunction.hh" #include "JTools/JGrid.hh" #include "JPhysics/JRadiation.hh" /** * \author mdejong */ namespace JPHYSICS {} namespace JPP { using namespace JPHYSICS; } namespace JPHYSICS { /** * Fast implementation of class JRadiation. * * In this, the methods * - JRadiation::TotalCrossSectionEErad, * - JRadiation::TotalCrossSectionGNrad, * - JRadiation::CalculateACoeff and * - JRadiation::IntegralofG * * are reimplemented using lookup tables. */ class JRadiationFunction : public JRadiation { typedef JTOOLS::JGridPolint1Function1D_t JFunction1D_t; typedef JTOOLS::JMultiFunction > JFunction2D_t; public: /** * Constructor. * * \param radiation JRadiation object * \param number_of_bins number of bins * \param Emin minimal muon energy [GeV] * \param Emax maximal muon energy [GeV] */ JRadiationFunction(const JRadiation& radiation, const unsigned int number_of_bins, const double Emin, const double Emax) : JRadiation(radiation) { using namespace JTOOLS; const double xmin = log(Emin); const double xmax = log(Emax); integral.configure(make_grid(number_of_bins, xmin, xmax)); for (JFunction2D_t::iterator i = integral.begin(); i != integral.end(); ++i) { const double x = i->getX(); const double E = exp(x); const double ymin = log(EminEErad/E); const double ymax = 0.0; if (ymax > ymin) { i->getY().configure(make_grid(number_of_bins, ymin, ymax)); for (JFunction1D_t::iterator j = i->getY().begin(); j != i->getY().end(); ++j) { const double y = j->getX(); const double eps = exp(y) * E; const double z = JRadiation::IntegralofG(E, eps); j->getY() = z; } } } integral.compile(); integral.setExceptionHandler(new JFunction1D_t::JDefaultResult(0.0)); sigmaEE.configure(make_grid(number_of_bins, xmin, xmax)); for (JFunction1D_t::iterator i = sigmaEE.begin(); i != sigmaEE.end(); ++i) { const double E = exp(i->getX()); const double y = JRadiation::TotalCrossSectionEErad(E); i->getY() = y; } sigmaEE.compile(); sigmaGN.configure(make_grid(number_of_bins, xmin, xmax)); for (JFunction1D_t::iterator i = sigmaGN.begin(); i != sigmaGN.end(); ++i) { const double E = exp(i->getX()); const double y = JRadiation::TotalCrossSectionGNrad(E); i->getY() = y; } sigmaGN.compile(); Acoeff.configure(make_grid(number_of_bins, xmin, xmax)); for (JFunction1D_t::iterator i = Acoeff.begin(); i != Acoeff.end(); ++i) { const double E = exp(i->getX()); const double y = JRadiation::CalculateACoeff(E); i->getY() = y; } Acoeff.compile(); } /** * Pair production cross section. * * \param E muon energy [GeV] * \return cross section [m^2/g] */ virtual double TotalCrossSectionEErad(const double E) const override { const double x = log(E); if (x >= sigmaEE. begin()->getX() && x <= sigmaEE.rbegin()->getX()) { try { return sigmaEE(x); } catch(std::exception& error) {} } return JRadiation::TotalCrossSectionEErad(E); } /** * Photo-nuclear cross section. * * \param E muon energy [GeV] * \return cross section [m^2/g] */ virtual double TotalCrossSectionGNrad(const double E) const override { const double x = log(E); if (x >= sigmaGN. begin()->getX() && x <= sigmaGN.rbegin()->getX()) { try { return sigmaGN(x); } catch(std::exception& error) {} } return JRadiation::TotalCrossSectionGNrad(E); } /** * Ionization a parameter. * * \param E muon energy [GeV] * \return ionization coefficient [GeV*m^2/g] */ virtual double CalculateACoeff(const double E) const override { const double x = log(E); if (x >= Acoeff. begin()->getX() && x <= Acoeff.rbegin()->getX()) { try { return Acoeff(x); } catch(std::exception& error) {} } return JRadiation::CalculateACoeff(E); } protected: virtual double IntegralofG(const double E, const double eps) const override { try { const double x = log(E); const double y = log(eps/E); const double z = integral(x, y); return z; } catch(std::exception& error) {} return JRadiation::IntegralofG(E, eps); } JFunction1D_t sigmaEE; JFunction1D_t sigmaGN; JFunction1D_t Acoeff; JFunction2D_t integral; }; } #endif