222{
225
227
228 string fileDescriptor;
230 JFileRecorder <JTYPELIST<JAAnetTypes_t, JMetaTypes_t, JRootTypes_t>::typelist>
outputFile;
231 JLimit_t& numberOfEvents = inputFile.getLimit();
232 string detectorFile;
233 JCalibration_t calibrationFile;
234 double Tmax_s;
236 bool writeEMShowers;
237 size_t numberOfHits;
238 double factor;
240
241 try {
242
244
254
257
258 JParser<> zap(
"Main program to simulate detector response to muons and showers.");
259
261 zap[
'F'] =
make_field(fileDescriptor,
"file name descriptor for CDF tables");
267 zap[
'T'] =
make_field(Tmax_s,
"dynamical update time [s]") = 100.0;
268 zap[
's'] =
make_field(writeEMShowers,
"store generated EM showers in event");
269 zap[
'N'] =
make_field(numberOfHits,
"minimum number of hits to output event") = 1;
270 zap[
'U'] =
make_field(factor,
"scaling factor applied to light yields") = 1.0;
273
274 zap(argc, argv);
275 }
276 catch(const exception &error) {
277 FATAL(error.what() << endl);
278 }
279
280
281 seed.set(gRandom);
282
283
284 const JMeta meta(argc, argv);
285
286 const double Zbed = 0.0;
287
290
291 if (fileDescriptor != "") {
292 CDF.push_back(JCDF_t(fileDescriptor, DIRECT_LIGHT_FROM_MUON));
293 CDF.push_back(JCDF_t(fileDescriptor, SCATTERED_LIGHT_FROM_MUON));
294 CDF.push_back(JCDF_t(fileDescriptor, DIRECT_LIGHT_FROM_DELTARAYS));
295 CDF.push_back(JCDF_t(fileDescriptor, SCATTERED_LIGHT_FROM_DELTARAYS));
296
297 CDG.push_back(JCDG_t(fileDescriptor, DIRECT_LIGHT_FROM_EMSHOWER));
298 CDG.push_back(JCDG_t(fileDescriptor, SCATTERED_LIGHT_FROM_EMSHOWER));
299 }
300
301 double maximal_road_width = 0.0;
302 double maximal_distance = 0.0;
303
304 for (size_t i = 0; i != CDF.size(); ++i) {
305
306 DEBUG(
"Range CDF["<< CDF[i].type <<
"] " << CDF[i].function.intensity.getXmax() <<
" m" << endl);
307
308 maximal_road_width = max(maximal_road_width, CDF[i].function.intensity.getXmax());
309 }
310
311 for (size_t i = 0; i != CDG.size(); ++i) {
312
313 DEBUG(
"Range CDG["<< CDG[i].type <<
"] " << CDG[i].function.intensity.getXmax() <<
" m" << endl);
314
316 maximal_road_width = max(maximal_road_width, CDG[i].function.intensity.getXmax());
317 }
318
319 maximal_distance = max(maximal_distance, CDG[i].function.intensity.getXmax());
320 }
321
322 NOTICE(
"Maximal road width [m] " << maximal_road_width << endl);
323 NOTICE(
"Maximal distance [m] " << maximal_distance << endl);
324
325
326 if (detectorFile == "" || inputFile.empty()) {
327 STATUS(
"Nothing to be done." << endl);
328 return 0;
329 }
330
331 struct {
333 } master;
334
335 try {
336
337 STATUS(
"Load detector... " << flush);
338
339 load(detectorFile, master.detector);
340
342 }
345 }
346
347 unique_ptr<JDynamics> dynamics;
348
349 if (!calibrationFile.empty()) {
350
351 try {
352
353 dynamics.reset(
new JDynamics(master.detector, Tmax_s));
354
355 dynamics->load(calibrationFile);
356 }
357 catch(const exception& error) {
359 }
360 }
361
362 const JDetector&
detector = (dynamics ? dynamics->getDetector() : master.detector);
363
366
367 if (true) {
368
369 STATUS(
"Setting up radiation tables... " << flush);
370
375#ifdef RADIATION
376 const JRadiation calcium (JSeaWater::Ca.Z, JSeaWater::Ca.A, 40, 0.01, 0.1, 0.1);
377 const JRadiation magnesium(JSeaWater::Mg.Z, JSeaWater::Mg.A, 40, 0.01, 0.1, 0.1);
378 const JRadiation potassium(JSeaWater::K .Z, JSeaWater::K .A, 40, 0.01, 0.1, 0.1);
379 const JRadiation sulphur (JSeaWater::S .Z, JSeaWater::S .A, 40, 0.01, 0.1, 0.1);
380#endif
381
382 shared_ptr<JRadiation> Hydrogen (make_shared<JRadiationFunction>(hydrogen, 300, 0.2, 1.0e11));
383 shared_ptr<JRadiation> Oxygen (make_shared<JRadiationFunction>(oxygen, 300, 0.2, 1.0e11));
384 shared_ptr<JRadiation> Chlorine (make_shared<JRadiationFunction>(chlorine, 300, 0.2, 1.0e11));
385 shared_ptr<JRadiation> Sodium (make_shared<JRadiationFunction>(sodium, 300, 0.2, 1.0e11));
386#ifdef RADIATION
387 shared_ptr<JRadiation> Calcium (make_shared<JRadiationFunction>(calcium, 300, 0.2, 1.0e11));
388 shared_ptr<JRadiation> Magnesium(make_shared<JRadiationFunction>(magnesium,300, 0.2, 1.0e11));
389 shared_ptr<JRadiation> Potassium(make_shared<JRadiationFunction>(potassium,300, 0.2, 1.0e11));
390 shared_ptr<JRadiation> Sulphur (make_shared<JRadiationFunction>(sulphur, 300, 0.2, 1.0e11));
391#endif
392
397#ifdef RADIATION
402#endif
403
408#ifdef RADIATION
413#endif
414
419#ifdef RADIATION
424#endif
425
427
428 radiation.push_back(make_shared<JDeltaRaysSource>(200,
DENSITY_SEA_WATER, parameters.Tmin_GeV));
429
434#ifdef RADIATION
435 ionization.push_back(make_shared<JACoeffSource>(Calcium,
DENSITY_SEA_WATER * JSeaWater::Ca()));
436 ionization.push_back(make_shared<JACoeffSource>(Magnesium,
DENSITY_SEA_WATER * JSeaWater::Mg()));
437 ionization.push_back(make_shared<JACoeffSource>(Potassium,
DENSITY_SEA_WATER * JSeaWater::K()));
438 ionization.push_back(make_shared<JACoeffSource>(Sulphur,
DENSITY_SEA_WATER * JSeaWater::S()));
439#endif
440
442 }
443
444
446
447 cylinder.addMargin(maximal_distance);
448
449 if (cylinder.getZmin() < Zbed) {
450 cylinder.setZmin(Zbed);
451 }
452
453 NOTICE(
"Light generation volume: " << cylinder << endl);
454
455
458
459 try {
460
461 header = inputFile.getHeader();
462
464
466
469 buffer.simul.rbegin()->date =
getDate();
470 buffer.simul.rbegin()->time =
getTime();
471
473
475
477 buffer.detector.rbegin()->filename = detectorFile;
478
480
481 offset +=
Vec(cylinder.getX(), cylinder.getY(), 0.0);
483
485
486 buffer.fixedcan.xcenter += offset.x;
487 buffer.fixedcan.ycenter += offset.y;
488 buffer.fixedcan.zmin += offset.z;
489 buffer.fixedcan.zmax += offset.z;
490
491 } else {
492
493 buffer.fixedcan.xcenter = cylinder.getX();
494 buffer.fixedcan.ycenter = cylinder.getY();
495
497
498 buffer.fixedcan.radius = buffer.can.r;
499 buffer.fixedcan.zmin = buffer.can.zmin + offset.z;
500 buffer.fixedcan.zmax = buffer.can.zmax + offset.z;
501 } else {
502
503 buffer.fixedcan.radius = cylinder.getRadius();
504 buffer.fixedcan.zmin = cylinder.getZmin();
505 buffer.fixedcan.zmax = cylinder.getZmax();
506 }
507 }
508
510
512
514
516 }
517
518 copy(buffer, header);
519 }
522 }
523
524 NOTICE(
"Offset applied to true tracks is: " << offset << endl);
525
526 TH1D job("job", NULL, 400, 0.5, 400.5);
527 TProfile cpu("cpu", NULL, 16, 0.0, 8.0);
528 TProfile2D rms("rms", NULL, 16, 0.0, 8.0, 251, -0.5, 250.5);
529 TProfile2D rad("rad", NULL, 16, 0.0, 8.0, 251, -0.5, 250.5);
530
531
533
536 }
537
541
542 const double epsilon = 1.0e-6;
544
546
548
549 STATUS(
"event: " << setw(10) << in.getCounter() <<
'\r');
DEBUG(endl);
550
551 job.Fill(1.0);
552
553 Evt* evt = in.next();
554
556 track->pos += offset;
557 }
558
560
561 event.mc_hits.clear();
562
563 if (dynamics) {
564
565 if (event.mc_event_time == TTimeStamp(0)) {
566 FATAL(
"Monte Carlo event time undefined." << endl);
567 }
568
569 dynamics->update(event.mc_event_time.AsDouble());
570 }
571
572
574
577
578 for (vector<Trk>::const_iterator track = evt->
mc_trks.begin(); track != evt->
mc_trks.end(); ++track) {
579
580 if (!track->is_finalstate()) {
581 continue;
582 }
583
585
586
587
588
589
590 job.Fill(2.0);
591
593
595
596 double Zmin = intersection.first;
597 double Zmax = intersection.second;
598
599 if (Zmax - Zmin <= parameters.Dmin_m) {
600 continue;
601 }
602
603 JVertex vertex(0.0, track->t, track->E);
604
605 if (track->pos.z < Zbed) {
606
607 if (track->dir.z > 0.0)
608 vertex.step(
gRock, (Zbed - track->pos.z) / track->dir.z);
609 else
610 continue;
611 }
612
613 if (vertex.getZ() < Zmin) {
614 vertex.step(gWater, Zmin - vertex.getZ());
615 }
616
617 if (vertex.getRange() <= parameters.Dmin_m) {
618 continue;
619 }
620
621 job.Fill(3.0);
622
624
625 if (subdetector.empty()) {
626 continue;
627 }
628
629 job.Fill(4.0);
630
631 JTrack muon(vertex);
632
633 while (vertex.getE() >= parameters.Emin_GeV && vertex.getZ() < Zmax) {
634
635 const int N = radiation.size();
636
637 double li[N];
639
640 for (int i = 0; i != N; ++i) {
641 ls += li[i] = radiation[i]->getInverseInteractionLength(vertex.getE());
642 }
643
644
645
647
648 for (size_t i = 0; i != ionization.size(); ++i) {
649 As += ionization[i]->getA(vertex.getE());
650 }
651
652 double step = gRandom->Exp(1.0) /
ls;
653 double range = vertex.getRange(As);
654
655 if (vertex.getE() < parameters.Emax_GeV) {
656 if (parameters.Dmax_m < range) {
657 range = parameters.Dmax_m;
658 }
659 }
660
661 double ts =
getThetaMCS(vertex.getE(), min(step,range));
662 double T2 = ts*ts;
663
664 rms.Fill(log10(vertex.getE()), (Double_t) 0, ts*ts);
665
666 vertex.getDirection() += getRandomDirection(T2/3.0);
667
668 vertex.step(As, min(step,range));
669
670 double Es = 0.0;
671
672 if (step < range) {
673
674 if (vertex.getE() >= parameters.Emin_GeV) {
675
676 double y = gRandom->Uniform(
ls);
677
678 for (int i = 0; i != N; ++i) {
679
681
682 if (y < 0.0) {
683
684 Es = radiation[i]->getEnergyOfShower(vertex.getE());
685 ts = radiation[i]->getThetaRMS(vertex.getE(), Es);
686
687 T2 += ts*ts;
688
689 rms.Fill(log10(vertex.getE()), (Double_t) radiation[i]->getID(), ts*ts);
690 rad.Fill(log10(vertex.getE()), (Double_t) radiation[i]->getID(), Es);
691
692 break;
693 }
694 }
695 }
696 }
697
698 vertex.applyEloss(getRandomDirection(T2), Es);
699
700 muon.push_back(vertex);
701
702 vertex.reset();
703 }
704
705
706
707 if (vertex.getZ() < Zmax && vertex.getRange() > 0.0) {
708
709 vertex.step(vertex.getRange());
710
711 muon.push_back(vertex);
712 }
713
714
715
717 event.mc_trks.end(),
718 make_predicate(&
Trk::id, track->id));
719
720 if (trk != event.mc_trks.end()) {
721 trk->len = (muon.rbegin()->getZ() < Zmax ? +1 : -1) * (muon.rbegin()->getZ() - muon.begin()->getZ());
723 }
724
725 for (JDetector::const_iterator module = subdetector.begin(); module != subdetector.end(); ++module) {
726
727 if (module->empty()) {
728 continue;
729 }
730
731 const double z0 = muon.begin()->getZ();
732 const double t0 = muon.begin()->getT();
733 const double Z = module->getZ() - module->getX() / getTanThetaC();
734
735 if (Z >= muon.begin()->getZ() && Z <= muon.rbegin()->getZ()) {
736
737 const JVector2D pos = muon.getPosition(Z);
738 const double R = hypot(module->getX() - pos.
getX(),
739 module->getY() - pos.
getY());
740
741 for (size_t i = 0; i != CDF.size(); ++i) {
742
743 if (R < CDF[i].integral.getXmax()) {
744
745 try {
746
747 double W = 1.0;
748
751 }
752
753 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
754 const size_t N = getPoisson(NPE);
755
756 if (N != 0) {
757
759
760 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
761
762 const double R = hypot(pmt->getX() - pos.
getX(),
763 pmt->getY() - pos.
getY());
764 const double theta = pi.constrain(pmt->getTheta());
765 const double phi = pi.constrain(fabs(pmt->getPhi()));
766
767 npe.push_back(CDF[i].function.getNPE(R, theta, phi) * factor * W);
768 }
769
771
772 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
773
774 const double R = hypot(pmt->getX() - pos.
getX(),
775 pmt->getY() - pos.
getY());
776 const double Z = pmt->getZ() - z0;
777 const double theta = pi.constrain(pmt->getTheta());
778 const double phi = pi.constrain(fabs(pmt->getPhi()));
779
780 size_t n0 = min(ns[
distance(module->begin(),pmt)], parameters.Nmax_PMT);
781
782 job.Fill((double) (100 + CDF[i].type), (double) n0);
783
784 while (n0 != 0) {
785
786 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
788
789 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
790 pmt->getID(),
792 track->id,
793 t0 + (R * getTanThetaC() + Z) / C + t1,
794 n1));
795
796 n0 -= n1;
797 }
798 }
799
800 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
801 job.Fill((double) (300 + CDF[i].type));
802 }
803 }
804 }
805 catch(const exception& error) {
806 job.Fill((double) (200 + CDF[i].type));
807 }
808 }
809 }
810 }
811 }
812
813 for (JTrack::const_iterator vertex = muon.begin(); vertex != muon.end(); ++vertex) {
814
815 const double Es = vertex->getEs();
816
817 if (Es >= parameters.Ecut_GeV) {
818
819 const double z0 = vertex->getZ();
820 const double t0 = vertex->getT();
822
824
825 if (writeEMShowers) {
826 origin =
event.mc_trks.size() + 1;
827 }
828
829 int number_of_hits = 0;
830
831 JDetectorSubset_t::range_type range = subdetector.getRange(z0 - maximal_distance,
832 z0 + maximal_distance);
833
834 for (JDetector::const_iterator module = range.begin(); module != range.end(); ++module) {
835
836 if (module->empty()) {
837 continue;
838 }
839
840 const double R = hypot(module->getX() - vertex->getX(),
841 module->getY() - vertex->getY());
842 const double Z = module->getZ() - z0 - DZ;
843 const double D = sqrt(R*R + Z*Z);
844 const double cd = Z / D;
845
846 for (size_t i = 0; i != CDG.size(); ++i) {
847
848 if (D < CDG[i].integral.getXmax()) {
849
850 try {
851
852 const double NPE = CDG[i].integral.getNPE(D, cd) * Es * module->size() * factor;
853 const size_t N = getPoisson(NPE);
854
855 if (N != 0) {
856
858
859 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
860
861 const double R = hypot(pmt->getX() - vertex->getX(),
862 pmt->getY() - vertex->getY());
863 const double Z = pmt->getZ() - z0 - DZ;
864 const double D = sqrt(R*R + Z*Z);
865 const double cd = Z / D;
866 const double theta = pi.constrain(pmt->getTheta());
867 const double phi = pi.constrain(fabs(pmt->getPhi()));
868
869 npe.push_back(CDG[i].function.getNPE(D, cd, theta, phi) * Es * factor);
870 }
871
873
874 for (JModule::const_iterator pmt = module->begin(); pmt != module->end(); ++pmt) {
875
876 const double R = hypot(pmt->getX() - vertex->getX(),
877 pmt->getY() - vertex->getY());
878 const double theta = pi.constrain(pmt->getTheta());
879 const double phi = pi.constrain(fabs(pmt->getPhi()));
880
881 size_t n0 = min(ns[
distance(module->begin(),pmt)], parameters.Nmax_PMT);
882
883 job.Fill((double) (100 + CDG[i].type), (double) n0);
884
885 while (n0 != 0) {
886
888 const double Z = pmt->getZ() - z0 - dz;
889 const double D = sqrt(R*R + Z*Z);
890 const double cd = Z / D;
891
892 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
894
895 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
896 pmt->getID(),
898 origin,
900 n1));
901
902 n0 -= n1;
903
904 number_of_hits += n1;
905 }
906 }
907
908 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
909 job.Fill((double) (300 + CDG[i].type));
910 }
911 }
912 }
913 catch(const exception& error) {
914 job.Fill((double) (200 + CDG[i].type));
915 }
916 }
917 }
918 }
919
920 if (writeEMShowers && number_of_hits != 0) {
921
922 event.mc_trks.push_back(
JTrk_t(origin,
924 track->id,
925 track->pos + track->dir * vertex->getZ(),
926 track->dir,
927 vertex->getT(),
928 Es));
929 }
930 }
931 }
932
933 } else if (track->len > 0.0) {
934
935
936
937
938
939 job.Fill(6.0);
940
941 const double z0 = 0.0;
942 const double z1 = z0 + track->len;
943 const double t0 = track->t;
944 const double E = track->E;
945
947
949
950 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
951
952 if (module->empty()) {
953 continue;
954 }
955
957
958 const double R = pos.
getX();
960
961 if (Z < z0 ||
962 Z > z1 ||
963 R > maximal_road_width) {
964 continue;
965 }
966
967 for (size_t i = 0; i != CDF.size(); ++i) {
968
969 double W = 1.0;
970
972
975 else
976 continue;
977 }
978
979 if (R < CDF[i].integral.getXmax()) {
980
981 try {
982
983 const double NPE = CDF[i].integral.getNPE(R) * module->size() * factor * W;
984 const size_t N = getPoisson(NPE);
985
986 if (N != 0) {
987
988 buffer = *module;
989
991
993
994 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
995
996 const double R = pmt->getX();
997 const double theta = pi.constrain(pmt->getTheta());
998 const double phi = pi.constrain(fabs(pmt->getPhi()));
999
1000 npe.push_back(CDF[i].function.getNPE(R, theta, phi) * factor * W);
1001 }
1002
1004
1005 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1006
1007 const double R = pmt->getX();
1008 const double Z = pmt->getZ() - z0;
1009 const double theta = pi.constrain(pmt->getTheta());
1010 const double phi = pi.constrain(fabs(pmt->getPhi()));
1011
1012 size_t n0 = min(ns[
distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
1013
1014 job.Fill((double) (120 + CDF[i].type), (double) n0);
1015
1016 while (n0 != 0) {
1017
1018 const double t1 = CDF[i].function.getTime(R, theta, phi, gRandom->Rndm());
1020
1021 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
1022 pmt->getID(),
1024 track->id,
1025 t0 + (R * getTanThetaC() + Z) / C + t1,
1026 n1));
1027
1028 n0 -= n1;
1029 }
1030 }
1031
1032 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
1033 job.Fill((double) (320 + CDF[i].type));
1034 }
1035 }
1036 }
1037 catch(const exception& error) {
1038 job.Fill((double) (220 + CDF[i].type));
1039 }
1040 }
1041 }
1042 }
1043
1044 if (!buffer.empty()) {
1045 job.Fill(7.0);
1046 }
1047
1049
1051
1052
1053
1054
1055
1056 job.Fill(8.0);
1057
1058 double E = track->E;
1059
1060 try {
1062 }
1063 catch(const exception& error) {
1064 ERROR(error.what() << endl);
1065 }
1066
1067 E =
pythia(track->type, E);
1068
1069 if (E >= parameters.Ecut_GeV && cylinder.getDistance(
getPosition(*track)) < parameters.Dmin_m) {
1070
1071 const double z0 = 0.0;
1072 const double t0 = track->t;
1074
1076
1078
1079 for (JDetector::const_iterator module =
detector.begin(); module !=
detector.end(); ++module) {
1080
1081 if (module->empty()) {
1082 continue;
1083 }
1084
1086
1087 const double R = pos.
getX();
1088 const double Z = pos.
getZ() - z0 - DZ;
1089 const double D = sqrt(R*R + Z*Z);
1090 const double cd = Z / D;
1091
1092 for (size_t i = 0; i != CDG.size(); ++i) {
1093
1094 if (D < CDG[i].integral.getXmax()) {
1095
1096 try {
1097
1098 const double NPE = CDG[i].integral.getNPE(D, cd) * E * module->size() * factor;
1099 const size_t N = getPoisson(NPE);
1100
1101 if (N != 0) {
1102
1103 buffer = *module;
1104
1106
1108
1109 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1110
1111 const double R = pmt->getX();
1112 const double Z = pmt->getZ() - z0 - DZ;
1113 const double D = sqrt(R*R + Z*Z);
1114 const double cd = Z / D;
1115 const double theta = pi.constrain(pmt->getTheta());
1116 const double phi = pi.constrain(fabs(pmt->getPhi()));
1117
1118 npe.push_back(CDG[i].function.getNPE(D, cd, theta, phi) * E * factor);
1119 }
1120
1122
1123 for (JModule::const_iterator pmt = buffer.begin(); pmt != buffer.end(); ++pmt) {
1124
1125 const double theta = pi.constrain(pmt->getTheta());
1126 const double phi = pi.constrain(fabs(pmt->getPhi()));
1127
1128 size_t n0 = min(ns[
distance(buffer.cbegin(),pmt)], parameters.Nmax_PMT);
1129
1130 job.Fill((double) (140 + CDG[i].type), (double) n0);
1131
1132 while (n0 != 0) {
1133
1135 const double Z = pmt->getZ() - z0 - dz;
1136 const double D = sqrt(R*R + Z*Z);
1137 const double cd = Z / D;
1138
1139 const double t1 = CDG[i].function.getTime(D, cd, theta, phi, gRandom->Rndm());
1141
1142 mc_hits.push_back(
JHit_t(mc_hits.size() + 1,
1143 pmt->getID(),
1145 track->id,
1146 t0 + (dz + D * getIndexOfRefraction()) / C + t1,
1147 n1));
1148
1149 n0 -= n1;
1150 }
1151 }
1152
1153 if (std::accumulate(npe.begin(), npe.end(), 0.0) > NPE) {
1154 job.Fill((double) (340 + CDG[i].type));
1155 }
1156 }
1157 }
1158 catch(const exception& error) {
1159 job.Fill((double) (240 + CDG[i].type));
1160 }
1161 }
1162 }
1163 }
1164
1165 if (!buffer.empty()) {
1166 job.Fill(9.0);
1167 }
1168 }
1169
1170 } else {
1171 job.Fill(21.0);
1172 }
1173 }
1174 }
1175
1176 if (!mc_hits.empty()) {
1177
1178 mc_hits.
merge(parameters.Tmax_ns);
1179
1180 event.mc_hits.resize(mc_hits.size());
1181
1182 copy(mc_hits.begin(), mc_hits.end(), event.mc_hits.begin());
1183 }
1184
1186
1188 cpu.Fill(log10(
get_neutrino(event).E), (
double) timer() * 1.0e-3);
1189 }
1190
1191 if (event.mc_hits.size() >= numberOfHits) {
1192
1194
1195 job.Fill(10.0);
1196 }
1197 }
1199
1205
1207
1209
1211}
#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.
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.
Auxiliary class for CPU timing.
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.