200 string fileDescriptor;
227 JParser<> zap(
"Main program to simulate detector response to muons and showers.");
230 zap[
'F'] =
make_field(fileDescriptor,
"file name descriptor for CDF tables");
233 zap[
'n'] =
make_field(numberOfEvents) = JLimit::max();
235 zap[
's'] =
make_field(writeEMShowers,
"store generated EM showers in event");
236 zap[
'k'] =
make_field(keep,
"keep position of tracks");
237 zap[
'N'] =
make_field(numberOfHits,
"minimum number of hits to output event") = 1;
238 zap[
'U'] =
make_field(factor,
"scaling factor applied to light yields") = 1.0;
244 catch(
const exception &error) {
245 FATAL(error.what() << endl);
249 gRandom->SetSeed(seed);
252 const JMeta meta(argc, argv);
254 const double Zbed = 0.0;
268 double maximal_road_width = 0.0;
269 double maximal_distance = 0.0;
271 for (
size_t i = 0; i != CDF.size(); ++i) {
273 DEBUG(
"Range CDF["<< CDF[i].type <<
"] " << CDF[i].
function.intensity.getXmax() <<
" m" << endl);
275 maximal_road_width = max(maximal_road_width, CDF[i].
function.intensity.getXmax());
278 for (
size_t i = 0; i != CDG.size(); ++i) {
280 DEBUG(
"Range CDG["<< CDG[i].type <<
"] " << CDG[i].
function.intensity.getXmax() <<
" m" << endl);
283 maximal_road_width = max(maximal_road_width, CDG[i].
function.intensity.getXmax());
286 maximal_distance = max(maximal_distance, CDG[i].
function.intensity.getXmax());
289 NOTICE(
"Maximal road width [m] " << maximal_road_width << endl);
290 NOTICE(
"Maximal distance [m] " << maximal_distance << endl);
293 if (detectorFile ==
"" || inputFile.empty()) {
294 STATUS(
"Nothing to be done." << endl);
302 STATUS(
"Load detector... " << flush);
314 for (JDetector::iterator module =
detector.begin(); module !=
detector.end(); ) {
315 if (!module->empty())
326 STATUS(
"Setting up radiation tables... " << flush);
330 const JRadiation hydrogen ( 1.0, 1.0, 40, 0.01, 0.1, 0.1);
331 const JRadiation oxygen ( 8.0, 16.0, 40, 0.01, 0.1, 0.1);
332 const JRadiation chlorine (17.0, 35.5, 40, 0.01, 0.1, 0.1);
333 const JRadiation sodium (11.0, 23.0, 40, 0.01, 0.1, 0.1);
400 header = inputFile.getHeader();
402 JHead buffer(header);
404 center = get<Vec>(buffer);
410 buffer.simul.rbegin()->date =
getDate();
411 buffer.simul.rbegin()->time =
getTime();
416 buffer.detector.rbegin()->filename = detectorFile;
418 buffer.push(&JHead::simul);
424 buffer.can.zmin += center.z;
425 buffer.can.zmax += center.z;
427 buffer.push(&JHead::coord_origin);
428 buffer.push(&JHead::can);
433 center +=
Vec(circle.getX(), circle.getY(), 0.0);
435 copy(buffer, header);
442 NOTICE(
"Offset applied to true tracks is: " << center << endl);
444 NOTICE(
"No offset applied to true tracks." << endl);
450 if (cylinder.getZmin() < Zbed) {
451 cylinder.setZmin(Zbed);
454 NOTICE(
"Light generation volume: " << cylinder << endl);
456 TH1D job(
"job", NULL, 400, 0.5, 400.5);
457 TProfile cpu(
"cpu", NULL, 16, 0.0, 8.0);
458 TProfile2D rms(
"rms", NULL, 16, 0.0, 8.0, 201, -0.5, 200.5);
459 TProfile2D rad(
"rad", NULL, 16, 0.0, 8.0, 201, -0.5, 200.5);
477 STATUS(
"event: " << setw(10) <<
in.getCounter() <<
'\r');
DEBUG(endl);
481 Evt* evt =
in.next();
485 track->pos += center;
491 event.mc_hits.clear();
500 if (!track->is_finalstate()) {
516 double Zmin = intersection.first;
517 double Zmax = intersection.second;
523 JVertex vertex(0.0, track->t, track->E);
525 if (track->pos.z < Zbed) {
527 if (track->dir.z > 0.0)
528 vertex.step(
gRock, (Zbed - track->pos.z) / track->dir.z);
533 if (vertex.getZ() < Zmin) {
534 vertex.step(
gWater, Zmin - vertex.getZ());
543 const JDetectorSubset_t subdetector(
detector,
getAxis(*track), maximal_road_width);
545 if (subdetector.empty()) {
553 while (vertex.getE() >=
parameters.Emin_GeV && vertex.getZ() < Zmax) {
555 const int N = radiation.size();
560 for (
int i = 0; i !=
N; ++i) {
561 ls += li[i] = radiation[i]->getInverseInteractionLength(vertex.getE());
566 for (
size_t i = 0; i != ionization.size(); ++i) {
567 As += ionization[i]->getA(vertex.getE());
570 double step = gRandom->Exp(1.0) / ls;
571 double range = vertex.getRange(As);
579 double ts =
getThetaMCS(vertex.getE(), min(step,range));
582 rms.Fill(
log10(vertex.getE()), (Double_t) 0, ts*ts);
584 vertex.getDirection() += getRandomDirection(T2/3.0);
586 vertex.step(As, min(step,range));
594 double y = gRandom->Uniform(ls);
596 for (
int i = 0; i !=
N; ++i) {
602 Es = radiation[i]->getEnergyOfShower(vertex.getE());
603 ts = radiation[i]->getThetaRMS(vertex.getE(), Es);
607 rms.Fill(
log10(vertex.getE()), (Double_t) radiation[i]->getID(), ts*ts);
608 rad.Fill(
log10(vertex.getE()), (Double_t) radiation[i]->getID(), Es);
616 vertex.applyEloss(getRandomDirection(T2), Es);
618 muon.push_back(vertex);
623 if (vertex.getZ() < Zmax && vertex.getRange() > 0.0) {
625 vertex.step(vertex.getRange());
627 muon.push_back(vertex);
636 if (trk != event.mc_trks.end()) {
637 trk->len = (muon.rbegin()->getZ() < Zmax ? +1 : -1) * (muon.rbegin()->getZ() - muon.begin()->getZ());
641 for (JDetector::const_iterator module = subdetector.begin(); module != subdetector.end(); ++module) {
643 const double z0 = muon.begin()->getZ();
644 const double t0 = muon.begin()->getT();
645 const double Z = module->getZ() - module->getX() /
getTanThetaC();
647 if (Z >= muon.begin()->getZ() && Z <= muon.rbegin()->getZ()) {
649 const JVector2D pos = muon.getPosition(Z);
650 const double R = hypot(module->getX() - pos.
getX(),
651 module->getY() - pos.
getY());
653 for (
size_t i = 0; i != CDF.size(); ++i) {
655 if (R < CDF[i].integral.getXmax()) {
665 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
666 const int N = gRandom->Poisson(NPE);
672 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
674 const double R = hypot(pmt->getX() - pos.
getX(),
675 pmt->getY() - pos.
getY());
676 const double Z = pmt->getZ() - z0;
677 const double theta = pmt->getTheta();
678 const double phi = fabs(pmt->getPhi());
680 const double npe = CDF[i].function.getNPE(R, theta, phi) * factor * W;
686 job.Fill((
double) (100 + CDF[i].type), (
double) n0);
690 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
693 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
705 job.Fill((
double) (300 + CDF[i].type));
709 catch(
const exception& error) {
710 job.Fill((
double) (200 + CDF[i].type));
717 for (JTrack::const_iterator vertex = muon.begin(); vertex != muon.end(); ++vertex) {
719 const double Es = vertex->getEs();
723 const double z0 = vertex->getZ();
724 const double t0 = vertex->getT();
727 int origin = track->id;
729 if (writeEMShowers) {
730 origin =
event.mc_trks.size() + 1;
733 int number_of_hits = 0;
735 JDetectorSubset_t::range_type range = subdetector.getRange(z0 - maximal_distance,
736 z0 + maximal_distance);
738 for (JDetector::const_iterator module = range.begin(); module != range.end(); ++module) {
740 const double R = hypot(module->getX() - vertex->getX(),
741 module->getY() - vertex->getY());
742 const double Z = module->getZ() - z0 -
DZ;
743 const double D = sqrt(R*R + Z*Z);
744 const double cd = Z /
D;
746 for (
size_t i = 0; i != CDG.size(); ++i) {
748 if (D < CDG[i].integral.getXmax()) {
752 const double NPE = CDG[i].integral.getNPE(D, cd) * Es * module->size() * factor;
753 const int N = gRandom->Poisson(NPE);
759 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
761 const double R = hypot(pmt->getX() - vertex->getX(),
762 pmt->getY() - vertex->getY());
763 const double Z = pmt->getZ() - z0 -
DZ;
764 const double D = sqrt(R*R + Z*Z);
765 const double cd = Z /
D;
766 const double theta = pmt->getTheta();
767 const double phi = fabs(pmt->getPhi());
769 const double npe = CDG[i].function.getNPE(D, cd, theta, phi) * Es * factor;
775 job.Fill((
double) (100 + CDG[i].type), (
double) n0);
780 const double Z = pmt->getZ() - z0 - dz;
781 const double D = sqrt(R*R + Z*Z);
782 const double cd = Z /
D;
784 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
787 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
796 number_of_hits += n1;
801 job.Fill((
double) (300 + CDG[i].type));
805 catch(
const exception& error) {
806 job.Fill((
double) (200 + CDG[i].type));
812 if (writeEMShowers && number_of_hits != 0) {
814 event.mc_trks.push_back(
JTrk_t(origin,
817 track->pos + track->dir * vertex->getZ(),
825 }
else if (track->len > 0.0) {
833 const double z0 = 0.0;
834 const double z1 = z0 + track->len;
835 const double t0 = track->t;
836 const double E = track->E;
842 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
846 const double R = pos.
getX();
851 R > maximal_road_width) {
855 for (
size_t i = 0; i != CDF.size(); ++i) {
867 if (R < CDF[i].integral.getXmax()) {
871 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
872 const int N = gRandom->Poisson(NPE);
882 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
884 const double R = pmt->getX();
885 const double Z = pmt->getZ() - z0;
886 const double theta = pmt->getTheta();
887 const double phi = fabs(pmt->getPhi());
889 const double npe = CDF[i].function.getNPE(R, theta, phi) * factor * W;
895 job.Fill((
double) (120 + CDF[i].type), (
double) n0);
899 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
902 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
914 job.Fill((
double) (320 + CDF[i].type));
918 catch(
const exception& error) {
919 job.Fill((
double) (220 + CDF[i].type));
926 if (!buffer.empty()) {
945 catch(
const exception& error) {
946 ERROR(error.what() << endl);
949 E =
pythia(track->type, E);
953 const double z0 = 0.0;
954 const double t0 = track->t;
961 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
965 const double R = pos.
getX();
966 const double Z = pos.
getZ() - z0 -
DZ;
967 const double D = sqrt(R*R + Z*Z);
968 const double cd = Z /
D;
970 for (
size_t i = 0; i != CDG.size(); ++i) {
972 if (D < CDG[i].integral.getXmax()) {
976 const double NPE = CDG[i].integral.getNPE(D, cd) * E * module->size() * factor;
977 const int N = gRandom->Poisson(NPE);
987 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
989 const double R = pmt->getX();
990 const double Z = pmt->getZ() - z0 -
DZ;
991 const double D = sqrt(R*R + Z*Z);
992 const double cd = Z /
D;
993 const double theta = pmt->getTheta();
994 const double phi = fabs(pmt->getPhi());
996 const double npe = CDG[i].function.getNPE(D, cd, theta, phi) * E * factor;
1002 job.Fill((
double) (140 + CDG[i].type), (
double) n0);
1007 const double Z = pmt->getZ() - z0 - dz;
1008 const double D = sqrt(R*R + Z*Z);
1009 const double cd = Z /
D;
1011 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
1014 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
1026 job.Fill((
double) (340 + CDG[i].type));
1030 catch(
const exception& error) {
1031 job.Fill((
double) (240 + CDG[i].type));
1037 if (!buffer.empty()) {
1048 if (!mc_hits.empty()) {
1052 event.mc_hits.resize(mc_hits.size());
1054 copy(mc_hits.begin(), mc_hits.end(),
event.mc_hits.begin());
1063 if (event.mc_hits.size() >= numberOfHits) {
const char *const energy_lost_in_can
Data structure for vector in two dimensions.
Utility class to parse command line options.
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 JRadiationSource_t EErad_t
Data structure for a composite optical module.
void merge(const double Tmax_ns)
Merge hits on same PMT that are within given time window.
Auxiliary class to set-up Trk.
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.
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.
Implementation for calculation of ionization constant.
JHitType_t getHitType(const JPDFType_t pdf, const bool shower=false)
Get hit type corresponding to given PDF type.
Auxiliary class for PMT parameters including threshold.
double getDeltaRaysFromTau(const double E)
Equivalent EM-shower energy due to delta-rays per unit tau track length.
Utility class to parse parameter values.
then JShowerPostfit f $INPUT_FILE o $OUTPUT_FILE N
static const double H
Planck constant [eV s].
*fatal Wrong number of arguments esac JCookie sh typeset Z DETECTOR typeset Z SOURCE_RUN typeset Z TARGET_RUN set_variable PARAMETERS_FILE $WORKDIR parameters
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 const double DENSITY_SEA_WATER
Fixed environment values.
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.
double getY() const
Get y position.
static const char *const APPLICATION_JSIRENE
detector simulation
Fast implementation of class JRadiation.
Implementation for calculation of inverse interaction length and shower energy.
Auxiliary data structure for list of hits with hit merging capability.
bool is_neutrino(const Trk &track)
Test whether given track is a neutrino.
static const double C
Physics constants.
scattered light from muon
Auxiliary class for defining the range of iterations of objects.
double getThetaMCS(const double E, const double x, const double X0, const double M, const double Q)
Get multiple Coulomb scattering angle.
Implementation for calculation of inverse interaction length and shower energy due to deep-inelastic ...
The Vec class is a straightforward 3-d vector, which also works in pyroot.
std::string getGITVersion(const std::string &tag)
Get GIT version for given GIT tag.
Auxiliary class for the calculation of the muon radiative cross sections.
T & getInstance(const T &object)
Get static instance from temporary object.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
set_variable E_E log10(E_{fit}/E_{#mu})"
static const JGeanz geanz(1.85, 0.62, 0.54)
Function object for longitudinal EM-shower profile.
double getX() const
Get x position.
JAxis3D getAxis(const Trk &track)
Get axis.
Auxiliary class for CPU timing and usage.
JPosition3D getPosition(const Vec &pos)
Get position.
scattered light from delta-rays
direct light from EM shower
void addMargin(const double D)
Add (safety) margin.
static const JRadiationSource_t Brems_t
double getKineticEnergy(const double E, const double m)
Get kinetic energy of particle with given mass.
const char * getDate(const JDateAndTimeFormat option=ISO8601)
Get ASCII formatted date.
then usage $script[distance] fi case set_variable R
Detector subset with binary search functionality.
Detector subset without binary search functionality.
Vertex of energy loss of muon.
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
direct light from delta-rays
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
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.
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&)).
then usage $script< input_file >< detector_file > fi set_variable OUTPUT_DIR set_variable SELECTOR JDAQTimesliceL1 set_variable DEBUG case set_variable DEBUG
bool is_deltarays(const int pdf)
Test if given PDF type corresponds to Cherenkov light from delta-rays.
Auxiliary class to set-up Hit.
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.
double getTanThetaC()
Get average tangent of Cherenkov angle of water corresponding to group velocity.
do set_variable MODULE getModule a $WORKDIR detector_a datx L $STRING JEditDetector a $WORKDIR detector_a datx M $MODULE setz o $WORKDIR detector_a datx JEditDetector a $WORKDIR detector_b datx M $MODULE setz o $WORKDIR detector_b datx done echo Output stored at $WORKDIR detector_a datx and $WORKDIR tripod_a txt JDrawDetector2D a $WORKDIR detector_a datx a $WORKDIR detector_b datx L BL o detector $FORMAT $BATCH JDrawDetector2D T $WORKDIR tripod_a txt T $WORKDIR tripod_b txt L BL o tripod $FORMAT $BATCH JCompareDetector a $WORKDIR detector_a datx b $WORKDIR detector_b datx o $WORKDIR abc root &dev null for KEY in X Y Z
Data structure for position in three dimensions.
const JLimit & getLimit() const
Get limit.
double getLength(const double E, const double P, const double eps=1.0e-3) const
Get shower length for a given integrated probability.
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
bool is_tau(const Trk &track)
Test whether given track is a (anti-)tau.
static const JRadiationSource_t GNrad_t
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 CHECK_EXIT_CODE typeset A TRIPODS get_tripods $WORKDIR tripod txt TRIPODS for EMITTER in
do echo Generating $dir eval D
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.
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.