200 string fileDescriptor;
228 JParser<> zap(
"Main program to simulate detector response to muons and showers.");
231 zap[
'F'] =
make_field(fileDescriptor,
"file name descriptor for CDF tables");
234 zap[
'n'] =
make_field(numberOfEvents) = JLimit::max();
236 zap[
's'] =
make_field(writeEMShowers,
"store generated EM showers in event");
237 zap[
'k'] =
make_field(keep,
"keep position of tracks");
238 zap[
'N'] =
make_field(numberOfHits,
"minimum number of hits to output event") = 1;
239 zap[
'U'] =
make_field(factor,
"scaling factor applied to light yields") = 1.0;
245 catch(
const exception &error) {
246 FATAL(error.what() << endl);
250 gRandom->SetSeed(seed);
253 const JMeta meta(argc, argv);
255 const double Zbed = 0.0;
269 double maximal_road_width = 0.0;
270 double maximal_distance = 0.0;
272 for (
size_t i = 0;
i != CDF.size(); ++
i) {
274 DEBUG(
"Range CDF["<< CDF[
i].type <<
"] " << CDF[
i].
function.intensity.getXmax() <<
" m" << endl);
276 maximal_road_width = max(maximal_road_width, CDF[
i].
function.intensity.getXmax());
279 for (
size_t i = 0;
i != CDG.size(); ++
i) {
281 DEBUG(
"Range CDG["<< CDG[
i].type <<
"] " << CDG[
i].
function.intensity.getXmax() <<
" m" << endl);
284 maximal_road_width = max(maximal_road_width, CDG[
i].
function.intensity.getXmax());
287 maximal_distance = max(maximal_distance, CDG[
i].
function.intensity.getXmax());
290 NOTICE(
"Maximal road width [m] " << maximal_road_width << endl);
291 NOTICE(
"Maximal distance [m] " << maximal_distance << endl);
294 if (detectorFile ==
"" || inputFile.empty()) {
295 STATUS(
"Nothing to be done." << endl);
303 STATUS(
"Load detector... " << flush);
315 for (JDetector::iterator module =
detector.begin(); module !=
detector.end(); ) {
316 if (!module->empty())
327 STATUS(
"Setting up radiation tables... " << flush);
331 const JRadiation hydrogen ( 1.0, 1.0, 40, 0.01, 0.1, 0.1);
332 const JRadiation oxygen ( 8.0, 16.0, 40, 0.01, 0.1, 0.1);
333 const JRadiation chlorine (17.0, 35.5, 40, 0.01, 0.1, 0.1);
334 const JRadiation sodium (11.0, 23.0, 40, 0.01, 0.1, 0.1);
336 const JRadiation calcium (20.0, 40.0, 40, 0.01, 0.1, 0.1);
337 const JRadiation magnesium(12.0, 24.3, 40, 0.01, 0.1, 0.1);
338 const JRadiation potassium(19.0, 39.0, 40, 0.01, 0.1, 0.1);
339 const JRadiation sulphur (16.0, 32.0, 40, 0.01, 0.1, 0.1);
408 header = inputFile.getHeader();
410 JHead buffer(header);
412 center = get<Vec>(buffer);
418 buffer.simul.rbegin()->date =
getDate();
419 buffer.simul.rbegin()->time =
getTime();
424 buffer.detector.rbegin()->filename = detectorFile;
426 buffer.push(&JHead::simul);
431 if (buffer.is_valid(&JHead::fixedcan)) {
433 buffer.fixedcan.xcenter += center.x;
434 buffer.fixedcan.ycenter += center.y;
435 buffer.fixedcan.zmin += center.z;
436 buffer.fixedcan.zmax += center.z;
438 buffer.push(&JHead::fixedcan);
440 }
else if (buffer.is_valid(&JHead::can)) {
442 buffer.can.zmin += center.z;
443 buffer.can.zmax += center.z;
445 buffer.push(&JHead::can);
450 buffer.push(&JHead::coord_origin);
455 center +=
Vec(circle.getX(), circle.getY(), 0.0);
457 copy(buffer, header);
464 NOTICE(
"Offset applied to true tracks is: " << center << endl);
466 NOTICE(
"No offset applied to true tracks." << endl);
472 if (cylinder.getZmin() < Zbed) {
473 cylinder.setZmin(Zbed);
476 NOTICE(
"Light generation volume: " << cylinder << endl);
478 TH1D job(
"job", NULL, 400, 0.5, 400.5);
479 TProfile cpu(
"cpu", NULL, 16, 0.0, 8.0);
480 TProfile2D rms(
"rms", NULL, 16, 0.0, 8.0, 201, -0.5, 200.5);
481 TProfile2D rad(
"rad", NULL, 16, 0.0, 8.0, 201, -0.5, 200.5);
501 STATUS(
"event: " << setw(10) <<
in.getCounter() <<
'\r');
DEBUG(endl);
505 Evt* evt =
in.next();
509 track->pos += center;
515 event.mc_hits.clear();
524 if (!track->is_finalstate()) {
540 double Zmin = intersection.first;
541 double Zmax = intersection.second;
547 JVertex vertex(0.0, track->t, track->E);
549 if (track->pos.z < Zbed) {
551 if (track->dir.z > 0.0)
552 vertex.step(
gRock, (Zbed - track->pos.z) / track->dir.z);
557 if (vertex.getZ() < Zmin) {
558 vertex.step(
gWater, Zmin - vertex.getZ());
567 const JDetectorSubset_t subdetector(
detector,
getAxis(*track), maximal_road_width);
569 if (subdetector.empty()) {
577 while (vertex.getE() >=
parameters.Emin_GeV && vertex.getZ() < Zmax) {
579 const int N = radiation.size();
584 for (
int i = 0;
i !=
N; ++
i) {
585 ls += li[
i] = radiation[
i]->getInverseInteractionLength(vertex.getE());
590 for (
size_t i = 0;
i != ionization.size(); ++
i) {
591 As += ionization[
i]->getA(vertex.getE());
594 double step = gRandom->Exp(1.0) / ls;
595 double range = vertex.getRange(As);
603 double ts =
getThetaMCS(vertex.getE(), min(step,range));
606 rms.Fill(
log10(vertex.getE()), (Double_t) 0, ts*ts);
608 vertex.getDirection() += getRandomDirection(T2/3.0);
610 vertex.step(As, min(step,range));
618 double y = gRandom->Uniform(ls);
620 for (
int i = 0;
i !=
N; ++
i) {
626 Es = radiation[
i]->getEnergyOfShower(vertex.getE());
627 ts = radiation[
i]->getThetaRMS(vertex.getE(), Es);
631 rms.Fill(
log10(vertex.getE()), (Double_t) radiation[
i]->getID(), ts*ts);
632 rad.Fill(
log10(vertex.getE()), (Double_t) radiation[
i]->getID(), Es);
640 vertex.applyEloss(getRandomDirection(T2), Es);
642 muon.push_back(vertex);
647 if (vertex.getZ() < Zmax && vertex.getRange() > 0.0) {
649 vertex.step(vertex.getRange());
651 muon.push_back(vertex);
660 if (trk != event.mc_trks.end()) {
661 trk->len = (muon.rbegin()->getZ() < Zmax ? +1 : -1) * (muon.rbegin()->getZ() - muon.begin()->getZ());
665 for (JDetector::const_iterator module = subdetector.begin(); module != subdetector.end(); ++module) {
667 const double z0 = muon.begin()->getZ();
668 const double t0 = muon.begin()->getT();
669 const double Z = module->getZ() - module->getX() /
getTanThetaC();
671 if (Z >= muon.begin()->getZ() && Z <= muon.rbegin()->getZ()) {
673 const JVector2D pos = muon.getPosition(Z);
674 const double R = hypot(module->getX() - pos.
getX(),
675 module->getY() - pos.
getY());
677 for (
size_t i = 0;
i != CDF.size(); ++
i) {
679 if (R < CDF[
i].integral.getXmax()) {
689 const double NPE = CDF[
i].integral.getNPE(R) * module->size() * factor * W;
690 const int N = gRandom->Poisson(NPE);
696 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
698 const double R = hypot(pmt->getX() - pos.
getX(),
699 pmt->getY() - pos.
getY());
700 const double theta = pi.constrain(pmt->getTheta());
701 const double phi = pi.constrain(fabs(pmt->getPhi()));
703 npe.push_back(CDF[
i].
function.
getNPE(R, theta, phi) * factor * W);
708 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
710 const double R = hypot(pmt->getX() - pos.
getX(),
711 pmt->getY() - pos.
getY());
712 const double Z = pmt->getZ() - z0;
713 const double theta = pi.constrain(pmt->getTheta());
714 const double phi = pi.constrain(fabs(pmt->getPhi()));
718 job.Fill((
double) (100 + CDF[
i].type), (
double) n0);
722 const double t1 = CDF[
i].function.getTime(R, theta, phi, gRandom->Rndm());
725 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
737 job.Fill((
double) (300 + CDF[
i].type));
741 catch(
const exception& error) {
742 job.Fill((
double) (200 + CDF[
i].type));
749 for (JTrack::const_iterator vertex = muon.begin(); vertex != muon.end(); ++vertex) {
751 const double Es = vertex->getEs();
755 const double z0 = vertex->getZ();
756 const double t0 = vertex->getT();
761 if (writeEMShowers) {
762 origin =
event.mc_trks.size() + 1;
765 int number_of_hits = 0;
767 JDetectorSubset_t::range_type range = subdetector.getRange(z0 - maximal_distance,
768 z0 + maximal_distance);
770 for (JDetector::const_iterator module = range.begin(); module != range.end(); ++module) {
772 const double R = hypot(module->getX() - vertex->getX(),
773 module->getY() - vertex->getY());
774 const double Z = module->getZ() - z0 -
DZ;
775 const double D = sqrt(R*R + Z*Z);
776 const double cd = Z /
D;
778 for (
size_t i = 0;
i != CDG.size(); ++
i) {
780 if (D < CDG[
i].integral.getXmax()) {
784 const double NPE = CDG[
i].integral.getNPE(D, cd) * Es * module->size() * factor;
785 const int N = gRandom->Poisson(NPE);
791 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
793 const double R = hypot(pmt->getX() - vertex->getX(),
794 pmt->getY() - vertex->getY());
795 const double Z = pmt->getZ() - z0 -
DZ;
796 const double D = sqrt(R*R + Z*Z);
797 const double cd = Z /
D;
798 const double theta = pi.constrain(pmt->getTheta());
799 const double phi = pi.constrain(fabs(pmt->getPhi()));
801 npe.push_back(CDG[
i].
function.
getNPE(D, cd, theta, phi) * Es * factor);
806 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
808 const double R = hypot(pmt->getX() - vertex->getX(),
809 pmt->getY() - vertex->getY());
810 const double theta = pi.constrain(pmt->getTheta());
811 const double phi = pi.constrain(fabs(pmt->getPhi()));
815 job.Fill((
double) (100 + CDG[
i].type), (
double) n0);
820 const double Z = pmt->getZ() - z0 - dz;
821 const double D = sqrt(R*R + Z*Z);
822 const double cd = Z /
D;
824 const double t1 = CDG[
i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
827 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
836 number_of_hits += n1;
841 job.Fill((
double) (300 + CDG[
i].type));
845 catch(
const exception& error) {
846 job.Fill((
double) (200 + CDG[
i].type));
852 if (writeEMShowers && number_of_hits != 0) {
854 event.mc_trks.push_back(
JTrk_t(origin,
857 track->pos + track->dir * vertex->getZ(),
865 }
else if (track->len > 0.0) {
873 const double z0 = 0.0;
874 const double z1 = z0 + track->len;
875 const double t0 = track->t;
876 const double E = track->E;
882 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
886 const double R = pos.
getX();
891 R > maximal_road_width) {
895 for (
size_t i = 0;
i != CDF.size(); ++
i) {
907 if (R < CDF[
i].integral.getXmax()) {
911 const double NPE = CDF[
i].integral.getNPE(R) * module->size() * factor * W;
912 const int N = gRandom->Poisson(NPE);
922 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
924 const double R = pmt->getX();
925 const double theta = pi.constrain(pmt->getTheta());
926 const double phi = pi.constrain(fabs(pmt->getPhi()));
928 npe.push_back(CDF[
i].
function.
getNPE(R, theta, phi) * factor * W);
933 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
935 const double R = pmt->getX();
936 const double Z = pmt->getZ() - z0;
937 const double theta = pi.constrain(pmt->getTheta());
938 const double phi = pi.constrain(fabs(pmt->getPhi()));
942 job.Fill((
double) (120 + CDF[
i].type), (
double) n0);
946 const double t1 = CDF[
i].function.getTime(R, theta, phi, gRandom->Rndm());
949 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
961 job.Fill((
double) (320 + CDF[
i].type));
965 catch(
const exception& error) {
966 job.Fill((
double) (220 + CDF[
i].type));
973 if (!buffer.empty()) {
992 catch(
const exception& error) {
993 ERROR(error.what() << endl);
996 E =
pythia(track->type, E);
1000 const double z0 = 0.0;
1001 const double t0 = track->t;
1008 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
1012 const double R = pos.
getX();
1013 const double Z = pos.
getZ() - z0 -
DZ;
1014 const double D = sqrt(R*R + Z*Z);
1015 const double cd = Z /
D;
1017 for (
size_t i = 0;
i != CDG.size(); ++
i) {
1019 if (D < CDG[
i].integral.getXmax()) {
1023 const double NPE = CDG[
i].integral.getNPE(D, cd) * E * module->size() * factor;
1024 const int N = gRandom->Poisson(NPE);
1034 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1036 const double R = pmt->getX();
1037 const double Z = pmt->getZ() - z0 -
DZ;
1038 const double D = sqrt(R*R + Z*Z);
1039 const double cd = Z /
D;
1040 const double theta = pi.constrain(pmt->getTheta());
1041 const double phi = pi.constrain(fabs(pmt->getPhi()));
1043 npe.push_back(CDG[
i].
function.
getNPE(D, cd, theta, phi) * E * factor);
1048 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1050 const double theta = pi.constrain(pmt->getTheta());
1051 const double phi = pi.constrain(fabs(pmt->getPhi()));
1055 job.Fill((
double) (140 + CDG[
i].type), (
double) n0);
1060 const double Z = pmt->getZ() - z0 - dz;
1061 const double D = sqrt(R*R + Z*Z);
1062 const double cd = Z /
D;
1064 const double t1 = CDG[
i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
1067 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
1079 job.Fill((
double) (340 + CDG[
i].type));
1083 catch(
const exception& error) {
1084 job.Fill((
double) (240 + CDG[
i].type));
1090 if (!buffer.empty()) {
1101 if (!mc_hits.empty()) {
1105 event.mc_hits.resize(mc_hits.size());
1107 copy(mc_hits.begin(), mc_hits.end(),
event.mc_hits.begin());
1116 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 uint32_t K[64]
static const JRadiationSource_t EErad_t
Data structure for a composite optical module.
then usage $script< input file >[option[primary[working directory]]] nWhere option can be E
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.
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Data structure for circle in two dimensions.
#define gmake_property(A)
macros 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.
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.
double getKineticEnergy(const double E, const double m)
Get kinetic energy of particle with given mass.
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
static const double PI
Mathematical constants.
void addMargin(const double D)
Add (safety) margin.
static const JRadiationSource_t Brems_t
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 ...
const char * getDate()
Get current local date conform ISO-8601 standard.
direct light from delta-rays
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
then JCookie sh JDataQuality D $DETECTOR_ID R
then usage $script< input file >[option[primary[working directory]]] nWhere option can be N
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&)).
struct JSIRENE::@62 getNumberOfPhotoElectrons
Auxiliary data structure for determination of number of photo-electrons.
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.
double getNPE(const Hit &hit)
Get true charge of hit.
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.
do set_variable DETECTOR_TXT $WORKDIR detector
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 JAcoustics sh $DETECTOR_ID source JAcousticsToolkit sh CHECK_EXIT_CODE typeset A EMITTERS get_tripods $WORKDIR tripod txt EMITTERS get_transmitters $WORKDIR transmitter txt EMITTERS 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.
#define DEBUG(A)
Message macros.