221{
224
226
227 string fileDescriptor;
229 JFileRecorder <JTYPELIST<JAAnetTypes_t, JMetaTypes_t, JRootTypes_t>::typelist>
outputFile;
230 JLimit_t& numberOfEvents = inputFile.getLimit();
231 string detectorFile;
232 JCalibration_t calibrationFile;
233 double Tmax_s;
235 bool writeEMShowers;
236 size_t numberOfHits;
237 double factor;
239
240 try {
241
243
253
256
257 JParser<> zap(
"Main program to simulate detector response to muons and showers.");
258
260 zap[
'F'] =
make_field(fileDescriptor,
"file name descriptor for CDF tables");
266 zap[
'T'] =
make_field(Tmax_s,
"dynamical update time [s]") = 100.0;
267 zap[
's'] =
make_field(writeEMShowers,
"store generated EM showers in event");
268 zap[
'N'] =
make_field(numberOfHits,
"minimum number of hits to output event") = 1;
269 zap[
'U'] =
make_field(factor,
"scaling factor applied to light yields") = 1.0;
272
273 zap(argc, argv);
274 }
275 catch(const exception &error) {
276 FATAL(error.what() << endl);
277 }
278
279
280 seed.set(gRandom);
281
282
283 const JMeta meta(argc, argv);
284
285 const double Zbed = 0.0;
286
289
290 if (fileDescriptor != "") {
291 CDF.push_back(JCDF_t(fileDescriptor, DIRECT_LIGHT_FROM_MUON));
292 CDF.push_back(JCDF_t(fileDescriptor, SCATTERED_LIGHT_FROM_MUON));
293 CDF.push_back(JCDF_t(fileDescriptor, DIRECT_LIGHT_FROM_DELTARAYS));
294 CDF.push_back(JCDF_t(fileDescriptor, SCATTERED_LIGHT_FROM_DELTARAYS));
295
296 CDG.push_back(JCDG_t(fileDescriptor, DIRECT_LIGHT_FROM_EMSHOWER));
297 CDG.push_back(JCDG_t(fileDescriptor, SCATTERED_LIGHT_FROM_EMSHOWER));
298 }
299
300 double maximal_road_width = 0.0;
301 double maximal_distance = 0.0;
302
303 for (size_t i = 0; i != CDF.size(); ++i) {
304
305 DEBUG(
"Range CDF["<< CDF[i].type <<
"] " << CDF[i].function.intensity.getXmax() <<
" m" << endl);
306
307 maximal_road_width = max(maximal_road_width, CDF[i].function.intensity.getXmax());
308 }
309
310 for (size_t i = 0; i != CDG.size(); ++i) {
311
312 DEBUG(
"Range CDG["<< CDG[i].type <<
"] " << CDG[i].function.intensity.getXmax() <<
" m" << endl);
313
315 maximal_road_width = max(maximal_road_width, CDG[i].function.intensity.getXmax());
316 }
317
318 maximal_distance = max(maximal_distance, CDG[i].function.intensity.getXmax());
319 }
320
321 NOTICE(
"Maximal road width [m] " << maximal_road_width << endl);
322 NOTICE(
"Maximal distance [m] " << maximal_distance << endl);
323
324
325 if (detectorFile == "" || inputFile.empty()) {
326 STATUS(
"Nothing to be done." << endl);
327 return 0;
328 }
329
330 struct {
332 } master;
333
334 try {
335
336 STATUS(
"Load detector... " << flush);
337
338 load(detectorFile, master.detector);
339
341 }
344 }
345
346 unique_ptr<JDynamics> dynamics;
347
348 if (!calibrationFile.empty()) {
349
350 try {
351
352 dynamics.reset(
new JDynamics(master.detector, Tmax_s));
353
354 dynamics->load(calibrationFile);
355 }
356 catch(const exception& error) {
358 }
359 }
360
361 const JDetector&
detector = (dynamics ? dynamics->getDetector() : master.detector);
362
365
366 if (true) {
367
368 STATUS(
"Setting up radiation tables... " << flush);
369
374#ifdef RADIATION
375 const JRadiation calcium (JSeaWater::Ca.Z, JSeaWater::Ca.A, 40, 0.01, 0.1, 0.1);
376 const JRadiation magnesium(JSeaWater::Mg.Z, JSeaWater::Mg.A, 40, 0.01, 0.1, 0.1);
377 const JRadiation potassium(JSeaWater::K .Z, JSeaWater::K .A, 40, 0.01, 0.1, 0.1);
378 const JRadiation sulphur (JSeaWater::S .Z, JSeaWater::S .A, 40, 0.01, 0.1, 0.1);
379#endif
380
381 shared_ptr<JRadiation> Hydrogen (make_shared<JRadiationFunction>(hydrogen, 300, 0.2, 1.0e11));
382 shared_ptr<JRadiation> Oxygen (make_shared<JRadiationFunction>(oxygen, 300, 0.2, 1.0e11));
383 shared_ptr<JRadiation> Chlorine (make_shared<JRadiationFunction>(chlorine, 300, 0.2, 1.0e11));
384 shared_ptr<JRadiation> Sodium (make_shared<JRadiationFunction>(sodium, 300, 0.2, 1.0e11));
385#ifdef RADIATION
386 shared_ptr<JRadiation> Calcium (make_shared<JRadiationFunction>(calcium, 300, 0.2, 1.0e11));
387 shared_ptr<JRadiation> Magnesium(make_shared<JRadiationFunction>(magnesium,300, 0.2, 1.0e11));
388 shared_ptr<JRadiation> Potassium(make_shared<JRadiationFunction>(potassium,300, 0.2, 1.0e11));
389 shared_ptr<JRadiation> Sulphur (make_shared<JRadiationFunction>(sulphur, 300, 0.2, 1.0e11));
390#endif
391
396#ifdef RADIATION
401#endif
402
407#ifdef RADIATION
412#endif
413
418#ifdef RADIATION
423#endif
424
426
427 radiation.push_back(make_shared<JDeltaRaysSource>(200,
DENSITY_SEA_WATER, parameters.Tmin_GeV));
428
433#ifdef RADIATION
434 ionization.push_back(make_shared<JACoeffSource>(Calcium,
DENSITY_SEA_WATER * JSeaWater::Ca()));
435 ionization.push_back(make_shared<JACoeffSource>(Magnesium,
DENSITY_SEA_WATER * JSeaWater::Mg()));
436 ionization.push_back(make_shared<JACoeffSource>(Potassium,
DENSITY_SEA_WATER * JSeaWater::K()));
437 ionization.push_back(make_shared<JACoeffSource>(Sulphur,
DENSITY_SEA_WATER * JSeaWater::S()));
438#endif
439
441 }
442
443
445
446 cylinder.addMargin(maximal_distance);
447
448 if (cylinder.getZmin() < Zbed) {
449 cylinder.setZmin(Zbed);
450 }
451
452 NOTICE(
"Light generation volume: " << cylinder << endl);
453
454
457
458 try {
459
460 header = inputFile.getHeader();
461
463
465
468 buffer.simul.rbegin()->date =
getDate();
469 buffer.simul.rbegin()->time =
getTime();
470
472
474
476 buffer.detector.rbegin()->filename = detectorFile;
477
479
480 offset +=
Vec(cylinder.getX(), cylinder.getY(), 0.0);
482
484
485 buffer.fixedcan.xcenter += offset.x;
486 buffer.fixedcan.ycenter += offset.y;
487 buffer.fixedcan.zmin += offset.z;
488 buffer.fixedcan.zmax += offset.z;
489
490 } else {
491
492 buffer.fixedcan.xcenter = cylinder.getX();
493 buffer.fixedcan.ycenter = cylinder.getY();
494
496
497 buffer.fixedcan.radius = buffer.can.r;
498 buffer.fixedcan.zmin = buffer.can.zmin + offset.z;
499 buffer.fixedcan.zmax = buffer.can.zmax + offset.z;
500 } else {
501
502 buffer.fixedcan.radius = cylinder.getRadius();
503 buffer.fixedcan.zmin = cylinder.getZmin();
504 buffer.fixedcan.zmax = cylinder.getZmax();
505 }
506 }
507
509
511
513
515 }
516
517 copy(buffer, header);
518 }
521 }
522
523 NOTICE(
"Offset applied to true tracks is: " << offset << endl);
524
525 TH1D job("job", NULL, 400, 0.5, 400.5);
526 TProfile cpu("cpu", NULL, 16, 0.0, 8.0);
527 TProfile2D rms("rms", NULL, 16, 0.0, 8.0, 251, -0.5, 250.5);
528 TProfile2D rad("rad", NULL, 16, 0.0, 8.0, 251, -0.5, 250.5);
529
530
532
535 }
536
540
541 const double epsilon = 1.0e-6;
543
545
547
548 STATUS(
"event: " << setw(10) << in.getCounter() <<
'\r');
DEBUG(endl);
549
550 job.Fill(1.0);
551
552 Evt* evt = in.next();
553
555 track->pos += offset;
556 }
557
559
560 event.mc_hits.clear();
561
562 if (dynamics) {
563
564 if (event.mc_event_time == TTimeStamp(0)) {
565 FATAL(
"Monte Carlo event time undefined." << endl);
566 }
567
568 dynamics->update(event.mc_event_time.AsDouble());
569 }
570
571
573
576
577 for (vector<Trk>::const_iterator track = evt->
mc_trks.begin(); track != evt->
mc_trks.end(); ++track) {
578
579 if (!track->is_finalstate()) {
580 continue;
581 }
582
584
585
586
587
588
589 job.Fill(2.0);
590
592
594
595 double Zmin = intersection.first;
596 double Zmax = intersection.second;
597
598 if (Zmax - Zmin <= parameters.Dmin_m) {
599 continue;
600 }
601
602 JVertex vertex(0.0, track->t, track->E);
603
604 if (track->pos.z < Zbed) {
605
606 if (track->dir.z > 0.0)
607 vertex.step(
gRock, (Zbed - track->pos.z) / track->dir.z);
608 else
609 continue;
610 }
611
612 if (vertex.getZ() < Zmin) {
613 vertex.step(gWater, Zmin - vertex.getZ());
614 }
615
616 if (vertex.getRange() <= parameters.Dmin_m) {
617 continue;
618 }
619
620 job.Fill(3.0);
621
623
624 if (subdetector.empty()) {
625 continue;
626 }
627
628 job.Fill(4.0);
629
630 JTrack muon(vertex);
631
632 while (vertex.getE() >= parameters.Emin_GeV && vertex.getZ() < Zmax) {
633
634 const int N = radiation.size();
635
636 double li[N];
638
639 for (int i = 0; i != N; ++i) {
640 ls += li[i] = radiation[i]->getInverseInteractionLength(vertex.getE());
641 }
642
643
644
646
647 for (size_t i = 0; i != ionization.size(); ++i) {
648 As += ionization[i]->getA(vertex.getE());
649 }
650
651 double step = gRandom->Exp(1.0) /
ls;
652 double range = vertex.getRange(As);
653
654 if (vertex.getE() < parameters.Emax_GeV) {
655 if (parameters.Dmax_m < range) {
656 range = parameters.Dmax_m;
657 }
658 }
659
660 double ts =
getThetaMCS(vertex.getE(), min(step,range));
661 double T2 = ts*ts;
662
663 rms.Fill(log10(vertex.getE()), (Double_t) 0, ts*ts);
664
665 vertex.getDirection() += getRandomDirection(T2/3.0);
666
667 vertex.step(As, min(step,range));
668
669 double Es = 0.0;
670
671 if (step < range) {
672
673 if (vertex.getE() >= parameters.Emin_GeV) {
674
675 double y = gRandom->Uniform(
ls);
676
677 for (int i = 0; i != N; ++i) {
678
680
681 if (y < 0.0) {
682
683 Es = radiation[i]->getEnergyOfShower(vertex.getE());
684 ts = radiation[i]->getThetaRMS(vertex.getE(), Es);
685
686 T2 += ts*ts;
687
688 rms.Fill(log10(vertex.getE()), (Double_t) radiation[i]->getID(), ts*ts);
689 rad.Fill(log10(vertex.getE()), (Double_t) radiation[i]->getID(), Es);
690
691 break;
692 }
693 }
694 }
695 }
696
697 vertex.applyEloss(getRandomDirection(T2), Es);
698
699 muon.push_back(vertex);
700
701 vertex.reset();
702 }
703
704
705
706 if (vertex.getZ() < Zmax && vertex.getRange() > 0.0) {
707
708 vertex.step(vertex.getRange());
709
710 muon.push_back(vertex);
711 }
712
713
714
716 event.mc_trks.end(),
717 make_predicate(&
Trk::id, track->id));
718
719 if (trk != event.mc_trks.end()) {
720 trk->len = (muon.rbegin()->getZ() < Zmax ? +1 : -1) * (muon.rbegin()->getZ() - muon.begin()->getZ());
722 }
723
724 for (JDetector::const_iterator module = subdetector.begin(); module != subdetector.end(); ++module) {
725
726 if (module->empty()) {
727 continue;
728 }
729
730 const double z0 = muon.begin()->getZ();
731 const double t0 = muon.begin()->getT();
732 const double Z = module->getZ() - module->getX() / getTanThetaC();
733
734 if (Z >= muon.begin()->getZ() && Z <= muon.rbegin()->getZ()) {
735
736 const JVector2D pos = muon.getPosition(Z);
737 const double R = hypot(module->getX() - pos.
getX(),
738 module->getY() - pos.
getY());
739
740 for (size_t i = 0; i != CDF.size(); ++i) {
741
742 if (R < CDF[i].integral.getXmax()) {
743
744 try {
745
746 double W = 1.0;
747
750 }
751
752 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
753 const size_t N = getPoisson(NPE);
754
755 if (N != 0) {
756
758
759 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
760
761 const double R = hypot(pmt->getX() - pos.
getX(),
762 pmt->getY() - pos.
getY());
763 const double theta = pi.constrain(pmt->getTheta());
764 const double phi = pi.constrain(fabs(pmt->getPhi()));
765
766 npe.push_back(CDF[i].function.getNPE(R, theta, phi) * factor * W);
767 }
768
770
771 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
772
773 const double R = hypot(pmt->getX() - pos.
getX(),
774 pmt->getY() - pos.
getY());
775 const double Z = pmt->getZ() - z0;
776 const double theta = pi.constrain(pmt->getTheta());
777 const double phi = pi.constrain(fabs(pmt->getPhi()));
778
779 size_t n0 = min(ns[
distance(module->begin(),pmt)], parameters.Nmax_PMT);
780
781 job.Fill((double) (100 + CDF[i].type), (double) n0);
782
783 while (n0 != 0) {
784
785 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
787
788 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
789 pmt->getID(),
791 track->id,
792 t0 + (R * getTanThetaC() + Z) / C + t1,
793 n1));
794
795 n0 -= n1;
796 }
797 }
798
799 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
800 job.Fill((double) (300 + CDF[i].type));
801 }
802 }
803 }
804 catch(const exception& error) {
805 job.Fill((double) (200 + CDF[i].type));
806 }
807 }
808 }
809 }
810 }
811
812 for (JTrack::const_iterator vertex = muon.begin(); vertex != muon.end(); ++vertex) {
813
814 const double Es = vertex->getEs();
815
816 if (Es >= parameters.Ecut_GeV) {
817
818 const double z0 = vertex->getZ();
819 const double t0 = vertex->getT();
821
823
824 if (writeEMShowers) {
825 origin =
event.mc_trks.size() + 1;
826 }
827
828 int number_of_hits = 0;
829
830 JDetectorSubset_t::range_type range = subdetector.getRange(z0 - maximal_distance,
831 z0 + maximal_distance);
832
833 for (JDetector::const_iterator module = range.begin(); module != range.end(); ++module) {
834
835 if (module->empty()) {
836 continue;
837 }
838
839 const double R = hypot(module->getX() - vertex->getX(),
840 module->getY() - vertex->getY());
841 const double Z = module->getZ() - z0 - DZ;
842 const double D = sqrt(R*R + Z*Z);
843 const double cd = Z / D;
844
845 for (size_t i = 0; i != CDG.size(); ++i) {
846
847 if (D < CDG[i].integral.getXmax()) {
848
849 try {
850
851 const double NPE = CDG[i].integral.getNPE(D, cd) * Es * module->size() * factor;
852 const size_t N = getPoisson(NPE);
853
854 if (N != 0) {
855
857
858 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
859
860 const double R = hypot(pmt->getX() - vertex->getX(),
861 pmt->getY() - vertex->getY());
862 const double Z = pmt->getZ() - z0 - DZ;
863 const double D = sqrt(R*R + Z*Z);
864 const double cd = Z / D;
865 const double theta = pi.constrain(pmt->getTheta());
866 const double phi = pi.constrain(fabs(pmt->getPhi()));
867
868 npe.push_back(CDG[i].function.getNPE(D, cd, theta, phi) * Es * factor);
869 }
870
872
873 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
874
875 const double R = hypot(pmt->getX() - vertex->getX(),
876 pmt->getY() - vertex->getY());
877 const double theta = pi.constrain(pmt->getTheta());
878 const double phi = pi.constrain(fabs(pmt->getPhi()));
879
880 size_t n0 = min(ns[
distance(module->begin(),pmt)], parameters.Nmax_PMT);
881
882 job.Fill((double) (100 + CDG[i].type), (double) n0);
883
884 while (n0 != 0) {
885
887 const double Z = pmt->getZ() - z0 - dz;
888 const double D = sqrt(R*R + Z*Z);
889 const double cd = Z / D;
890
891 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
893
894 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
895 pmt->getID(),
897 origin,
899 n1));
900
901 n0 -= n1;
902
903 number_of_hits += n1;
904 }
905 }
906
907 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
908 job.Fill((double) (300 + CDG[i].type));
909 }
910 }
911 }
912 catch(const exception& error) {
913 job.Fill((double) (200 + CDG[i].type));
914 }
915 }
916 }
917 }
918
919 if (writeEMShowers && number_of_hits != 0) {
920
921 event.mc_trks.push_back(
JTrk_t(origin,
923 track->id,
924 track->pos + track->dir * vertex->getZ(),
925 track->dir,
926 vertex->getT(),
927 Es));
928 }
929 }
930 }
931
932 } else if (track->len > 0.0) {
933
934
935
936
937
938 job.Fill(6.0);
939
940 const double z0 = 0.0;
941 const double z1 = z0 + track->len;
942 const double t0 = track->t;
943 const double E = track->E;
944
946
948
949 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
950
951 if (module->empty()) {
952 continue;
953 }
954
956
957 const double R = pos.
getX();
959
960 if (Z < z0 ||
961 Z > z1 ||
962 R > maximal_road_width) {
963 continue;
964 }
965
966 for (size_t i = 0; i != CDF.size(); ++i) {
967
968 double W = 1.0;
969
971
974 else
975 continue;
976 }
977
978 if (R < CDF[i].integral.getXmax()) {
979
980 try {
981
982 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
983 const size_t N = getPoisson(NPE);
984
985 if (N != 0) {
986
987 buffer = *module;
988
990
992
993 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
994
995 const double R = pmt->getX();
996 const double theta = pi.constrain(pmt->getTheta());
997 const double phi = pi.constrain(fabs(pmt->getPhi()));
998
999 npe.push_back(CDF[i].function.getNPE(R, theta, phi) * factor * W);
1000 }
1001
1003
1004 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1005
1006 const double R = pmt->getX();
1007 const double Z = pmt->getZ() - z0;
1008 const double theta = pi.constrain(pmt->getTheta());
1009 const double phi = pi.constrain(fabs(pmt->getPhi()));
1010
1011 size_t n0 = min(ns[
distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
1012
1013 job.Fill((double) (120 + CDF[i].type), (double) n0);
1014
1015 while (n0 != 0) {
1016
1017 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
1019
1020 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
1021 pmt->getID(),
1023 track->id,
1024 t0 + (R * getTanThetaC() + Z) / C + t1,
1025 n1));
1026
1027 n0 -= n1;
1028 }
1029 }
1030
1031 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
1032 job.Fill((double) (320 + CDF[i].type));
1033 }
1034 }
1035 }
1036 catch(const exception& error) {
1037 job.Fill((double) (220 + CDF[i].type));
1038 }
1039 }
1040 }
1041 }
1042
1043 if (!buffer.empty()) {
1044 job.Fill(7.0);
1045 }
1046
1048
1050
1051
1052
1053
1054
1055 job.Fill(8.0);
1056
1057 double E = track->E;
1058
1059 try {
1061 }
1062 catch(const exception& error) {
1063 ERROR(error.what() << endl);
1064 }
1065
1066 E =
pythia(track->type, E);
1067
1068 if (E >= parameters.Ecut_GeV && cylinder.getDistance(
getPosition(*track)) < parameters.Dmin_m) {
1069
1070 const double z0 = 0.0;
1071 const double t0 = track->t;
1073
1075
1077
1078 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
1079
1080 if (module->empty()) {
1081 continue;
1082 }
1083
1085
1086 const double R = pos.
getX();
1087 const double Z = pos.
getZ() - z0 - DZ;
1088 const double D = sqrt(R*R + Z*Z);
1089 const double cd = Z / D;
1090
1091 for (size_t i = 0; i != CDG.size(); ++i) {
1092
1093 if (D < CDG[i].integral.getXmax()) {
1094
1095 try {
1096
1097 const double NPE = CDG[i].integral.getNPE(D, cd) * E * module->size() * factor;
1098 const size_t N = getPoisson(NPE);
1099
1100 if (N != 0) {
1101
1102 buffer = *module;
1103
1105
1107
1108 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1109
1110 const double R = pmt->getX();
1111 const double Z = pmt->getZ() - z0 - DZ;
1112 const double D = sqrt(R*R + Z*Z);
1113 const double cd = Z / D;
1114 const double theta = pi.constrain(pmt->getTheta());
1115 const double phi = pi.constrain(fabs(pmt->getPhi()));
1116
1117 npe.push_back(CDG[i].function.getNPE(D, cd, theta, phi) * E * factor);
1118 }
1119
1121
1122 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1123
1124 const double theta = pi.constrain(pmt->getTheta());
1125 const double phi = pi.constrain(fabs(pmt->getPhi()));
1126
1127 size_t n0 = min(ns[
distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
1128
1129 job.Fill((double) (140 + CDG[i].type), (double) n0);
1130
1131 while (n0 != 0) {
1132
1134 const double Z = pmt->getZ() - z0 - dz;
1135 const double D = sqrt(R*R + Z*Z);
1136 const double cd = Z / D;
1137
1138 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
1140
1141 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
1142 pmt->getID(),
1144 track->id,
1145 t0 + (dz + D * getIndexOfRefraction()) / C + t1,
1146 n1));
1147
1148 n0 -= n1;
1149 }
1150 }
1151
1152 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
1153 job.Fill((double) (340 + CDG[i].type));
1154 }
1155 }
1156 }
1157 catch(const exception& error) {
1158 job.Fill((double) (240 + CDG[i].type));
1159 }
1160 }
1161 }
1162 }
1163
1164 if (!buffer.empty()) {
1165 job.Fill(9.0);
1166 }
1167
1168 } else {
1169 job.Fill(21.0);
1170 }
1171 }
1172 }
1173 }
1174
1175 if (!mc_hits.empty()) {
1176
1177 mc_hits.
merge(parameters.Tmax_ns);
1178
1179 event.mc_hits.resize(mc_hits.size());
1180
1181 copy(mc_hits.begin(), mc_hits.end(), event.mc_hits.begin());
1182 }
1183
1185
1188 }
1189
1190 if (event.mc_hits.size() >= numberOfHits) {
1191
1193
1194 job.Fill(10.0);
1195 }
1196 }
1198
1204
1206
1208
1210}
#define DEBUG(A)
Message macros.
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
#define gmake_property(A)
macros to convert (template) parameter to JPropertiesElement object
int numberOfBins
number of bins for average CDF integral of optical module
double safetyFactor
safety factor for average CDF integral of optical module
static const char *const APPLICATION_JSIRENE
detector simulation
std::vector< JAANET::simul > simul
JAANET::coord_origin coord_origin
std::vector< JAANET::detector > detector
JAANET::fixedcan fixedcan
Detector subset without binary search functionality.
Detector subset with binary search functionality.
Data structure for a composite optical module.
void transform(const JRotation3D &R, const JVector3D &pos)
Transformation of geometry (see method JGEOMETRY3D::JPosition3D::transform(const JRotation3D&,...
Utility class to parse parameter values.
Auxiliary class for CPU timing and usage.
unsigned long long usec_ucpu
Data structure for vector in two dimensions.
double getY() const
Get y position.
double getX() const
Get x position.
Data structure for position in three dimensions.
double getZ() const
Get z position.
double getX() const
Get x position.
Utility class to parse command line options.
double getLength(const double E, const double P, const double eps=1.0e-5) const
Get shower length for a given integrated probability.
double getMaximum(const double E) const
Get depth of shower maximum.
Auxiliary class for the calculation of the muon radiative cross sections.
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.
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.
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.
const char * getGITVersion()
Get GIT version.
bool is_deltarays(const int pdf)
Test if given PDF type corresponds to Cherenkov light from delta-rays.
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.
double getTanThetaC()
Get average tangent of Cherenkov angle of water corresponding to group velocity.
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.
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
The Evt class respresent a Monte Carlo (MC) event as well as an offline event.
std::vector< Trk > mc_trks
MC: list of MC truth tracks.
The Head class reflects the header of Monte-Carlo event files, which consists of keys (also referred ...
static const JPDB & getInstance()
Get particle data book.
Generator for simulation.
Auxiliary class for PMT parameters including threshold.
Dynamic detector calibration.
Template definition of random value generator.
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
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.
static constexpr double TMAX_GEV
Maximum allowed delta-ray kinetic energy [GeV].
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
static constexpr atom_type H
static constexpr atom_type O
static constexpr atom_type Na
Auxiliary class to set-up Hit.
Auxiliary data structure for list of hits with hit merging capability.
void merge(const double Tmax_ns)
Merge hits on same PMT that are within given time window.
Auxiliary class to set-up Trk.
Vertex of energy loss of muon.
Auxiliary class for defining the range of iterations of objects.
static counter_type max()
Get maximum counter value.
Auxiliary data structure to list files in directory.
The Vec class is a straightforward 3-d vector, which also works in pyroot.