StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
LowEnergySigma.cc
1 // LowEnergySigma.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // Function definitions (not found in the header) for the LowEnergySigma class.
7 // Many cross sections and methods used here are based on UrQMD; see
8 // https://doi.org/10.1016/S0146-6410(98)00058-1
9 
10 #include "Pythia8/MathTools.h"
11 #include "Pythia8/LowEnergySigma.h"
12 
13 namespace Pythia8 {
14 
15 //==========================================================================
16 
17 // Tables for interpolation.
18 
19 //--------------------------------------------------------------------------
20 
21 // Important cross sections based on data interpolation.
22 // http://pdg.lbl.gov/2018/hadronic-xsections/hadron.html
23 
24 static const LinearInterpolator ppTotalData(1.88, 5.0, {
25  272.648, 40.1762, 24.645, 23.5487, 23.8546, 24.0346, 26.2545, 28.4582,
26  33.1757, 38.4119, 43.3832, 46.0882, 47.1465, 47.4971, 47.8746, 47.4705,
27  47.434, 47.339, 47.3373, 47.1153, 46.8987, 46.5044, 46.1466, 45.8345,
28  45.511, 45.2259, 45.0478, 44.7954, 44.4798, 44.2947, 44.0139, 43.6164,
29  43.378, 43.0795, 43.1889, 42.8338, 42.5581, 42.343, 42.2069, 42.1636,
30  42.1013, 41.8453, 41.9952, 41.5904, 41.4213, 41.3825, 41.2637, 41.1657,
31  41.1684, 41.1655, 41.0521, 40.9387, 40.8723, 40.8602, 40.8481, 40.9184,
32  40.6, 40.6, 40.6, 40.6, 40.6, 40.6, 40.6, 40.6,
33  40.5405, 40.4559, 40.3713, 40.2868, 40.2022, 40.1176, 40, 40.0422,
34  40.1045, 40.1122, 40.1199, 40.1276, 40.1353, 40.143, 40.1507, 40.1584,
35  40.1661, 40.1739, 40.1816, 40.1893, 40.197, 40.0306, 39.9698, 39.936,
36  39.9021, 39.8682, 39.8343, 39.8005, 39.7666, 39.7327, 39.6988, 39.6649,
37  39.6311, 39.5964, 39.5534, 39.5103,
38 });
39 
40 static const LinearInterpolator pnTotalData(1.88, 5.0, {
41  142.64, 114.626, 56.8113, 41.9946, 37.7012, 33.7894, 32.415, 32.9202,
42  33.7572, 35.0413, 37.2901, 38.3799, 37.8479, 38.1157, 38.199, 38.7035,
43  39.1832, 39.6465, 40.0639, 40.3346, 40.5307, 40.6096, 40.6775, 40.7091,
44  40.7408, 40.7521, 40.7552, 40.7582, 40.7682, 40.7889, 40.8095, 40.8335,
45  41.1568, 41.4801, 41.8033, 42.1266, 42.4499, 42.7732, 43.0965, 43.0604,
46  43.0204, 42.9803, 42.9403, 42.9002, 42.8602, 42.8202, 42.7801, 42.7401,
47  42.7, 42.66, 42.62, 42.5799, 42.5399, 42.4994, 42.3413, 42.1832,
48  42.0251, 41.867, 41.7089, 41.5508, 41.3928, 41.2347, 41.0766, 40.9185,
49  40.7604, 40.6023, 40.4442, 40.2861, 40.128, 39.97, 39.8119, 39.6957,
50  39.6811, 39.6665, 39.6519, 39.6373, 39.6227, 39.6081, 39.5935, 39.5789,
51  39.5643, 39.5497, 39.5351, 39.5205, 39.5059, 39.4906, 39.475, 39.4593,
52  39.4437, 39.428, 39.4124, 39.3966, 39.3803, 39.364, 39.3477, 39.3314,
53  39.3151, 39.2962, 39.2454, 39.1946,
54 });
55 
56 static const LinearInterpolator NNElasticData(2.1, 5.0, {
57  25.8, 25.4777, 25.2635, 24.738, 24.3857, 24.1983, 24.2628, 24.7068,
58  23.8799, 22.6501, 22.4714, 22.15, 21.432, 20.6408, 19.8587, 19.7608,
59  19.6628, 19.5648, 19.4668, 19.3689, 19.2709, 18.8591, 17.9313, 17.1393,
60  16.8528, 16.5662, 16.2797, 15.9932, 15.7066, 15.4201, 15.3088, 14.7717,
61  14.2346, 13.6974, 13.448, 13.3659, 13.2837, 13.2015, 13.1193, 13.0372,
62  12.955, 12.8728, 12.7906, 12.7085, 12.5667, 12.418, 12.2694, 12.1208,
63  11.9762, 11.861, 11.7459, 11.6308, 11.5157, 11.495, 11.4891, 11.4833,
64  11.4774, 11.4716, 11.42, 11.35, 11.3132, 11.2642, 11.19721, 11.0205,
65  10.9438, 10.8671, 10.7904, 10.6137, 10.537, 10.4603, 10.3422, 9.66659,
66  9.60099, 9.57099, 9.8932, 9.8799, 9.7429, 9.6975, 9.622, 9.62194,
67  9.56262, 9.50331, 9.944, 9.7, 9.7993, 9.8534, 9.6074, 9.7615,
68  9.9155, 9.7173, 9.89788, 9.89375, 9.88963, 9.8855, 9.88138, 9.87726,
69  9.87313, 9.91815, 10.1181, 10.3181,
70 });
71 
72 static const LinearInterpolator ppiplusElData(1.75, 4.0, {
73  14.9884, 13.1613, 17.5848, 17.1952, 14.932, 13.0259, 11.8972, 9.86683,
74  9.39563, 8.70279, 9.05966, 7.03901, 7.47933, 8.05845, 7.78532, 7.00014,
75  6.97142, 6.94208, 7.03342, 6.6845, 6.39362, 6.29438, 6.1932, 6.09007,
76  5.98499, 5.87796, 5.72224, 5.62947, 5.53506, 5.43903, 5.34137, 5.36345,
77  5.40184, 5.44085, 5.44156, 5.33228, 5.22132, 5.10868, 4.99435, 4.90088,
78 });
79 
80 static const LinearInterpolator ppiminusElData(1.75, 4.0, {
81  18.7143, 13.5115, 12.7121, 11.7892, 9.83201, 10.4961, 10.9317, 7.64778,
82  9.47316, 8.90622, 8.28179, 7.9987, 7.70873, 7.7451, 7.53732, 6.25046,
83  7.2379, 7.10072, 6.96453, 6.88106, 6.52894, 5.81146, 6.04954, 4.95788,
84  4.73199, 6.09415, 5.63338, 5.53531, 5.46113, 5.38567, 5.30893, 5.26751,
85  5.23021, 5.19231, 5.1538, 4.7455, 4.73382, 4.72196, 4.70993, 5.05733,
86 });
87 
88 
89 //--------------------------------------------------------------------------
90 
91 // Parameterisation of cross sections for pi pi, from Pelàez et al.
92 // https://doi.org/10.1140/epjc/s10052-019-7509-6
93 
94 static const LinearInterpolator PelaezpippimData(0.27914, 1.42, {
95  0., 9.438, 10.6387, 11.9123, 13.2528, 14.6531, 16.1051, 17.5997,
96  19.1267, 20.6754, 22.234, 23.7909, 25.3345, 26.8535, 28.3379,
97  29.7789, 31.1701, 32.5071, 33.7888, 35.0171, 36.1979, 37.3411,
98  38.461, 39.5772, 40.7148, 41.9052, 43.1878, 44.611, 46.2344, 48.132,
99  50.3953, 53.1381, 56.501, 60.6557, 65.8059, 72.1792, 79.9974,
100  89.4075, 100.345, 112.319, 124.18, 134.079, 139.906, 140.23, 135.099,
101  125.944, 114.732, 103.138, 92.209, 82.4338, 73.9345, 66.6381,
102  60.3804, 54.9732, 50.2289, 45.9671, 42.0124, 38.1876, 34.3082,
103  30.1856, 25.6749, 20.9198, 18.0155, 24.4665, 23.7801, 23.3174,
104  23.0671, 23.0193, 23.1631, 23.4885, 23.9846, 24.6426, 25.3704,
105  26.203, 27.2053, 28.3814, 29.7409, 31.295, 33.0523, 35.014, 37.1648,
106  39.4605, 41.8131, 44.0776, 46.0493, 47.4853, 48.1553, 47.9114,
107  46.7423, 44.7782, 42.2424, 39.3806, 36.4036, 33.4611, 30.6419,
108  27.9869, 25.505, 23.1868, 21.0128, 18.9585, 16.9936 }
109 );
110 
111 static const LinearInterpolator Pelaezpippi0Data(0.27914, 1.42, {
112  0., 0.582125, 0.711825, 0.856636, 1.01562, 1.18828, 1.37453, 1.57464,
113  1.78922, 2.01923, 2.26594, 2.53105, 2.81662, 3.1252, 3.45986,
114  3.82432, 4.22302, 4.66131, 5.14562, 5.68371, 6.28496, 6.96081,
115  7.7252, 8.59529, 9.59224, 10.7424, 12.0785, 13.6419, 15.4846,
116  17.6725, 20.2891, 23.4401, 27.2586, 31.9088, 37.5878, 44.5166,
117  52.9115, 62.914, 74.4548, 87.0394, 99.5153, 110.029, 116.468,
118  117.401, 112.871, 104.312, 93.687, 82.6714, 72.3139, 63.1025,
119  55.1613, 48.4257, 42.7537, 37.9837, 33.964, 30.5625, 27.6687, 25.192,
120  23.0588, 21.2093, 19.5951, 18.1764, 16.9204, 15.8036, 14.7875,
121  13.8567, 13.0046, 12.2253, 11.514, 10.8678, 10.2798, 9.74475,
122  9.25798, 8.81533, 8.41296, 8.04736, 7.71532, 7.41386, 7.14027,
123  6.89203, 6.66685, 6.46261, 6.27736, 6.10933, 5.95688, 5.81849,
124  5.69279, 5.57851, 5.47445, 5.37952, 5.2927, 5.213, 5.13949, 5.07123,
125  5.00728, 4.94662, 4.88814, 4.83048, 4.77189, 4.70984, 4.64022 }
126 );
127 
128 static const LinearInterpolator Pelaezpi0pi0Data(0.27914, 1.42, {
129  0., 10.0054, 11.2925, 12.6399, 14.0407, 15.4871, 16.9701, 18.4796,
130  20.0042, 21.5317, 23.0489, 24.542, 25.9971, 27.4003, 28.7384,
131  29.9989, 31.1705, 32.2438, 33.2109, 34.0661, 34.8057, 35.4283,
132  35.9342, 36.3257, 36.6068, 36.7826, 36.8596, 36.8448, 36.746,
133  36.5712, 36.3283, 36.0254, 35.67, 35.2696, 34.8309, 34.3602, 33.8634,
134  33.3456, 32.8114, 32.265, 31.7099, 31.1492, 30.5853, 30.0204, 29.456,
135  28.8933, 28.3329, 27.7752, 27.2196, 26.6654, 26.1108, 25.5498,
136  24.9632, 24.3243, 23.5973, 22.7338, 21.6687, 20.3155, 18.5633,
137  16.2832, 13.3786, 10.033, 8.37422, 15.9303, 16.2469, 16.7007,
138  17.2866, 18.0008, 18.8389, 19.7985, 20.8717, 22.0535, 23.2558,
139  24.5172, 25.906, 27.4297, 29.101, 30.9338, 32.9395, 35.1217, 37.4672,
140  39.934, 42.436, 44.8299, 46.9127, 48.4428, 49.1914, 49.0118, 47.8937,
141  45.9682, 43.4596, 40.6144, 37.644, 34.6989, 31.8682, 29.1932,
142  26.6834, 24.3292, 22.1114, 20.005, 17.979 }
143 );
144 
145 static const LinearInterpolator PelaezpimpimData(0.27914, 1.42, {
146  0., 1.14955, 1.36568, 1.58422, 1.80352, 2.02229, 2.23956, 2.45456,
147  2.66672, 2.87558, 3.08079, 3.28206, 3.4792, 3.67203, 3.86041,
148  4.04425, 4.22345, 4.39796, 4.56771, 4.73267, 4.89278, 5.04802,
149  5.19837, 5.34378, 5.48425, 5.61975, 5.75026, 5.87577, 5.99624,
150  6.11168, 6.22207, 6.32738, 6.42762, 6.52275, 6.61278, 6.69769,
151  6.77746, 6.85208, 6.92153, 6.9858, 7.04486, 7.09868, 7.14723,
152  7.19046, 7.22833, 7.26076, 7.28766, 7.30894, 7.32447, 7.33409,
153  7.33762, 7.33743, 7.33651, 7.33484, 7.33239, 7.32911, 7.32497,
154  7.31992, 7.31391, 7.30689, 7.29878, 7.28954, 7.2791, 7.2674, 7.25437,
155  7.23997, 7.22413, 7.20679, 7.18972, 7.17776, 7.16691, 7.1557,
156  7.14338, 7.12947, 7.11365, 7.09569, 7.07542, 7.05272, 7.0275,
157  6.99969, 6.96925, 6.93612, 6.90027, 6.86167, 6.82028, 6.77606,
158  6.72895, 6.67888, 6.62576, 6.56948, 6.50989, 6.4468, 6.37995,
159  6.30902, 6.23356, 6.153, 6.0665, 5.97291, 5.87046, 5.75634, 5.62556 }
160 );
161 
162 // pipi -> f_0(500) cross section, without Clebsh-Gordan coefficients.
163 static const LinearInterpolator pipiTof0500Data(0.27915, 1., {
164  8.15994, 9.53565, 11.0102, 12.5738, 14.2131, 15.9117, 17.6494, 19.4033,
165  21.1478, 22.8556, 24.4988, 26.0502, 27.4844, 28.7791, 29.9161, 30.8821,
166  31.669, 32.2741, 32.6997, 32.9524, 33.0426, 32.9833, 32.7894, 32.4769,
167  32.0621, 31.5607, 30.9881, 30.3583, 29.6841, 28.9768, 28.2464, 27.5015,
168  26.749, 25.995, 25.244, 24.4994, 23.7637, 23.0379, 22.3219, 21.6142,
169  20.9102, 20.182, 19.3792, 18.4299, 17.2295, 15.6266, 13.4101, 10.3267,
170  6.29745, 3.39533, }
171 );
172 
173 // Elastic contribution to pipi scattering, below 1.42 GeV.
174 static const LinearInterpolator pipidWaveData(0.27914, 1.42, {
175  0., 1.36571, 1.8036, 2.23967, 2.66687, 3.08096, 3.47941, 3.86064,
176  4.2237, 4.56798, 4.89306, 5.19865, 5.48454, 5.75055, 5.99653,
177  6.22235, 6.42789, 6.61304, 6.7777, 6.92175, 7.04505, 7.1474, 7.22846,
178  7.28776, 7.32452, 7.33762, 7.33651, 7.33237, 7.32495, 7.31388,
179  7.29873, 7.27904, 7.2543, 7.22403, 7.18964, 7.16684, 7.1433, 7.11354,
180  7.07528, 7.02732, 6.96902, 6.9, 6.81997, 6.72858, 6.62534, 6.50941,
181  6.37939, 6.23292, 6.06575, 5.86953, 5.62432 }
182 );
183 
184 //--------------------------------------------------------------------------
185 
186 // Parameterisation of total cross sections for pi K, from Pelàez et al.
187 // This disregards Clebsch-Gordan coefficients.
188 // https://doi.org/10.1103/PhysRevD.93.074025
189 
190 static const LinearInterpolator PelaezpiK12TotData(0.64527, 1.800, {
191  12.8347, 13.4543, 14.0733, 14.691, 15.3069, 15.9207, 16.5323,
192  17.1416, 17.7488, 18.3545, 18.9594, 19.5647, 20.1719, 20.7829,
193  21.4004, 22.0274, 22.668, 23.3271, 24.0107, 24.7262, 25.4827,
194  26.2916, 27.1668, 28.1256, 29.1899, 30.387, 31.7519, 33.3291,
195  35.1764, 37.3692, 40.0068, 43.2209, 47.1879, 52.1452, 58.411,
196  66.4084, 76.6817, 89.8813, 106.652, 127.296, 151.028, 174.909,
197  193.406, 200.496, 193.953, 177.122, 155.853, 134.776, 116.185,
198  100.692, 88.0982, 77.9397, 69.7307, 63.0521, 57.5679, 53.0177,
199  49.2015, 45.9667, 43.1962, 40.7997, 38.7069, 36.8628, 35.224,
200  33.7556, 32.4297, 31.2237, 30.1187, 29.0994, 28.1526, 27.1998,
201  26.4297, 25.8274, 25.2935, 24.8079, 24.3608, 23.9459, 23.5589,
202  23.1967, 22.8569, 22.5375, 22.237, 21.9542, 21.6882, 21.438, 21.2032,
203  20.9832, 20.7777, 20.5866, 20.4095, 20.2466, 20.0979, 19.9634,
204  19.8434, 19.7382, 19.6481, 19.5735, 19.5149, 19.4729, 19.448,
205  19.4409, 19.4525, 19.4833, 19.5344, 19.6065, 19.7007, 19.818,
206  19.9595, 20.1262, 20.3194, 20.5405, 20.7909, 21.0722, 21.3862,
207  21.7351, 22.1215, 22.5483, 23.0191, 23.5384, 24.1113, 24.7441,
208  25.4439, 26.2189, 27.0775, 28.0281, 29.078, 30.2311, 31.4861,
209  32.8328, 34.2485, 35.6941, 37.1118, 38.4247, 39.5421, 40.3687,
210  40.8195, 40.8346, 40.3919, 39.5111, 38.2492, 36.6887, 34.9232,
211  33.0443, 31.1324, 29.2521, 27.4508, 25.7605, 24.2, 22.7783, 21.4973,
212  20.3539, 19.3421, 18.4542, 17.6815, 17.0154, 16.4476, 15.9701,
213  15.5758, 15.2581, 15.0111, 14.8293, 14.7081, 14.6429, 14.6297,
214  14.6644, 14.7431, 14.8616, 15.0158, 15.2007, 15.4114, 15.6419,
215  15.8861, 16.1373, 16.3885, 16.6328, 16.8638, 17.0759, 17.2647,
216  17.4278, 17.5647, 17.6768, 17.7677, 17.8424, 17.9067, 17.967, 18.029,
217  18.098, 18.1777, 18.2704, 18.3766, 18.4956, 18.6245, 18.7591, 18.893,
218  19.0179, 19.1233, 19.1971, 19.227, 19.2025, 19.1176, 18.9719, 19.02 }
219 );
220 
221 static const LinearInterpolator PelaezpiK32TotData(0.64527, 1.800, {
222  7.37595, 9.30047, 11.1782, 12.9339, 14.5161, 15.896, 17.063, 18.0201,
223  18.7794, 19.3582, 19.7763, 20.0538, 20.2102, 20.2636, 20.2301,
224  20.1239, 19.9575, 19.7412, 19.4842, 19.1941, 18.8771, 18.5387,
225  18.1832, 17.8142, 17.4347, 17.0473, 16.6537, 16.2558, 15.8546,
226  15.4511, 15.0461, 14.64, 14.2332, 13.8258, 13.4177, 13.0089, 12.599,
227  12.1876, 11.774, 11.3574, 10.937, 10.5113, 10.0788, 9.6376, 9.18503,
228  8.71768, 8.23082, 7.71761, 7.16748, 6.56219, 7.67088 }
229 );
230 
231 static const LinearInterpolator PelaezpiK32ElData(0.64527, 1.800, {
232  0.64527, 1.800, 4.0221, 5.08067, 6.11084, 7.06899, 7.92639, 8.66777, 9.28859,
233  9.79193, 10.1857, 10.4807, 10.6885, 10.8209, 10.889, 10.903, 10.8717,
234  10.8031, 10.7037, 10.5793, 10.4347, 10.2738, 10.1, 9.91604, 9.72414,
235  9.52616, 9.32358, 9.11763, 8.90926, 8.69924, 8.48814, 8.27641,
236  8.06436, 7.85219, 7.64002, 7.42787, 7.21568, 7.00333, 6.79061,
237  6.57724, 6.36287, 6.14703, 5.92916, 5.70857, 5.48438, 5.2555,
238  5.02051, 4.77753, 4.52398, 4.25615, 3.96826, 3.6504, 3.28237 }
239 );
240 
241 //--------------------------------------------------------------------------
242 
243 // Definitions of static variables used for SaS/DL diffractive cross sections.
244 
245 // Type of the two incoming hadrons as function of the process number:
246 // = 0 : p/n ; = 1 : pi/rho/omega; = 2 : phi.
247 static constexpr int IHADATABLE[] = { 0, 0, 1, 1, 1, 2, 1, 1, 2};
248 static constexpr int IHADBTABLE[] = { 0, 0, 0, 0, 0, 0, 1, 2, 2};
249 
250 // Hadron-Pomeron coupling beta(t) = beta(0) * exp(b*t).
251 static constexpr double BETA0[] = { 4.658, 2.926, 2.149};
252 static constexpr double BHAD[] = { 2.3, 1.4, 1.4};
253 static constexpr double XPROC[] = { 21.70, 21.70, 13.63, 13.63, 13.63,
254  10.01, 8.56, 6.29, 4.62};
255 
256 // Pomeron trajectory alpha(t) = 1 + epsilon + alpha' * t.
257 static constexpr double ALPHAPRIME = 0.25;
258 static constexpr double ALP2 = 2. * ALPHAPRIME;
259 static constexpr double SZERO = 1. / ALPHAPRIME;
260 
261 // Conversion coefficients = 1/(16pi) * (mb <-> GeV^2) * (G_3P)^n,
262 // with n = 0 elastic, n = 1 single and n = 2 double diffractive.
263 static constexpr double CONVERTSD = 0.0336;
264 static constexpr double CONVERTDD = 0.0084;
265 
266 // Minimum threshold below which no cross sections will be defined.
267 static constexpr double MMIN = 0.5;
268 
269 // Lowest energy for parametrized diffractive cross sections.
270 static constexpr double ECMMIN = 10.;
271 
272 // Diffractive mass spectrum starts at m + MMIN0 and has a low-mass
273 // enhancement, factor cRes, up to around m + mRes0.
274 static constexpr double MMIN0 = 0.28;
275 static constexpr double CRES = 2.0;
276 static constexpr double MRES0 = 1.062;
277 
278 // Parameters and coefficients for single diffractive scattering.
279 static constexpr int ISDTABLE[] = { 0, 0, 1, 1, 1, 2, 3, 4, 5};
280 static constexpr double CSD[6][8] = {
281  { 0.213, 0.0, -0.47, 150., 0.213, 0.0, -0.47, 150., } ,
282  { 0.213, 0.0, -0.47, 150., 0.267, 0.0, -0.47, 100., } ,
283  { 0.213, 0.0, -0.47, 150., 0.232, 0.0, -0.47, 110., } ,
284  { 0.267, 0.0, -0.46, 75., 0.267, 0.0, -0.46, 75., } ,
285  { 0.232, 0.0, -0.46, 85., 0.267, 0.0, -0.48, 100., } ,
286  { 0.232, 0.0, -0.48, 110., 0.232, 0.0, -0.48, 110., } };
287 
288 // Parameters and coefficients for double diffractive scattering.
289 static constexpr int IDDTABLE[] = { 0, 0, 1, 1, 1, 2, 3, 4, 5};
290 static constexpr double CDD[6][9] = {
291  { 3.11, -7.34, 9.71, 0.068, -0.42, 1.31, -1.37, 35.0, 118., } ,
292  { 3.11, -7.10, 10.6, 0.073, -0.41, 1.17, -1.41, 31.6, 95., } ,
293  { 3.12, -7.43, 9.21, 0.067, -0.44, 1.41, -1.35, 36.5, 132., } ,
294  { 3.11, -6.90, 11.4, 0.078, -0.40, 1.05, -1.40, 28.4, 78., } ,
295  { 3.11, -7.13, 10.0, 0.071, -0.41, 1.23, -1.34, 33.1, 105., } ,
296  { 3.11, -7.39, 8.22, 0.065, -0.44, 1.45, -1.36, 38.1, 148., } };
297 
298 //==========================================================================
299 
300 // The LowEnergySigma class.
301 
302 //--------------------------------------------------------------------------
303 
304 // Initialize.
305 
306 void LowEnergySigma::init(NucleonExcitations* nucleonExcitationsPtrIn) {
307 
308  // Flag to allow or suppress inelastic processes.
309  doInelastic = flag("Rescattering:inelastic");
310 
311  // Mode for calculating total cross sections for pi pi and pi K.
312  useSummedResonances = flag("LowEnergyQCD:useSummedResonances");
313 
314  // Suppression factors in Additive Quark Model (AQM).
315  sEffAQM = parm("LowEnergyQCD:sEffAQM");
316  cEffAQM = parm("LowEnergyQCD:cEffAQM");
317  bEffAQM = parm("LowEnergyQCD:bEffAQM");
318 
319  // Mixing for eta and eta'; specifically fraction of s sbar.
320  double theta = parm("StringFlav:thetaPS");
321  double alpha = (theta + 54.7) * M_PI / 180.;
322  fracEtass = pow2(sin(alpha));
323  fracEtaPss = 1. - fracEtass;
324 
325  // Some standard masses.
326  mp = particleDataPtr->m0(2212);
327  sp = mp * mp;
328  s4p = 4. * sp;
329  mpi = particleDataPtr->m0(211);
330  mK = particleDataPtr->m0(321);
331 
332  // Store pointer
333  nucleonExcitationsPtr = nucleonExcitationsPtrIn;
334 
335 }
336 
337 //--------------------------------------------------------------------------
338 
339 // Get the total cross section for the specified collision
340 
341 double LowEnergySigma::sigmaTotal(int idAIn, int idBIn, double eCMIn,
342  double mAIn, double mBIn) {
343 
344  // Energy cannot be less than the hadron masses.
345  if (eCMIn <= mAIn + mBIn) {
346  infoPtr->errorMsg("Error in LowEnergySigma::sigmaTotal: nominal masses "
347  "are higher than total energy", "for " + to_string(idAIn) + " "
348  + to_string(idBIn) + " @ " + to_string(eCMIn));
349  return 0.;
350  }
351 
352  // For K0S/K0L, take average of K0 and K0bar.
353  if (idAIn == 310 || idAIn == 130)
354  return 0.5 * (sigmaTotal( 311, idBIn, eCMIn, mAIn, mBIn)
355  + sigmaTotal(-311, idBIn, eCMIn, mAIn, mBIn));
356  if (idBIn == 310 || idBIn == 130)
357  return 0.5 * (sigmaTotal(idAIn, 311, eCMIn, mAIn, mBIn)
358  + sigmaTotal(idAIn, -311, eCMIn, mAIn, mBIn));
359 
360  // Fix particle ordering.
361  setConfig(idAIn, idBIn, eCMIn, mAIn, mBIn);
362 
363  // Special handling for pi pi and pi K cross sections
364  if (!useSummedResonances && eCM < 1.42) {
365  if (idA == 211 && idB == -211)
366  return PelaezpippimData(eCM);
367  else if (idA == 211 && idB == 111)
368  return Pelaezpippi0Data(eCM);
369  else if (idA == 111 && idB == 111)
370  return Pelaezpi0pi0Data(eCM);
371  else if (idA == 211 && idB == 211)
372  return PelaezpimpimData(eCM);
373  }
374  if (!useSummedResonances && eCM < 1.8) {
375  if ((idA == 321 && idB == 211) || (idA == 311 && idB == -211))
376  return PelaezpiK32TotData(eCM);
377  else if ((idA == 321 || idA == 311) && (abs(idB) == 211 || idB == 111))
378  return PelaezpiK12TotData(eCM) * (idB == 111 ? 1./3. : 2./3.);
379  }
380 
381  // Calculate total.
382  calcTot();
383 
384  return sigTot;
385 }
386 
387 //--------------------------------------------------------------------------
388 
389 // Gets the partial cross section for the specified process.
390 
391 double LowEnergySigma::sigmaPartial(int idAIn, int idBIn, double eCMIn,
392  double mAIn, double mBIn, int proc) {
393 
394  // Energy cannot be less than the hadron masses.
395  if (eCMIn <= mAIn + mBIn) {
396  infoPtr->errorMsg("Error in LowEnergySigma::sigmaPartial: nominal masses "
397  "are higher than total energy", "for " + to_string(idAIn) + " "
398  + to_string(idBIn) + " @ " + to_string(eCMIn));
399  return 0.;
400  }
401 
402  // For K0S/K0L, take average of K0 and K0bar.
403  if (idAIn == 310 || idAIn == 130)
404  return 0.5 * (sigmaPartial( 311, idBIn, eCMIn, mAIn, mBIn, proc)
405  + sigmaPartial(-311, idBIn, eCMIn, mAIn, mBIn, proc));
406  if (idBIn == 310 || idBIn == 130)
407  return 0.5 * (sigmaPartial(idAIn, 311, eCMIn, mAIn, mBIn, proc)
408  + sigmaPartial(idAIn, -311, eCMIn, mAIn, mBIn, proc));
409 
410  // Total cross section.
411  if (proc == 0) return sigmaTotal(idAIn, idBIn, eCMIn, mAIn, mBIn);
412 
413  // Get all partial cross sections.
414  vector<int> procs;
415  vector<double> sigmas;
416  if (!sigmaPartial(idAIn, idBIn, eCMIn, mAIn, mBIn, procs, sigmas))
417  return 0.;
418 
419  if (proc == 9)
420  return sigResTot;
421 
422  // Return partial cross section.
423  for (size_t i = 0; i < procs.size(); ++i)
424  if (procs[i] == proc) return sigmas[i];
425 
426  return 0.;
427 }
428 
429 //--------------------------------------------------------------------------
430 
431 // Gets all partial cross sections for the specified collision.
432 // Returns whether any processes have positive cross sections.
433 
434 bool LowEnergySigma::sigmaPartial(int idAIn, int idBIn, double eCMIn,
435  double mAIn, double mBIn, vector<int>& procsOut, vector<double>& sigmasOut) {
436 
437  // No cross sections below threshold.
438  if (eCMIn <= mAIn + mBIn) return false;
439 
440  // If K_S/K_L + X then take the average K0 and K0bar.
441  if (idAIn == 130 || idAIn == 310) {
442  vector<int> procsK, procsKbar;
443  vector<double> sigmasK, sigmasKbar;
444  if ( !sigmaPartial( 311, idBIn, eCMIn, mAIn, mBIn, procsK, sigmasK)
445  || !sigmaPartial(-311, idBIn, eCMIn, mAIn, mBIn, procsKbar, sigmasKbar))
446  return false;
447  for (size_t i = 0; i < procsK.size(); ++i) {
448  procsOut.push_back(procsK[i]);
449  sigmasOut.push_back(0.5 * sigmasK[i]);
450  }
451  for (size_t iKbar = 0; iKbar < procsKbar.size(); ++iKbar) {
452  auto iter = std::find(procsOut.begin(), procsOut.end(),
453  procsKbar[iKbar]);
454  if (iter == procsOut.end()) {
455  procsOut.push_back(procsKbar[iKbar]);
456  sigmasOut.push_back(0.5 * sigmasKbar[iKbar]);
457  } else {
458  int iK = std::distance(procsOut.begin(), iter);
459  sigmasOut[iK] += 0.5 * sigmasKbar[iKbar];
460  }
461  }
462  return true;
463  }
464 
465  // If X + K_S/K_L then take the average K0 and K0bar.
466  if (idBIn == 130 || idBIn == 310) {
467  vector<int> procsK, procsKbar;
468  vector<double> sigmasK, sigmasKbar;
469  if ( !sigmaPartial(idAIn, 311, eCMIn, mAIn, mBIn, procsK, sigmasK)
470  || !sigmaPartial(idAIn, -311, eCMIn, mAIn, mBIn, procsKbar, sigmasKbar))
471  return false;
472  for (size_t i = 0; i < procsK.size(); ++i) {
473  procsOut.push_back(procsK[i]);
474  sigmasOut.push_back(0.5 * sigmasK[i]);
475  }
476  for (size_t iKbar = 0; iKbar < procsKbar.size(); ++iKbar) {
477  auto iter = std::find(procsOut.begin(), procsOut.end(),
478  procsKbar[iKbar]);
479  if (iter == procsOut.end()) {
480  procsOut.push_back(procsKbar[iKbar]);
481  sigmasOut.push_back(0.5 * sigmasKbar[iKbar]);
482  } else {
483  int iK = std::distance(procsOut.begin(), iter);
484  sigmasOut[iK] += 0.5 * sigmasKbar[iKbar];
485  }
486  }
487  return true;
488  }
489 
490  // Store current configuration.
491  setConfig(idAIn, idBIn, eCMIn, mAIn, mBIn);
492 
493  // Calculate total, annihilation and resonant cross sections (if needed).
494  calcTot();
495 
496  // Abort early if total cross section vanishes.
497  if (sigTot == 0.)
498  return false;
499 
500  // If inelastic is off, return only elastic cros ssection.
501  if (!doInelastic) {
502  procsOut.push_back(2);
503  sigmasOut.push_back(sigTot);
504  return true;
505  }
506 
507  // Calculate diffractive cross sections.
508  calcDiff();
509 
510  // Calculate elastic cross sections.
511  calcEla();
512 
513  // Calculate excitation cross sections for NN.
514  calcEx();
515 
516  // Calculate nondiffractive as difference between total and the others.
517  sigND = sigTot - sigEl - sigXB - sigAX - sigXX - sigEx - sigAnn - sigResTot;
518 
519  // Give warning if sigmaND is very negative.
520  if (sigND < -0.1) {
521  infoPtr->errorMsg("Warning in LowEnergySigma::sigmaPartial: sum of "
522  "partial sigmas is larger than total sigma", " for " + to_string(idA)
523  + " + " + to_string(idB) + " @ " + to_string(eCM) + " GeV");
524  }
525 
526  // Rescale pi pi and pi K cross sections to match Pelàez total cross
527  // section.
528  if (!useSummedResonances) {
529  // Rescale for pi pi below 1.42 GeV, and for pi K below 1.8 GeV
530  if ( (eCM < 1.42 && (abs(idA) == 211 || idA == 111)
531  && (abs(idB) == 211 || idB == 111))
532  || (eCM < 1.8 && (idA == 321 || idA == 311)
533  && (abs(idB) == 211 || idB == 111))) {
534 
535  // Get cross section from parameterization.
536  double sigPelaez;
537  if (idA == 211 && idB == -211)
538  sigPelaez = PelaezpippimData(eCM);
539  else if (idA == 211 && idB == 111)
540  sigPelaez = Pelaezpippi0Data(eCM);
541  else if (idA == 111 && idB == 111)
542  sigPelaez = Pelaezpi0pi0Data(eCM);
543  else if (idA == 211 && idB == 211)
544  sigPelaez = PelaezpimpimData(eCM);
545  else if ( (idA == 321 && idB == 211) || (idA == 311 && idB == -211) )
546  sigPelaez = PelaezpiK32TotData(eCM);
547  else if ( (idA == 321 && idB == -211) || (idA == 311 && idB == 211) )
548  sigPelaez = 2./3. * PelaezpiK12TotData(eCM);
549  else if ((idA == 321 || idA == 311) && idB == 111)
550  sigPelaez = 1./3. * PelaezpiK12TotData(eCM);
551  else
552  sigPelaez = sigTot;
553 
554  double scale = sigPelaez / sigTot;
555  sigTot *= scale;
556  sigEl *= scale;
557  sigXB *= scale;
558  sigAX *= scale;
559  sigXX *= scale;
560  sigND *= scale;
561  sigResTot *= scale;
562  for (auto& res : sigRes)
563  res.second *= scale;
564  }
565  }
566 
567  // Write results to output arrays.
568  bool gotAny = false;
569  procsOut.clear();
570  sigmasOut.clear();
571 
572  // sigND is a difference and prone to small numerical imprecisions.
573  if (sigND > 1.0e-9) {
574  procsOut.push_back(1); sigmasOut.push_back(sigND); gotAny = true; }
575  if (sigEl > 0) {
576  procsOut.push_back(2); sigmasOut.push_back(sigEl); gotAny = true; }
577  if (sigXB > 0) {
578  procsOut.push_back(3); sigmasOut.push_back(sigXB); gotAny = true; }
579  if (sigAX > 0) {
580  procsOut.push_back(4); sigmasOut.push_back(sigAX); gotAny = true; }
581  if (sigXX > 0) {
582  procsOut.push_back(5); sigmasOut.push_back(sigXX); gotAny = true; }
583  if (sigEx > 0) {
584  procsOut.push_back(7); sigmasOut.push_back(sigEx); gotAny = true; }
585  if (sigAnn > 0) {
586  procsOut.push_back(8); sigmasOut.push_back(sigAnn); gotAny = true; }
587 
588  for (auto resonance : sigRes) {
589  procsOut.push_back(resonance.first);
590  sigmasOut.push_back(resonance.second);
591  gotAny = true;
592  }
593 
594  return gotAny;
595 
596 }
597 
598 //--------------------------------------------------------------------------
599 
600 // Picks a process randomly according to their partial cross sections.
601 
602 int LowEnergySigma::pickProcess(int idAIn, int idBIn, double eCMIn,
603  double mAIn, double mBIn) {
604 
605  vector<int> processes;
606  vector<double> sigmas;
607  if (!sigmaPartial(idAIn, idBIn, eCMIn, mAIn, mBIn, processes, sigmas))
608  return 0;
609  return processes[rndmPtr->pick(sigmas)];
610 }
611 
612 //--------------------------------------------------------------------------
613 
614 // Picks a resonance according to their partial cross sections.
615 
616 int LowEnergySigma::pickResonance(int idAIn, int idBIn, double eCMIn) {
617 
618  // Set canonical ordering.
619  setConfig(idAIn, idBIn, eCMIn,
620  particleDataPtr->m0(idAIn), particleDataPtr->m0(idBIn));
621 
622  // Fail if no resonances exist.
623  if (!hasExplicitResonances()) return 0;
624 
625  // Calculate cross section for each resonance.
626  calcRes();
627 
628  // Return zero if no resonances are available.
629  if (sigResTot == 0.)
630  return 0;
631 
632  vector<int> ids;
633  vector<double> sigmas;
634  for (auto resonance : sigRes) {
635  if (resonance.second != 0.) {
636  ids.push_back(resonance.first);
637  sigmas.push_back(resonance.second);
638  }
639  }
640 
641  // Pick resonance at random.
642  int resPick = ids[rndmPtr->pick(sigmas)];
643  // Change to antiparticle if the canonical ordering changed signs.
644  return (didFlipSign) ? particleDataPtr->antiId(resPick) : resPick;
645 
646 }
647 
648 //--------------------------------------------------------------------------
649 
650 // Calculate total cross section. This will also calculate annihilation and
651 // resonance cross sections, if necessary.
652 
653 void LowEnergySigma::calcTot() {
654 
655  // pipi special case.
656  if ((idA == 211 || idA == 111) && (abs(idB) == 211 || idB == 111)) {
657 
658  // Resonances are available for all cases except pi+pi+
659  if (!(idA == 211 && idB == 211))
660  calcRes();
661 
662  if (eCM < 1.42) {
663  // Below threshold, use resonances + d-wave
664  double dWaveFactor = (idA == 211 && idB == -211) ? 1./6.
665  : (idA == 211 && idB == 111) ? 1./2.
666  : (idA == 111 && idB == 111) ? 2./3.
667  : 1.;
668  sigTot = sigResTot + dWaveFactor * pipidWaveData(eCM);
669  }
670  else {
671  // Above threshold, use parameterisation based on Pelaez et al.
672  double sCM = eCM * eCM;
673  double h = pow2(2. * M_PI) * GEVSQINV2MB
674  / (eCM * sqrt(sCM - 4. * mpi * mpi));
675  double sCM1 = pow(sCM, 0.53), sCM2 = pow(sCM, 0.06);
676 
677  if (idA == 211 && idB == -211)
678  sigTot = h * (0.83 * sCM + 1.01 * sCM1 + 0.013 * sCM2);
679  else if (idA == 211 && idB == 111)
680  sigTot = h * (0.83 * sCM + 0.267 * sCM1 - 0.0267 * sCM2);
681  else if (idA == 111 && idB == 111)
682  sigTot = h * (0.83 * sCM + 0.267 * sCM1 + 0.053 * sCM2);
683  else // if (idA == 211 && idB == 211)
684  sigTot = h * (0.83 * sCM - 0.473 * sCM1 + 0.013 * sCM2);
685  }
686  }
687 
688  // piK special case. idA must be K+ or K0bar due to canonical ordering.
689  else if ((idA == 321 || idA == 311) && (abs(idB) == 211 || idB == 111)) {
690 
691  // 2 * isospin. Resonances are available if |I| = 1/2.
692  int isoType = abs( (idA == 321 ? 1 : -1)
693  + (idB == 211 ? 2 : idB == -211 ? -2 : 0) );
694 
695  if (isoType == 1)
696  calcRes();
697 
698  double cg2 = isoType == 3 ? 1. : (idB == 111) ? 1./3. : 2./3.;
699 
700  if (eCM < 1.8) {
701  sigTot = (isoType == 1) ? sigResTot : PelaezpiK32TotData(eCM);
702  }
703  else {
704  double sCM = eCM * eCM;
705  double pCoefficient = (isoType == 1 ? 12.3189 : -5.76786);
706  sigTot = cg2 * (10.3548 * sCM + pCoefficient * pow(sCM, 0.53))
707  / sqrt((sCM - pow2(mpi + mK)) * (sCM - pow2(mpi - mK)));
708  }
709  }
710 
711  // Npi special case.
712  else if ((idA == 2212 || idA == 2112) && (abs(idB) == 211 || idB == 111)) {
713  calcRes();
714  if (eCM < meltpoint(idA, idB))
715  sigTot = sigResTot;
716  else {
717  // Npi-.
718  if (idB == -211)
719  sigTot = HPR1R2(18.75, 9.56, 1.767, mA, mB, eCM * eCM);
720  // Npi+, Npi0.
721  else
722  sigTot = HPR1R2(18.75, 9.56, -1.767, mA, mB, eCM * eCM);
723  }
724  }
725 
726  // NKbar special case.
727  else if ((idA == 2212 || idA == 2112) && (idB == -321 || idB == -311)) {
728 
729  calcRes();
730 
731  if (eCM < 2.16) {
732 
733  sigTot = sigResTot;
734 
735  // Add non-diffractive contribution based on description by UrQMD.
736  static constexpr double e0 = 1.433;
737  if (eCM < 1.4738188)
738  sigTot += 5.93763355 / pow2(eCM - 1.251377);
739  else if (eCM < 1.485215)
740  sigTot += -1.296457765e7 * pow4(eCM - e0)
741  + 2.160975431e4 * pow2(eCM - e0) + 120.;
742  else if (eCM < 1.977)
743  sigTot += 3. + 1.0777e6 * exp(-6.4463 * eCM)
744  - 10. * exp(-pow2(eCM - 1.644) / 0.004)
745  + 10. * exp(-pow2(eCM - 1.977) / 0.004);
746  else
747  sigTot += 1.0777e6 * exp(-6.44463 * eCM) + 12.5;
748  }
749 
750  // Use HPR1R2 parametrisations above meltpoint.
751  // pK-, pKbar0.
752  else if (idA == 2212 && (idB == -321 || idB == -311))
753  sigTot = HPR1R2(16.36, 4.29, 3.408, mA, mB, eCM * eCM);
754  // nK-, nKbar0.
755  else if (idA == 2112 && (idB == -321 || idB == -311))
756  sigTot = HPR1R2(16.31, 3.70, 1.826, mA, mB, eCM * eCM);
757  }
758 
759  // NK+ and NK0: use a very simple fit to data.
760  else if ((idA == 2212 || idA == 2112) && (idB == 321 || idB == 311)) {
761  double t = clamp((eCM - 1.65) / (1.9 - 1.65), 0, 1);
762  sigTot = 12.5 * (1 - t) + 17.5 * t;
763  }
764 
765  // pp/nn: use parametrisation.
766  else if ((idA == 2212 && idB == 2212) || (idA == 2112 && idB == 2112))
767  sigTot = (eCM < 5.) ? ppTotalData(eCM)
768  : HPR1R2(34.41, 13.07, -7.394, mA, mB, eCM * eCM);
769 
770  // pn: use parametrisation.
771  else if (idA == 2212 && idB == 2112)
772  sigTot = (eCM < 5.) ? pnTotalData(eCM)
773  : HPR1R2(34.71, 12.52, -6.66, mA, mB, eCM * eCM);
774 
775  // Other BB: use AQM.
776  else if (collType == 1)
777  sigTot = totalAQM();
778 
779  // BBbar: use generic parametrisation.
780  else if (collType == 2) {
781  // Calculate effective energy, i.e. eCM of protons with the same momenta.
782  double sBB = pow2(eCM);
783  double sNN = s4p + (sBB - pow2(mA + mB)) * (sBB - pow2(mA - mB)) / sBB;
784  double pLab = sqrt(sNN * (sNN - s4p)) / (2. * mp);
785 
786  // Calculate ppbar cross section based on UrQMD parameterization.
787  double sigmaTotNN
788  = (pLab < 0.3) ? 271.6 * exp(-1.1 * pLab * pLab)
789  : (pLab < 6.5) ? 75.0 + 43.1 / pLab + 2.6 / pow2(pLab) - 3.9 * pLab
790  : HPR1R2(34.41, 13.07, 7.394, mA, mB, sNN);
791 
792  // Scale pp cross section scaled by AQM factor.
793  double aqmFactor = factorAQM();
794  sigTot = sigmaTotNN * aqmFactor;
795 
796  // Calculate annihilation sigma. If quarks can annihilate, store it;
797  // otherwise, subtract it from the total cross section.
798  double sigmaAnnNN;
799  if (sNN < pow2(2.1)) {
800  calcEla();
801  sigmaAnnNN = sigTot - sigEl;
802  }
803  else {
804  static constexpr double sigma0 = 120., A = 0.050, B = 0.6;
805  sigmaAnnNN = sigma0 * s4p / sNN
806  * ((A * A * s4p) / (pow2(sNN - s4p) + A * A * s4p) + B);
807  }
808 
809  // Check that particles can annihilate.
810  vector<int> countA(5), countB(5);
811  for (int quarksA = ( idA / 10) % 1000; quarksA > 0; quarksA /= 10)
812  countA[quarksA % 10 - 1] += 1;
813  for (int quarksB = (-idB / 10) % 1000; quarksB > 0; quarksB /= 10)
814  countB[quarksB % 10 - 1] += 1;
815  int nMutual = 0;
816  for (int i = 0; i < 5; ++i) nMutual += min(countA[i], countB[i]);
817 
818  // At least one mutual quark pair is needed for baryon number annihilation.
819  if (nMutual >= 1)
820  sigAnn = sigmaAnnNN * aqmFactor;
821  else
822  sigTot -= sigmaAnnNN * aqmFactor;
823  }
824 
825  // If explicit resonances are available.
826  else if (hasExplicitResonances()) {
827  // Calculate resonances.
828  calcRes();
829  if (eCM < meltpoint(idA, idB))
830  sigTot = sigResTot + elasticAQM();
831  else
832  sigTot = totalAQM();
833  }
834 
835  // Last resort: use AQM.
836  else
837  sigTot = totalAQM();
838 
839 }
840 
841 //--------------------------------------------------------------------------
842 
843 // Calculate all resonance cross sections.
844 
845 void LowEnergySigma::calcRes() {
846  for (auto idR : hadronWidthsPtr->possibleResonances(idA, idB)) {
847  double sigResNow = calcRes(idR);
848  if (sigResNow > 0.) {
849  if (didFlipSign) idR = particleDataPtr->antiId(idR);
850  sigResTot += sigResNow;
851  sigRes.push_back(make_pair(idR, sigResNow));
852  }
853  }
854 }
855 
856 //--------------------------------------------------------------------------
857 
858 // Calculate and return cross sections for forming the specified resonance.
859 
860 double LowEnergySigma::calcRes(int idR) const {
861 
862  // Do special case for f0(500).
863  if (idR == 9000221) {
864  if ((idA == 211 && idB == -211) || (idA == 111 && idB == 111))
865  return pipiTof0500Data(eCM);
866  else
867  return 0.;
868  }
869 
870  double gammaR = hadronWidthsPtr->width(idR, eCM);
871  double brR = hadronWidthsPtr->br(idR, idA, idB, eCM);
872 
873  if (gammaR == 0. || brR == 0.)
874  return 0.;
875 
876  // Find particle entries
877  auto* entryR = particleDataPtr->findParticle(idR);
878  auto* entryA = particleDataPtr->findParticle(idA);
879  auto* entryB = particleDataPtr->findParticle(idB);
880 
881  if (entryR == nullptr || entryA == nullptr || entryB == nullptr) {
882  infoPtr->errorMsg("Error in HadronWidths::sigmaResonant: particle does "
883  "not exist", to_string(idR) + " --> " + to_string(idA) + " "
884  + to_string(idB));
885  return 0.;
886  }
887 
888  // Calculate the resonance sigma
889  double s = pow2(eCM), mA0 = entryA->m0(), mB0 = entryB->m0();
890  double pCMS2 = 1 / (4 * s) * (s - pow2(mA0 + mB0)) * (s - pow2(mA0 - mB0));
891 
892  return GEVSQINV2MB * M_PI / pCMS2
893  * entryR->spinType() / (entryA->spinType() * entryB->spinType())
894  * brR * pow2(gammaR) / (pow2(entryR->m0() - eCM) + 0.25 * pow2(gammaR));
895 }
896 
897 //--------------------------------------------------------------------------
898 
899 // Calculate elastic cross section. This may be dependent on the sigTot.
900 
901 void LowEnergySigma::calcEla() {
902 
903  double sCM = eCM * eCM;
904 
905  // Special case for pipi.
906  if ((abs(idA) == 211 || idA == 111) && (abs(idB) == 211 || idB == 111)) {
907  if (eCM < 1.42) {
908  double dWaveFactor = (idA == 211 && idB == -211) ? 1./6.
909  : (idA == 211 && idB == 111) ? 1./2.
910  : (idA == 111 && idB == 111) ? 2./3.
911  : 1.;
912  sigEl = dWaveFactor * pipidWaveData(eCM);
913  }
914  else
915  sigEl = 4.;
916  }
917 
918  // Special case for K pi.
919  else if ((idA == 321 || idA == 311) && (abs(idB) == 211 || idB == 111)) {
920  if (eCM <= 1.8 && ((idA == 321 && idB == 211)
921  || (idA == 311 && idB == -211)))
922  sigEl = PelaezpiK32TotData(eCM);
923  else if (eCM > 1.8)
924  sigEl = 1.5;
925  }
926 
927  // Special cases for Npi.
928  else if ((idA == 2212 || idA == 2112) && (abs(idB) == 211 || idB == 111)) {
929  // Below meltpoint, resonance scattering dominates.
930  if (eCM < meltpoint(idA, idB))
931  sigEl = 0.;
932  else if (eCM < 4.0) {
933  // Data exists for ppi+ and for ppi-.
934  // For general Npi, pick the case that has the corresponding isospin.
935  double sigData
936  = ((idA == 2212 && idB == 211) || (idA == 2112 && idB == -211))
937  ? ppiplusElData(eCM) : ppiminusElData(eCM);
938 
939  double sigResEla = 0.;
940  for (auto resonance : sigRes)
941  sigResEla += resonance.second
942  * hadronWidthsPtr->br(resonance.first, idA, idB, eCM);
943 
944  sigEl = clamp(sigData - sigResEla, 0., sigTot - sigResTot);
945  } else {
946  double pLab = sqrt((sCM - pow2(mA + mB)) * (sCM - pow2(mA - mB)))
947  / (2. * mA);
948  sigEl = HERAFit(0., 11.4, -0.4, 0.079, 0., pLab);
949  }
950  }
951 
952  // Special case for NK- and NKbar0.
953  else if ((idA == 2212 || idA == 2112) && (idB == -321 || idB == -311)) {
954  // Use ad hoc parameterization from UrQMD.
955  static constexpr double e0 = 1.433;
956  if (eCM < 1.67)
957  sigEl = 1.93763355 / pow2(eCM - 1.251377);
958  else if (eCM < 1.485215)
959  sigEl = -1.296457765e7 * pow4(eCM - e0)
960  + 2.160975431e4 * pow2(eCM - e0) + 120.;
961  else if (eCM < 1.91)
962  sigEl = 1.1777e6 * exp(-6.4463 * eCM)
963  - 12. * exp(-pow2(eCM - 1.646) / 0.004)
964  + 10. * exp(-pow2(eCM - 1.937) / 0.004);
965  else
966  sigEl = 5.0 + 5.5777e5 * exp(-6.44463 * eCM);
967  }
968 
969  // Special case for NK+ and NK0.
970  else if ((idA == 2212 || idA == 2112) && (idB == 321 || idB == 311)) {
971  double t = clamp((eCM - 1.7) / (2.5 - 1.7), 0., 1.);
972  sigEl = 12.5 * (1 - t) + 4.0 * t;
973  }
974 
975  // Special case for pp/nn/pn
976  else if ((idA == 2112 || idA == 2212) && (idB == 2112 || idB == 2212)) {
977  // Below 2.1 GeV, only elastic scattering can occur.
978  // Below 5.0 GeV, fit to data.
979  // Above 5.0 GeV, use HERA fit.
980  if (eCM < 2.1)
981  sigEl = sigTot;
982  else if (eCM < 5.0)
983  sigEl = NNElasticData(eCM);
984  else {
985  double pLab = sqrt((sCM - pow2(mA + mB)) * (sCM - pow2(mA - mB)))
986  / (2. * mA);
987  sigEl = HERAFit(11.9, 26.9, -1.21, 0.169, -1.85, pLab);
988  }
989  }
990 
991  // Other BB.
992  else if (collType == 1)
993  sigEl = eCM < mA + mB + 2. * mpi ? totalAQM() : elasticAQM();
994 
995  // BBbar.
996  else if (collType == 2) {
997  double sNN = s4p + (sCM - pow2(mA + mB)) * (sCM - pow2(mA - mB)) / sCM;
998  double pLab = sqrt(sNN * (sNN - s4p)) / (2. * mp);
999 
1000  // Get elastic cross section for ppbar, based on UrQMD parameterization.
1001  double sigmaElNN
1002  = (pLab < 0.3) ? 78.6
1003  : (pLab < 5.) ? 31.6 + 18.3 / pLab - 1.1 / pow2(pLab) - 3.8 * pLab
1004  : HERAFit(10.2, 52.7, -1.16, 0.125, -1.28, pLab);
1005 
1006  // Scale by AQM factor.
1007  sigEl = sigmaElNN * factorAQM();
1008  }
1009 
1010  // For mesons at low energy with no resonances, all interactions are elastic.
1011  else if ((eCM < mA + mB + 2. * mpi) && !hasExplicitResonances())
1012  sigEl = totalAQM();
1013 
1014  // For other baryon+meson/meson+meson, use AQM.
1015  else
1016  sigEl = elasticAQM();
1017 
1018 }
1019 
1020 //--------------------------------------------------------------------------
1021 
1022 void LowEnergySigma::calcDiff() {
1023 
1024  int idANow = idA, idBNow = idB;
1025  double eCMNow = eCM, mANow = mA, mBNow = mB;
1026  bool withEnhancement = !hasExcitation(idA, idB);
1027 
1028  // Real variables. Reset some to zero or unity to begin with.
1029  double sCM, bA, bB, scaleA, scaleB, scaleC, mMinXBsave, mMinAXsave,
1030  mResXBsave, mResAXsave, sum1, sum2, sum3, sum4, sMinXB, sMaxXB, sResXB,
1031  sRMavgXB, sRMlogXB, BcorrXB, sMinAX, sMaxAX, sResAX, sRMavgAX, sRMlogAX,
1032  BcorrAX, y0min, sLog, Delta0, sMaxXX, sLogUp, sLogDn, BcorrXX;
1033  sCM = bA = bB = sum1 = sum2 = sum3 = sum4 = 0.;
1034  scaleA = scaleB = scaleC = 1.;
1035  double eCMsave = eCMNow;
1036 
1037  // Quark content, stripped of spin and radial and orbital excitations.
1038  int idqA = (abs(idANow) / 10) % 1000;
1039  int idqB = (abs(idBNow) / 10) % 1000;
1040  bool sameSign = (idANow > 0 && idBNow > 0) || (idANow < 0 && idBNow < 0);
1041 
1042  // Order flavour of incoming hadrons: idAbsA < idAbsB (restore later).
1043  bool swapped = false;
1044  if (idqA > idqB) {
1045  swap( idANow , idBNow );
1046  swap( idqA, idqB);
1047  swap( mANow , mBNow );
1048  swapped = true;
1049  }
1050 
1051  // Check that (well) above the mass threshold.
1052  // For pseudoscalar mesons use the corresponding vector meson masses.
1053  if (abs(idANow) < 400 && abs(idANow) % 10 == 1)
1054  mANow = particleDataPtr->m0(abs(idANow) + 2);
1055  if (idANow == 130 || idANow == 310) mANow = particleDataPtr->m0(313);
1056  if (abs(idBNow) < 400 && abs(idBNow) % 10 == 1)
1057  mBNow = particleDataPtr->m0(abs(idBNow) + 2);
1058  if (idBNow == 130 || idBNow == 310) mBNow = particleDataPtr->m0(313);
1059  if (eCMNow < mANow + mBNow + MMIN) return;
1060 
1061  // Convert all baryons to protons, with appropriate scale factor,
1062  // and all mesons to pi0 or phi0, again with scale factor.
1063  // Exception: heavy hadrons turned to protons, to go for heavier object.
1064  int idqAtmp = idqA;
1065  bool heavyA = false;
1066  if (idqAtmp == 11 || idqAtmp == 22) {
1067  idqA = 11;
1068  if (idANow == 221) scaleA = 1. - fracEtass + sEffAQM * fracEtass;
1069  } else if (idqAtmp == 33) {
1070  if (idANow == 331) scaleA = fracEtaPss + (1. - fracEtaPss) / sEffAQM;
1071  } else {
1072  int nq[6] = {};
1073  ++nq[idqA%10];
1074  ++nq[(idqA/10)%10];
1075  ++nq[(idqA/100)%10];
1076  heavyA = (nq[4] > 0) || (nq[5] > 0);
1077  idqA = (idqAtmp < 100 && !heavyA) ? 11 : 221;
1078  double nqA = (idqAtmp < 100 && !heavyA) ? 2. : 3.;
1079  scaleA = (nq[1] + nq[2] + sEffAQM * nq[3] + cEffAQM * nq[4]
1080  + bEffAQM * nq[5]) / nqA;
1081  }
1082  int idqBtmp = idqB;
1083  bool heavyB = false;
1084  if (idqBtmp == 11 || idqBtmp == 22) {
1085  idqB = 11;
1086  if (idBNow == 221) scaleB = 1. - fracEtass + sEffAQM * fracEtass;
1087  } else if (idqBtmp == 33) {
1088  if (idBNow == 331) scaleB = fracEtaPss + (1. - fracEtaPss) / sEffAQM;
1089  } else {
1090  int nq[6] = {};
1091  ++nq[idqB%10];
1092  ++nq[(idqB/10)%10];
1093  ++nq[(idqB/100)%10];
1094  heavyB = (nq[4] > 0) || (nq[5] > 0);
1095  idqB = (idqBtmp < 100 && !heavyB) ? 11 : 221;
1096  double nqB = (idqBtmp < 100 && !heavyB) ? 2. : 3.;
1097  scaleB = (nq[1] + nq[2] + sEffAQM * nq[3] + cEffAQM * nq[4]
1098  + bEffAQM * nq[5]) / nqB;
1099  }
1100  scaleC = scaleA * scaleB;
1101 
1102  // Find process number.
1103  int iProc = -1;
1104  if (idqA > 100) {
1105  iProc = (sameSign) ? 0 : 1;
1106  } else if (idqB > 100) {
1107  iProc = (sameSign) ? 2 : 3;
1108  if (idqA == 11) iProc = 4;
1109  if (idqA == 33) iProc = 5;
1110  } else if (idqA > 10) {
1111  iProc = 6;
1112  if (idqB == 33) iProc = 7;
1113  if (idqA == 33) iProc = 8;
1114  }
1115  if (iProc == -1) return;
1116 
1117  // Collision energy, rescaled to same p_CM as for proton if heavy flavour.
1118  if (!heavyA && !heavyB) {
1119  sCM = eCMNow * eCMNow;
1120  } else {
1121  double sAB = eCMNow * eCMNow;
1122  sCM = s4p + (sAB - pow2(mANow + mBNow))
1123  * (sAB - pow2(mANow - mBNow)) / sAB;
1124  eCMNow = sqrt(sCM);
1125  if (heavyA) mANow = mp;
1126  if (heavyB) mBNow = mp;
1127  if (eCMNow < mANow + mBNow + MMIN) return;
1128  eCMsave = eCMNow;
1129  }
1130 
1131  // Slope of hadron form factors.
1132  int iHadA = IHADATABLE[iProc];
1133  int iHadB = IHADBTABLE[iProc];
1134  bA = BHAD[iHadA];
1135  bB = BHAD[iHadB];
1136 
1137  // Smooth interpolation of diffractive cross sections at low energies.
1138  bool lowE = (eCMNow < ECMMIN);
1139  if (lowE) {
1140  eCMNow = ECMMIN;
1141  sCM = eCMNow * eCMNow;
1142  }
1143 
1144  // Lookup coefficients for single and double diffraction.
1145  int iSD = ISDTABLE[iProc];
1146  int iDD = IDDTABLE[iProc];
1147 
1148  // Single diffractive scattering A + B -> X + B cross section.
1149  mMinXBsave = mANow + MMIN0;
1150  sMinXB = pow2(mMinXBsave);
1151  sMaxXB = CSD[iSD][0] * sCM + CSD[iSD][1];
1152  sum1 = log( (2.*bB + ALP2 * log(sCM/sMinXB))
1153  / (2.*bB + ALP2 * log(sCM/sMaxXB)) ) / ALP2;
1154  if (withEnhancement) {
1155  mResXBsave = mANow + MRES0;
1156  sResXB = pow2(mResXBsave);
1157  sRMavgXB = mResXBsave * mMinXBsave;
1158  sRMlogXB = log(1. + sResXB/sMinXB);
1159  BcorrXB = CSD[iSD][2] + CSD[iSD][3] / sCM;
1160  sum2 = CRES * sRMlogXB / (2.*bB + ALP2 * log(sCM/sRMavgXB) + BcorrXB);
1161  }
1162  if (lowE) {
1163  double ratio = max( 0., eCMsave - mMinXBsave - mBNow)
1164  / (ECMMIN - mMinXBsave - mBNow);
1165  double ratio03 = pow(ratio, 0.3);
1166  double ratio06 = pow2(ratio03);
1167  sum1 *= ratio06;
1168  sum2 *= ratio03;
1169  }
1170  sigXB = CONVERTSD * scaleC * XPROC[iProc] * BETA0[iHadB]
1171  * max( 0., sum1 + sum2);
1172 
1173  // Single diffractive scattering A + B -> A + X cross section.
1174  mMinAXsave = mBNow + MMIN0;
1175  sMinAX = pow2(mMinAXsave);
1176  sMaxAX = CSD[iSD][4] * sCM + CSD[iSD][5];
1177  sum1 = log( (2.*bA + ALP2 * log(sCM/sMinAX))
1178  / (2.*bA + ALP2 * log(sCM/sMaxAX)) ) / ALP2;
1179  if (withEnhancement) {
1180  mResAXsave = mBNow + MRES0;
1181  sResAX = pow2(mResAXsave);
1182  sRMavgAX = mResAXsave * mMinAXsave;
1183  sRMlogAX = log(1. + sResAX/sMinAX);
1184  BcorrAX = CSD[iSD][6] + CSD[iSD][7] / sCM;
1185  sum2 = CRES * sRMlogAX / (2.*bA + ALP2 * log(sCM/sRMavgAX) + BcorrAX);
1186  }
1187  if (lowE) {
1188  double ratio = max( 0., eCMsave - mANow - mMinAXsave)
1189  / (ECMMIN - mANow - mMinAXsave);
1190  double ratio03 = pow(ratio, 0.3);
1191  double ratio06 = pow2(ratio03);
1192  sum1 *= ratio06;
1193  sum2 *= ratio03;
1194  }
1195  sigAX = CONVERTSD * scaleC * XPROC[iProc] * BETA0[iHadA]
1196  * max( 0., sum1 + sum2);
1197 
1198  // Double diffractive scattering A + B -> X1 + X2 cross section.
1199  y0min = log( sCM * sp / (sMinXB * sMinAX) ) ;
1200  sLog = log(sCM);
1201  Delta0 = CDD[iDD][0] + CDD[iDD][1] / sLog + CDD[iDD][2] / pow2(sLog);
1202  sum1 = (y0min * (log( max( 1e-10, y0min/Delta0) ) - 1.) + Delta0)
1203  / ALP2;
1204  if (y0min < 0.) sum1 = 0.;
1205  if (withEnhancement) {
1206  sMaxXX = sCM * ( CDD[iDD][3] + CDD[iDD][4] / sLog
1207  + CDD[iDD][5] / pow2(sLog) );
1208  sLogUp = log( max( 1.1, sCM * SZERO / (sMinXB * sRMavgAX) ));
1209  sLogDn = log( max( 1.1, sCM * SZERO / (sMaxXX * sRMavgAX) ));
1210  sum2 = CRES * log( sLogUp / sLogDn ) * sRMlogAX / ALP2;
1211  sLogUp = log( max( 1.1, sCM * SZERO / (sMinAX * sRMavgXB) ));
1212  sLogDn = log( max( 1.1, sCM * SZERO / (sMaxXX * sRMavgXB) ));
1213  sum3 = CRES * log(sLogUp / sLogDn) * sRMlogXB / ALP2;
1214  BcorrXX = CDD[iDD][6] + CDD[iDD][7] / eCMNow + CDD[iDD][8] / sCM;
1215  sum4 = pow2(CRES) * sRMlogAX * sRMlogXB / max( 0.1,
1216  ALP2 * log( sCM * SZERO / (sRMavgAX * sRMavgXB) ) + BcorrXX);
1217  }
1218  if (lowE) {
1219  double ratio = max( 0., eCMsave - mMinXBsave - mMinAXsave)
1220  / (ECMMIN - mMinXBsave - mMinAXsave);
1221  double ratio05 = sqrt(ratio);
1222  double ratio025 = sqrt(ratio05);
1223  sum1 *= ratio * ratio05;
1224  sum2 *= ratio * ratio025;
1225  sum3 *= ratio * ratio025;
1226  sum4 *= ratio;
1227  }
1228  sigXX = CONVERTDD * scaleC * XPROC[iProc]
1229  * max( 0., sum1 + sum2 + sum3 + sum4);
1230  if (eCMsave < mMinXBsave + mMinAXsave) sigXX = 0.;
1231 
1232  // Restore original order, and order single diffractive correctly.
1233  if (swapped) {
1234  swap( idBNow, idANow);
1235  swap( mBNow, mANow);
1236  swap( bB, bA);
1237  swap( sigXB, sigAX);
1238  swap( mMinXBsave, mMinAXsave);
1239  swap( mResXBsave, mResAXsave);
1240  }
1241 
1242  if (didSwapIds)
1243  swap(sigXB, sigAX);
1244 
1245 }
1246 
1247 //--------------------------------------------------------------------------
1248 
1249 // Calculate excitation cross section. This may be dependent on total,
1250 // elastic and diffractive cross sections.
1251 
1252 void LowEnergySigma::calcEx() {
1253 
1254  // Excitations are available only for NN collisions
1255  if ( (abs(idA) == 2212 || abs(idA) == 2112)
1256  && (abs(idB) == 2212 || abs(idB) == 2112) ) {
1257  if (eCM < 3.)
1258  sigEx = sigTot - sigEl - sigXB - sigAX - sigXX - sigAnn;
1259  else
1260  sigEx = min(nucleonExcitationsPtr->sigmaExTotal(eCM),
1261  sigTot - sigEl - sigXB - sigAX - sigXX - sigAnn);
1262  }
1263  else
1264  sigEx = 0.;
1265 }
1266 
1267 //--------------------------------------------------------------------------
1268 
1269 // Sets the configuration of colliding particles, ensuring canonical ordering.
1270 //
1271 // The canonical ordering of A and B is defined as follows:
1272 // 1) If one is a baryon and the other is meson, then A must be the baryon.
1273 // Otherwise, select them such that |A| >= |B|.
1274 // 2) A must be positive.
1275 //
1276 // Implications:
1277 // - In BB, the antiparticle cross sections are the same as the particle ones,
1278 // so BbarBbar is replaced by BB.
1279 // - In BBbar, A is always the particle and B is the antiparticle.
1280 // Again signs are flipped if necessary.
1281 // - In XM, X is a baryon or meson and B is always a meson.
1282 //
1283 // This sets collType for the overall process type:
1284 // 1: BB;
1285 // 2: BBbar;
1286 // 3: XM;
1287 // This also sets didFlipSign if both particles were replaced by their
1288 // antiparticles, and didSwapIds if the particle ids were swapped.
1289 //
1290 void LowEnergySigma::setConfig(int idAIn, int idBIn, double eCMIn,
1291  double mAIn, double mBIn) {
1292 
1293  // Store input and clear cross sections.
1294  idA = idAIn;
1295  idB = idBIn;
1296  eCM = eCMIn;
1297  mA = mAIn;
1298  mB = mBIn;
1299 
1300  sigTot = sigND = sigEl = sigXB = sigAX = sigXX
1301  = sigAnn = sigEx = sigResTot = 0.;
1302  sigRes.clear();
1303 
1304  // Ensure |A| >= |B|.
1305  bool mesA = particleDataPtr->isMeson(idA);
1306  bool mesB = particleDataPtr->isMeson(idB);
1307  didSwapIds = (mesA && !mesB) || (mesA == mesB && abs(idA) < abs(idB));
1308  if (didSwapIds) {
1309  swap(idA, idB);
1310  swap(mA, mB);
1311  swap(mesA, mesB);
1312  }
1313 
1314  // Ensure A > 0.
1315  didFlipSign = idA < 0;
1316  if (didFlipSign) {
1317  idA = -idA;
1318  idB = particleDataPtr->antiId(idB);
1319  }
1320 
1321  // Get type of overall collision: XM, BBbar, BB.
1322  if (mesB) collType = 3;
1323  else if (idB < 0) collType = 2;
1324  else collType = 1;
1325 
1326 }
1327 
1328 //--------------------------------------------------------------------------
1329 
1330 // HPR1R2 fit for parameterizing certain total cross sections.
1331 // http://doi.org/10.1088/1674-1137/40/10/100001 p. 591
1332 
1333 double LowEnergySigma::HPR1R2(double p, double r1, double r2,
1334  double mAIn, double mBIn, double s) const {
1335 
1336  static constexpr double H = 0.2720;
1337  static constexpr double M = 2.1206;
1338  static constexpr double eta1 = 0.4473;
1339  static constexpr double eta2 = 0.5486;
1340 
1341  double ss = s / pow2(mAIn + mBIn + M);
1342  return p + H * pow2(log(ss)) + r1 * pow(ss, -eta1) + r2 * pow(ss, -eta2);
1343 
1344 }
1345 
1346 //--------------------------------------------------------------------------
1347 
1348 // HERA/CERN fit for parameterizing certain elastic cross sections.
1349 // https://doi.org/10.1103/PhysRevD.50.1173 p. 1335
1350 
1351 double LowEnergySigma::HERAFit(double a, double b, double n, double c,
1352  double d, double p) const {
1353  return a + b * pow(p, n) + c * pow2(log(p)) + d * log(p);
1354 }
1355 
1356 //--------------------------------------------------------------------------
1357 
1358 // Additive quark model for generic collisions and for scale factors.
1359 
1360 double LowEnergySigma::nqEffAQM(int id) const {
1361 
1362  // ssbar mixing into eta and eta' handled as special cases.
1363  if (id == 221) return 2. * (1. - fracEtass + sEffAQM * fracEtass);
1364  if (id == 331) return 2. * (1. - fracEtaPss + sEffAQM * fracEtaPss);
1365 
1366  // Count up number of quarks of each kind for hadron and combine.
1367  int idAbs = abs(id);
1368  int nq[6] = {};
1369  ++nq[(idAbs/10)%10];
1370  ++nq[(idAbs/100)%10];
1371  ++nq[(idAbs/1000)%10];
1372  return nq[1] + nq[2] + sEffAQM * nq[3] + cEffAQM * nq[4] + bEffAQM * nq[5];
1373 
1374 }
1375 
1376 double LowEnergySigma::factorAQM() const {
1377  return nqEffAQM(idA) * nqEffAQM(idB) / 9.;
1378 }
1379 
1380 double LowEnergySigma::totalAQM() const {
1381  return 40. * factorAQM();
1382 }
1383 
1384 double LowEnergySigma::elasticAQM() const {
1385  double aqmT = totalAQM();
1386  return 0.039 * sqrt(aqmT) * aqmT;
1387 }
1388 
1389 //--------------------------------------------------------------------------
1390 
1391 // Check which cross sections contain explicit resonances.
1392 
1393 bool LowEnergySigma::hasExplicitResonances() const {
1394 
1395  // N has explicit resonances with pi, Kbar, eta and omega.
1396  if (idA == 2212 || idA == 2112)
1397  return abs(idB) == 211 || idB == 111 || idB == -321 || idB == -311
1398  || idB == 221 || idB == 223;
1399 
1400  // pi+pi0, pi+pi-, pi0pi0 and pi0pi-.
1401  if (idA == 211 && (idB == 111 || idB == -211))
1402  return true;
1403  if (idA == 111 && idB == 111)
1404  return true;
1405 
1406  // K pi and K Kbar.
1407  if (idA == 321)
1408  return idB == 111 || idB == -211 || idB == -321 || idB == -311;
1409  if (idA == 311)
1410  return idB == 111 || idB == 211 || idB == -321 || idB == -311;
1411 
1412  // Sigma+ and Sigma- can have resonances with pi and Kbar,
1413  // and always have resonances with K.
1414  if (idA == 3222)
1415  return idB == 111 || idB == -211 || idB == -321
1416  || idB == 321 || idB == 311;
1417  if (idA == 3112)
1418  return idB == 111 || idB == 211 || idB == -311
1419  || idB == 321 || idB == 311;
1420 
1421  // Sigma0/Lambda have resonances with all pi, K and Kbar.
1422  if (idA == 3212 || idA == 3122)
1423  return idB == 211 || idB == 111 || idB == -211
1424  || idB == 321 || idB == 311 || idB == -321 || idB == -311;
1425 
1426  // Xi0 and Xi- can have resonances with pi.
1427  // They can in principle have resonances with K/Kbar, but
1428  // 1) Omega resonances are not implemented, and
1429  // 2) Sigma* -> Xi+K branching ratios are very small.
1430  if (idA == 3322)
1431  return idB == 111 || idB == -211;
1432  if (idA == 3312)
1433  return idB == 111 || idB == 211;
1434 
1435  // No further combinations have implemented resonances.
1436  return false;
1437 
1438 }
1439 
1440 
1441 //--------------------------------------------------------------------------
1442 
1443 // Give meltpoint, below which sigma(total) = sum sigma(res) + sigma(elastic).
1444 
1445 double LowEnergySigma::meltpoint(int idX, int idM) const {
1446 
1447  // p+M.
1448  if (idX == 2212)
1449  return idM == -211 ? 1.74
1450  : idM == 211 ? 2.05
1451  : idM == 111 ? 2.00
1452  : idM == -321 ? 2.10
1453  : idM == -311 ? 2.10
1454  : idM == 221 ? 1.75
1455  : idM == 223 ? 1.95
1456  : 0.;
1457 
1458  // n0M.
1459  if (idX == 2112)
1460  return idM == -211 ? 2.00
1461  : idM == 211 ? 1.90
1462  : idM == 111 ? 2.00
1463  : idM == -321 ? 2.10
1464  : idM == -311 ? 2.10
1465  : idM == 221 ? 1.75
1466  : idM == 223 ? 1.95
1467  : 0.;
1468 
1469  // LambdaM.
1470  if (idX == 3122)
1471  return abs(idM) == 211 || idM == 111 ? 2.05
1472  : abs(idM) == 321 || abs(idM) == 311 ? 2.00
1473  : 0.;
1474 
1475  // SigmaM.
1476  if (idX == 3222 || idX == 3212 || idX == 3112)
1477  return abs(idM) == 211 || idM == 111 ? 2.0
1478  : abs(idM) == 321 || abs(idM) == 311 ? 2.05
1479  : 0.;
1480 
1481  // XiM.
1482  if (idX == 3322 || idX == 3312) {
1483  if (abs(idM) == 211 || idM == 111)
1484  return 1.6;
1485  else
1486  return 0.;
1487  }
1488 
1489  // pipi.
1490  if ((abs(idX) == 211 || idX == 111) && (abs(idM) == 211 || idM == 111))
1491  return 1.42;
1492 
1493  // Kpi.
1494  if ((abs(idX) == 321 || abs(idX) == 311)
1495  && (abs(idM) == 211 || abs(idM) == 111))
1496  return 1.60;
1497 
1498  // KK.
1499  if ((abs(idX) == 321 || abs(idX) == 311)
1500  && (abs(idM) == 321 || abs(idM) == 311))
1501  return 1.65;
1502 
1503  // No further combinations are defined with resonances.
1504  return 0.;
1505 }
1506 
1507 //==========================================================================
1508 
1509 }