92 template<
class function_type,
101 JCDFHelper(
const std::string& file_descriptor,
const JPDFType_t type)
107 const string file_name =
getFilename(file_descriptor, this->type);
109 STATUS(
"loading input from file " << file_name <<
"... " << flush);
112 function.load(file_name.c_str());
124 function_type
function;
125 integral_type integral;
129 typedef JCDFHelper<JCDF4D_t, JCDF1D_t> JCDF_t;
130 typedef JCDFHelper<JCDF5D_t, JCDF2D_t> JCDG_t;
175 int main(
int argc,
char **argv)
180 string fileDescriptor;
185 double Ecut_GeV = 0.1;
186 double Emin_GeV = 1.0;
188 double Tmax_ns = 0.1;
189 int Nmax_npe = numeric_limits<int>::max();
208 JParser<> zap(
"Main program to simulate detector response to muons and showers.");
211 zap[
'F'] =
make_field(fileDescriptor,
"file name descriptor for CDF tables");
216 zap[
's'] =
make_field(writeEMShowers,
"store generated EM showers in event");
217 zap[
'k'] =
make_field(keep,
"keep position of tracks");
218 zap[
'N'] =
make_field(numberOfHits,
"minimum number of hits to output event") = 1;
219 zap[
'U'] =
make_field(factor,
"scaling factor applied to light yields") = 1.0;
225 catch(
const exception &error) {
226 FATAL(error.what() << endl);
230 gRandom->SetSeed(seed);
233 const JMeta meta(argc, argv);
235 const double Zbed = 0.0;
249 double maximal_road_width = 0.0;
250 double maximal_distance = 0.0;
252 for (
size_t i = 0; i !=
CDF.size(); ++i) {
254 DEBUG(
"Range CDF["<<
CDF[i].type <<
"] " <<
CDF[i].
function.intensity.getXmax() <<
" m" << endl);
256 maximal_road_width = max(maximal_road_width,
CDF[i].
function.intensity.getXmax());
259 for (
size_t i = 0; i != CDG.size(); ++i) {
261 DEBUG(
"Range CDG["<< CDG[i].type <<
"] " << CDG[i].
function.intensity.getXmax() <<
" m" << endl);
264 maximal_road_width = max(maximal_road_width, CDG[i].
function.intensity.getXmax());
267 maximal_distance = max(maximal_distance, CDG[i].
function.intensity.getXmax());
270 NOTICE(
"Maximal road width [m] " << maximal_road_width << endl);
271 NOTICE(
"Maximal distance [m] " << maximal_distance << endl);
274 if (detectorFile ==
"" || inputFile.empty()) {
275 STATUS(
"Nothing to be done." << endl);
283 STATUS(
"Load detector... " << flush);
295 for (JDetector::iterator module =
detector.begin(); module !=
detector.end(); ) {
296 if (!module->empty())
306 STATUS(
"Setting up radiation tables... " << flush);
310 const JRadiation hydrogen ( 1.0, 1.0, 40, 0.01, 0.1, 0.1);
311 const JRadiation oxygen ( 8.0, 16.0, 40, 0.01, 0.1, 0.1);
312 const JRadiation chlorine (17.0, 35.5, 40, 0.01, 0.1, 0.1);
313 const JRadiation sodium (11.0, 23.0, 40, 0.01, 0.1, 0.1);
383 header = inputFile.getHeader();
385 JHead buffer(header);
387 center = get<Vec>(buffer);
399 buffer.
detector.rbegin()->filename = detectorFile;
416 center +=
Vec(circle.getX(), circle.getY(), 0.0);
418 copy(buffer, header);
425 NOTICE(
"Offset applied to true tracks is: " << center << endl);
427 NOTICE(
"No offset applied to true tracks." << endl);
433 if (cylinder.getZmin() < Zbed) {
434 cylinder.setZmin(Zbed);
437 NOTICE(
"Light generation volume: " << cylinder << endl);
439 TProfile cpu(
"cpu", NULL, 14, 1.0, 8.0);
440 TH1D job(
"job", NULL, 400, 0.5, 400.5);
458 STATUS(
"event: " << setw(10) <<
in.getCounter() <<
'\r');
DEBUG(endl);
462 Evt* evt =
in.next();
466 track->pos += center;
472 event.mc_hits.clear();
481 if (!track->is_finalstate())
continue;
495 double Zmin = intersection.first;
496 double Zmax = intersection.second;
498 if (Zmax - Zmin <= Dmin_m) {
502 JVertex vertex(0.0, track->t, track->E);
504 if (track->pos.z < Zbed) {
506 if (track->dir.z > 0.0)
507 vertex.
step(
gRock, (Zbed - track->pos.z) / track->dir.z);
512 if (vertex.
getZ() < Zmin) {
522 const JDetectorSubset_t subdetector(
detector,
getAxis(*track), maximal_road_width);
524 if (subdetector.empty()) {
532 while (vertex.
getE() >= Emin_GeV && vertex.
getZ() < Zmax) {
534 const int Nr = radiation.size();
539 for (
int i = 0; i != Nr; ++i) {
540 ls += li[i] = radiation[i]->getInverseInteractionLength(vertex.
getE());
543 const int Ni = ionization.size();
548 for (
int i = 0; i != Ni; ++i) {
549 As +=Ai[i]= ionization[i]->getA(vertex.
getE());
552 const double ds = min(gRandom->Exp(1.0) / ls, vertex.
getRange(As));
556 if (vertex.
getE() >= Emin_GeV) {
559 double y = gRandom->Uniform(ls);
561 for (
int i = 0; i != Nr; ++i) {
566 Es = radiation[i]->getEnergyOfShower(vertex.
getE());
573 if (Es >= Ecut_GeV) {
574 muon.push_back(vertex);
581 if (vertex.
getE() < Emin_GeV && vertex.
getRange() > 0.0) {
585 muon.push_back(vertex);
594 if (trk != event.
mc_trks.end()) {
595 trk->len = (muon.rbegin()->getZ() < Zmax ? +1 : -1) * (muon.rbegin()->getZ() - muon.begin()->getZ());
599 for (JDetector::const_iterator module = subdetector.begin(); module != subdetector.end(); ++module) {
601 const double z0 = muon.begin()->getZ();
602 const double t0 = muon.begin()->getT();
603 const double R = module->getX();
606 if (Z >= muon.begin()->getZ() && Z <= muon.rbegin()->getZ()) {
608 for (
size_t i = 0; i !=
CDF.size(); ++i) {
610 if (R <
CDF[i].integral.getXmax()) {
620 const double NPE =
CDF[i].integral.getNPE(R) * module->size() * factor * W;
621 const int N = gRandom->Poisson(NPE);
627 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
629 const double R = pmt->getX();
630 const double Z = pmt->getZ() - z0;
631 const double theta = pmt->getTheta();
632 const double phi = fabs(pmt->getPhi());
634 const double npe =
CDF[i].function.getNPE(R, theta, phi) * factor * W;
640 job.Fill((
double) (100 +
CDF[i].type), (
double) n0);
644 const double t1 =
CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
647 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
659 job.Fill((
double) (300 +
CDF[i].type));
663 catch(
const exception& error) {
664 job.Fill((
double) (200 +
CDF[i].type));
671 for (JTrack::const_iterator vertex = muon.begin(); vertex != muon.end(); ++vertex) {
673 const double z0 = vertex->
getZ();
674 const double t0 = vertex->
getT();
675 const double Es = vertex->
getEs();
677 int origin = track->id;
679 if (writeEMShowers) {
680 origin =
event.mc_trks.size() + 1;
683 int number_of_hits = 0;
685 JDetectorSubset_t::range_type
range = subdetector.getRange(z0 - maximal_distance,
686 z0 + maximal_distance);
688 for (JDetector::const_iterator module = range.begin(); module != range.end(); ++module) {
691 const double R = module->getX();
692 const double Z = module->getZ() - z0 - dz;
693 const double D = sqrt(R*R + Z*Z);
694 const double cd = Z /
D;
696 for (
size_t i = 0; i != CDG.size(); ++i) {
698 if (D < CDG[i].integral.getXmax()) {
702 const double NPE = CDG[i].integral.getNPE(D, cd) * Es * module->size() * factor;
703 const int N = gRandom->Poisson(NPE);
709 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
712 const double R = pmt->getX();
713 const double Z = pmt->getZ() - z0 - dz;
714 const double theta = pmt->getTheta();
715 const double phi = fabs(pmt->getPhi());
716 const double D = sqrt(R*R + Z*Z);
717 const double cd = Z /
D;
719 const double npe = CDG[i].function.getNPE(D, cd, theta, phi) * Es * factor;
725 job.Fill((
double) (100 + CDG[i].type), (
double) n0);
730 const double Z = pmt->getZ() - z0 - dz;
731 const double D = sqrt(R*R + Z*Z);
732 const double cd = Z /
D;
734 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
737 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
746 number_of_hits += n1;
751 job.Fill((
double) (300 + CDG[i].type));
755 catch(
const exception& error) {
756 job.Fill((
double) (200 + CDG[i].type));
762 if (writeEMShowers && number_of_hits != 0) {
764 event.mc_trks.push_back(
JTrk_t(origin,
767 track->pos + track->dir * vertex->
getZ(),
774 }
else if (track->len>0) {
782 const double z0 = 0.0;
783 const double z1 = z0 + track->len;
784 const double t0 = track->t;
785 const double E = track->E;
791 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
795 const double R = pos.
getX();
800 R > maximal_road_width) {
804 for (
size_t i = 0; i !=
CDF.size(); ++i) {
813 if (R <
CDF[i].integral.getXmax()) {
817 const double NPE =
CDF[i].integral.getNPE(R) * module->size() * factor * W;
818 const int N = gRandom->Poisson(NPE);
828 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
830 const double R = pmt->getX();
831 const double Z = pmt->getZ() - z0;
832 const double theta = pmt->getTheta();
833 const double phi = fabs(pmt->getPhi());
835 const double npe =
CDF[i].function.getNPE(R, theta, phi) * factor * W;
841 job.Fill((
double) (120 +
CDF[i].type), (
double) n0);
845 const double t1 =
CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
848 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
860 job.Fill((
double) (320 +
CDF[i].type));
864 catch(
const exception& error) {
865 job.Fill((
double) (220 +
CDF[i].type));
872 if (!buffer.empty()) {
891 catch(
const exception& error) {
892 ERROR(error.what() << endl);
895 E =
pythia(track->type, E);
897 if (E < Ecut_GeV || cylinder.getDistance(
getPosition(*track)) > Dmin_m) {
901 const double z0 = 0.0;
902 const double t0 = track->t;
908 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
913 const double R = pos.
getX();
914 const double Z = pos.
getZ() - z0 - dz;
915 const double D = sqrt(R*R + Z*Z);
916 const double cd = Z /
D;
918 if (D > maximal_distance) {
922 for (
size_t i = 0; i != CDG.size(); ++i) {
924 if (D < CDG[i].integral.getXmax()) {
928 const double NPE = CDG[i].integral.getNPE(D, cd) * E * module->size() * factor;
929 const int N = gRandom->Poisson(NPE);
939 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
942 const double R = pmt->getX();
943 const double Z = pmt->getZ() - z0 - dz;
944 const double theta = pmt->getTheta();
945 const double phi = fabs(pmt->getPhi());
946 const double D = sqrt(R*R + Z*Z);
947 const double cd = Z /
D;
949 const double npe = CDG[i].function.getNPE(D, cd, theta, phi) * E * factor;
955 job.Fill((
double) (140 + CDG[i].type), (
double) n0);
960 const double Z = pmt->getZ() - z0 - dz;
961 const double D = sqrt(R*R + Z*Z);
962 const double cd = Z /
D;
964 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
967 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
979 job.Fill((
double) (340 + CDG[i].type));
983 catch(
const exception& error) {
984 job.Fill((
double) (240 + CDG[i].type));
990 if (!buffer.empty()) {
1000 if (!mc_hits.empty()) {
1002 mc_hits.
merge(Tmax_ns);
1004 event.mc_hits.resize(mc_hits.size());
1006 copy(mc_hits.begin(), mc_hits.end(),
event.mc_hits.begin());
1012 cpu.Fill(log10(
get_neutrino(event).
E), (
double) timer.usec_ucpu * 1.0e-3);
1015 if (event.
mc_hits.size() >= numberOfHits) {
Auxiliary class to set-up Hit.
const char *const energy_lost_in_can
Utility class to parse command line options.
Custom class for CDF table in 2 dimensions.
double getEs() const
Get shower energy.
do echo Generating $dir eval D
Multi-dimensional CDF table for arrival time of Cherenkov light.
double getT() const
Get time.
JPredicate< JResult_t T::*, JComparison::eq > make_predicate(JResult_t T::*member, const JResult_t value)
Helper method to create predicate for data member.
ROOT TTree parameter settings of various packages.
JVertex & step(const double ds)
Step.
Data structure for a composite optical module.
void applyEloss(const double Es)
Apply energy loss energy.
JTransformation3D getTransformation(const Trk &track)
Get transformation.
Data structure for circle in two dimensions.
#define gmake_property(A)
macro to convert (template) parameter to JPropertiesElement object
double safetyFactor
safety factor for average CDF integral of optical module
Generator for simulation.
double getIndexOfRefraction()
Get average index of refraction of water corresponding to group velocity.
double EfromBrems(const double E) const
Bremsstrahlung shower energy.
scattered light from EM shower
bool has_neutrino(const Evt &evt)
Test whether given event has an incoming neutrino.
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon.
Recording of objects on file according a format that follows from the file name extension.
JHitType_t getHitType(const JPDFType_t pdf, const bool shower=false)
Get hit type corresponding to given PDF type.
double getDeltaRaysFromTau(const double E)
Equivalent EM-shower energy due to delta-rays per unit tau track length.
Utility class to parse parameter values.
static double O()
Estimated mass fractions of chemical elements in sea water.
double getE() const
Get muon energy.
Jpp environment information.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
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.
static const JGeaneWater gWater
Function object for energy loss of muon in sea water.
static counter_type max()
Get maximum counter value.
void merge(const double Tmax_ns)
Merge hits on same PMT that are within given time window.
static const double DENSITY_SEA_WATER
Fixed environment values.
std::vector< JAANET::simul > simul
static const JPythia pythia
Function object for relative light yield as a function of GEANT particle code.
double getTime(const Hit &hit)
Get true time of hit.
Data structure for detector geometry and calibration.
static const char *const APPLICATION_JSIRENE
detector simulation
Utility class to parse parameter values.
Fast implementation of class JRadiation.
Various implementations of functional maps.
static const JPDB & getInstance()
Get particle data book.
double TotalCrossSectionBrems(const double E) const
Bremsstrahlung cross section.
Numbering scheme for PDF types.
bool is_neutrino(const Trk &track)
Test whether given track is a neutrino.
static const double C
Physics constants.
Auxiliary class to extract a subset of optical modules from a detector.
scattered light from muon
Auxiliary class for defining the range of iterations of objects.
The Vec class is a straightforward 3-d vector, which also works in pyroot.
void push(T JHead::*pd)
Push given data member to Head.
double getZ() const
Get position.
I/O formatting auxiliaries.
std::string getGITVersion(const std::string &tag)
Get GIT version for given GIT tag.
The template JSharedPointer class can be used to share a pointer to an object.
Auxiliary class for the calculation of the muon radiative cross sections.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
static const JGeanz geanz(1.85, 0.62, 0.54)
Function object for longitudinal EM-shower profile.
JAxis3D getAxis(const Trk &track)
Get axis.
double getE(const double z) const
Get muon energy at given position.
Auxiliary class for CPU timing and usage.
JPosition3D getPosition(const Vec &pos)
Get position.
scattered light from delta-rays
direct light from EM shower
Auxiliary data structure for list of hits with hit merging capability.
void addMargin(const double D)
Add (safety) margin.
double EfromGNrad(const double E) const
Photo-nuclear shower energy.
then usage $script[detector file[input file[output file[CDF file descriptor]]]] nNote that if more than one input file is all other arguments must be provided fi case set_variable CDF
double getKineticEnergy(const double E, const double m)
Get kinetic energy of particle with given mass.
then usage $script[distance] fi case set_variable R
General purpose messaging.
Detector subset with binary search functionality.
Detector subset without binary search functionality.
Vertex of energy loss of muon.
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi mv $WORKDIR/fit.root $MODULE_ROOT typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
Scanning of objects from multiple files according a format that follows from the extension of each fi...
Custom class for CDF table in 1 dimension.
direct light from delta-rays
virtual const char * what() const override
Get error message.
std::vector< JAANET::detector > detector
int getNumberOfPhotoElectrons(const double NPE, const int N, const double npe)
Get number of photo-electrons of a hit given the expectation values of the number of photo-electrons ...
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
double getMaximum(const double E) const
Get depth of shower maximum.
General purpose class for object reading from a list of file names.
Utility class to parse command line options.
std::vector< Hit > mc_hits
MC: list of MC truth hits.
bool is_scattered(const int pdf)
Test if given PDF type corresponds to scattered light.
void transform(const JRotation3D &R, const JVector3D &pos)
Transformation of geometry (see method JGEOMETRY3D::JPosition3D::transform(const JRotation3D&, const JVector3D&)).
virtual double TotalCrossSectionEErad(const double E) const
Pair production cross section.
bool is_deltarays(const int pdf)
Test if given PDF type corresponds to Cherenkov light from delta-rays.
double getX() const
Get x position.
double getDeltaRaysFromMuon(const double E)
Equivalent EM-shower energy due to delta-rays per unit muon track length.
void copy(const Head &from, JHead &to)
Copy header from from to to.
Auxiliary data structure to list files in directory.
std::string getFilename(const std::string &file_name)
Get file name part, i.e. part after last JEEP::PATHNAME_SEPARATOR if any.
double getTanThetaC()
Get average tangent of Cherenkov angle of water corresponding to group velocity.
Data structure for position in three dimensions.
const JLimit & getLimit() const
Get limit.
Longitudinal emission profile EM-shower.
virtual double CalculateACoeff(double Energy) const
Ionization a parameter.
double getLength(const double E, const double P, const double eps=1.0e-3) const
Get shower length for a given integrated probability.
double EfromEErad(const double E) const
Pair production shower energy.
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
do set_variable DETECTOR_TXT $WORKDIR detector
bool is_tau(const Trk &track)
Test whether given track is a (anti-)tau.
virtual double TotalCrossSectionGNrad(const double E) const
Photo-nuclear cross section.
double getRange() const
Get range of muon.
JAANET::coord_origin coord_origin
then fatal Wrong number of arguments fi set_variable DETECTOR $argv[1] set_variable INPUT_FILE $argv[2] eval JPrintDetector a $DETECTOR O IDENTIFIER eval JPrintDetector a $DETECTOR O SUMMARY source JAcoustics sh $DETECTOR_ID typeset A TRIPODS get_tripods $WORKDIR tripod txt TRIPODS for EMITTER in
then usage $script[input file[working directory[option]]] nWhere option can be N
Vec coord_origin() const
Get coordinate origin.
int numberOfBins
number of bins for average CDF integral of optical module
double getZ() const
Get z position.
std::vector< Trk > mc_trks
MC: list of MC truth tracks.
Auxiliary class to set-up Trk.
const char * getDate(const JDateAndTimeFormat option=HUMAN_READABLE)
Get ASCII formatted date.
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
then usage $script[input file[working directory[option]]] nWhere option can be E
#define DEBUG(A)
Message macros.
int main(int argc, char *argv[])