14#include "TProfile2D.h"
101 template<
class function_type,
118 STATUS(
"loading input from file " << file_name <<
"... " << flush);
121 function.load(file_name.c_str());
133 function_type function;
150 const double tv = sqrt(
gRandom->Exp(1.0) * t2);
151 const double phi =
gRandom->Uniform(-PI, +PI);
163 inline size_t getPoisson(
const double x)
168 return (
size_t)
gRandom->Poisson(x);
170 return (
size_t)
gRandom->Gaus(x, sqrt(x));
223 string fileDescriptor;
226 JLimit_t& numberOfEvents = inputFile.getLimit();
251 JParser<> zap(
"Main program to simulate detector response to muons and showers.");
254 zap[
'F'] =
make_field(fileDescriptor,
"file name descriptor for CDF tables");
260 zap[
'N'] =
make_field(numberOfHits,
"minimum number of hits to output event") = 1;
261 zap[
'U'] =
make_field(factor,
"scaling factor applied to light yields") = 1.0;
267 catch(
const exception &error) {
277 const double Zbed = 0.0;
282 if (fileDescriptor !=
"") {
283 CDF.push_back(JCDF_t(fileDescriptor, DIRECT_LIGHT_FROM_MUON));
284 CDF.push_back(JCDF_t(fileDescriptor, SCATTERED_LIGHT_FROM_MUON));
285 CDF.push_back(JCDF_t(fileDescriptor, DIRECT_LIGHT_FROM_DELTARAYS));
286 CDF.push_back(JCDF_t(fileDescriptor, SCATTERED_LIGHT_FROM_DELTARAYS));
288 CDG.push_back(
JCDG_t(fileDescriptor, DIRECT_LIGHT_FROM_EMSHOWER));
289 CDG.push_back(
JCDG_t(fileDescriptor, SCATTERED_LIGHT_FROM_EMSHOWER));
295 for (
size_t i = 0; i !=
CDF.size(); ++i) {
297 DEBUG(
"Range CDF["<<
CDF[i].type <<
"] " <<
CDF[i].function.intensity.getXmax() <<
" m" <<
endl);
302 for (
size_t i = 0; i !=
CDG.size(); ++i) {
304 DEBUG(
"Range CDG["<<
CDG[i].type <<
"] " <<
CDG[i].function.intensity.getXmax() <<
" m" <<
endl);
326 STATUS(
"Load detector... " << flush);
338 for (JDetector::iterator
module =
detector.begin();
module != detector.end(); ) {
342 module = detector.erase(module);
350 STATUS(
"Setting up radiation tables... " << flush);
442 header = inputFile.getHeader();
444 JHead buffer(header);
499 copy(buffer, header);
505 NOTICE(
"Offset applied to true tracks is: " << offset <<
endl);
523 const double epsilon = 1.0e-6;
534 Evt* evt = in.next();
537 track->pos += offset;
542 event.mc_hits.clear();
551 if (!
track->is_finalstate()) {
570 if (
Zmax -
Zmin <= parameters.Dmin_m) {
578 if (
track->dir.z > 0.0)
588 if (
vertex.getRange() <= parameters.Dmin_m) {
611 for (
int i = 0; i != N; ++i) {
619 for (
size_t i = 0; i !=
ionization.size(); ++i) {
626 if (
vertex.getE() < parameters.Emax_GeV) {
627 if (parameters.Dmax_m < range) {
628 range = parameters.Dmax_m;
645 if (
vertex.getE() >= parameters.Emin_GeV) {
649 for (
int i = 0; i != N; ++i) {
692 trk->len = (muon.rbegin()->getZ() <
Zmax ? +1 : -1) * (muon.rbegin()->getZ() - muon.begin()->getZ());
698 const double z0 = muon.begin()->getZ();
699 const double t0 = muon.begin()->getT();
700 const double Z =
module->getZ() - module->getX() / getTanThetaC();
702 if (Z >= muon.begin()->getZ() && Z <= muon.rbegin()->getZ()) {
704 const JVector2D pos = muon.getPosition(Z);
708 for (
size_t i = 0; i !=
CDF.size(); ++i) {
710 if (R <
CDF[i].integral.getXmax()) {
720 const double NPE =
CDF[i].integral.getNPE(R) *
module->size() * factor * W;
721 const size_t N = getPoisson(NPE);
727 for (JModule::const_iterator pmt =
module->begin(); pmt !=
module->end(); ++pmt) {
729 const double R =
hypot(pmt->getX() - pos.
getX(),
730 pmt->getY() - pos.
getY());
731 const double theta =
pi.constrain(pmt->getTheta());
732 const double phi =
pi.constrain(fabs(pmt->getPhi()));
734 npe.push_back(
CDF[i].function.getNPE(R, theta, phi) * factor * W);
739 for (JModule::const_iterator pmt =
module->begin(); pmt !=
module->end(); ++pmt) {
741 const double R =
hypot(pmt->getX() - pos.
getX(),
742 pmt->getY() - pos.
getY());
743 const double Z = pmt->getZ() - z0;
744 const double theta =
pi.constrain(pmt->getTheta());
745 const double phi =
pi.constrain(fabs(pmt->getPhi()));
749 job.Fill((
double) (100 +
CDF[i].type), (
double)
n0);
753 const double t1 =
CDF[i].function.getTime(R, theta, phi,
gRandom->Rndm());
756 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
760 t0 + (R * getTanThetaC() + Z) / C + t1,
767 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
768 job.Fill((
double) (300 +
CDF[i].type));
772 catch(
const exception& error) {
773 job.Fill((
double) (200 +
CDF[i].type));
784 if (
Es >= parameters.Ecut_GeV) {
786 const double z0 =
vertex->getZ();
787 const double t0 =
vertex->getT();
790 int origin =
track->id;
793 origin =
event.mc_trks.size() + 1;
801 for (JDetector::const_iterator
module = range.begin();
module != range.end(); ++
module) {
805 const double Z =
module->getZ() - z0 - DZ;
806 const double D = sqrt(R*R + Z*Z);
807 const double cd = Z / D;
809 for (
size_t i = 0; i !=
CDG.size(); ++i) {
811 if (D <
CDG[i].integral.getXmax()) {
815 const double NPE =
CDG[i].integral.getNPE(D,
cd) *
Es *
module->size() * factor;
816 const size_t N = getPoisson(NPE);
822 for (JModule::const_iterator pmt =
module->begin(); pmt !=
module->end(); ++pmt) {
824 const double R =
hypot(pmt->getX() -
vertex->getX(),
825 pmt->getY() -
vertex->getY());
826 const double Z = pmt->getZ() - z0 -
DZ;
827 const double D = sqrt(R*R + Z*Z);
828 const double cd = Z / D;
829 const double theta =
pi.constrain(pmt->getTheta());
830 const double phi =
pi.constrain(fabs(pmt->getPhi()));
832 npe.push_back(
CDG[i].function.getNPE(D,
cd, theta, phi) *
Es * factor);
837 for (JModule::const_iterator pmt =
module->begin(); pmt !=
module->end(); ++pmt) {
839 const double R =
hypot(pmt->getX() -
vertex->getX(),
840 pmt->getY() -
vertex->getY());
841 const double theta =
pi.constrain(pmt->getTheta());
842 const double phi =
pi.constrain(fabs(pmt->getPhi()));
846 job.Fill((
double) (100 +
CDG[i].type), (
double)
n0);
851 const double Z = pmt->getZ() - z0 -
dz;
852 const double D = sqrt(R*R + Z*Z);
853 const double cd = Z / D;
855 const double t1 =
CDG[i].function.getTime(D,
cd, theta, phi,
gRandom->Rndm());
858 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
871 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
872 job.Fill((
double) (300 +
CDG[i].type));
876 catch(
const exception& error) {
877 job.Fill((
double) (200 +
CDG[i].type));
885 event.mc_trks.push_back(
JTrk_t(origin,
896 }
else if (
track->len > 0.0) {
904 const double z0 = 0.0;
905 const double z1 = z0 +
track->len;
906 const double t0 =
track->t;
907 const double E =
track->E;
917 const double R = pos.
getX();
926 for (
size_t i = 0; i !=
CDF.size(); ++i) {
938 if (R <
CDF[i].integral.getXmax()) {
942 const double NPE =
CDF[i].integral.getNPE(R) *
module->size() * factor * W;
943 const size_t N = getPoisson(NPE);
953 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
955 const double R = pmt->getX();
956 const double theta =
pi.constrain(pmt->getTheta());
957 const double phi =
pi.constrain(fabs(pmt->getPhi()));
959 npe.push_back(
CDF[i].function.getNPE(R, theta, phi) * factor * W);
964 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
966 const double R = pmt->getX();
967 const double Z = pmt->getZ() - z0;
968 const double theta =
pi.constrain(pmt->getTheta());
969 const double phi =
pi.constrain(fabs(pmt->getPhi()));
971 size_t n0 = min(ns[
distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
973 job.Fill((
double) (120 +
CDF[i].type), (
double)
n0);
977 const double t1 =
CDF[i].function.getTime(R, theta, phi,
gRandom->Rndm());
980 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
984 t0 + (R * getTanThetaC() + Z) / C + t1,
991 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
992 job.Fill((
double) (320 +
CDF[i].type));
996 catch(
const exception& error) {
997 job.Fill((
double) (220 +
CDF[i].type));
1003 if (!buffer.empty()) {
1017 double E =
track->E;
1022 catch(
const exception& error) {
1030 const double z0 = 0.0;
1031 const double t0 =
track->t;
1032 const double DZ =
geanz.getMaximum(E);
1038 for (JDetector::const_iterator
module =
detector.begin();
module != detector.end(); ++
module) {
1042 const double R = pos.
getX();
1043 const double Z = pos.
getZ() - z0 -
DZ;
1044 const double D = sqrt(R*R + Z*Z);
1045 const double cd = Z / D;
1047 for (
size_t i = 0; i !=
CDG.size(); ++i) {
1049 if (D <
CDG[i].integral.getXmax()) {
1053 const double NPE =
CDG[i].integral.getNPE(D,
cd) * E *
module->size() * factor;
1054 const size_t N = getPoisson(NPE);
1064 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1066 const double R = pmt->getX();
1067 const double Z = pmt->getZ() - z0 -
DZ;
1068 const double D = sqrt(R*R + Z*Z);
1069 const double cd = Z / D;
1070 const double theta =
pi.constrain(pmt->getTheta());
1071 const double phi =
pi.constrain(fabs(pmt->getPhi()));
1073 npe.push_back(
CDG[i].function.getNPE(D,
cd, theta, phi) * E * factor);
1078 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1080 const double theta =
pi.constrain(pmt->getTheta());
1081 const double phi =
pi.constrain(fabs(pmt->getPhi()));
1083 size_t n0 = min(ns[
distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
1085 job.Fill((
double) (140 +
CDG[i].type), (
double)
n0);
1090 const double Z = pmt->getZ() - z0 -
dz;
1091 const double D = sqrt(R*R + Z*Z);
1092 const double cd = Z / D;
1094 const double t1 =
CDG[i].function.getTime(D,
cd, theta, phi,
gRandom->Rndm());
1097 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
1101 t0 + (
dz + D * getIndexOfRefraction()) / C + t1,
1108 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
1109 job.Fill((
double) (340 +
CDG[i].type));
1113 catch(
const exception& error) {
1114 job.Fill((
double) (240 +
CDG[i].type));
1120 if (!buffer.empty()) {
1131 if (!mc_hits.empty()) {
1133 mc_hits.
merge(parameters.Tmax_ns);
1135 event.mc_hits.resize(mc_hits.size());
1137 copy(mc_hits.begin(), mc_hits.end(), event.
mc_hits.begin());
1146 if (event.
mc_hits.size() >= numberOfHits) {
Auxiliary class to extract a subset of optical modules from a detector.
Data structure for detector geometry and calibration.
Recording of objects on file according a format that follows from the file name extension.
Various implementations of functional maps.
Longitudinal emission profile EM-shower.
General purpose messaging.
#define DEBUG(A)
Message macros.
Scanning of objects from multiple files according a format that follows from the extension of each fi...
Numbering scheme for PDF types.
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
I/O formatting auxiliaries.
Utility class to parse parameter values.
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
Muon radiative cross sections.
int numberOfBins
number of bins for average CDF integral of optical module
double safetyFactor
safety factor for average CDF integral of optical module
int main(int argc, char **argv)
ROOT TTree parameter settings of various packages.
Jpp environment information.
static const char *const APPLICATION_JSIRENE
detector simulation
std::vector< JAANET::simul > simul
JAANET::coord_origin coord_origin
void push(T JHead::*pd)
Push given data member to Head.
std::vector< JAANET::detector > detector
JAANET::fixedcan fixedcan
bool is_valid(T JHead::*pd) const
Check validity of given data member in JHead.
Detector subset without binary search functionality.
Data structure for a composite optical module.
void transform(const JRotation3D &R, const JVector3D &pos)
Transformation of geometry (see method JGEOMETRY3D::JPosition3D::transform(const JRotation3D&,...
Utility class to parse parameter values.
Auxiliary class for CPU timing and usage.
unsigned long long usec_ucpu
Data structure for vector in two dimensions.
double getY() const
Get y position.
double getX() const
Get x position.
Data structure for position in three dimensions.
double getZ() const
Get z position.
double getX() const
Get x position.
Data structure for normalised vector in positive z-direction.
virtual const char * what() const override
Get error message.
Template definition of a multi-dimensional oscillation probability interpolation table.
Auxiliary class for the calculation of the muon radiative cross sections.
static constexpr radiation_type GNrad_t
static constexpr radiation_type Brems_t
static constexpr radiation_type EErad_t
JAxis3D getAxis(const Trk &track)
Get axis.
Vec getOrigin(const JHead &header)
Get origin.
double getKineticEnergy(const Trk &trk)
Get track kinetic energy.
JTransformation3D getTransformation(const Trk &track)
Get transformation.
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
bool is_neutrino(const Trk &track)
Test whether given track is a neutrino.
void copy(const Head &from, JHead &to)
Copy header from from to to.
JPosition3D getPosition(const Vec &pos)
Get position.
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon.
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
bool is_tau(const Trk &track)
Test whether given track is a (anti-)tau.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
std::string getFilename(const std::string &file_name)
Get file name part, i.e. part after last JEEP::PATHNAME_SEPARATOR if any.
const char * getGITVersion()
Get GIT version.
bool is_deltarays(const int pdf)
Test if given PDF type corresponds to Cherenkov light from delta-rays.
static const double DENSITY_SEA_WATER
Fixed environment values.
static const JGeanz geanz(1.85, 0.62, 0.54)
Function object for longitudinal EM-shower profile.
double getThetaMCS(const double E, const double x, const double X0, const double M, const double Q)
Get multiple Coulomb scattering angle.
double getIndexOfRefraction()
Get average index of refraction of water corresponding to group velocity.
static const JGeane_t gRock(2.67e-1 *0.9 *DENSITY_ROCK, 3.40e-4 *1.2 *DENSITY_ROCK)
Function object for energy loss of muon in rock.
bool is_scattered(const int pdf)
Test if given PDF type corresponds to scattered light.
double getTanThetaC()
Get average tangent of Cherenkov angle of water corresponding to group velocity.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
JHitType_t getHitType(const JPDFType_t pdf, const bool shower=false)
Get hit type corresponding to given PDF type.
static const JPythia pythia
Function object for relative light yield as a function of GEANT particle code.
const struct JSIRENE::number_of_photo_electrons_type getNumberOfPhotoElectrons
const char * getTime()
Get current local time conform ISO-8601 standard.
const char * getDate()
Get current local date conform ISO-8601 standard.
const char *const energy_lost_in_can
This file contains converted Fortran code from km3.
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
std::vector< Hit > mc_hits
MC: list of MC truth hits.
std::vector< Trk > mc_trks
MC: list of MC truth tracks.
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
static const JPDB & getInstance()
Get particle data book.
double ycenter
y-center [m]
double xcenter
x-center [m]
Generator for simulation.
Auxiliary class for PMT parameters including threshold.
Template definition of random value generator.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
static double getEnergyLossFromMuon(const double E, const JEnergyRange T_GeV=JEnergyRange(TMIN_GEV, TMAX_GEV))
Equivalent EM-shower energy loss due to delta-rays per unit muon track length in sea water.
static double getTmin()
Get minimum delta-ray kinetic energy.
static constexpr double TMAX_GEV
Maximum allowed delta-ray kinetic energy [GeV].
static double getEnergyLossFromTau(const double E, const JEnergyRange T_GeV=JEnergyRange(TMIN_GEV, TMAX_GEV))
Equivalent EM-shower energy loss due to delta-rays per unit tau track length in sea water.
static constexpr atom_type Cl
static constexpr atom_type H
static constexpr atom_type O
static constexpr atom_type Na
Auxiliary class to set-up Hit.
Auxiliary data structure for list of hits with hit merging capability.
void merge(const double Tmax_ns)
Merge hits on same PMT that are within given time window.
Auxiliary class to set-up Trk.
Vertex of energy loss of muon.
Auxiliary class for defining the range of iterations of objects.
static counter_type max()
Get maximum counter value.
Auxiliary data structure to list files in directory.
The Vec class is a straightforward 3-d vector, which also works in pyroot.