Jpp 20.0.0-rc.9-22-g74b57fa79
the software that should make you happy
Loading...
Searching...
No Matches
JSirene.cc
Go to the documentation of this file.
1#include <string>
2#include <iostream>
3#include <iomanip>
4#include <vector>
5#include <limits>
6#include <numeric>
7#include <memory>
8
9#include "TROOT.h"
10#include "TFile.h"
11#include "TH1D.h"
12#include "TH2D.h"
13#include "TProfile.h"
14#include "TProfile2D.h"
15#include "TRandom3.h"
16
22
23#include "JLang/Jpp.hh"
24#include "JLang/JPredicate.hh"
25
27
28#include "JPhysics/JCDFTable.hh"
29#include "JPhysics/JPDFTypes.hh"
31#include "JPhysics/JGeane.hh"
32#include "JPhysics/JGeanz.hh"
39#include "JPhysics/JSeaWater.hh"
42
44#include "JAAnet/JPDB.hh"
45
46#include "JSirene/JSirene.hh"
47#include "JSirene/pythia.hh"
51
56
60#include "JSupport/JSupport.hh"
61#include "JSupport/JMeta.hh"
62
63#include "JROOT/JRandom.hh"
64
65#include "Jeep/JProperties.hh"
66#include "Jeep/JPrint.hh"
67#include "Jeep/JTimer.hh"
68#include "Jeep/JParser.hh"
69#include "Jeep/JMessage.hh"
70
71
72int debug; //!< debug level
73int numberOfBins = 200; //!< number of bins for average CDF integral of optical module
74double safetyFactor = 1.7; //!< safety factor for average CDF integral of optical module
75
76
77namespace {
78
79 using namespace JPP;
80
81 typedef JHermiteSplineFunction1D_t JFunction1D_t;
84 JPolint1FunctionalGridMap>::maplist J3DMap_t;
88 JPolint1FunctionalGridMap>::maplist J4DMap_t;
89
90 typedef JCDFTable<JFunction1D_t, J3DMap_t> JCDF4D_t; // muon
91 typedef JCDFTable<JFunction1D_t, J4DMap_t> JCDF5D_t; // shower
92
95
96
97
98 /**
99 * Auxiliary class for CDF tables.
100 */
101 template<class function_type, // CDF function
102 class integral_type> // CDF integral
103 struct JCDFHelper {
104 /**
105 * Constructor.
106 *
107 * \param file_descriptor file name descriptor
108 * \param type PDF type
109 */
110 JCDFHelper(const std::string& file_descriptor, const JPDFType_t type)
111 {
112 using namespace std;
113
114 this->type = type;
115
116 const string file_name = getFilename(file_descriptor, this->type);
117
118 STATUS("loading input from file " << file_name << "... " << flush);
119
120 try {
121 function.load(file_name.c_str());
122 }
123 catch(const JException& error) {
124 FATAL(error.what() << endl);
125 }
126
127 new (&integral) integral_type(function, numberOfBins, safetyFactor);
128
129 STATUS("OK" << endl);
130 }
131
132 JPDFType_t type;
133 function_type function;
134 integral_type integral;
135 };
136
137
138 typedef JCDFHelper<JCDF4D_t, JCDF1D_t> JCDF_t; //!< muon light
139 typedef JCDFHelper<JCDF5D_t, JCDF2D_t> JCDG_t; //!< shower light
140
141
142 /**
143 * Get random direction.
144 *
145 * \param t2 square of theta RMS [rad^2]
146 * \return direction
147 */
148 inline JVersor3Z getRandomDirection(const double t2)
149 {
150 const double tv = sqrt(gRandom->Exp(1.0) * t2);
151 const double phi = gRandom->Uniform(-PI, +PI);
152
153 return JVersor3Z(tv*cos(phi), tv*sin(phi));
154 }
155
156
157 /**
158 * Get Poisson number.
159 *
160 * \param x expectation value
161 * \return number
162 */
163 inline size_t getPoisson(const double x)
164 {
165 using namespace std;
166
167 if (x < numeric_limits<int32_t>::max())
168 return (size_t) gRandom->Poisson(x);
169 else
170 return (size_t) gRandom->Gaus(x, sqrt(x));
171 }
172}
173
174
175/**
176 * \file
177 *
178 * Main program to simulate detector response to muons and showers.
179 *
180 * \image html sirene.png "Picture by Claudine Colnard"
181 *
182 * Note that CDF file descriptor should contain the wild card character JPHYSICS::WILDCARD;\n
183 * The file names are obtained by replacing JPHYSICS::WILDCARD; with
184 * - JPHYSICS::DIRECT_LIGHT_FROM_MUON;
185 * - JPHYSICS::SCATTERED_LIGHT_FROM_MUON;
186 * - JPHYSICS::DIRECT_LIGHT_FROM_DELTARAYS;
187 * - JPHYSICS::SCATTERED_LIGHT_FROM_DELTARAYS;
188 * - JPHYSICS::DIRECT_LIGHT_FROM_EMSHOWER; and
189 * - JPHYSICS::SCATTERED_LIGHT_FROM_EMSHOWER,
190 * respectively.
191 *
192 * More accuracy can be achieved by setting compile option RADITION but it will run slower.
193 *
194 * The CDF tables can be produced with the script <tt>JMakePDF.sh</tt>:
195 * <pre>
196 * JMakePDF.sh -P
197 * </pre>
198 * (option <tt>-h</tt> will print all available options).
199 * Note that the script will launch a large number of processes (<tt>JMakePDF</tt> and <tt>JMakePDG</tt>)\n
200 * which may take a considerable amount of time to completion.\n
201 * On a standard desktop, all jobs should be finished within 1/2 a day or so.
202 *
203 * The same script should then be run with option <tt>-M</tt> to merge the PDF files, i.e:
204 * <pre>
205 * JMakePDF.sh -M
206 * </pre>
207 *
208 * CDF tables are obtained by running the same script with option <tt>-C</tt>, i.e:
209 * <pre>
210 * JMakePDF.sh -C
211 * </pre>
212 *
213 * The various PDFs can be drawn using the <tt>JDrawPDF</tt> or <tt>JDrawPDG</tt> applications.\n
214 * The tabulated PDFs can be plotted using the <tt>JPlotPDF</tt> or <tt>JPlotPDG</tt> applications.\n
215 * The tabulated CDFs can be plotted using the <tt>JPlotCDF</tt> or <tt>JPlotCDG</tt> applications.
216 * \author mdejong
217 */
218int main(int argc, char **argv)
219{
220 using namespace std;
221 using namespace JPP;
222
223 string fileDescriptor;
225 JFileRecorder <JTYPELIST<JAAnetTypes_t, JMetaTypes_t, JRootTypes_t>::typelist> outputFile;
226 JLimit_t& numberOfEvents = inputFile.getLimit();
227 string detectorFile;
228 JParameters parameters;
229 bool writeEMShowers;
230 size_t numberOfHits;
231 double factor;
232 JRandom seed;
233
234 try {
235
236 JProperties properties;
237
238 properties.insert(gmake_property(parameters.Ecut_GeV));
239 properties.insert(gmake_property(parameters.Emin_GeV));
240 properties.insert(gmake_property(parameters.Dmin_m));
241 properties.insert(gmake_property(parameters.Emax_GeV));
242 properties.insert(gmake_property(parameters.Dmax_m));
243 properties.insert(gmake_property(parameters.Tmax_ns));
244 properties.insert(gmake_property(parameters.Nmax_NPE));
245 properties.insert(gmake_property(parameters.Nmax_PMT));
246 properties.insert(gmake_property(parameters.Tmin_GeV));
247
248 properties.insert(gmake_property(numberOfBins));
249 properties.insert(gmake_property(safetyFactor));
250
251 JParser<> zap("Main program to simulate detector response to muons and showers.");
252
253 zap['@'] = make_field(properties) = JPARSER::initialised();
254 zap['F'] = make_field(fileDescriptor, "file name descriptor for CDF tables");
255 zap['f'] = make_field(inputFile) = JPARSER::initialised();
256 zap['o'] = make_field(outputFile) = "sirene.root";
257 zap['n'] = make_field(numberOfEvents) = JLimit::max();
258 zap['a'] = make_field(detectorFile) = "";
259 zap['s'] = make_field(writeEMShowers, "store generated EM showers in event");
260 zap['N'] = make_field(numberOfHits, "minimum number of hits to output event") = 1;
261 zap['U'] = make_field(factor, "scaling factor applied to light yields") = 1.0;
262 zap['S'] = make_field(seed) = 0;
263 zap['d'] = make_field(debug) = 1;
264
265 zap(argc, argv);
266 }
267 catch(const exception &error) {
268 FATAL(error.what() << endl);
269 }
270
271
272 seed.set(gRandom);
273
274
275 const JMeta meta(argc, argv);
276
277 const double Zbed = 0.0; // level of seabed [m]
278
279 vector<JCDF_t> CDF;
280 vector<JCDG_t> CDG;
281
282 if (fileDescriptor != "") {
283 CDF.push_back(JCDF_t(fileDescriptor, DIRECT_LIGHT_FROM_MUON));
284 CDF.push_back(JCDF_t(fileDescriptor, SCATTERED_LIGHT_FROM_MUON));
285 CDF.push_back(JCDF_t(fileDescriptor, DIRECT_LIGHT_FROM_DELTARAYS));
286 CDF.push_back(JCDF_t(fileDescriptor, SCATTERED_LIGHT_FROM_DELTARAYS));
287
288 CDG.push_back(JCDG_t(fileDescriptor, DIRECT_LIGHT_FROM_EMSHOWER));
289 CDG.push_back(JCDG_t(fileDescriptor, SCATTERED_LIGHT_FROM_EMSHOWER));
290 }
291
292 double maximal_road_width = 0.0; // road width [m]
293 double maximal_distance = 0.0; // road width [m]
294
295 for (size_t i = 0; i != CDF.size(); ++i) {
296
297 DEBUG("Range CDF["<< CDF[i].type << "] " << CDF[i].function.intensity.getXmax() << " m" << endl);
298
299 maximal_road_width = max(maximal_road_width, CDF[i].function.intensity.getXmax());
300 }
301
302 for (size_t i = 0; i != CDG.size(); ++i) {
303
304 DEBUG("Range CDG["<< CDG[i].type << "] " << CDG[i].function.intensity.getXmax() << " m" << endl);
305
306 if (!is_scattered(CDF[i].type)) {
307 maximal_road_width = max(maximal_road_width, CDG[i].function.intensity.getXmax());
308 }
309
310 maximal_distance = max(maximal_distance, CDG[i].function.intensity.getXmax());
311 }
312
313 NOTICE("Maximal road width [m] " << maximal_road_width << endl);
314 NOTICE("Maximal distance [m] " << maximal_distance << endl);
315
316
317 if (detectorFile == "" || inputFile.empty()) {
318 STATUS("Nothing to be done." << endl);
319 return 0;
320 }
321
323
324 try {
325
326 STATUS("Load detector... " << flush);
327
328 load(detectorFile, detector);
329
330 STATUS("OK" << endl);
331 }
332 catch(const JException& error) {
333 FATAL(error);
334 }
335
336 // remove empty modules
337
338 for (JDetector::iterator module = detector.begin(); module != detector.end(); ) {
339 if (!module->empty())
340 ++module;
341 else
342 module = detector.erase(module);
343 }
344
347
348 if (true) {
349
350 STATUS("Setting up radiation tables... " << flush);
351
352 const JRadiation hydrogen (JSeaWater::H .Z, JSeaWater::H .A, 40, 0.01, 0.1, 0.1);
353 const JRadiation oxygen (JSeaWater::O .Z, JSeaWater::O .A, 40, 0.01, 0.1, 0.1);
354 const JRadiation chlorine (JSeaWater::Cl.Z, JSeaWater::Cl.A, 40, 0.01, 0.1, 0.1);
355 const JRadiation sodium (JSeaWater::Na.Z, JSeaWater::Na.A, 40, 0.01, 0.1, 0.1);
356#ifdef RADIATION
357 const JRadiation calcium (JSeaWater::Ca.Z, JSeaWater::Ca.A, 40, 0.01, 0.1, 0.1);
358 const JRadiation magnesium(JSeaWater::Mg.Z, JSeaWater::Mg.A, 40, 0.01, 0.1, 0.1);
359 const JRadiation potassium(JSeaWater::K .Z, JSeaWater::K .A, 40, 0.01, 0.1, 0.1);
360 const JRadiation sulphur (JSeaWater::S .Z, JSeaWater::S .A, 40, 0.01, 0.1, 0.1);
361#endif
362
363 shared_ptr<JRadiation> Hydrogen (make_shared<JRadiationFunction>(hydrogen, 300, 0.2, 1.0e11));
364 shared_ptr<JRadiation> Oxygen (make_shared<JRadiationFunction>(oxygen, 300, 0.2, 1.0e11));
365 shared_ptr<JRadiation> Chlorine (make_shared<JRadiationFunction>(chlorine, 300, 0.2, 1.0e11));
366 shared_ptr<JRadiation> Sodium (make_shared<JRadiationFunction>(sodium, 300, 0.2, 1.0e11));
367#ifdef RADIATION
368 shared_ptr<JRadiation> Calcium (make_shared<JRadiationFunction>(calcium, 300, 0.2, 1.0e11));
369 shared_ptr<JRadiation> Magnesium(make_shared<JRadiationFunction>(magnesium,300, 0.2, 1.0e11));
370 shared_ptr<JRadiation> Potassium(make_shared<JRadiationFunction>(potassium,300, 0.2, 1.0e11));
371 shared_ptr<JRadiation> Sulphur (make_shared<JRadiationFunction>(sulphur, 300, 0.2, 1.0e11));
372#endif
373
374 radiation.push_back(make_shared<JRadiationSource>(11, Oxygen, DENSITY_SEA_WATER * JSeaWater::O(), JRadiation::EErad_t));
375 radiation.push_back(make_shared<JRadiationSource>(12, Chlorine, DENSITY_SEA_WATER * JSeaWater::Cl(), JRadiation::EErad_t));
376 radiation.push_back(make_shared<JRadiationSource>(13, Hydrogen, DENSITY_SEA_WATER * JSeaWater::H(), JRadiation::EErad_t));
377 radiation.push_back(make_shared<JRadiationSource>(14, Sodium, DENSITY_SEA_WATER * JSeaWater::Na(), JRadiation::EErad_t));
378#ifdef RADIATION
379 radiation.push_back(make_shared<JRadiationSource>(15, Calcium, DENSITY_SEA_WATER * JSeaWater::Ca(), JRadiation::EErad_t));
380 radiation.push_back(make_shared<JRadiationSource>(16, Magnesium,DENSITY_SEA_WATER * JSeaWater::Mg(), JRadiation::EErad_t));
381 radiation.push_back(make_shared<JRadiationSource>(17, Potassium,DENSITY_SEA_WATER * JSeaWater::K(), JRadiation::EErad_t));
382 radiation.push_back(make_shared<JRadiationSource>(18, Sulphur, DENSITY_SEA_WATER * JSeaWater::S(), JRadiation::EErad_t));
383#endif
384
385 radiation.push_back(make_shared<JRadiationSource>(21, Oxygen, DENSITY_SEA_WATER * JSeaWater::O(), JRadiation::Brems_t));
386 radiation.push_back(make_shared<JRadiationSource>(22, Chlorine, DENSITY_SEA_WATER * JSeaWater::Cl(), JRadiation::Brems_t));
387 radiation.push_back(make_shared<JRadiationSource>(23, Hydrogen, DENSITY_SEA_WATER * JSeaWater::H(), JRadiation::Brems_t));
388 radiation.push_back(make_shared<JRadiationSource>(24, Sodium, DENSITY_SEA_WATER * JSeaWater::Na(), JRadiation::Brems_t));
389#ifdef RADIATION
390 radiation.push_back(make_shared<JRadiationSource>(25, Calcium, DENSITY_SEA_WATER * JSeaWater::Ca(), JRadiation::Brems_t));
391 radiation.push_back(make_shared<JRadiationSource>(26, Magnesium,DENSITY_SEA_WATER * JSeaWater::Mg(), JRadiation::Brems_t));
392 radiation.push_back(make_shared<JRadiationSource>(27, Potassium,DENSITY_SEA_WATER * JSeaWater::K(), JRadiation::Brems_t));
393 radiation.push_back(make_shared<JRadiationSource>(28, Sulphur, DENSITY_SEA_WATER * JSeaWater::S(), JRadiation::Brems_t));
394#endif
395
396 radiation.push_back(make_shared<JRadiationSource>(31, Oxygen, DENSITY_SEA_WATER * JSeaWater::O(), JRadiation::GNrad_t));
397 radiation.push_back(make_shared<JRadiationSource>(32, Chlorine, DENSITY_SEA_WATER * JSeaWater::Cl(), JRadiation::GNrad_t));
398 radiation.push_back(make_shared<JRadiationSource>(33, Hydrogen, DENSITY_SEA_WATER * JSeaWater::H(), JRadiation::GNrad_t));
399 radiation.push_back(make_shared<JRadiationSource>(34, Sodium, DENSITY_SEA_WATER * JSeaWater::Na(), JRadiation::GNrad_t));
400#ifdef RADIATION
401 radiation.push_back(make_shared<JRadiationSource>(35, Calcium, DENSITY_SEA_WATER * JSeaWater::Ca(), JRadiation::GNrad_t));
402 radiation.push_back(make_shared<JRadiationSource>(36, Magnesium,DENSITY_SEA_WATER * JSeaWater::Mg(), JRadiation::GNrad_t));
403 radiation.push_back(make_shared<JRadiationSource>(37, Potassium,DENSITY_SEA_WATER * JSeaWater::K(), JRadiation::GNrad_t));
404 radiation.push_back(make_shared<JRadiationSource>(38, Sulphur, DENSITY_SEA_WATER * JSeaWater::S(), JRadiation::GNrad_t));
405#endif
406
407 radiation.push_back(make_shared<JDISSource>(100, DENSITY_SEA_WATER));
408
409 radiation.push_back(make_shared<JDeltaRaysSource>(200, DENSITY_SEA_WATER, parameters.Tmin_GeV));
410
411 ionization.push_back(make_shared<JACoeffSource>(Oxygen, DENSITY_SEA_WATER * JSeaWater::O()));
412 ionization.push_back(make_shared<JACoeffSource>(Chlorine, DENSITY_SEA_WATER * JSeaWater::Cl()));
413 ionization.push_back(make_shared<JACoeffSource>(Hydrogen, DENSITY_SEA_WATER * JSeaWater::H()));
414 ionization.push_back(make_shared<JACoeffSource>(Sodium, DENSITY_SEA_WATER * JSeaWater::Na()));
415#ifdef RADIATION
416 ionization.push_back(make_shared<JACoeffSource>(Calcium, DENSITY_SEA_WATER * JSeaWater::Ca()));
417 ionization.push_back(make_shared<JACoeffSource>(Magnesium,DENSITY_SEA_WATER * JSeaWater::Mg()));
418 ionization.push_back(make_shared<JACoeffSource>(Potassium,DENSITY_SEA_WATER * JSeaWater::K()));
419 ionization.push_back(make_shared<JACoeffSource>(Sulphur, DENSITY_SEA_WATER * JSeaWater::S()));
420#endif
421
422 STATUS("OK" << endl);
423 }
424
425
426 JCylinder3D cylinder(detector.begin(), detector.end());
427
428 cylinder.addMargin(maximal_distance);
429
430 if (cylinder.getZmin() < Zbed) {
431 cylinder.setZmin(Zbed);
432 }
433
434 NOTICE("Light generation volume: " << cylinder << endl);
435
436
437 Vec offset(0,0,0);
438 Head header;
439
440 try {
441
442 header = inputFile.getHeader();
443
444 JHead buffer(header);
445
446 buffer.simul.push_back(JAANET::simul());
447
448 buffer.simul.rbegin()->program = APPLICATION_JSIRENE;
449 buffer.simul.rbegin()->version = getGITVersion();
450 buffer.simul.rbegin()->date = getDate();
451 buffer.simul.rbegin()->time = getTime();
452
453 buffer.push(&JHead::simul);
454
455 buffer.detector.push_back(JAANET::detector());
456
457 buffer.detector.rbegin()->program = APPLICATION_JSIRENE;
458 buffer.detector.rbegin()->filename = detectorFile;
459
460 buffer.push(&JHead::detector);
461
462 offset += Vec(cylinder.getX(), cylinder.getY(), 0.0);
463 offset -= getOrigin(buffer);
464
465 if (buffer.is_valid(&JHead::fixedcan)) {
466
467 buffer.fixedcan.xcenter += offset.x;
468 buffer.fixedcan.ycenter += offset.y;
469 buffer.fixedcan.zmin += offset.z;
470 buffer.fixedcan.zmax += offset.z;
471
472 } else {
473
474 buffer.fixedcan.xcenter = cylinder.getX();
475 buffer.fixedcan.ycenter = cylinder.getY();
476
477 if (buffer.is_valid(&JHead::can)) {
478
479 buffer.fixedcan.radius = buffer.can.r;
480 buffer.fixedcan.zmin = buffer.can.zmin + offset.z;
481 buffer.fixedcan.zmax = buffer.can.zmax + offset.z;
482 } else {
483
484 buffer.fixedcan.radius = cylinder.getRadius();
485 buffer.fixedcan.zmin = cylinder.getZmin();
486 buffer.fixedcan.zmax = cylinder.getZmax();
487 }
488 }
489
490 buffer.push(&JHead::fixedcan);
491
492 if (buffer.is_valid(&JHead::coord_origin)) {
493
494 buffer.coord_origin = coord_origin(0.0, 0.0, 0.0);
495
496 buffer.push(&JHead::coord_origin);
497 }
498
499 copy(buffer, header);
500 }
501 catch(const JException& error) {
502 FATAL(error);
503 }
504
505 NOTICE("Offset applied to true tracks is: " << offset << endl);
506
507 TH1D job("job", NULL, 400, 0.5, 400.5);
508 TProfile cpu("cpu", NULL, 16, 0.0, 8.0);
509 TProfile2D rms("rms", NULL, 16, 0.0, 8.0, 251, -0.5, 250.5);
510 TProfile2D rad("rad", NULL, 16, 0.0, 8.0, 251, -0.5, 250.5);
511
512
513 outputFile.open();
514
515 if (!outputFile.is_open()) {
516 FATAL("Error opening file " << outputFile << endl);
517 }
518
519 outputFile.put(meta);
520 outputFile.put(header);
521 outputFile.put(*gRandom);
522
523 const double epsilon = 1.0e-6; // precision angle [rad]
524 const JRange<double> pi(epsilon, PI - epsilon); // constrain angle
525
526 JTimer timer;
527
528 for (JMultipleFileScanner<Evt>& in = inputFile; in.hasNext(); ) {
529
530 STATUS("event: " << setw(10) << in.getCounter() << '\r'); DEBUG(endl);
531
532 job.Fill(1.0);
533
534 Evt* evt = in.next();
535
536 for (vector<Trk>::iterator track = evt->mc_trks.begin(); track != evt->mc_trks.end(); ++track) {
537 track->pos += offset;
538 }
539
540 Evt event(*evt); // output
541
542 event.mc_hits.clear();
543
544 JHits_t mc_hits; // temporary buffer
545
546 timer.reset();
547 timer.start();
548
549 for (vector<Trk>::const_iterator track = evt->mc_trks.begin(); track != evt->mc_trks.end(); ++track) {
550
551 if (!track->is_finalstate()) {
552 continue; // only final state particles produce light
553 }
554
555 if (is_muon(*track)) {
556
557 // -----------------------------------------------
558 // muon
559 // -----------------------------------------------
560
561 job.Fill(2.0);
562
564
565 const JCylinder3D::intersection_type intersection = cylinder.getIntersection(getAxis(*track));
566
567 double Zmin = intersection.first;
568 double Zmax = intersection.second;
569
570 if (Zmax - Zmin <= parameters.Dmin_m) {
571 continue;
572 }
573
574 JVertex vertex(0.0, track->t, track->E); // start of muon
575
576 if (track->pos.z < Zbed) { // propagate muon through rock
577
578 if (track->dir.z > 0.0)
579 vertex.step(gRock, (Zbed - track->pos.z) / track->dir.z);
580 else
581 continue;
582 }
583
584 if (vertex.getZ() < Zmin) { // propagate muon through water
585 vertex.step(gWater, Zmin - vertex.getZ());
586 }
587
588 if (vertex.getRange() <= parameters.Dmin_m) {
589 continue;
590 }
591
592 job.Fill(3.0);
593
594 const JDetectorSubset_t subdetector(detector, getAxis(*track), maximal_road_width);
595
596 if (subdetector.empty()) {
597 continue;
598 }
599
600 job.Fill(4.0);
601
602 JTrack muon(vertex); // propagate muon trough detector
603
604 while (vertex.getE() >= parameters.Emin_GeV && vertex.getZ() < Zmax) {
605
606 const int N = radiation.size();
607
608 double li[N]; // inverse interaction lengths
609 double ls = 1.0e-5; // minimal total inverse interaction length [m^-1]
610
611 for (int i = 0; i != N; ++i) {
612 ls += li[i] = radiation[i]->getInverseInteractionLength(vertex.getE());
613 }
614
615 double As = 0.0; // ionization energy loss
616
617 for (size_t i = 0; i != ionization.size(); ++i) {
618 As += ionization[i]->getA(vertex.getE());
619 }
620
621 double step = gRandom->Exp(1.0) / ls; // distance to next radiation process
622 double range = vertex.getRange(As); // range of muon
623
624 if (vertex.getE() < parameters.Emax_GeV) { // limited step size
625 if (parameters.Dmax_m < range) {
626 range = parameters.Dmax_m;
627 }
628 }
629
630 double ts = getThetaMCS(vertex.getE(), min(step,range)); // multiple Coulomb scattering angle [rad]
631 double T2 = ts*ts; //
632
633 rms.Fill(log10(vertex.getE()), (Double_t) 0, ts*ts);
634
635 vertex.getDirection() += getRandomDirection(T2/3.0); // multiple Coulomb planar scattering
636
637 vertex.step(As, min(step,range)); // ionization energy loss
638
639 double Es = 0.0; // shower energy [GeV]
640
641 if (step < range) {
642
643 if (vertex.getE() >= parameters.Emin_GeV) {
644
645 double y = gRandom->Uniform(ls);
646
647 for (int i = 0; i != N; ++i) {
648
649 y -= li[i];
650
651 if (y < 0.0) {
652
653 Es = radiation[i]->getEnergyOfShower(vertex.getE()); // shower energy [GeV]
654 ts = radiation[i]->getThetaRMS(vertex.getE(), Es); // scattering angle [rad]
655
656 T2 += ts*ts;
657
658 rms.Fill(log10(vertex.getE()), (Double_t) radiation[i]->getID(), ts*ts);
659 rad.Fill(log10(vertex.getE()), (Double_t) radiation[i]->getID(), Es);
660
661 break;
662 }
663 }
664 }
665 }
666
667 vertex.applyEloss(getRandomDirection(T2), Es);
668
669 muon.push_back(vertex);
670
671 vertex.reset(); // reset after being added to muon
672 }
673
674 // add muon end point
675
676 if (vertex.getZ() < Zmax && vertex.getRange() > 0.0) {
677
678 vertex.step(vertex.getRange());
679
680 muon.push_back(vertex);
681 }
682
683 // add information to output muon
684
685 vector<Trk>::iterator trk = find_if(event.mc_trks.begin(),
686 event.mc_trks.end(),
687 make_predicate(&Trk::id, track->id));
688
689 if (trk != event.mc_trks.end()) {
690 trk->len = (muon.rbegin()->getZ() < Zmax ? +1 : -1) * (muon.rbegin()->getZ() - muon.begin()->getZ());
691 trk->setusr(mc_usr_keys::energy_lost_in_can, muon.begin()->getE() - muon.rbegin()->getE());
692 }
693
694 for (JDetector::const_iterator module = subdetector.begin(); module != subdetector.end(); ++module) {
695
696 const double z0 = muon.begin()->getZ();
697 const double t0 = muon.begin()->getT();
698 const double Z = module->getZ() - module->getX() / getTanThetaC();
699
700 if (Z >= muon.begin()->getZ() && Z <= muon.rbegin()->getZ()) {
701
702 const JVector2D pos = muon.getPosition(Z);
703 const double R = hypot(module->getX() - pos.getX(),
704 module->getY() - pos.getY());
705
706 for (size_t i = 0; i != CDF.size(); ++i) {
707
708 if (R < CDF[i].integral.getXmax()) {
709
710 try {
711
712 double W = 1.0; // mip
713
714 if (is_deltarays(CDF[i].type)) {
715 W = JDeltaRays::getEnergyLossFromMuon(muon.getE(Z), // delta-rays
716 JEnergyRange(JDeltaRays::getTmin(), parameters.Tmin_GeV));
717 }
718
719 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
720 const size_t N = getPoisson(NPE);
721
722 if (N != 0) {
723
724 vector<double> npe;
725
726 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
727
728 const double R = hypot(pmt->getX() - pos.getX(),
729 pmt->getY() - pos.getY());
730 const double theta = pi.constrain(pmt->getTheta());
731 const double phi = pi.constrain(fabs(pmt->getPhi()));
732
733 npe.push_back(CDF[i].function.getNPE(R, theta, phi) * factor * W);
734 }
735
736 const vector<size_t>& ns = getNumberOfPhotoElectrons(NPE, N, npe, NPE < parameters.Nmax_NPE);
737
738 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
739
740 const double R = hypot(pmt->getX() - pos.getX(),
741 pmt->getY() - pos.getY());
742 const double Z = pmt->getZ() - z0;
743 const double theta = pi.constrain(pmt->getTheta());
744 const double phi = pi.constrain(fabs(pmt->getPhi()));
745
746 size_t n0 = min(ns[distance(module->begin(),pmt)], parameters.Nmax_PMT);
747
748 job.Fill((double) (100 + CDF[i].type), (double) n0);
749
750 while (n0 != 0) {
751
752 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
753 const int n1 = getNumberOfPhotoElectrons(n0);
754
755 mc_hits.push_back(JHit_t(mc_hits.size() + 1,
756 pmt->getID(),
757 getHitType(CDF[i].type),
758 track->id,
759 t0 + (R * getTanThetaC() + Z) / C + t1,
760 n1));
761
762 n0 -= n1;
763 }
764 }
765
766 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
767 job.Fill((double) (300 + CDF[i].type));
768 }
769 }
770 }
771 catch(const exception& error) {
772 job.Fill((double) (200 + CDF[i].type));
773 }
774 }
775 }
776 }
777 }
778
779 for (JTrack::const_iterator vertex = muon.begin(); vertex != muon.end(); ++vertex) {
780
781 const double Es = vertex->getEs();
782
783 if (Es >= parameters.Ecut_GeV) {
784
785 const double z0 = vertex->getZ();
786 const double t0 = vertex->getT();
787 const double DZ = geanz.getMaximum(Es);
788
789 int origin = track->id;
790
791 if (writeEMShowers) {
792 origin = event.mc_trks.size() + 1;
793 }
794
795 int number_of_hits = 0;
796
797 JDetectorSubset_t::range_type range = subdetector.getRange(z0 - maximal_distance,
798 z0 + maximal_distance);
799
800 for (JDetector::const_iterator module = range.begin(); module != range.end(); ++module) {
801
802 const double R = hypot(module->getX() - vertex->getX(),
803 module->getY() - vertex->getY());
804 const double Z = module->getZ() - z0 - DZ;
805 const double D = sqrt(R*R + Z*Z);
806 const double cd = Z / D;
807
808 for (size_t i = 0; i != CDG.size(); ++i) {
809
810 if (D < CDG[i].integral.getXmax()) {
811
812 try {
813
814 const double NPE = CDG[i].integral.getNPE(D, cd) * Es * module->size() * factor;
815 const size_t N = getPoisson(NPE);
816
817 if (N != 0) {
818
819 vector<double> npe;
820
821 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
822
823 const double R = hypot(pmt->getX() - vertex->getX(),
824 pmt->getY() - vertex->getY());
825 const double Z = pmt->getZ() - z0 - DZ;
826 const double D = sqrt(R*R + Z*Z);
827 const double cd = Z / D;
828 const double theta = pi.constrain(pmt->getTheta());
829 const double phi = pi.constrain(fabs(pmt->getPhi()));
830
831 npe.push_back(CDG[i].function.getNPE(D, cd, theta, phi) * Es * factor);
832 }
833
834 const vector<size_t>& ns = getNumberOfPhotoElectrons(NPE, N, npe, NPE < parameters.Nmax_NPE);
835
836 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
837
838 const double R = hypot(pmt->getX() - vertex->getX(),
839 pmt->getY() - vertex->getY());
840 const double theta = pi.constrain(pmt->getTheta());
841 const double phi = pi.constrain(fabs(pmt->getPhi()));
842
843 size_t n0 = min(ns[distance(module->begin(),pmt)], parameters.Nmax_PMT);
844
845 job.Fill((double) (100 + CDG[i].type), (double) n0);
846
847 while (n0 != 0) {
848
849 const double dz = geanz.getLength(Es, gRandom->Rndm());
850 const double Z = pmt->getZ() - z0 - dz;
851 const double D = sqrt(R*R + Z*Z);
852 const double cd = Z / D;
853
854 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
855 const int n1 = getNumberOfPhotoElectrons(n0);
856
857 mc_hits.push_back(JHit_t(mc_hits.size() + 1,
858 pmt->getID(),
859 getHitType(CDG[i].type),
860 origin,
861 t0 + (dz + D * getIndexOfRefraction()) / C + t1,
862 n1));
863
864 n0 -= n1;
865
866 number_of_hits += n1;
867 }
868 }
869
870 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
871 job.Fill((double) (300 + CDG[i].type));
872 }
873 }
874 }
875 catch(const exception& error) {
876 job.Fill((double) (200 + CDG[i].type));
877 }
878 }
879 }
880 }
881
882 if (writeEMShowers && number_of_hits != 0) {
883
884 event.mc_trks.push_back(JTrk_t(origin,
886 track->id,
887 track->pos + track->dir * vertex->getZ(),
888 track->dir,
889 vertex->getT(),
890 Es));
891 }
892 }
893 }
894
895 } else if (track->len > 0.0) {
896
897 // -----------------------------------------------
898 // decayed particles treated as mip (tau includes mip+deltaray)
899 // -----------------------------------------------
900
901 job.Fill(6.0);
902
903 const double z0 = 0.0;
904 const double z1 = z0 + track->len;
905 const double t0 = track->t;
906 const double E = track->E;
907
908 const JTransformation3D transformation = getTransformation(*track);
909
910 JModule buffer;
911
912 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
913
914 const JPosition3D pos = transformation.transform(module->getPosition());
915
916 const double R = pos.getX();
917 const double Z = pos.getZ() - R / getTanThetaC();
918
919 if (Z < z0 ||
920 Z > z1 ||
921 R > maximal_road_width) {
922 continue;
923 }
924
925 for (size_t i = 0; i != CDF.size(); ++i) {
926
927 double W = 1.0; // mip
928
929 if (is_deltarays(CDF[i].type)) {
930
931 if (is_tau(*track))
932 W = JDeltaRays::getEnergyLossFromTau(E); // delta-rays
933 else
934 continue;
935 }
936
937 if (R < CDF[i].integral.getXmax()) {
938
939 try {
940
941 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
942 const size_t N = getPoisson(NPE);
943
944 if (N != 0) {
945
946 buffer = *module;
947
948 buffer.transform(transformation);
949
950 vector<double> npe;
951
952 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
953
954 const double R = pmt->getX();
955 const double theta = pi.constrain(pmt->getTheta());
956 const double phi = pi.constrain(fabs(pmt->getPhi()));
957
958 npe.push_back(CDF[i].function.getNPE(R, theta, phi) * factor * W);
959 }
960
961 const vector<size_t>& ns = getNumberOfPhotoElectrons(NPE, N, npe, NPE < parameters.Nmax_NPE);
962
963 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
964
965 const double R = pmt->getX();
966 const double Z = pmt->getZ() - z0;
967 const double theta = pi.constrain(pmt->getTheta());
968 const double phi = pi.constrain(fabs(pmt->getPhi()));
969
970 size_t n0 = min(ns[distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
971
972 job.Fill((double) (120 + CDF[i].type), (double) n0);
973
974 while (n0 != 0) {
975
976 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
977 const int n1 = getNumberOfPhotoElectrons(n0);
978
979 mc_hits.push_back(JHit_t(mc_hits.size() + 1,
980 pmt->getID(),
981 getHitType(CDF[i].type),
982 track->id,
983 t0 + (R * getTanThetaC() + Z) / C + t1,
984 n1));
985
986 n0 -= n1;
987 }
988 }
989
990 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
991 job.Fill((double) (320 + CDF[i].type));
992 }
993 }
994 }
995 catch(const exception& error) {
996 job.Fill((double) (220 + CDF[i].type));
997 }
998 }
999 }
1000 }
1001
1002 if (!buffer.empty()) {
1003 job.Fill(7.0);
1004 }
1005
1006 } else if (!is_neutrino(*track)) {
1007
1008 if (JPDB::getInstance().hasPDG(track->type)) {
1009
1010 // -----------------------------------------------
1011 // electron or hadron
1012 // -----------------------------------------------
1013
1014 job.Fill(8.0);
1015
1016 double E = track->E;
1017
1018 try {
1019 E = getKineticEnergy(E, JPDB::getInstance().getPDG(track->type).mass);
1020 }
1021 catch(const exception& error) {
1022 ERROR(error.what() << endl);
1023 }
1024
1025 E = pythia(track->type, E);
1026
1027 if (E >= parameters.Ecut_GeV && cylinder.getDistance(getPosition(*track)) < parameters.Dmin_m) {
1028
1029 const double z0 = 0.0;
1030 const double t0 = track->t;
1031 const double DZ = geanz.getMaximum(E);
1032
1033 const JTransformation3D transformation = getTransformation(*track);
1034
1035 JModule buffer;
1036
1037 for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
1038
1039 const JPosition3D pos = transformation.transform(module->getPosition());
1040
1041 const double R = pos.getX();
1042 const double Z = pos.getZ() - z0 - DZ;
1043 const double D = sqrt(R*R + Z*Z);
1044 const double cd = Z / D;
1045
1046 for (size_t i = 0; i != CDG.size(); ++i) {
1047
1048 if (D < CDG[i].integral.getXmax()) {
1049
1050 try {
1051
1052 const double NPE = CDG[i].integral.getNPE(D, cd) * E * module->size() * factor;
1053 const size_t N = getPoisson(NPE);
1054
1055 if (N != 0) {
1056
1057 buffer = *module;
1058
1059 buffer.transform(transformation);
1060
1061 vector<double> npe;
1062
1063 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1064
1065 const double R = pmt->getX();
1066 const double Z = pmt->getZ() - z0 - DZ;
1067 const double D = sqrt(R*R + Z*Z);
1068 const double cd = Z / D;
1069 const double theta = pi.constrain(pmt->getTheta());
1070 const double phi = pi.constrain(fabs(pmt->getPhi()));
1071
1072 npe.push_back(CDG[i].function.getNPE(D, cd, theta, phi) * E * factor);
1073 }
1074
1075 const vector<size_t>& ns = getNumberOfPhotoElectrons(NPE, N, npe, NPE < parameters.Nmax_NPE);
1076
1077 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1078
1079 const double theta = pi.constrain(pmt->getTheta());
1080 const double phi = pi.constrain(fabs(pmt->getPhi()));
1081
1082 size_t n0 = min(ns[distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
1083
1084 job.Fill((double) (140 + CDG[i].type), (double) n0);
1085
1086 while (n0 != 0) {
1087
1088 const double dz = geanz.getLength(E, gRandom->Rndm());
1089 const double Z = pmt->getZ() - z0 - dz;
1090 const double D = sqrt(R*R + Z*Z);
1091 const double cd = Z / D;
1092
1093 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
1094 const int n1 = getNumberOfPhotoElectrons(n0);
1095
1096 mc_hits.push_back(JHit_t(mc_hits.size() + 1,
1097 pmt->getID(),
1098 getHitType(CDG[i].type, true),
1099 track->id,
1100 t0 + (dz + D * getIndexOfRefraction()) / C + t1,
1101 n1));
1102
1103 n0 -= n1;
1104 }
1105 }
1106
1107 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
1108 job.Fill((double) (340 + CDG[i].type));
1109 }
1110 }
1111 }
1112 catch(const exception& error) {
1113 job.Fill((double) (240 + CDG[i].type));
1114 }
1115 }
1116 }
1117 }
1118
1119 if (!buffer.empty()) {
1120 job.Fill(9.0);
1121 }
1122
1123 } else {
1124 job.Fill(21.0);
1125 }
1126 }
1127 }
1128 }
1129
1130 if (!mc_hits.empty()) {
1131
1132 mc_hits.merge(parameters.Tmax_ns);
1133
1134 event.mc_hits.resize(mc_hits.size());
1135
1136 copy(mc_hits.begin(), mc_hits.end(), event.mc_hits.begin());
1137 }
1138
1139 timer.stop();
1140
1141 if (has_neutrino(event)) {
1142 cpu.Fill(log10(get_neutrino(event).E), (double) timer.usec_ucpu * 1.0e-3);
1143 }
1144
1145 if (event.mc_hits.size() >= numberOfHits) {
1146
1147 outputFile.put(event);
1148
1149 job.Fill(10.0);
1150 }
1151 }
1152 STATUS(endl);
1153
1154 outputFile.put(job);
1155 outputFile.put(cpu);
1156 outputFile.put(rms);
1157 outputFile.put(rad);
1158 outputFile.put(*gRandom);
1159
1161
1162 io >> outputFile;
1163
1164 outputFile.close();
1165}
Definition of hit and track types and auxiliary methods for handling Monte Carlo data.
string outputFile
Date and time functions.
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.
Energy loss of muon.
Longitudinal emission profile EM-shower.
General purpose messaging.
#define DEBUG(A)
Message macros.
Definition JMessage.hh:62
#define STATUS(A)
Definition JMessage.hh:63
#define NOTICE(A)
Definition JMessage.hh:64
#define FATAL(A)
Definition JMessage.hh:67
ROOT I/O of application specific meta data.
Scanning of objects from multiple files according a format that follows from the extension of each fi...
Auxiliary methods for PDF calculations.
Numbering scheme for PDF types.
Utility class to parse command line options.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition JParser.hh:2142
Auxiliary methods for physics calculations.
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.
Toolkit for JSirene.
int numberOfBins
number of bins for average CDF integral of optical module
Definition JSirene.cc:73
double safetyFactor
safety factor for average CDF integral of optical module
Definition JSirene.cc:74
int main(int argc, char **argv)
Definition JSirene.cc:218
int debug
debug level
Definition JSirene.cc:72
ROOT TTree parameter settings of various packages.
Jpp environment information.
static const char *const APPLICATION_JSIRENE
detector simulation
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance.
Monte Carlo run header.
Definition JHead.hh:1236
std::vector< JAANET::simul > simul
Definition JHead.hh:1609
JAANET::coord_origin coord_origin
Definition JHead.hh:1619
void push(T JHead::*pd)
Push given data member to Head.
Definition JHead.hh:1374
std::vector< JAANET::detector > detector
Definition JHead.hh:1605
JAANET::can can
Definition JHead.hh:1616
JAANET::fixedcan fixedcan
Definition JHead.hh:1617
bool is_valid(T JHead::*pd) const
Check validity of given data member in JHead.
Definition JHead.hh:1319
Detector subset without binary search functionality.
Detector subset with binary search functionality.
Detector data structure.
Definition JDetector.hh:96
Data structure for a composite optical module.
Definition JModule.hh:76
void transform(const JRotation3D &R, const JVector3D &pos)
Transformation of geometry (see method JGEOMETRY3D::JPosition3D::transform(const JRotation3D&,...
Definition JModule.hh:346
Utility class to parse parameter values.
Auxiliary class for CPU timing and usage.
Definition JTimer.hh:33
unsigned long long usec_ucpu
Definition JTimer.hh:239
void stop()
Stop timer.
Definition JTimer.hh:127
void reset()
Reset timer.
Definition JTimer.hh:93
void start()
Start timer.
Definition JTimer.hh:106
double getRadius() const
Get radius.
Definition JCircle2D.hh:144
Data structure for vector in two dimensions.
Definition JVector2D.hh:34
double getY() const
Get y position.
Definition JVector2D.hh:74
double getX() const
Get x position.
Definition JVector2D.hh:63
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.
Definition JVector3D.hh:104
double getZ() const
Get z position.
Definition JVector3D.hh:115
double getX() const
Get x position.
Definition JVector3D.hh:94
Data structure for normalised vector in positive z-direction.
Definition JVersor3Z.hh:41
const JVersor3Z & getDirection() const
Get direction.
Definition JVersor3Z.hh:81
General exception.
Definition JException.hh:24
virtual const char * what() const override
Get error message.
Definition JException.hh:64
Utility class to parse command line options.
Definition JParser.hh:1698
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.
Definition JCDFTable.hh:58
double getLength(const double E, const double P, const double eps=1.0e-5) const
Get shower length for a given integrated probability.
Definition JGeanz.hh:146
double getMaximum(const double E) const
Get depth of shower maximum.
Definition JGeanz.hh:187
Auxiliary class for the calculation of the muon radiative cross sections.
Definition JRadiation.hh:36
static constexpr radiation_type GNrad_t
static constexpr radiation_type Brems_t
static constexpr radiation_type EErad_t
General purpose class for object reading from a list of file names.
virtual bool hasNext() override
Check availability of next element.
Range of values.
Definition JRange.hh:42
T constrain(argument_type x) const
Constrain value to range.
Definition JRange.hh:350
JAxis3D getAxis(const Trk &track)
Get axis.
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.
void copy(const Head &from, JHead &to)
Copy header from from to to.
Definition JHead.cc:163
JPosition3D getPosition(const Vec &pos)
Get position.
bool is_muon(const Trk &track)
Test whether given track is a (anti-)muon.
const Trk & get_neutrino(const Evt &evt)
Get incoming neutrino.
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.
const char * getGITVersion()
Get GIT version.
Definition Jpp.cc:9
bool is_deltarays(const int pdf)
Test if given PDF type corresponds to Cherenkov light from delta-rays.
Definition JPDFTypes.hh:151
static const double DENSITY_SEA_WATER
Fixed environment values.
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.
Definition JPDFTypes.hh:165
double getTanThetaC()
Get average tangent of Cherenkov angle of water corresponding to group velocity.
JPDFType_t
PDF types.
Definition JPDFTypes.hh:24
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.
static const JPythia pythia
Function object for relative light yield as a function of GEANT particle code.
Definition JPythia.hh:96
const struct JSIRENE::number_of_photo_electrons_type getNumberOfPhotoElectrons
const char * getTime()
Get current local time conform ISO-8601 standard.
const char * getDate()
Get current local date conform ISO-8601 standard.
const char *const energy_lost_in_can
Definition io_ascii.hh:46
This file contains converted Fortran code from km3.
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
Definition Evt.hh:21
std::vector< Hit > mc_hits
MC: list of MC truth hits.
Definition Evt.hh:48
std::vector< Trk > mc_trks
MC: list of MC truth tracks.
Definition Evt.hh:49
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
Definition Head.hh:65
static const JPDB & getInstance()
Get particle data book.
Definition JPDB.hh:131
double zmin
Bottom [m].
Definition JHead.hh:598
double zmax
Top [m].
Definition JHead.hh:599
double r
Radius [m].
Definition JHead.hh:600
Coordinate origin.
Definition JHead.hh:732
Detector file.
Definition JHead.hh:227
double zmax
Top [m].
Definition JHead.hh:639
double radius
Radius [m].
Definition JHead.hh:640
double zmin
Bottom [m].
Definition JHead.hh:638
double ycenter
y-center [m]
Definition JHead.hh:637
double xcenter
x-center [m]
Definition JHead.hh:636
Generator for simulation.
Definition JHead.hh:528
Auxiliary class for PMT parameters including threshold.
JPosition3D transform(const JPosition3D &pos) const
Transform position.
Template definition of random value generator.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition JParser.hh:68
static double getEnergyLossFromMuon(const double E, const JEnergyRange T_GeV=JEnergyRange(TMIN_GEV, TMAX_GEV))
Equivalent EM-shower energy loss due to delta-rays per unit muon track length in sea water.
static double getTmin()
Get minimum delta-ray kinetic energy.
Definition JDeltaRays.hh:59
static double getEnergyLossFromTau(const double E, const JEnergyRange T_GeV=JEnergyRange(TMIN_GEV, TMAX_GEV))
Equivalent EM-shower energy loss due to delta-rays per unit tau track length in sea water.
static constexpr atom_type Cl
Definition JSeaWater.hh:32
static constexpr atom_type H
Definition JSeaWater.hh:29
static constexpr atom_type O
Definition JSeaWater.hh:30
static constexpr atom_type Na
Definition JSeaWater.hh:31
Auxiliary class to set-up Hit.
Definition JSirene.hh:60
Auxiliary data structure for list of hits with hit merging capability.
Definition JSirene.hh:141
void merge(const double Tmax_ns)
Merge hits on same PMT that are within given time window.
Definition JSirene.hh:150
double getE() const
Get muon energy.
double getEs() const
Get shower energy.
Auxiliary class to set-up Trk.
Definition JSirene.hh:192
Vertex of energy loss of muon.
JVertex & step(const double ds)
Step using default ionisation energy loss.
double getRange() const
Get visible range of muon using default ionisation energy loss.
void applyEloss(const JVersor3Z &Ts, const double Es)
Apply shower energy loss.
void reset()
Reset shower energy loss.
Auxiliary class for defining the range of iterations of objects.
Definition JLimit.hh:45
static counter_type max()
Get maximum counter value.
Definition JLimit.hh:128
Auxiliary class for ROOT I/O of application specific meta data.
Definition JMeta.hh:72
Auxiliary data structure to list files in directory.
Type definition of a spline interpolation method based on a JCollection with double result type.
Auxiliary class for recursive map list generation.
Definition JMapList.hh:109
Type definition of a 1st degree polynomial interpolation based on a JGridMap implementation.
Type definition of a 1st degree polynomial interpolation based on a JMap implementation.
int id
track identifier
Definition Trk.hh:16
The Vec class is a straightforward 3-d vector, which also works in pyroot.
Definition Vec.hh:13
double z
Definition Vec.hh:14
double x
Definition Vec.hh:14
double y
Definition Vec.hh:14