49 const float mt2w::RELATIVE_PRECISION = 0.00001;
50 const float mt2w::ABSOLUTE_PRECISION = 0.0;
51 const float mt2w::MIN_MASS = 0.1;
52 const float mt2w::ZERO_MASS = 0.0;
53 const float mt2w::SCANSTEP = 0.1;
55 mt2w::mt2w(
double upper_bound,
double error_value,
double scan_step)
60 this->upper_bound = upper_bound;
61 this->error_value = error_value;
62 this->scan_step = scan_step;
65 double mt2w::get_mt2w()
69 cout <<
" Please set momenta first!" << endl;
73 if (!solved) mt2w_bisect();
78 void mt2w::set_momenta(
double *pl,
double *pb1,
double *pb2,
double* pmiss)
82 set_momenta(pl[0], pl[1], pl[2], pl[3],
83 pb1[0], pb1[1], pb1[2], pb1[3],
84 pb2[0], pb2[1], pb2[2], pb2[3],
90 void mt2w::set_momenta(
double El,
double plx,
double ply,
double plz,
91 double Eb1,
double pb1x,
double pb1y,
double pb1z,
92 double Eb2,
double pb2x,
double pb2y,
double pb2z,
93 double pmissx,
double pmissy)
109 msqtemp = El*El-plx*plx-ply*ply-plz*plz;
110 if (msqtemp > 0.0) {mlsq = msqtemp;}
123 msqtemp = Eb1*Eb1-pb1x*pb1x-pb1y*pb1y-pb1z*pb1z;
124 if (msqtemp > 0.0) {mb1sq = msqtemp;}
137 msqtemp = Eb2*Eb2-pb2x*pb2x-pb2y*pb2y-pb2z*pb2z;
138 if (msqtemp > 0.0) {mb2sq = msqtemp;}
146 this->pmissx = pmissx;
147 this->pmissy = pmissy;
157 if (ABSOLUTE_PRECISION > 100.*RELATIVE_PRECISION)
precision = ABSOLUTE_PRECISION;
158 else precision = 100.*RELATIVE_PRECISION;
162 void mt2w::mt2w_bisect()
170 double mtop_high = upper_bound;
174 else {mtop_low = mw +
mb2;}
181 if (teco(mtop_high)==0) {mtop_high = mtop_low;}
185 while (teco(mtop_high)==0 && mtop_high < upper_bound + 2.*scan_step) {
188 mtop_high = mtop_high + scan_step;
192 if (mtop_high > upper_bound) {
193 mt2w_b = error_value;
200 double mtop_mid,teco_mid;
202 mtop_mid = (mtop_high+mtop_low)/2.;
203 teco_mid = teco(mtop_mid);
205 if(teco_mid == 0) {mtop_low = mtop_mid;}
206 else {mtop_high = mtop_mid;}
216 int mt2w::teco(
double mtop)
221 if (mtop <
mb1+mw || mtop <
mb2+mw) {
return 0;}
225 double ETb2sq = Eb2sq - pb2z*pb2z;
226 double delta = (mtop*mtop-mw*mw-mb2sq)/(2.*ETb2sq);
231 double del1 = mw*mw - mv*mv - mlsq;
232 double del2 = mtop*mtop - mw*mw - mb1sq - 2*(El*Eb1-plx*pb1x-ply*pb1y-plz*pb1z);
236 double aa = (El*pb1x-Eb1*plx)/(Eb1*plz-El*pb1z);
237 double bb = (El*pb1y-Eb1*ply)/(Eb1*plz-El*pb1z);
238 double cc = (El*del2-Eb1*del1)/(2.*Eb1*plz-2.*El*pb1z);
249 a1 = Eb1sq*(1.+aa*aa)-(pb1x+pb1z*aa)*(pb1x+pb1z*aa);
250 b1 = Eb1sq*aa*bb - (pb1x+pb1z*aa)*(pb1y+pb1z*bb);
251 c1 = Eb1sq*(1.+bb*bb)-(pb1y+pb1z*bb)*(pb1y+pb1z*bb);
252 d1 = Eb1sq*aa*cc - (pb1x+pb1z*aa)*(pb1z*cc+del2/2.0);
253 e1 = Eb1sq*bb*cc - (pb1y+pb1z*bb)*(pb1z*cc+del2/2.0);
254 f1 = Eb1sq*(mv*mv+cc*cc) - (pb1z*cc+del2/2.0)*(pb1z*cc+del2/2.0);
258 double det1 = (a1*(
c1*
f1 - e1*e1) - b1*(b1*
f1 - d1*e1) + d1*(b1*e1-
c1*d1))/(a1+
c1);
260 if (det1 > 0.0) {
return 0;}
264 a2 = 1-pb2x*pb2x/(ETb2sq);
265 b2 = -pb2x*pb2y/(ETb2sq);
266 c2 = 1-pb2y*pb2y/(ETb2sq);
272 f2o = mw*mw - delta*delta*ETb2sq;
274 d2 = -d2o -a2*pmissx -b2*pmissy;
275 e2 = -e2o -c2*pmissy -b2*pmissx;
276 f2 = a2*pmissx*pmissx + 2*b2*pmissx*pmissy + c2*pmissy*pmissy + 2*d2o*pmissx + 2*e2o*pmissy + f2o;
279 double x0, h0, y0, r0;
280 x0 = (
c1*d1-b1*e1)/(b1*b1-a1*
c1);
281 h0 = (b1*x0 + e1)*(b1*x0 + e1) - c1*(a1*x0*x0 + 2*d1*x0 +
f1);
282 if (h0 < 0.0) {
return 0;}
283 y0 = (-b1*x0 -e1 +
sqrt(h0))/c1;
284 r0 = a2*x0*x0 + 2*b2*x0*y0 + c2*y0*y0 + 2*d2*x0 + 2*e2*y0 +
f2;
285 if (r0 < 0.0) {
return 1;}
290 long double A4, A3, A2, A1, A0;
293 -4*a2*b1*b2*c1 + 4*a1*b2*b2*c1 +a2*a2*c1*c1 +
294 4*a2*b1*b1*c2 - 4*a1*b1*b2*c2 - 2*a1*a2*c1*c2 +
298 (-4*a2*b2*c1*d1 + 8*a2*b1*c2*d1 - 4*a1*b2*c2*d1 - 4*a2*b1*c1*d2 +
299 8*a1*b2*c1*d2 - 4*a1*b1*c2*d2 - 8*a2*b1*b2*e1 + 8*a1*b2*b2*e1 +
300 4*a2*a2*c1*e1 - 4*a1*a2*c2*e1 + 8*a2*b1*b1*e2 - 8*a1*b1*b2*e2 -
301 4*a1*a2*c1*e2 + 4*a1*a1*c2*e2)/Eb1;
305 (4*a2*c2*d1*d1 - 4*a2*c1*d1*d2 - 4*a1*c2*d1*d2 + 4*a1*c1*d2*d2 -
306 8*a2*b2*d1*e1 - 8*a2*b1*d2*e1 + 16*a1*b2*d2*e1 +
307 4*a2*a2*e1*e1 + 16*a2*b1*d1*e2 - 8*a1*b2*d1*e2 -
308 8*a1*b1*d2*e2 - 8*a1*a2*e1*e2 + 4*a1*a1*e2*e2 - 4*a2*b1*b2*
f1 +
309 4*a1*b2*b2*
f1 + 2*a2*a2*c1*
f1 - 2*a1*a2*c2*
f1 +
310 4*a2*b1*b1*f2 - 4*a1*b1*b2*f2 - 2*a1*a2*c1*f2 + 2*a1*a1*c2*
f2)/Eb1sq;
313 (-8*a2*d1*d2*e1 + 8*a1*d2*d2*e1 + 8*a2*d1*d1*e2 - 8*a1*d1*d2*e2 -
314 4*a2*b2*d1*
f1 - 4*a2*b1*d2*
f1 + 8*a1*b2*d2*
f1 + 4*a2*a2*e1*
f1 -
315 4*a1*a2*e2*
f1 + 8*a2*b1*d1*f2 - 4*a1*b2*d1*f2 - 4*a1*b1*d2*f2 -
316 4*a1*a2*e1*f2 + 4*a1*a1*e2*
f2)/(Eb1sq*Eb1);
319 (-4*a2*d1*d2*
f1 + 4*a1*d2*d2*
f1 + a2*a2*
f1*
f1 +
320 4*a2*d1*d1*f2 - 4*a1*d1*d2*f2 - 2*a1*a2*
f1*f2 +
321 a1*a1*f2*
f2)/(Eb1sq*Eb1sq);
333 long double B3, B2, B1, B0;
339 long double C2, C1, C0;
340 C2 = -(A2/2 - 3*A3sq/(16*A4));
341 C1 = -(3*A1/4. -A2*A3/(8*A4));
342 C0 = -A0 + A1*A3/(16*A4);
345 D1 = -B1 - (B3*C1*C1/C2 - B3*C0 -B2*C1)/C2;
346 D0 = -B0 - B3 *C0 *C1/(C2*C2)+ B2*C0/C2;
349 E0 = -C0 - C2*D0*D0/(D1*
D1) + C1*D0/D1;
351 long double t1,t2,t3,t4,t5;
362 nsol = signchange_n(t1,t2,t3,t4,t5) - signchange_p(t1,t2,t3,t4,t5);
365 if (nsol < 0) nsol = 0;
368 if (nsol == 0) {out = 0;}
375 inline int mt2w::signchange_n(
long double t1,
long double t2,
long double t3,
long double t4,
long double t5)
385 inline int mt2w::signchange_p(
long double t1,
long double t2,
long double t3,
long double t4,
long double t5)
TAKEN FROM http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/ElectroWeakAnalysis/Utilities/src/PdfWeig...