CMS 3D CMS Logo

NuclearInteractionFTFSimulator.cc
Go to the documentation of this file.
1 // system headers
2 #include <mutex>
3 
4 // Framework Headers
7 
8 // Fast Sim headers
13 
14 // Geant4 headers
15 #include "G4ParticleDefinition.hh"
16 #include "G4DynamicParticle.hh"
17 #include "G4Track.hh"
18 #include "G4Step.hh"
19 #include "G4StepPoint.hh"
20 #include "G4TheoFSGenerator.hh"
21 #include "G4FTFModel.hh"
22 #include "G4ExcitedStringDecay.hh"
23 #include "G4LundStringFragmentation.hh"
24 #include "G4GeneratorPrecompoundInterface.hh"
25 #include "G4CascadeInterface.hh"
26 #include "G4DiffuseElastic.hh"
27 
28 #include "G4Proton.hh"
29 #include "G4Neutron.hh"
30 #include "G4PionPlus.hh"
31 #include "G4PionMinus.hh"
32 #include "G4AntiProton.hh"
33 #include "G4AntiNeutron.hh"
34 #include "G4KaonPlus.hh"
35 #include "G4KaonMinus.hh"
36 #include "G4KaonZeroLong.hh"
37 #include "G4KaonZeroShort.hh"
38 #include "G4KaonZero.hh"
39 #include "G4AntiKaonZero.hh"
40 #include "G4GenericIon.hh"
41 
42 #include "G4Lambda.hh"
43 #include "G4OmegaMinus.hh"
44 #include "G4SigmaMinus.hh"
45 #include "G4SigmaPlus.hh"
46 #include "G4SigmaZero.hh"
47 #include "G4XiMinus.hh"
48 #include "G4XiZero.hh"
49 #include "G4AntiLambda.hh"
50 #include "G4AntiOmegaMinus.hh"
51 #include "G4AntiSigmaMinus.hh"
52 #include "G4AntiSigmaPlus.hh"
53 #include "G4AntiSigmaZero.hh"
54 #include "G4AntiXiMinus.hh"
55 #include "G4AntiXiZero.hh"
56 #include "G4AntiAlpha.hh"
57 #include "G4AntiDeuteron.hh"
58 #include "G4AntiTriton.hh"
59 #include "G4AntiHe3.hh"
60 
61 #include "G4Material.hh"
62 #include "G4DecayPhysics.hh"
63 #include "G4ParticleTable.hh"
64 #include "G4IonTable.hh"
65 #include "G4ProcessManager.hh"
66 #include "G4PhysicsLogVector.hh"
67 #include "G4SystemOfUnits.hh"
68 
69 static std::once_flag initializeOnce;
70 CMS_THREAD_GUARD(initializeOnce) const G4ParticleDefinition* NuclearInteractionFTFSimulator::theG4Hadron[] = {nullptr};
72 
73 const double fact = 1.0/CLHEP::GeV;
74 
75 // inelastic interaction length corrections per particle and energy
77  {1.0872, 1.1026, 1.111, 1.111, 1.0105, 0.97622, 0.9511, 0.9526, 0.97591, 0.99277, 1.0099, 1.015, 1.0217, 1.0305, 1.0391, 1.0438, 1.0397, 1.0328, 1.0232, 1.0123, 1.0},
78  {1.0416, 1.1044, 1.1467, 1.1273, 1.026, 0.99085, 0.96572, 0.96724, 0.99091, 1.008, 1.0247, 1.0306, 1.0378, 1.0427, 1.0448, 1.0438, 1.0397, 1.0328, 1.0232, 1.0123, 1.0},
79  {0.5308, 0.53589, 0.67059, 0.80253, 0.82341, 0.79083, 0.85967, 0.90248, 0.93792, 0.9673, 1.0034, 1.022, 1.0418, 1.0596, 1.0749, 1.079, 1.0704, 1.0576, 1.0408, 1.0214, 1.0},
80  {0.49107, 0.50571, 0.64149, 0.77209, 0.80472, 0.78166, 0.83509, 0.8971, 0.93234, 0.96154, 0.99744, 1.0159, 1.0355, 1.0533, 1.0685, 1.0732, 1.0675, 1.0485, 1.0355, 1.0191, 1.0},
81  {1.9746, 1.7887, 1.5645, 1.2817, 1.0187, 0.95216, 0.9998, 1.035, 1.0498, 1.0535, 1.0524, 1.0495, 1.0461, 1.0424, 1.0383, 1.0338, 1.0287, 1.0228, 1.0161, 1.0085, 1.0},
82  {0.46028, 0.59514, 0.70355, 0.70698, 0.62461, 0.65103, 0.71945, 0.77753, 0.83582, 0.88422, 0.92117, 0.94889, 0.96963, 0.98497, 0.99596, 1.0033, 1.0075, 1.0091, 1.0081, 1.005, 1.0},
83  {0.75016, 0.89607, 0.97185, 0.91083, 0.77425, 0.77412, 0.8374, 0.88848, 0.93104, 0.96174, 0.98262, 0.99684, 1.0065, 1.0129, 1.0168, 1.0184, 1.018, 1.0159, 1.0121, 1.0068, 1.0},
84  {0.75016, 0.89607, 0.97185, 0.91083, 0.77425, 0.77412, 0.8374, 0.88848, 0.93104, 0.96174, 0.98262, 0.99684, 1.0065, 1.0129, 1.0168, 1.0184, 1.018, 1.0159, 1.0121, 1.0068, 1.0},
85  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0},
86  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0},
87  {1.1006, 1.1332, 1.121, 1.1008, 1.086, 1.077, 1.0717, 1.0679, 1.0643, 1.0608, 1.057, 1.053, 1.0487, 1.0441, 1.0392, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
88  {1.1318, 1.1255, 1.1062, 1.0904, 1.0802, 1.0742, 1.0701, 1.0668, 1.0636, 1.0602, 1.0566, 1.0527, 1.0485, 1.044, 1.0391, 1.0337, 1.028, 1.0217, 1.015, 1.0078, 1.0},
89  {1.1094, 1.1332, 1.1184, 1.0988, 1.0848, 1.0765, 1.0714, 1.0677, 1.0642, 1.0607, 1.0569, 1.053, 1.0487, 1.0441, 1.0391, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
90  {1.1087, 1.1332, 1.1187, 1.099, 1.0849, 1.0765, 1.0715, 1.0677, 1.0642, 1.0607, 1.057, 1.053, 1.0487, 1.0441, 1.0391, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
91  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0},
92  {1.1192, 1.132, 1.1147, 1.0961, 1.0834, 1.0758, 1.0711, 1.0674, 1.064, 1.0606, 1.0569, 1.0529, 1.0486, 1.0441, 1.0391, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
93  {1.1188, 1.1321, 1.1149, 1.0963, 1.0834, 1.0758, 1.0711, 1.0675, 1.0641, 1.0606, 1.0569, 1.0529, 1.0486, 1.0441, 1.0391, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
94  {0.50776, 0.5463, 0.5833, 0.61873, 0.65355, 0.68954, 0.72837, 0.7701, 0.81267, 0.85332, 0.89037, 0.92329, 0.95177, 0.97539, 0.99373, 1.0066, 1.014, 1.0164, 1.0144, 1.0087, 1.0},
95  {0.50787, 0.5464, 0.58338, 0.6188, 0.65361, 0.6896, 0.72841, 0.77013, 0.8127, 0.85333, 0.89038, 0.92329, 0.95178, 0.9754, 0.99373, 1.0066, 1.014, 1.0164, 1.0144, 1.0087, 1.0},
96  {1.1006, 1.1332, 1.121, 1.1008, 1.086, 1.077, 1.0717, 1.0679, 1.0643, 1.0608, 1.057, 1.053, 1.0487, 1.0441, 1.0392, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
97  {1.1318, 1.1255, 1.1062, 1.0904, 1.0802, 1.0742, 1.0701, 1.0668, 1.0636, 1.0602, 1.0566, 1.0527, 1.0485, 1.044, 1.0391, 1.0337, 1.028, 1.0217, 1.015, 1.0078, 1.0},
98  {1.1094, 1.1332, 1.1184, 1.0988, 1.0848, 1.0765, 1.0714, 1.0677, 1.0642, 1.0607, 1.0569, 1.053, 1.0487, 1.0441, 1.0391, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
99  {1.1087, 1.1332, 1.1187, 1.099, 1.0849, 1.0765, 1.0715, 1.0677, 1.0642, 1.0607, 1.057, 1.053, 1.0487, 1.0441, 1.0391, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
100  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0},
101  {1.1192, 1.132, 1.1147, 1.0961, 1.0834, 1.0758, 1.0711, 1.0674, 1.064, 1.0606, 1.0569, 1.0529, 1.0486, 1.0441, 1.0391, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
102  {1.1188, 1.1321, 1.1149, 1.0963, 1.0834, 1.0758, 1.0711, 1.0675, 1.0641, 1.0606, 1.0569, 1.0529, 1.0486, 1.0441, 1.0391, 1.0338, 1.028, 1.0218, 1.015, 1.0078, 1.0},
103  {0.47677, 0.51941, 0.56129, 0.60176, 0.64014, 0.67589, 0.70891, 0.73991, 0.77025, 0.80104, 0.83222, 0.86236, 0.8901, 0.91518, 0.9377, 0.95733, 0.97351, 0.98584, 0.9942, 0.99879, 1.0},
104  {0.49361, 0.53221, 0.56976, 0.60563, 0.63954, 0.67193, 0.70411, 0.73777, 0.77378, 0.81114, 0.84754, 0.88109, 0.91113, 0.93745, 0.95974, 0.97762, 0.99081, 0.99929, 1.0033, 1.0034, 1.0},
105  {0.4873, 0.52744, 0.56669, 0.60443, 0.64007, 0.67337, 0.70482, 0.73572, 0.76755, 0.80086, 0.83456, 0.86665, 0.8959, 0.92208, 0.94503, 0.96437, 0.97967, 0.99072, 0.99756, 1.0005, 1.0},
106  {0.48729, 0.52742, 0.56668, 0.60442, 0.64006, 0.67336, 0.70482, 0.73571, 0.76754, 0.80086, 0.83455, 0.86665, 0.8959, 0.92208, 0.94503, 0.96437, 0.97967, 0.99072, 0.99756, 1.0005, 1.0},
107 };
108 
109 // elastic interaction length corrections per particle and energy
111  {0.58834, 1.1238, 1.7896, 1.4409, 0.93175, 0.80587, 0.80937, 0.83954, 0.87453, 0.91082, 0.94713, 0.98195, 1.0134, 1.0397, 1.0593, 1.071, 1.0739, 1.0678, 1.053, 1.03, 1.0},
112  {0.40938, 0.92337, 1.3365, 1.1607, 1.008, 0.82206, 0.81163, 0.79489, 0.82919, 0.91812, 0.96688, 1.0225, 1.0734, 1.0833, 1.0874, 1.0854, 1.0773, 1.0637, 1.0448, 1.0235, 1.0},
113  {0.43699, 0.42165, 0.46594, 0.64917, 0.85314, 0.80782, 0.83204, 0.91162, 1.0155, 1.0665, 1.0967, 1.1125, 1.1275, 1.1376, 1.1464, 1.1477, 1.1312, 1.1067, 1.0751, 1.039, 1.0},
114  {0.3888, 0.39527, 0.43921, 0.62834, 0.8164, 0.79866, 0.82272, 0.90163, 1.0045, 1.055, 1.0849, 1.1005, 1.1153, 1.1253, 1.134, 1.1365, 1.1255, 1.0895, 1.0652, 1.0348, 1.0},
115  {0.32004, 0.31119, 0.30453, 0.30004, 0.31954, 0.40148, 0.5481, 0.74485, 0.99317, 1.1642, 1.2117, 1.2351, 1.2649, 1.3054, 1.375, 1.4992, 1.4098, 1.3191, 1.2232, 1.118, 1.0},
116  {0.10553, 0.14623, 0.20655, 0.26279, 0.19996, 0.40125, 0.5139, 0.71271, 0.89269, 1.0108, 1.1673, 1.3052, 1.4149, 1.429, 1.4521, 1.4886, 1.4006, 1.3116, 1.2177, 1.1151, 1.0},
117  {0.106, 0.14692, 0.20755, 0.26257, 0.20089, 0.40236, 0.51452, 0.71316, 0.89295, 1.0109, 1.1673, 1.3053, 1.4149, 1.429, 1.4521, 1.4886, 1.4006, 1.3116, 1.2177, 1.1151, 1.0},
118  {0.31991, 0.31111, 0.30445, 0.30004, 0.31995, 0.40221, 0.54884, 0.74534, 0.99364, 1.1644, 1.2117, 1.2351, 1.265, 1.3054, 1.375, 1.4992, 1.4098, 1.3191, 1.2232, 1.118, 1.0},
119  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0},
120  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0},
121  {0.37579, 0.39922, 0.37445, 0.32631, 0.39002, 0.42161, 0.54251, 0.69127, 0.90332, 1.0664, 1.1346, 1.1481, 1.1692, 1.2036, 1.2625, 1.3633, 1.2913, 1.2215, 1.1516, 1.0788, 1.0},
122  {0.31756, 0.33409, 0.25339, 0.35525, 0.52989, 0.63382, 0.7453, 0.93505, 1.1464, 1.2942, 1.3161, 1.328, 1.3393, 1.3525, 1.374, 1.4051, 1.3282, 1.2523, 1.1745, 1.0916, 1.0},
123  {0.38204, 0.39694, 0.36502, 0.33367, 0.39229, 0.43119, 0.54898, 0.70169, 0.91004, 1.0696, 1.1348, 1.1483, 1.1694, 1.2038, 1.2627, 1.3632, 1.2913, 1.2215, 1.1516, 1.0788, 1.0},
124  {0.38143, 0.39716, 0.36609, 0.33294, 0.39207, 0.43021, 0.54834, 0.70066, 0.90945, 1.0693, 1.1348, 1.1482, 1.1694, 1.2038, 1.2627, 1.3632, 1.2913, 1.2215, 1.1516, 1.0788, 1.0},
125  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0},
126  {0.29564, 0.32645, 0.29986, 0.30611, 0.48808, 0.59902, 0.71207, 0.8832, 1.1164, 1.2817, 1.3154, 1.3273, 1.3389, 1.3521, 1.3736, 1.4056, 1.3285, 1.2524, 1.1746, 1.0916, 1.0},
127  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0},
128  {0.3265, 0.3591, 0.39232, 0.42635, 0.46259, 0.50365, 0.55244, 0.61014, 0.67446, 0.74026, 0.80252, 0.85858, 0.90765, 0.94928, 0.9827, 1.0071, 1.0221, 1.0279, 1.0253, 1.0155, 1.0},
129  {0.13808, 0.15585, 0.17798, 0.2045, 0.22596, 0.25427, 0.33214, 0.44821, 0.5856, 0.74959, 0.89334, 1.0081, 1.0964, 1.1248, 1.173, 1.2548, 1.1952, 1.1406, 1.0903, 1.0437, 1.0},
130  {0.20585, 0.23253, 0.26371, 0.28117, 0.30433, 0.35417, 0.44902, 0.58211, 0.73486, 0.90579, 1.0395, 1.1488, 1.2211, 1.2341, 1.2553, 1.2877, 1.2245, 1.1654, 1.1093, 1.0547, 1.0},
131  {0.2852, 0.32363, 0.31419, 0.35164, 0.45463, 0.54331, 0.66908, 0.81735, 0.98253, 1.1557, 1.2557, 1.3702, 1.4186, 1.401, 1.374, 1.3325, 1.2644, 1.1991, 1.1348, 1.0694, 1.0},
132  {0.20928, 0.23671, 0.2664, 0.28392, 0.30584, 0.35929, 0.45725, 0.5893, 0.74047, 0.9101, 1.0407, 1.1503, 1.2212, 1.2342, 1.2554, 1.2876, 1.2245, 1.1654, 1.1093, 1.0547, 1.0},
133  {0.11897, 0.13611, 0.15796, 0.1797, 0.21335, 0.26367, 0.34705, 0.46115, 0.6016, 0.7759, 0.91619, 1.0523, 1.1484, 1.1714, 1.2098, 1.2721, 1.2106, 1.1537, 1.1004, 1.0496, 1.0},
134  {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.0},
135  {0.26663, 0.30469, 0.32886, 0.33487, 0.41692, 0.51616, 0.63323, 0.78162, 0.95551, 1.1372, 1.2502, 1.3634, 1.4189, 1.4013, 1.3743, 1.3329, 1.2646, 1.1992, 1.1349, 1.0694, 1.0},
136  {0.16553, 0.19066, 0.21468, 0.23609, 0.30416, 0.38821, 0.49644, 0.63386, 0.80299, 0.99907, 1.1304, 1.2724, 1.3535, 1.3475, 1.3381, 1.3219, 1.2549, 1.191, 1.1287, 1.0659, 1.0},
137  {0.37736, 0.41414, 0.45135, 0.48843, 0.52473, 0.55973, 0.59348, 0.62696, 0.66202, 0.70042, 0.74241, 0.786, 0.82819, 0.86688, 0.90128, 0.93107, 0.95589, 0.97532, 0.98908, 0.99719, 1.0},
138  {0.34354, 0.37692, 0.4109, 0.44492, 0.47873, 0.51296, 0.54937, 0.59047, 0.63799, 0.69117, 0.74652, 0.7998, 0.84832, 0.89111, 0.92783, 0.95798, 0.98095, 0.99635, 1.0043, 1.0052, 1.0},
139  {0.36364, 0.39792, 0.43277, 0.4676, 0.50186, 0.53538, 0.56884, 0.604, 0.64308, 0.68729, 0.73544, 0.7842, 0.83019, 0.87156, 0.90777, 0.93854, 0.96346, 0.98209, 0.99421, 1, 1.0},
140  {0.36362, 0.39791, 0.43276, 0.46759, 0.50185, 0.53537, 0.56883, 0.604, 0.64307, 0.68728, 0.73544, 0.7842, 0.83019, 0.87156, 0.90777, 0.93854, 0.96346, 0.98209, 0.99421, 1, 1.0},
141 };
142 
143 // inelastic interaction length in Silicon at 1 TeV per particle
144 const double nuclInelLength[numHadrons] = {
145 4.5606, 4.4916, 5.7511, 5.7856, 6.797, 6.8373, 6.8171, 6.8171, 0, 0, 4.6926, 4.6926, 4.6926, 4.6926, 0, 4.6926, 4.6926, 4.3171, 4.3171, 4.6926, 4.6926, 4.6926, 4.6926, 0, 4.6926, 4.6926, 2.509, 2.9048, 2.5479, 2.5479
146 };
147 
148 // elastic interaction length in Silicon at 1 TeV per particle
149 const double nuclElLength[numHadrons] = {
150 9.248, 9.451, 11.545, 11.671, 32.081, 34.373, 34.373, 32.081, 0, 0, 15.739, 20.348, 15.739, 15.739, 0, 20.349, 0, 9.7514, 12.864, 15.836, 20.516, 15.836, 15.744, 0, 20.517, 20.44, 4.129, 6.0904, 4.5204, 4.5204
151 };
152 
153 
155  unsigned int distAlgo, double distCut, double elimit, double eth) :
156  curr4Mom(0.,0.,0.,0.),
157  vectProj(0.,0.,1.),
158  theBoost(0.,0.,0.),
159  theBertiniLimit(elimit),
160  theEnergyLimit(eth),
161  theDistCut(distCut),
162  distMin(1E99),
163  theDistAlgo(distAlgo)
164 {
165  // FTF model
166  theHadronicModel = new G4TheoFSGenerator("FTF");
167  theStringModel = new G4FTFModel();
168  G4GeneratorPrecompoundInterface* cascade
169  = new G4GeneratorPrecompoundInterface(new CMSDummyDeexcitation());
170  theLund = new G4LundStringFragmentation();
171  theStringDecay = new G4ExcitedStringDecay(theLund);
172  theStringModel->SetFragmentationModel(theStringDecay);
173 
174  theHadronicModel->SetTransport(cascade);
175  theHadronicModel->SetHighEnergyGenerator(theStringModel);
176  theHadronicModel->SetMinEnergy(theEnergyLimit);
177 
178  // Bertini Cascade
179  theBertiniCascade = new G4CascadeInterface();
180 
181  theDiffuseElastic = new G4DiffuseElastic();
182 
183  // Geant4 particles and cross sections
184  std::call_once(initializeOnce, [this] () {
185  theG4Hadron[0] = G4Proton::Proton();
186  theG4Hadron[1] = G4Neutron::Neutron();
187  theG4Hadron[2] = G4PionPlus::PionPlus();
188  theG4Hadron[3] = G4PionMinus::PionMinus();
189  theG4Hadron[4] = G4KaonPlus::KaonPlus();
190  theG4Hadron[5] = G4KaonMinus::KaonMinus();
191  theG4Hadron[6] = G4KaonZeroLong::KaonZeroLong();
192  theG4Hadron[7] = G4KaonZeroShort::KaonZeroShort();
193  theG4Hadron[8] = G4KaonZero::KaonZero();
194  theG4Hadron[9] = G4AntiKaonZero::AntiKaonZero();
196  theG4Hadron[11]= G4OmegaMinus::OmegaMinus();
197  theG4Hadron[12]= G4SigmaMinus::SigmaMinus();
198  theG4Hadron[13]= G4SigmaPlus::SigmaPlus();
200  theG4Hadron[15]= G4XiMinus::XiMinus();
201  theG4Hadron[16]= G4XiZero::XiZero();
202  theG4Hadron[17]= G4AntiProton::AntiProton();
203  theG4Hadron[18]= G4AntiNeutron::AntiNeutron();
204  theG4Hadron[19]= G4AntiLambda::AntiLambda();
205  theG4Hadron[20]= G4AntiOmegaMinus::AntiOmegaMinus();
206  theG4Hadron[21]= G4AntiSigmaMinus::AntiSigmaMinus();
207  theG4Hadron[22]= G4AntiSigmaPlus::AntiSigmaPlus();
208  theG4Hadron[23]= G4AntiSigmaZero::AntiSigmaZero();
209  theG4Hadron[24]= G4AntiXiMinus::AntiXiMinus();
210  theG4Hadron[25]= G4AntiXiZero::AntiXiZero();
211  theG4Hadron[26]= G4AntiAlpha::AntiAlpha();
212  theG4Hadron[27]= G4AntiDeuteron::AntiDeuteron();
213  theG4Hadron[28]= G4AntiTriton::AntiTriton();
214  theG4Hadron[29]= G4AntiHe3::AntiHe3();
215 
216  // other Geant4 particles
217  G4ParticleDefinition* ion = G4GenericIon::GenericIon();
218  ion->SetProcessManager(new G4ProcessManager(ion));
219  G4DecayPhysics decays;
220  decays.ConstructParticle();
221  G4ParticleTable* partTable = G4ParticleTable::GetParticleTable();
222  partTable->SetVerboseLevel(0);
223  partTable->SetReadiness();
224 
225  for(int i=0; i<numHadrons; ++i) {
226  theId[i] = theG4Hadron[i]->GetPDGEncoding();
227  }
228  });
229 
230  // local objects
231  vect = new G4PhysicsLogVector(npoints-1,100*MeV,TeV);
233  currIdx = 0;
234  index = 0;
235  currTrack = nullptr;
237 
238  // fill projectile particle definitions
239  dummyStep = new G4Step();
240  dummyStep->SetPreStepPoint(new G4StepPoint());
241 
242  // target is always Silicon
243  targetNucleus.SetParameters(28, 14);
244 }
245 
247 
248  delete theStringDecay;
249  delete theStringModel;
250  delete theLund;
251  delete vect;
252 }
253 
256 {
257  //std::cout << "#### Primary " << Particle.pid() << " E(GeV)= "
258  // << Particle.momentum().e() << std::endl;
259 
260  int thePid = Particle.pid();
261  if(thePid != theId[currIdx]) {
262  currParticle = nullptr;
263  currIdx = 0;
264  for(; currIdx<numHadrons; ++currIdx) {
265  if(theId[currIdx] == thePid) {
267  // neutral kaons
268  if(7 == currIdx || 8 == currIdx) {
270  if(random->flatShoot() > 0.5) { currParticle = theG4Hadron[10]; }
271  }
272  break;
273  }
274  }
275  }
276  if(!currParticle) { return; }
277 
278  // fill projectile for Geant4
279  double mass = currParticle->GetPDGMass();
280  double ekin = CLHEP::GeV*Particle.momentum().e() - mass;
281 
282  // check interaction length
285  if(0.0 == intLengthInelastic) { return; }
286 
287  // apply corrections
288  if(ekin <= vect->Energy(0)) {
291  } else if(ekin < vect->Energy(npoints-1)) {
292  index = vect->FindBin(ekin, index);
293  double e1 = vect->Energy(index);
294  double e2 = vect->Energy(index+1);
295  intLengthElastic *= ((corrfactors_el[currIdx][index]*(e2 - ekin) +
296  corrfactors_el[currIdx][index+1]*(ekin - e1))/(e2 - e1));
297  intLengthInelastic *= ((corrfactors_inel[currIdx][index]*(e2 - ekin) +
298  corrfactors_inel[currIdx][index+1]*(ekin - e1))/(e2 - e1));
299  }
300  /*
301  std::cout << " Primary " << currParticle->GetParticleName()
302  << " E(GeV)= " << e*fact << std::endl;
303  */
304 
305  double currInteractionLength = -G4Log(random->flatShoot())*intLengthElastic*intLengthInelastic
307  /*
308  std::cout << "*NuclearInteractionFTFSimulator::compute: R(X0)= " << radLengths
309  << " Rnuc(X0)= " << theNuclIntLength[currIdx] << " IntLength(X0)= "
310  << currInteractionLength << std::endl;
311  */
312  // Check position of nuclear interaction
313  if (currInteractionLength > radLengths) { return; }
314 
315  // fill projectile for Geant4
316  double px = Particle.momentum().px();
317  double py = Particle.momentum().py();
318  double pz = Particle.momentum().pz();
319  double ptot = sqrt(px*px + py*py + pz*pz);
320  double norm = 1./ptot;
321  G4ThreeVector dir(px*norm, py*norm, pz*norm);
322  /*
323  std::cout << " Primary " << currParticle->GetParticleName()
324  << " E(GeV)= " << e*fact << " P(GeV/c)= ("
325  << px << " " << py << " " << pz << ")" << std::endl;
326  */
327 
328  G4DynamicParticle* dynParticle = new G4DynamicParticle(theG4Hadron[currIdx],dir,ekin);
329  currTrack = new G4Track(dynParticle, 0.0, vectProj);
330  currTrack->SetStep(dummyStep);
331 
332  theProjectile.Initialise(*currTrack);
333  delete currTrack;
334 
335  G4HadFinalState* result;
336 
337  // elastic interaction
339 
340  result = theDiffuseElastic->ApplyYourself(theProjectile, targetNucleus);
341  G4ThreeVector dirnew = result->GetMomentumChange().unit();
342  double cost = (dir*dirnew);
343  double sint = std::sqrt((1. - cost)*(1. + cost));
344 
345  curr4Mom.set(ptot*dirnew.x(),ptot*dirnew.y(),ptot*dirnew.z(),Particle.momentum().e());
346 
347  // Always create a daughter if the kink is large engough
348  if (sint > theDistCut) {
349  saveDaughter(Particle, curr4Mom, thePid);
350  } else {
351  Particle.SetXYZT(curr4Mom.px(), curr4Mom.py(), curr4Mom.pz(), curr4Mom.e());
352  }
353 
354  // inelastic interaction
355  } else {
356 
357  // Bertini cascade for low-energy hadrons (except light anti-nuclei)
358  // FTFP is applied above energy limit and for all anti-hyperons and anti-ions
359  if(ekin <= theBertiniLimit && currIdx < 17) {
360  result = theBertiniCascade->ApplyYourself(theProjectile, targetNucleus);
361  } else {
362  result = theHadronicModel->ApplyYourself(theProjectile, targetNucleus);
363  }
364  if(result) {
365 
366  int nsec = result->GetNumberOfSecondaries();
367  if(0 < nsec) {
368 
369  result->SetTrafoToLab(theProjectile.GetTrafoToLab());
370  _theUpdatedState.clear();
371 
372  //std::cout << " " << nsec << " secondaries" << std::endl;
373  // Generate angle
374  double phi = random->flatShoot()*CLHEP::twopi;
376  distMin = 1e99;
377 
378  // rotate and store secondaries
379  for (int j=0; j<nsec; ++j) {
380 
381  const G4DynamicParticle* dp = result->GetSecondary(j)->GetParticle();
382  int thePid = dp->GetParticleDefinition()->GetPDGEncoding();
383 
384  // rotate around primary direction
385  curr4Mom = dp->Get4Momentum();
386  curr4Mom.rotate(phi, vectProj);
387  curr4Mom *= result->GetTrafoToLab();
388  /*
389  std::cout << j << ". " << dp->GetParticleDefinition()->GetParticleName()
390  << " " << thePid
391  << " " << curr4Mom*fact << std::endl;
392  */
393  // prompt 2-gamma decay for pi0, eta, eta'p
394  if(111 == thePid || 221 == thePid || 331 == thePid) {
395  theBoost = curr4Mom.boostVector();
396  double e = 0.5*dp->GetParticleDefinition()->GetPDGMass();
397  double fi = random->flatShoot()*CLHEP::twopi;
398  double cth = 2*random->flatShoot() - 1.0;
399  double sth = sqrt((1.0 - cth)*(1.0 + cth));
400  G4LorentzVector lv(e*sth*cos(fi),e*sth*sin(fi),e*cth,e);
401  lv.boost(theBoost);
402  saveDaughter(Particle, lv, 22);
403  curr4Mom -= lv;
404  if(curr4Mom.e() > theEnergyLimit) {
405  saveDaughter(Particle, curr4Mom, 22);
406  }
407  } else {
408  if(curr4Mom.e() > theEnergyLimit + dp->GetParticleDefinition()->GetPDGMass()) {
409  saveDaughter(Particle, curr4Mom, thePid);
410  }
411  }
412  }
413  result->Clear();
414  }
415  }
416  }
417 }
418 
420  const G4LorentzVector& lv, int pdgid)
421 {
422  unsigned int idx = _theUpdatedState.size();
423  _theUpdatedState.push_back(Particle);
424  _theUpdatedState[idx].SetXYZT(lv.px()*fact,lv.py()*fact,lv.pz()*fact,lv.e()*fact);
425  _theUpdatedState[idx].setID(pdgid);
426 
427  // Store the closest daughter index (for later tracking purposes, so charged particles only)
428  double distance = distanceToPrimary(Particle,_theUpdatedState[idx]);
429  // Find the closest daughter, if closer than a given upper limit.
430  if ( distance < distMin && distance < theDistCut ) {
431  distMin = distance;
433  }
434  // std::cout << _theUpdatedState[idx] << std::endl;
435 }
436 
437 double
439  const RawParticle& aDaughter) const
440 {
441  double distance = 2E99;
442  // Compute the distance only for charged primaries
443  if ( fabs(Particle.charge()) > 1E-6 ) {
444 
445  // The secondary must have the same charge
446  double chargeDiff = fabs(aDaughter.charge()-Particle.charge());
447  if ( fabs(chargeDiff) < 1E-6 ) {
448 
449  // Here are two distance definitions * to be tuned *
450  switch ( theDistAlgo ) {
451 
452  case 1:
453  // sin(theta12)
454  distance = (aDaughter.Vect().Unit().Cross(Particle.Vect().Unit())).R();
455  break;
456 
457  case 2:
458  // sin(theta12) * p1/p2
459  distance = (aDaughter.Vect().Cross(Particle.Vect())).R()
460  /aDaughter.Vect().Mag2();
461  break;
462 
463  default:
464  // Should not happen
465  break;
466  }
467  }
468  }
469  return distance;
470 }
const double nuclInelLength[numHadrons]
const double GeV
Definition: MathUtil.h:16
double flatShoot(double xmin=0.0, double xmax=1.0) const
void compute(ParticlePropagator &Particle, RandomEngineAndDistribution const *) override
Generate a nuclear interaction according to the probability that it happens.
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
int pid() const
get the HEP particle ID number
Definition: RawParticle.h:265
TRandom random
Definition: MVATrainer.cc:138
const double corrfactors_inel[numHadrons][npoints]
~NuclearInteractionFTFSimulator() override
Default Destructor.
const double MeV
const XYZTLorentzVector & momentum() const
the momentum fourvector
Definition: RawParticle.h:286
void saveDaughter(ParticlePropagator &Particle, const G4LorentzVector &lv, int pdgid)
T sqrt(T t)
Definition: SSEVec.h:18
static std::once_flag initializeOnce
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
#define CMS_THREAD_GUARD(_var_)
const double nuclElLength[numHadrons]
static const int npoints
double charge() const
get the MEASURED charge
Definition: RawParticle.h:282
double distanceToPrimary(const RawParticle &Particle, const RawParticle &aDaughter) const
static const int numHadrons
const double corrfactors_el[numHadrons][npoints]
NuclearInteractionFTFSimulator(unsigned int distAlgo, double distCut, double elimit, double eth)
Constructor.
const G4ParticleDefinition * currParticle
const double fact
static const G4ParticleDefinition * theG4Hadron[numHadrons]
std::vector< RawParticle > _theUpdatedState
dbl *** dir
Definition: mlp_gen.cc:35