43 namespace mt2w_bisect {
47 const float mt2w::RELATIVE_PRECISION = 0.00001;
48 const float mt2w::ABSOLUTE_PRECISION = 0.0;
49 const float mt2w::MIN_MASS = 0.1;
50 const float mt2w::ZERO_MASS = 0.0;
51 const float mt2w::SCANSTEP = 0.1;
53 mt2w::mt2w(
double upper_bound,
double error_value,
double scan_step) {
60 this->scan_step = scan_step;
63 double mt2w::get_mt2w() {
65 cout <<
" Please set momenta first!" << endl;
74 void mt2w::set_momenta(
double *pl,
double *pb1,
double *pb2,
double *pmiss) {
78 pl[0], pl[1], pl[2], pl[3], pb1[0], pb1[1], pb1[2], pb1[3], pb2[0], pb2[1], pb2[2], pb2[3], pmiss[1], pmiss[2]);
81 void mt2w::set_momenta(
double El,
109 msqtemp = El * El - plx * plx - ply * ply - plz * plz;
126 msqtemp = Eb1 * Eb1 - pb1x * pb1x - pb1y * pb1y - pb1z * pb1z;
143 msqtemp = Eb2 * Eb2 - pb2x * pb2x - pb2y * pb2y - pb2z * pb2z;
153 this->pmissx = pmissx;
154 this->pmissy = pmissy;
163 if (ABSOLUTE_PRECISION > 100. * RELATIVE_PRECISION)
164 precision = ABSOLUTE_PRECISION;
166 precision = 100. * RELATIVE_PRECISION;
169 void mt2w::mt2w_bisect() {
188 if (teco(mtop_high) == 0) {
189 mtop_high = mtop_low;
194 while (teco(mtop_high) == 0 && mtop_high <
upper_bound + 2. * scan_step) {
195 mtop_low = mtop_high;
196 mtop_high = mtop_high + scan_step;
201 mt2w_b = error_value;
206 while (mtop_high - mtop_low > precision) {
207 double mtop_mid, teco_mid;
209 mtop_mid = (mtop_high + mtop_low) / 2.;
210 teco_mid = teco(mtop_mid);
215 mtop_high = mtop_mid;
224 int mt2w::teco(
double mtop) {
227 if (mtop <
mb1 + mw || mtop <
mb2 + mw) {
233 double ETb2sq = Eb2sq - pb2z * pb2z;
234 double delta = (mtop * mtop - mw * mw - mb2sq) / (2. * ETb2sq);
238 double del1 = mw * mw - mv * mv - mlsq;
239 double del2 = mtop * mtop - mw * mw - mb1sq - 2 * (El * Eb1 - plx * pb1x - ply * pb1y - plz * pb1z);
243 double aa = (El * pb1x - Eb1 * plx) / (Eb1 * plz - El * pb1z);
244 double bb = (El * pb1y - Eb1 * ply) / (Eb1 * plz - El * pb1z);
245 double cc = (El * del2 - Eb1 * del1) / (2. * Eb1 * plz - 2. * El * pb1z);
255 a1 = Eb1sq * (1. + aa * aa) - (pb1x + pb1z * aa) * (pb1x + pb1z * aa);
256 b1 = Eb1sq * aa * bb - (pb1x + pb1z * aa) * (pb1y + pb1z * bb);
257 c1 = Eb1sq * (1. + bb * bb) - (pb1y + pb1z * bb) * (pb1y + pb1z * bb);
258 d1 = Eb1sq * aa * cc - (pb1x + pb1z * aa) * (pb1z * cc + del2 / 2.0);
259 e1 = Eb1sq * bb * cc - (pb1y + pb1z * bb) * (pb1z * cc + del2 / 2.0);
260 f1 = Eb1sq * (mv * mv + cc * cc) - (pb1z * cc + del2 / 2.0) * (pb1z * cc + del2 / 2.0);
272 a2 = 1 - pb2x * pb2x / (ETb2sq);
273 b2 = -pb2x * pb2y / (ETb2sq);
274 c2 = 1 - pb2y * pb2y / (ETb2sq);
280 f2o = mw * mw - delta * delta * ETb2sq;
282 d2 = -d2o -
a2 * pmissx -
b2 * pmissy;
283 e2 = -e2o - c2 * pmissy -
b2 * pmissx;
284 f2 =
a2 * pmissx * pmissx + 2 *
b2 * pmissx * pmissy + c2 * pmissy * pmissy + 2 * d2o * pmissx +
285 2 * e2o * pmissy + f2o;
288 double x0, h0, y0, r0;
290 h0 = (
b1 * x0 + e1) * (
b1 * x0 + e1) - c1 * (
a1 * x0 * x0 + 2 *
d1 * x0 +
f1);
294 y0 = (-
b1 * x0 - e1 +
sqrt(h0)) / c1;
295 r0 =
a2 * x0 * x0 + 2 *
b2 * x0 * y0 + c2 * y0 * y0 + 2 * d2 * x0 + 2 * e2 * y0 +
f2;
302 long double A4, A3, A2, A1, A0;
305 4 *
a1 *
b1 *
b2 * c2 - 2 *
a1 *
a2 * c1 * c2 +
a1 *
a1 * c2 * c2;
310 4 *
a1 *
a2 * c1 * e2 + 4 *
a1 *
a1 * c2 * e2) /
313 A2 = (4 *
a2 * c2 *
d1 *
d1 - 4 *
a2 * c1 *
d1 * d2 - 4 *
a1 * c2 *
d1 * d2 + 4 *
a1 * c1 * d2 * d2 -
314 8 *
a2 *
b2 *
d1 * e1 - 8 *
a2 *
b1 * d2 * e1 + 16 *
a1 *
b2 * d2 * e1 + 4 *
a2 *
a2 * e1 * e1 +
315 16 *
a2 *
b1 *
d1 * e2 - 8 *
a1 *
b2 *
d1 * e2 - 8 *
a1 *
b1 * d2 * e2 - 8 *
a1 *
a2 * e1 * e2 +
321 A1 = (-8 *
a2 *
d1 * d2 * e1 + 8 *
a1 * d2 * d2 * e1 + 8 *
a2 *
d1 *
d1 * e2 - 8 *
a1 *
d1 * d2 * e2 -
324 4 *
a1 *
a2 * e1 * f2 + 4 *
a1 *
a1 * e2 *
f2) /
341 long double B3, B2, B1, B0;
347 long double C2, C1, C0;
348 C2 = -(A2 / 2 - 3 * A3sq / (16 * A4));
349 C1 = -(3 * A1 / 4. - A2 * A3 / (8 * A4));
350 C0 = -A0 + A1 * A3 / (16 * A4);
353 D1 = -B1 - (B3 * C1 * C1 / C2 - B3 * C0 - B2 * C1) / C2;
354 D0 = -B0 - B3 * C0 * C1 / (C2 * C2) + B2 * C0 / C2;
357 E0 = -C0 - C2 * D0 * D0 / (D1 *
D1) + C1 * D0 / D1;
359 long double t1, t2, t3, t4, t5;
369 nsol = signchange_n(t1, t2, t3, t4, t5) - signchange_p(t1, t2, t3, t4, t5);
386 inline int mt2w::signchange_n(
long double t1,
long double t2,
long double t3,
long double t4,
long double t5) {
399 inline int mt2w::signchange_p(
long double t1,
long double t2,
long double t3,
long double t4,
long double t5) {
__host__ __device__ constexpr RandomIt upper_bound(RandomIt first, RandomIt last, const T &value, Compare comp={})
static constexpr float b2
static constexpr float d1
static constexpr float b1