#include #include #include #include #include #include #include #include "Jeep/JParser.hh" #include "Jeep/JMessage.hh" #include "JTools/JFunction1D_t.hh" #include "JTools/JFunctionalMap_t.hh" #include "JTools/JQuadrature.hh" #include "JPhysics/JPDF.hh" #include "JPhysics/JTransformer.hh" #include "JPhysics/JPDFTable.hh" #include "JPhysics/Antares.hh" #include "JPhysics/KM3NeT.hh" /** * Scaling of absorption and scattering length. */ double absorptionLengthFactor; double scatteringLengthFactor; inline double getAbsorptionLength(const double lambda) { return absorptionLengthFactor * NAMESPACE::getAbsorptionLength(lambda); } inline double getScatteringLength(const double lambda) { return scatteringLengthFactor * NAMESPACE::getScatteringLength(lambda); } /** * Use attenutation. */ bool useAttenuation; /** * Get attenuation length. * * \param lambda wavelength of photon [nm] * \return attenuation length [m] */ inline double getAttenuationLength(const double lambda) { static const double f = 0.17; const double l_abs = getAbsorptionLength(lambda); const double ls = getScatteringLength(lambda) / f; double y = 1.0 / l_abs; if (useAttenuation) y += 1.0 / ls; return 1.0 / y; } /** * Main program to create interpolation tables for PDFs. */ int main(int argc, char **argv) { using namespace std; string outputFile; int numberOfPoints; double epsilon; int function; int debug; try { JParser<> zap; zap['o'] = make_field(outputFile); zap['n'] = make_field(numberOfPoints) = 25; zap['e'] = make_field(epsilon) = 1.0e-10; zap['A'] = make_field(absorptionLengthFactor) = 1.0; zap['S'] = make_field(scatteringLengthFactor) = 1.0; zap['F'] = make_field(function) = 12, 13, 14; zap['U'] = make_field(useAttenuation); zap['d'] = make_field(debug) = 0; zap['F'] = JPARSER::not_initialised(); if (zap.read(argc, argv) != 0) return 1; } catch(const exception &error) { FATAL(error.what() << endl); } using namespace JPHYSICS; using namespace JTOOLS; typedef double (JPDF::*fcn)(const double, const double, const double, const double, const double) const; // set global parameters const double P_atm = 240.0; // ambient pressure [Atm] const double wmin = 320.0; // minimal wavelength [nm] const double wmax = 610.0; // maximal wavelength [nm] const JPDF_C pdf_c(NAMESPACE::getPhotocathodeArea(), NAMESPACE::getQE, NAMESPACE::getAngularAcceptance, getAttenuationLength, getScatteringLength, NAMESPACE::p00075, P_atm, wmin, wmax, numberOfPoints, epsilon); typedef JSplineFunction1D_t JFunction1D_t; typedef JMultipleMap<4, JPolint1FunctionalMap>::type_list JMapList_t; typedef JPDFTable JPDF_t; typedef JFunctionTransformer<4, JFunction1D_t::argument_type> JFunction4DTransformer_t; typedef JArray<4, JFunction1D_t::argument_type> JArray_t; JPDF_t pdf; NOTICE("building multi-dimensional function object <" << function << ">... " << flush); const double ng[] = { pdf_c.getIndexOfRefractionGroup(wmax), pdf_c.getIndexOfRefractionGroup(wmin) }; map > zmap; zmap[12] = make_pair((fcn) &JPDF::getScatteredLightFromMuon, JFunction4DTransformer_t(21.5, 2, ng[0], 0.0, JGeant(JGeanx(0.33, -9.5)), 6e-4, NAMESPACE::getAngularAcceptance, 0.06)); zmap[13] = make_pair((fcn) &JPDF::getDirectLightFromEMshower, JFunction4DTransformer_t(21.5, 2, ng[0], ng[1], JGeant(JGeanx(0.35, -5.4)), 1e-5, NAMESPACE::getAngularAcceptance, 0.001)); zmap[14] = make_pair((fcn) &JPDF::getScatteredLightFromEMshower, JFunction4DTransformer_t(21.5, 2, ng[0], 0.0, JGeant(JGeanx(0.55, -4.5)), 1e-2, NAMESPACE::getAngularAcceptance, 0.05)); if (zmap.find(function) == zmap.end()) { FATAL("illegal function specifier" << endl); } fcn f = zmap[function].first; // PDF JFunction4DTransformer_t transformer = zmap[function].second; // transformer set D; // distance [m] D.insert( 0.10); D.insert( 0.50); D.insert( 1.00); D.insert( 5.00); D.insert( 10.00); D.insert( 20.00); D.insert( 30.00); D.insert( 40.00); D.insert( 50.00); D.insert( 60.00); D.insert( 70.00); D.insert( 80.00); D.insert( 90.00); D.insert(100.00); D.insert(120.00); D.insert(150.00); D.insert(170.00); D.insert(190.00); D.insert(210.00); set C; // cosine emission angle JQuadrature qeant(-1.0, +1.0, 30, geanx); for (JQuadrature::const_iterator i = qeant.begin(); i != qeant.end(); ++i) C.insert(i->getX()); C.insert(-1.00); C.insert(+1.00); set X; // time [ns] if (function == 13) { for (double buffer[] = { 0.0, 0.005, 0.01, 0.015, -1 }, *x = buffer; *x >= 0; ++x) { X.insert(0.0 + *x); X.insert(1.0 - *x); } for (double x = 0.02; x < 0.99; x += 0.01) X.insert(x); } else { X.insert( 0.00); X.insert( 0.10); X.insert( 0.20); X.insert( 0.30); X.insert( 0.40); X.insert( 0.50); X.insert( 0.60); X.insert( 0.70); X.insert( 0.80); X.insert( 0.90); X.insert( 1.00); X.insert( 1.00); X.insert( 1.10); X.insert( 1.20); X.insert( 1.30); X.insert( 1.40); X.insert( 1.50); X.insert( 1.60); X.insert( 1.70); X.insert( 1.80); X.insert( 1.90); X.insert( 2.00); X.insert( 2.20); X.insert( 2.40); X.insert( 2.60); X.insert( 2.80); X.insert( 3.00); X.insert( 3.25); X.insert( 3.50); X.insert( 3.75); X.insert( 4.00); X.insert( 4.25); X.insert( 4.50); X.insert( 4.75); X.insert( 5.0); X.insert( 6.0); X.insert( 7.0); X.insert( 8.0); X.insert( 9.0); X.insert( 10.0); X.insert( 15.0); X.insert( 20.0); X.insert( 25.0); X.insert( 30.0); X.insert( 40.0); X.insert( 50.0); X.insert( 60.0); X.insert( 70.0); X.insert( 80.0); X.insert( 90.0); X.insert(100.0); X.insert(120.0); X.insert(140.0); X.insert(160.0); X.insert(180.0); X.insert(200.0); X.insert(250.0); X.insert(300.0); X.insert(350.0); X.insert(400.0); X.insert(450.0); X.insert(500.0); X.insert(600.0); X.insert(700.0); X.insert(800.0); X.insert(900.0); X.insert(999.0); } const double grid = 5.0; // [deg] const double alpha = 2.0 * sqrt(1.0 - cos(grid * PI / 180.0)); // azimuth angle unit step size for (set::const_iterator d = D.begin(); d != D.end(); ++d) { const double D_m = *d; for (set::const_iterator c = C.begin(); c != C.end(); ++c) { const double cd = *c; const unsigned int number_of_theta_points = max(2u, (unsigned int) (180.0/(1.4 * grid))); for (double theta = 0.0; theta <= PI + epsilon; theta += PI/number_of_theta_points) { const unsigned int number_of_phi_points = max(2u, (unsigned int) (PI * sin(theta) / alpha)); for (double phi = 0.0; phi <= PI + epsilon; phi += PI/number_of_phi_points) { JFunction1D_t& f1 = pdf[D_m][cd][theta][phi]; const JArray_t array(D_m, cd, theta, phi); double t_old = transformer.getXn(array, *X.begin()); double y_old = 0.0; for (set::const_iterator x = X.begin(); x != X.end(); ++x) { const double t = transformer.getXn(array, *x); const double y = (pdf_c.*f)(D_m, cd, theta, phi, t); if (y != 0.0) { if (*x < 0.0) { WARNING("dt < 0 " << *x << ' ' << D_m << ' ' << t << ' ' << y << endl); } if (y_old == 0.0) f1[t_old] = y_old; f1[t] = y; } else { if (y_old != 0.0) f1[t] = y; } t_old = t; y_old = y; } } } } } pdf.transform(transformer); pdf.compile(); NOTICE("OK" << endl); try { NOTICE("storing output to file " << outputFile << "... " << flush); pdf.store(outputFile.c_str()); NOTICE("OK" << endl); } catch(const JException& error) { FATAL(error.what() << endl); } }