13 #include "TProfile2D.h"
98 template<
class function_type,
107 JCDFHelper(
const std::string& file_descriptor,
const JPDFType_t type)
113 const string file_name =
getFilename(file_descriptor, this->type);
115 STATUS(
"loading input from file " << file_name <<
"... " << flush);
118 function.load(file_name.c_str());
130 function_type
function;
131 integral_type integral;
135 typedef JCDFHelper<JCDF4D_t, JCDF1D_t> JCDF_t;
136 typedef JCDFHelper<JCDF5D_t, JCDF2D_t> JCDG_t;
145 inline JVersor3Z getRandomDirection(
const double t2)
147 const double tv = sqrt(gRandom->Exp(1.0) * t2);
148 const double phi = gRandom->Uniform(-
PI, +
PI);
150 return JVersor3Z(tv*cos(phi), tv*sin(phi));
160 inline size_t getPoisson(
const double x)
164 if (
x < numeric_limits<int32_t>::max())
165 return (
size_t) gRandom->Poisson(
x);
167 return (
size_t) gRandom->Gaus(
x, sqrt(
x));
215 int main(
int argc,
char **argv)
220 string fileDescriptor;
223 JLimit_t& numberOfEvents = inputFile.getLimit();
247 JParser<> zap(
"Main program to simulate detector response to muons and showers.");
250 zap[
'F'] =
make_field(fileDescriptor,
"file name descriptor for CDF tables");
255 zap[
's'] =
make_field(writeEMShowers,
"store generated EM showers in event");
256 zap[
'N'] =
make_field(numberOfHits,
"minimum number of hits to output event") = 1;
257 zap[
'U'] =
make_field(factor,
"scaling factor applied to light yields") = 1.0;
263 catch(
const exception &error) {
264 FATAL(error.what() << endl);
268 gRandom->SetSeed(seed);
271 const JMeta meta(argc, argv);
273 const double Zbed = 0.0;
287 double maximal_road_width = 0.0;
288 double maximal_distance = 0.0;
290 for (
size_t i = 0; i != CDF.size(); ++i) {
292 DEBUG(
"Range CDF["<< CDF[i].type <<
"] " << CDF[i].
function.intensity.getXmax() <<
" m" << endl);
294 maximal_road_width = max(maximal_road_width, CDF[i].
function.intensity.getXmax());
297 for (
size_t i = 0; i != CDG.size(); ++i) {
299 DEBUG(
"Range CDG["<< CDG[i].type <<
"] " << CDG[i].
function.intensity.getXmax() <<
" m" << endl);
302 maximal_road_width = max(maximal_road_width, CDG[i].
function.intensity.getXmax());
305 maximal_distance = max(maximal_distance, CDG[i].
function.intensity.getXmax());
308 NOTICE(
"Maximal road width [m] " << maximal_road_width << endl);
309 NOTICE(
"Maximal distance [m] " << maximal_distance << endl);
312 if (detectorFile ==
"" || inputFile.empty()) {
313 STATUS(
"Nothing to be done." << endl);
321 STATUS(
"Load detector... " << flush);
333 for (JDetector::iterator module =
detector.begin(); module !=
detector.end(); ) {
334 if (!module->empty())
345 STATUS(
"Setting up radiation tables... " << flush);
347 const JRadiation hydrogen ( 1.0, 1.0, 40, 0.01, 0.1, 0.1);
348 const JRadiation oxygen ( 8.0, 16.0, 40, 0.01, 0.1, 0.1);
349 const JRadiation chlorine (17.0, 35.5, 40, 0.01, 0.1, 0.1);
350 const JRadiation sodium (11.0, 23.0, 40, 0.01, 0.1, 0.1);
352 const JRadiation calcium (20.0, 40.0, 40, 0.01, 0.1, 0.1);
353 const JRadiation magnesium(12.0, 24.3, 40, 0.01, 0.1, 0.1);
354 const JRadiation potassium(19.0, 39.0, 40, 0.01, 0.1, 0.1);
355 const JRadiation sulphur (16.0, 32.0, 40, 0.01, 0.1, 0.1);
423 if (cylinder.
getZmin() < Zbed) {
427 NOTICE(
"Light generation volume: " << cylinder << endl);
435 header = inputFile.getHeader();
437 JHead buffer(header);
451 buffer.
detector.rbegin()->filename = detectorFile;
455 offset +=
Vec(cylinder.
getX(), cylinder.
getY(), 0.0);
492 copy(buffer, header);
498 NOTICE(
"Offset applied to true tracks is: " << offset << endl);
500 TH1D job(
"job", NULL, 400, 0.5, 400.5);
501 TProfile cpu(
"cpu", NULL, 16, 0.0, 8.0);
502 TProfile2D rms(
"rms", NULL, 16, 0.0, 8.0, 201, -0.5, 200.5);
503 TProfile2D rad(
"rad", NULL, 16, 0.0, 8.0, 201, -0.5, 200.5);
523 STATUS(
"event: " << setw(10) << in.getCounter() <<
'\r');
DEBUG(endl);
527 Evt* evt = in.next();
530 track->pos += offset;
535 event.mc_hits.clear();
544 if (!track->is_finalstate()) {
560 double Zmin = intersection.first;
561 double Zmax = intersection.second;
563 if (Zmax - Zmin <= parameters.Dmin_m) {
567 JVertex vertex(0.0, track->t, track->E);
569 if (track->pos.z < Zbed) {
571 if (track->dir.z > 0.0)
572 vertex.
step(
gRock, (Zbed - track->pos.z) / track->dir.z);
577 if (vertex.
getZ() < Zmin) {
581 if (vertex.
getRange() <= parameters.Dmin_m) {
589 if (subdetector.empty()) {
597 while (vertex.
getE() >= parameters.Emin_GeV && vertex.
getZ() < Zmax) {
599 const int N = radiation.size();
604 for (
int i = 0; i != N; ++i) {
605 ls += li[i] = radiation[i]->getInverseInteractionLength(vertex.
getE());
610 for (
size_t i = 0; i != ionization.size(); ++i) {
611 As += ionization[i]->getA(vertex.
getE());
614 double step = gRandom->Exp(1.0) /
ls;
617 if (vertex.
getE() < parameters.Emax_GeV) {
618 if (parameters.Dmax_m < range) {
619 range = parameters.Dmax_m;
626 rms.Fill(log10(vertex.
getE()), (Double_t) 0, ts*ts);
630 vertex.
step(As, min(step,range));
636 if (vertex.
getE() >= parameters.Emin_GeV) {
638 double y = gRandom->Uniform(
ls);
640 for (
int i = 0; i != N; ++i) {
646 Es = radiation[i]->getEnergyOfShower(vertex.
getE());
647 ts = radiation[i]->getThetaRMS(vertex.
getE(), Es);
651 rms.Fill(log10(vertex.
getE()), (Double_t) radiation[i]->getID(), ts*ts);
652 rad.Fill(log10(vertex.
getE()), (Double_t) radiation[i]->getID(), Es);
660 vertex.
applyEloss(getRandomDirection(T2), Es);
662 muon.push_back(vertex);
671 muon.push_back(vertex);
680 if (trk != event.
mc_trks.end()) {
681 trk->len = (muon.rbegin()->getZ() < Zmax ? +1 : -1) * (muon.rbegin()->getZ() - muon.begin()->getZ());
685 for (JDetector::const_iterator module = subdetector.begin(); module != subdetector.end(); ++module) {
687 const double z0 = muon.begin()->getZ();
688 const double t0 = muon.begin()->getT();
689 const double Z = module->getZ() - module->getX() /
getTanThetaC();
691 if (Z >= muon.begin()->getZ() && Z <= muon.rbegin()->getZ()) {
694 const double R = hypot(module->getX() - pos.
getX(),
695 module->getY() - pos.
getY());
697 for (
size_t i = 0; i != CDF.size(); ++i) {
699 if (R < CDF[i].integral.getXmax()) {
709 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
710 const size_t N = getPoisson(NPE);
716 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
718 const double R = hypot(pmt->getX() - pos.
getX(),
719 pmt->getY() - pos.
getY());
720 const double theta = pi.
constrain(pmt->getTheta());
721 const double phi = pi.
constrain(fabs(pmt->getPhi()));
723 npe.push_back(CDF[i].
function.
getNPE(R, theta, phi) * factor * W);
728 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
730 const double R = hypot(pmt->getX() - pos.
getX(),
731 pmt->getY() - pos.
getY());
732 const double Z = pmt->getZ() - z0;
733 const double theta = pi.
constrain(pmt->getTheta());
734 const double phi = pi.
constrain(fabs(pmt->getPhi()));
736 size_t n0 = min(
ns[
distance(module->begin(),pmt)], parameters.Nmax_PMT);
738 job.Fill((
double) (100 + CDF[i].type), (
double) n0);
742 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
745 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
757 job.Fill((
double) (300 + CDF[i].type));
761 catch(
const exception& error) {
762 job.Fill((
double) (200 + CDF[i].type));
769 for (JTrack::const_iterator vertex = muon.begin(); vertex != muon.end(); ++vertex) {
771 const double Es = vertex->
getEs();
773 if (Es >= parameters.Ecut_GeV) {
775 const double z0 = vertex->
getZ();
776 const double t0 = vertex->
getT();
781 if (writeEMShowers) {
782 origin =
event.mc_trks.size() + 1;
785 int number_of_hits = 0;
788 z0 + maximal_distance);
790 for (JDetector::const_iterator module = range.begin(); module != range.end(); ++module) {
792 const double R = hypot(module->getX() - vertex->
getX(),
793 module->getY() - vertex->
getY());
794 const double Z = module->getZ() - z0 - DZ;
795 const double D = sqrt(R*R + Z*Z);
796 const double cd = Z / D;
798 for (
size_t i = 0; i != CDG.size(); ++i) {
800 if (D < CDG[i].integral.getXmax()) {
804 const double NPE = CDG[i].integral.getNPE(D, cd) * Es * module->size() * factor;
805 const size_t N = getPoisson(NPE);
811 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
813 const double R = hypot(pmt->getX() - vertex->
getX(),
814 pmt->getY() - vertex->
getY());
815 const double Z = pmt->getZ() - z0 - DZ;
816 const double D = sqrt(R*R + Z*Z);
817 const double cd = Z / D;
818 const double theta = pi.
constrain(pmt->getTheta());
819 const double phi = pi.
constrain(fabs(pmt->getPhi()));
821 npe.push_back(CDG[i].
function.
getNPE(D, cd, theta, phi) * Es * factor);
826 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
828 const double R = hypot(pmt->getX() - vertex->
getX(),
829 pmt->getY() - vertex->
getY());
830 const double theta = pi.
constrain(pmt->getTheta());
831 const double phi = pi.
constrain(fabs(pmt->getPhi()));
833 size_t n0 = min(
ns[
distance(module->begin(),pmt)], parameters.Nmax_PMT);
835 job.Fill((
double) (100 + CDG[i].type), (
double) n0);
840 const double Z = pmt->getZ() - z0 - dz;
841 const double D = sqrt(R*R + Z*Z);
842 const double cd = Z / D;
844 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
847 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
856 number_of_hits += n1;
861 job.Fill((
double) (300 + CDG[i].type));
865 catch(
const exception& error) {
866 job.Fill((
double) (200 + CDG[i].type));
872 if (writeEMShowers && number_of_hits != 0) {
877 track->pos + track->dir * vertex->
getZ(),
885 }
else if (track->len > 0.0) {
893 const double z0 = 0.0;
894 const double z1 = z0 + track->len;
895 const double t0 = track->t;
896 const double E = track->E;
902 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
906 const double R = pos.
getX();
911 R > maximal_road_width) {
915 for (
size_t i = 0; i != CDF.size(); ++i) {
927 if (R < CDF[i].integral.getXmax()) {
931 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
932 const size_t N = getPoisson(NPE);
942 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
944 const double R = pmt->getX();
945 const double theta = pi.
constrain(pmt->getTheta());
946 const double phi = pi.
constrain(fabs(pmt->getPhi()));
948 npe.push_back(CDF[i].
function.
getNPE(R, theta, phi) * factor * W);
953 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
955 const double R = pmt->getX();
956 const double Z = pmt->getZ() - z0;
957 const double theta = pi.
constrain(pmt->getTheta());
958 const double phi = pi.
constrain(fabs(pmt->getPhi()));
960 size_t n0 = min(
ns[
distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
962 job.Fill((
double) (120 + CDF[i].type), (
double) n0);
966 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
969 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
981 job.Fill((
double) (320 + CDF[i].type));
985 catch(
const exception& error) {
986 job.Fill((
double) (220 + CDF[i].type));
992 if (!buffer.empty()) {
1006 double E = track->E;
1011 catch(
const exception& error) {
1012 ERROR(error.what() << endl);
1015 E =
pythia(track->type, E);
1019 const double z0 = 0.0;
1020 const double t0 = track->t;
1027 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
1031 const double R = pos.
getX();
1032 const double Z = pos.
getZ() - z0 - DZ;
1033 const double D = sqrt(R*R + Z*Z);
1034 const double cd = Z / D;
1036 for (
size_t i = 0; i != CDG.size(); ++i) {
1038 if (D < CDG[i].integral.getXmax()) {
1042 const double NPE = CDG[i].integral.getNPE(D, cd) * E * module->size() * factor;
1043 const size_t N = getPoisson(NPE);
1053 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1055 const double R = pmt->getX();
1056 const double Z = pmt->getZ() - z0 - DZ;
1057 const double D = sqrt(R*R + Z*Z);
1058 const double cd = Z / D;
1059 const double theta = pi.
constrain(pmt->getTheta());
1060 const double phi = pi.
constrain(fabs(pmt->getPhi()));
1062 npe.push_back(CDG[i].
function.
getNPE(D, cd, theta, phi) * E * factor);
1067 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1069 const double theta = pi.
constrain(pmt->getTheta());
1070 const double phi = pi.
constrain(fabs(pmt->getPhi()));
1072 size_t n0 = min(
ns[
distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
1074 job.Fill((
double) (140 + CDG[i].type), (
double) n0);
1079 const double Z = pmt->getZ() - z0 - dz;
1080 const double D = sqrt(R*R + Z*Z);
1081 const double cd = Z / D;
1083 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
1086 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
1098 job.Fill((
double) (340 + CDG[i].type));
1102 catch(
const exception& error) {
1103 job.Fill((
double) (240 + CDG[i].type));
1109 if (!buffer.empty()) {
1120 if (!mc_hits.empty()) {
1122 mc_hits.
merge(parameters.Tmax_ns);
1124 event.mc_hits.resize(mc_hits.size());
1126 copy(mc_hits.begin(), mc_hits.end(), event.
mc_hits.begin());
1135 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.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
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.
Detector subset with 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
double getRadius() const
Get radius.
Data structure for vector in two dimensions.
double getY() const
Get y position.
double getX() const
Get x position.
double getZmin() const
Get minimal z position.
intersection_type getIntersection(const JAxis3D &axis) const
Get intersection points of axis with cylinder.
void setZmin(const double zmin)
Set minimal z position.
void addMargin(const double D)
Add (safety) margin.
double getDistance(const JVector3D &pos) const
Get distance between cylinder wall and given position.
double getZmax() const
Get maximal z position.
Data structure for position in three dimensions.
double getT() const
Get time.
double getY() const
Get y position.
double getZ() const
Get z position.
double getX() const
Get x position.
Data structure for normalised vector in positive z-direction.
const JVersor3Z & getDirection() const
Get direction.
virtual const char * what() const override
Get error message.
Utility class to parse command line options.
Implementation for calculation of ionization constant.
Custom class for CDF table in 1 dimension.
Custom class for CDF table in 2 dimensions.
Multi-dimensional CDF table for arrival time of Cherenkov light.
Implementation for calculation of inverse interaction length and shower energy due to deep-inelastic ...
double getLength(const double E, const double P, const double eps=1.0e-3) const
Get shower length for a given integrated probability.
double getMaximum(const double E) const
Get depth of shower maximum.
Fast implementation of class JRadiation.
Implementation for calculation of inverse interaction length and shower energy.
Auxiliary class for the calculation of the muon radiative cross sections.
static double O()
Estimated mass fractions of chemical elements in sea water.
General purpose class for object reading from a list of file names.
virtual bool hasNext() override
Check availability of next element.
static const uint32_t K[64]
JAxis3D getAxis(const Trk &track)
Get axis.
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
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.
double getTime(const Hit &hit)
Get true time of hit.
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.
double getNPE(const Hit &hit)
Get true charge of hit.
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.
std::string getGITVersion(const std::string &tag)
Get GIT version for given GIT tag.
JPredicate< JResult_t T::*, JComparison::eq > make_predicate(JResult_t T::*member, const JResult_t value)
Helper method to create predicate for data member.
static const double PI
Mathematical constants.
double getDeltaRaysFromMuon(const double E, const JRange< double > T_GeV=JRange< double >(DELTARAY_TMIN, DELTARAY_TMAX))
Equivalent EM-shower energy due to delta-rays per unit muon track length.
bool is_deltarays(const int pdf)
Test if given PDF type corresponds to Cherenkov light from delta-rays.
static const JRadiationSource_t GNrad_t
static const double DENSITY_SEA_WATER
Fixed environment values.
static const JRadiationSource_t Brems_t
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.
static const JGeaneWater gWater
Function object for energy loss of muon in sea water.
double getTanThetaC()
Get average tangent of Cherenkov angle of water corresponding to group velocity.
static const JRadiationSource_t EErad_t
@ SCATTERED_LIGHT_FROM_EMSHOWER
scattered light from EM shower
@ SCATTERED_LIGHT_FROM_DELTARAYS
scattered light from delta-rays
@ SCATTERED_LIGHT_FROM_MUON
scattered light from muon
@ DIRECT_LIGHT_FROM_EMSHOWER
direct light from EM shower
@ DIRECT_LIGHT_FROM_DELTARAYS
direct light from delta-rays
@ DIRECT_LIGHT_FROM_MUON
direct light from muon
double getDeltaRaysFromTau(const double E, const JRange< double > T_GeV=JRange< double >(DELTARAY_TMIN, DELTARAY_TMAX))
Equivalent EM-shower energy due to delta-rays per unit tau track length.
static const double C
Physics constants.
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.
const struct JSIRENE::@64 getNumberOfPhotoElectrons
Auxiliary data structure for determination of number of photo-electrons.
static const JPythia pythia
Function object for relative light yield as a function of GEANT particle code.
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.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
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.
double getE() const
Get muon energy.
double getEs() const
Get shower energy.
JVector2D getPosition(const double z) const
Get muon position at given position along trajectory.
double getE(const double z) const
Get muon energy at given position along trajectory.
Auxiliary class to set-up Trk.
Vertex of energy loss of muon.
double getRange() const
Get visible range of muon using default ionisation energy loss.
JVertex & step(const double ds)
Step using default ionisation energy loss.
void applyEloss(const JVersor3Z &Ts, const double Es)
Apply shower energy loss.
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.