178   string         fileDescriptor;
 
  183   double         Ecut_GeV  =  0.1;                            
 
  184   double         Emin_GeV  =  1.0;                            
 
  186   double         Tmax_ns   =  0.1;                            
 
  187   int            Nmax_npe  =  numeric_limits<int>::max();     
 
  204     JParser<> zap(
"Main program to simulate detector response to muons and showers.");
 
  207     zap[
'F'] = 
make_field(fileDescriptor,    
"file name descriptor for CDF tables");
 
  210     zap[
'n'] = 
make_field(numberOfEvents)    = JLimit::max();
 
  212     zap[
's'] = 
make_field(writeEMShowers,    
"store generated EM showers in event");
 
  213     zap[
'k'] = 
make_field(keep,              
"keep position of tracks");
 
  214     zap[
'N'] = 
make_field(numberOfHits,      
"minimum number of hits to output event") = 1;
 
  215     zap[
'U'] = 
make_field(factor,            
"scaling factor applied to light yields") = 1.0;
 
  221   catch(
const exception &error) {
 
  222     FATAL(error.what() << endl);
 
  226   gRandom->SetSeed(seed);
 
  229   const JMeta meta(argc, argv);
 
  231   const double Zbed = 0.0;                             
 
  245   double maximal_road_width = 0.0;                     
 
  246   double maximal_distance   = 0.0;                     
 
  248   for (
size_t i = 0; i != 
CDF.size(); ++i) {
 
  250     DEBUG(
"Range CDF["<< 
CDF[i].type << 
"] " << 
CDF[i].
function.intensity.getXmax() << 
" m" << endl);
 
  252     maximal_road_width = max(maximal_road_width, 
CDF[i].
function.intensity.getXmax());
 
  255   for (
size_t i = 0; i != CDG.size(); ++i) {
 
  257     DEBUG(
"Range CDG["<< CDG[i].type << 
"] " << CDG[i].
function.intensity.getXmax() << 
" m" << endl);
 
  260       maximal_road_width = max(maximal_road_width, CDG[i].
function.intensity.getXmax());
 
  263     maximal_distance   = max(maximal_distance,   CDG[i].
function.intensity.getXmax());
 
  266   NOTICE(
"Maximal road width [m] " << maximal_road_width << endl);
 
  267   NOTICE(
"Maximal distance   [m] " << maximal_distance   << endl);
 
  270   if (detectorFile == 
"" || inputFile.empty()) {
 
  271     STATUS(
"Nothing to be done." << endl);
 
  279     STATUS(
"Load detector... " << flush);
 
  294     STATUS(
"Setting up radiation tables... " << flush);
 
  296     const JRadiation hydrogen( 1.0,  1.0, 40, 0.01, 0.1, 0.1);
 
  297     const JRadiation oxygen  ( 8.0, 16.0, 40, 0.01, 0.1, 0.1);
 
  298     const JRadiation chlorine(17.0, 35.0, 40, 0.01, 0.1, 0.1);
 
  329     header = inputFile.getHeader();
 
  331     JHead buffer(header);
 
  333     center = get<Vec>(buffer);
 
  337     buffer.simul.rbegin()->program = 
"JSirene";
 
  339     buffer.simul.rbegin()->date    = 
getDate();
 
  340     buffer.simul.rbegin()->time    = 
getTime();
 
  342     buffer.push(&JHead::simul);
 
  347       buffer.can.zmin     += center.z;
 
  348       buffer.can.zmax     += center.z;
 
  350       buffer.push(&JHead::coord_origin);
 
  351       buffer.push(&JHead::can);
 
  356     center += 
Vec(circle.getX(), circle.getY(), 0.0);
 
  358     copy(buffer, header);
 
  365     NOTICE(
"Offset applied to true tracks is: " << center << endl);
 
  367     NOTICE(
"No offset applied to true tracks." << endl);
 
  373   if (cylinder.getZmin() < Zbed) {
 
  374     cylinder.setZmin(Zbed);
 
  377   NOTICE(
"Light generation volume: " << cylinder << endl);
 
  379   TProfile cpu(
"cpu", NULL,  14,  1.0,   8.0);
 
  380   TH1D     job(
"job", NULL, 400,  0.5, 400.5);
 
  398     STATUS(
"event: " << setw(10) << 
in.getCounter() << 
'\r'); 
DEBUG(endl);
 
  402     Evt* evt = 
in.next(); 
 
  406         track->pos += center;
 
  412     event.mc_hits.clear();
 
  433         double Zmin = intersection.first;
 
  434         double Zmax = intersection.second;
 
  436         if (Zmax - Zmin <= Dmin_m) {
 
  440         JVertex vertex(0.0, track->t, track->E);                        
 
  442         if (track->pos.z < Zbed) {                                      
 
  444           if (track->dir.z > 0.0)
 
  445             vertex.step(
gRock, (Zbed - track->pos.z) / track->dir.z); 
 
  450         if (vertex.getZ() < Zmin) {                                     
 
  451           vertex.step(
gWater, Zmin - vertex.getZ());
 
  454         if (vertex.getRange() <= Dmin_m) {
 
  460         const JDetectorSubset_t subdetector(
detector, 
getAxis(*track), maximal_road_width);
 
  462         if (subdetector.empty()) {
 
  470         while (vertex.getE() >= Emin_GeV && vertex.getZ() < Zmax) {
 
  472           const int N = radiation.size();
 
  477           for (
int i = 0; i != 
N; ++i) {
 
  478             ls += li[i] = radiation[i]->getInverseInteractionLength(vertex.getE());
 
  481           const double ds = min(gRandom->Exp(1.0) / ls, vertex.getRange());
 
  485           if (vertex.getE() >= Emin_GeV) {
 
  488             double y  = gRandom->Uniform(ls);
 
  490             for (
int i = 0; i != 
N; ++i) {
 
  495                 Es = radiation[i]->getEnergyOfShower(vertex.getE());    
 
  500             vertex.applyEloss(Es);
 
  502             if (Es >= Ecut_GeV) {
 
  503               muon.push_back(vertex);
 
  510         if (vertex.getE() < Emin_GeV && vertex.getRange() > 0.0) {
 
  512           vertex.step(vertex.getRange());
 
  514           muon.push_back(vertex);
 
  523         if (trk != event.mc_trks.end()) {
 
  524           trk->len = (muon.rbegin()->getZ() < Zmax ? +1 : -1) * (muon.rbegin()->getZ() - muon.begin()->getZ());
 
  528         for (JDetector::const_iterator module = subdetector.begin(); module != subdetector.end(); ++module) {
 
  530           const double z0 = muon.begin()->getZ();
 
  531           const double t0 = muon.begin()->getT();
 
  532           const double R  = module->getX();
 
  535           if (Z >= muon.begin()->getZ() && Z <= muon.rbegin()->getZ()) {
 
  537             for (
size_t i = 0; i != 
CDF.size(); ++i) {
 
  539               if (R < 
CDF[i].integral.getXmax()) {
 
  549                   const double NPE = 
CDF[i].integral.getNPE(R) * module->size() * factor * W;
 
  550                   const int    N   = gRandom->Poisson(NPE); 
 
  556                     for (JModule::const_iterator 
pmt = module->begin(); 
pmt != module->end(); ++
pmt) {
 
  558                       const double R     = 
pmt->getX();
 
  559                       const double Z     = 
pmt->getZ() - z0;
 
  560                       const double theta = 
pmt->getTheta();
 
  561                       const double phi   = fabs(
pmt->getPhi());
 
  563                       const double npe   = 
CDF[i].function.getNPE(R, theta, phi) * factor * W;
 
  569                       job.Fill((
double) (100 + 
CDF[i].type), (
double) n0);
 
  573                         const double t1 = 
CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
 
  576                         mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
 
  588                       job.Fill((
double) (300 + 
CDF[i].type));
 
  592                 catch(
const exception& error) {
 
  593                   job.Fill((
double) (200 + 
CDF[i].type));
 
  600         for (JTrack::const_iterator vertex = muon.begin(); vertex != muon.end(); ++vertex) {
 
  602           const double z0 = vertex->getZ();
 
  603           const double t0 = vertex->getT();
 
  604           const double Es = vertex->getEs();
 
  606           int origin = track->id;
 
  608           if (writeEMShowers) {
 
  609             origin = 
event.mc_trks.size() + 1;
 
  612           int number_of_hits = 0;
 
  614           JDetectorSubset_t::range_type range = subdetector.getRange(z0 - maximal_distance,
 
  615                                                                      z0 + maximal_distance);
 
  617           for (JDetector::const_iterator module = range.begin(); module != range.end(); ++module) {
 
  620             const double R  = module->getX();
 
  621             const double Z  = module->getZ() - z0 - dz;
 
  622             const double D  = sqrt(R*R + Z*Z);
 
  623             const double cd = Z / 
D; 
 
  625             for (
size_t i = 0; i != CDG.size(); ++i) {
 
  627               if (D < CDG[i].integral.getXmax()) {
 
  631                   const double NPE = CDG[i].integral.getNPE(D, cd) * Es * module->size() * factor;
 
  632                   const int    N   = gRandom->Poisson(NPE); 
 
  638                     for (JModule::const_iterator 
pmt = module->begin(); 
pmt != module->end(); ++
pmt) {
 
  641                       const double R     = 
pmt->getX();
 
  642                       const double Z     = 
pmt->getZ() - z0 - dz;
 
  643                       const double theta = 
pmt->getTheta();
 
  644                       const double phi   = fabs(
pmt->getPhi());
 
  645                       const double D     = sqrt(R*R + Z*Z);
 
  646                       const double cd    = Z / 
D; 
 
  648                       const double npe   = CDG[i].function.getNPE(D, cd, theta, phi) * Es * factor;
 
  654                       job.Fill((
double) (100 + CDG[i].type), (
double) n0);
 
  659                         const double Z  = 
pmt->getZ() - z0 - dz;
 
  660                         const double D  = sqrt(R*R + Z*Z);
 
  661                         const double cd = Z / 
D; 
 
  663                         const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
 
  666                         mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
 
  675                         number_of_hits += n1;
 
  680                       job.Fill((
double) (300 + CDG[i].type));
 
  684                 catch(
const exception& error) {
 
  685                   job.Fill((
double) (200 + CDG[i].type));
 
  691           if (writeEMShowers && number_of_hits != 0) {
 
  693             event.mc_trks.push_back(
JTrk_t(origin,
 
  696                                            track->pos + track->dir * vertex->getZ(),
 
  703       } 
else if (
is_tau(*track)) {
 
  711         const double z0 = 0.0;
 
  712         const double z1 = z0 + track->len;
 
  713         const double t0 = track->t;
 
  714         const double E  = track->E;
 
  720         for (JDetector::const_iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  724           const double R  = pos.
getX();
 
  729               R > maximal_road_width) {
 
  733           for (
size_t i = 0; i != 
CDF.size(); ++i) {
 
  735             if (R < 
CDF[i].integral.getXmax()) {
 
  745                 const double NPE = 
CDF[i].integral.getNPE(R) * module->size() * factor * W;
 
  746                 const int    N   = gRandom->Poisson(NPE); 
 
  756                   for (JModule::const_iterator 
pmt = buffer.begin(); 
pmt != buffer.end(); ++
pmt) {
 
  758                     const double R     = 
pmt->getX();
 
  759                     const double Z     = 
pmt->getZ() - z0;
 
  760                     const double theta = 
pmt->getTheta();
 
  761                     const double phi   = fabs(
pmt->getPhi());
 
  763                     const double npe   = 
CDF[i].function.getNPE(R, theta, phi) * factor * W;
 
  769                     job.Fill((
double) (120 + 
CDF[i].type), (
double) n0);
 
  773                       const double t1 = 
CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
 
  776                       mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
 
  788                     job.Fill((
double) (320 + 
CDF[i].type));
 
  792               catch(
const exception& error) {
 
  793                 job.Fill((
double) (220 + 
CDF[i].type));
 
  800         if (!buffer.empty()) {
 
  819           catch(
const exception& error) {
 
  820             ERROR(error.what() << endl);
 
  823           E = 
pythia(track->type, E);
 
  825           if (E < Ecut_GeV || cylinder.getDistance(
getPosition(*track)) > Dmin_m) {
 
  829           const double z0 = 0.0;
 
  830           const double t0 = track->t;
 
  836           for (JDetector::const_iterator module = 
detector.begin(); module != 
detector.end(); ++module) {
 
  841             const double R  = pos.
getX();
 
  842             const double Z  = pos.
getZ() - z0 - dz;
 
  843             const double D  = sqrt(R*R + Z*Z);
 
  844             const double cd = Z / 
D; 
 
  846             if (D > maximal_distance) {
 
  850             for (
size_t i = 0; i != CDG.size(); ++i) {
 
  852               if (D < CDG[i].integral.getXmax()) {
 
  856                   const double NPE = CDG[i].integral.getNPE(D, cd) * E * module->size() * factor;
 
  857                   const int    N   = gRandom->Poisson(NPE); 
 
  867                     for (JModule::const_iterator 
pmt = buffer.begin(); 
pmt != buffer.end(); ++
pmt) {
 
  870                       const double R     = 
pmt->getX();
 
  871                       const double Z     = 
pmt->getZ() - z0 - dz;
 
  872                       const double theta = 
pmt->getTheta();
 
  873                       const double phi   = fabs(
pmt->getPhi());
 
  874                       const double D     = sqrt(R*R + Z*Z);
 
  875                       const double cd    = Z / 
D; 
 
  877                       const double npe   = CDG[i].function.getNPE(D, cd, theta, phi) * E * factor;
 
  883                       job.Fill((
double) (140 + CDG[i].type), (
double) n0);
 
  888                         const double Z  = 
pmt->getZ() - z0 - dz;
 
  889                         const double D  = sqrt(R*R + Z*Z);
 
  890                         const double cd = Z / 
D;
 
  892                         const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
 
  895                         mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
 
  907                       job.Fill((
double) (340 + CDG[i].type));
 
  911                 catch(
const exception& error) {
 
  912                   job.Fill((
double) (240 + CDG[i].type));
 
  918           if (!buffer.empty()) {
 
  929     if (!mc_hits.empty()) {
 
  931       mc_hits.
merge(Tmax_ns);
 
  933       event.mc_hits.resize(mc_hits.size());
 
  935       copy(mc_hits.begin(), mc_hits.end(), 
event.mc_hits.begin());
 
  941       cpu.Fill(log10(
get_neutrino(event).E), (
double) timer.usec_ucpu * 1.0e-3);
 
  944     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. 
 
do echo Generating $dir eval D
 
JPredicate< JResult_t T::*, JComparison::eq > make_predicate(JResult_t T::*member, const JResult_t value)
Helper method to create predicate for data member. 
 
Data structure for a composite optical module. 
 
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 
 
Generator for simulation. 
 
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. 
 
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. 
 
esac print_variable DETECTOR INPUT_FILE OUTPUT_FILE CDF for TYPE in
 
Utility class to parse parameter values. 
 
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. 
 
void merge(const double Tmax_ns)
Merge hits on same PMT that are within given time window. 
 
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. 
 
Fast implementation of class JRadiation. 
 
esac $JPP_DIR examples JDetector JTransitTime o $OUTPUT_FILE n N $NPE T $TTS_NS d $DEBUG for HISTOGRAM in tts tt2 pmt
 
bool is_neutrino(const Trk &track)
Test whether given track is a neutrino. 
 
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. 
 
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. 
 
T & getInstance(const T &object)
Get static instance from temporary object. 
 
#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. 
 
int getID() const 
Get identifier. 
 
Auxiliary class for CPU timing and usage. 
 
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. 
 
void load(const JString &file_name, JDetector &detector)
Load detector from input file. 
 
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
 
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 ASCII formatted date. 
 
direct light from delta-rays 
 
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 ...
 
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&)). 
 
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 class to list files. 
 
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. 
 
then usage $script[input file[working directory[option]]] nWhere option can be N
 
double getZ() const 
Get z position. 
 
std::vector< Trk > mc_trks
MC: list of MC truth tracks. 
 
Auxiliary class to set-up Trk. 
 
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. 
 
JPosition3D getPosition(const Vec &v)
Get position.