45 const float Davismt2::RELATIVE_PRECISION = 0.00001;
46 const float Davismt2::ABSOLUTE_PRECISION = 0.0;
47 const float Davismt2::ZERO_MASS = 0.0;
48 const float Davismt2::MIN_MASS = 0.1;
49 const float Davismt2::SCANSTEP = 0.1;
59 Davismt2::~Davismt2(){}
61 double Davismt2::get_mt2(){
64 cout <<
"Davismt2::get_mt2() ==> Please set momenta first!" << endl;
68 if (!solved) mt2_bisect();
72 void Davismt2::set_momenta(
double* pa0,
double* pb0,
double* pmiss0){
78 if (ma < ZERO_MASS) ma = ZERO_MASS;
83 Easq = masq+pax*pax+pay*pay;
88 if (mb < ZERO_MASS) mb = ZERO_MASS;
93 Ebsq = mbsq+pbx*pbx+pby*pby;
96 pmissx = pmiss0[1]; pmissy = pmiss0[2];
97 pmissxsq = pmissx*pmissx;
98 pmissysq = pmissy*pmissy;
104 temp = pax; pax = pbx; pbx =
temp;
105 temp = pay; pay = pby; pby =
temp;
106 temp = Ea; Ea = Eb; Eb =
temp;
107 temp = Easq; Easq = Ebsq; Ebsq =
temp;
108 temp = masq; masq = mbsq; mbsq =
temp;
109 temp = ma; ma = mb; mb =
temp;
112 if (Ea > Eb)
scale = Ea/100.;
113 else scale = Eb/100.;
128 pmissx = pmissx/
scale;
129 pmissy = pmissy/
scale;
130 pmissxsq = pmissxsq/scalesq;
131 pmissysq = pmissysq/scalesq;
132 mn = mn_unscale/
scale;
135 if (ABSOLUTE_PRECISION > 100.*RELATIVE_PRECISION)
precision = ABSOLUTE_PRECISION;
136 else precision = 100.*RELATIVE_PRECISION;
139 void Davismt2::set_mn(
double mn0){
141 mn_unscale = fabs(mn0);
142 mn = mn_unscale/
scale;
147 cout <<
" Davismt2::print() ==> pax = " << pax*
scale <<
"; pay = " << pay*
scale <<
"; ma = " << ma*
scale <<
";"<< endl;
148 cout <<
" Davismt2::print() ==> pbx = " << pbx*
scale <<
"; pby = " << pby*
scale <<
"; mb = " << mb*
scale <<
";"<< endl;
149 cout <<
" Davismt2::print() ==> pmissx = " << pmissx*
scale <<
"; pmissy = " << pmissy*
scale <<
";"<< endl;
150 cout <<
" Davismt2::print() ==> mn = " << mn_unscale<<
";" << endl;
154 void Davismt2::mt2_massless(){
158 theta = atan(pay/pax);
162 double pxtemp,pytemp;
163 Easq = pax*pax+pay*pay;
164 Ebsq = pbx*pbx+pby*pby;
168 pxtemp = pax*c+pay*
s;
171 pxtemp = pbx*c+pby*
s;
172 pytemp = -s*pbx+c*pby;
175 pxtemp = pmissx*c+pmissy*
s;
176 pytemp = -s*pmissx+c*pmissy;
180 a2 = 1-pbx*pbx/(Ebsq);
181 b2 = -pbx*pby/(Ebsq);
182 c2 = 1-pby*pby/(Ebsq);
184 d21 = (Easq*pbx)/Ebsq;
185 d20 = - pmissx + (pbx*(pbx*pmissx + pby*pmissy))/Ebsq;
186 e21 = (Easq*pby)/Ebsq;
187 e20 = - pmissy + (pby*(pbx*pmissx + pby*pmissy))/Ebsq;
188 f22 = -(Easq*Easq/Ebsq);
189 f21 = -2*Easq*(pbx*pmissx + pby*pmissy)/Ebsq;
190 f20 = mnsq + pmissxsq + pmissysq - (pbx*pmissx + pby*pmissy)*(pbx*pmissx + pby*pmissy)/Ebsq;
193 double Deltasq_low, Deltasq_high;
194 int nsols_high, nsols_low;
197 nsols_low = nsols_massless(Deltasq_low);
201 mt2_b = (double)
sqrt(Deltasq0+mnsq);
213 double Deltasq_high1, Deltasq_high2;
214 Deltasq_high1 = 2*Eb*
sqrt(pmissx*pmissx+pmissy*pmissy+mnsq)-2*pbx*pmissx-2*pby*pmissy;
215 Deltasq_high2 = 2*Ea*mn;
217 if(Deltasq_high1 < Deltasq_high2) Deltasq_high = Deltasq_high2;
218 else Deltasq_high = Deltasq_high1;
220 nsols_high=nsols_massless(Deltasq_high);
223 if (nsols_high == nsols_low)
229 double minmass, maxmass;
231 maxmass =
sqrt(mnsq + Deltasq_high);
232 for(
double mass = minmass + SCANSTEP;
mass < maxmass;
mass += SCANSTEP)
236 nsols_high = nsols_massless(Deltasq_high);
240 Deltasq_low = (
mass-SCANSTEP)*(
mass-SCANSTEP) - mnsq;
247 if(
verbose > 0)
cout <<
"Davismt2::mt2_massless() ==> Deltasq_high not found at event " <<
nevt <<endl;
250 mt2_b = (double)
sqrt(Deltasq_low+mnsq);
255 if(nsols_high == nsols_low)
257 if(
verbose > 0)
cout <<
"Davismt2::mt2_massless() ==> error: nsols_low=nsols_high=" << nsols_high << endl;
258 if(
verbose > 0)
cout <<
"Davismt2::mt2_massless() ==> Deltasq_high=" << Deltasq_high << endl;
259 if(
verbose > 0)
cout <<
"Davismt2::mt2_massless() ==> Deltasq_low= "<< Deltasq_low << endl;
261 mt2_b =
sqrt(mnsq + Deltasq_low);
264 double minmass, maxmass;
265 minmass =
sqrt(Deltasq_low+mnsq);
266 maxmass =
sqrt(Deltasq_high+mnsq);
267 while(maxmass - minmass > precision)
269 double Delta_mid, midmass, nsols_mid;
270 midmass = (minmass+maxmass)/2.;
271 Delta_mid = midmass * midmass - mnsq;
272 nsols_mid = nsols_massless(Delta_mid);
273 if(nsols_mid != nsols_low) maxmass = midmass;
274 if(nsols_mid == nsols_low) minmass = midmass;
280 int Davismt2::nsols_massless(
double Dsq){
282 delta = Dsq/(2*Easq);
285 f1 = f12*delta*delta+f10;
288 f2 = f22*delta*delta+f21*delta+f20;
291 if (pax > 0) a = Ea/Dsq;
293 if (pax > 0) b = -Dsq/(4*Ea)+mnsq*Ea/Dsq;
294 else b = Dsq/(4*Ea)-mnsq*Ea/Dsq;
296 double A4,A3,A2,A1,A0;
300 A2 = (2*a*a2*b+c2+2*a*d2)/(Easq);
301 A1 = (2*b*b2+2*
e2)/(Easq*Ea);
302 A0 = (a2*b*b+2*b*d2+
f2)/(Easq*Easq);
315 long double B3, B2, B1, B0;
320 long double C2, C1, C0;
321 C2 = -(A2/2 - 3*A3sq/(16*A4));
322 C1 = -(3*A1/4. -A2*A3/(8*A4));
323 C0 = -A0 + A1*A3/(16*A4);
325 D1 = -B1 - (B3*C1*C1/C2 - B3*C0 -B2*C1)/C2;
326 D0 = -B0 - B3 *C0 *C1/(C2*C2)+ B2*C0/C2;
329 E0 = -C0 - C2*D0*D0/(D1*
D1) + C1*D0/D1;
331 long double t1,
t2,t3,t4,t5;
341 nsol = signchange_n(t1,t2,t3,t4,t5)-signchange_p(t1,t2,t3,t4,t5);
342 if( nsol < 0 ) nsol=0;
347 void Davismt2::mt2_bisect(){
353 if(masq < MIN_MASS && mbsq < MIN_MASS){
360 Deltasq0 = ma*(ma + 2*mn);
364 a1 = 1-pax*pax/(Easq);
365 b1 = -pax*pay/(Easq);
366 c1 = 1-pay*pay/(Easq);
367 d1 = -pax*(Deltasq0-masq)/(2*Easq);
368 e1 = -pay*(Deltasq0-masq)/(2*Easq);
369 a2 = 1-pbx*pbx/(Ebsq);
370 b2 = -pbx*pby/(Ebsq);
371 c2 = 1-pby*pby/(Ebsq);
372 d2 = -pmissx+pbx*(Deltasq0-mbsq)/(2*Ebsq)+pbx*(pbx*pmissx+pby*pmissy)/(Ebsq);
373 e2 = -pmissy+pby*(Deltasq0-mbsq)/(2*Ebsq)+pby*(pbx*pmissx+pby*pmissy)/(Ebsq);
374 f2 = pmissx*pmissx+pmissy*pmissy-((Deltasq0-mbsq)/(2*Eb)+
375 (pbx*pmissx+pby*pmissy)/Eb)*((Deltasq0-mbsq)/(2*Eb)+
376 (pbx*pmissx+pby*pmissy)/Eb)+mnsq;
380 x0 = (
c1*d1-b1*
e1)/(b1*b1-a1*
c1);
381 y0 = (a1*
e1-b1*d1)/(b1*b1-a1*c1);
385 double dis=a2*x0*x0+2*b2*x0*y0+c2*y0*y0+2*d2*x0+2*
e2*y0+
f2;
389 mt2_b = (double)
sqrt(mnsq+Deltasq0);
402 d21 = (Easq*pbx)/Ebsq;
403 d20 = ((masq - mbsq)*pbx)/(2.*Ebsq) - pmissx +
404 (pbx*(pbx*pmissx + pby*pmissy))/Ebsq;
405 e21 = (Easq*pby)/Ebsq;
406 e20 = ((masq - mbsq)*pby)/(2.*Ebsq) - pmissy +
407 (pby*(pbx*pmissx + pby*pmissy))/Ebsq;
408 f22 = -Easq*Easq/Ebsq;
409 f21 = (-2*Easq*((masq - mbsq)/(2.*Eb) + (pbx*pmissx + pby*pmissy)/Eb))/Eb;
410 f20 = mnsq + pmissx*pmissx + pmissy*pmissy -
411 ((masq - mbsq)/(2.*Eb) + (pbx*pmissx + pby*pmissy)/Eb)
412 *((masq - mbsq)/(2.*Eb) + (pbx*pmissx + pby*pmissy)/Eb);
417 double Deltasq_high1;
420 Deltasq_high1 = 2*Eb*
sqrt(p2x0*p2x0+p2y0*p2y0+mnsq)-2*pbx*p2x0-2*pby*p2y0+mbsq;
424 double Deltasq_high2, Deltasq_high21, Deltasq_high22;
425 Deltasq_high21 = 2*Eb*
sqrt(pmissx*pmissx+pmissy*pmissy+mnsq)-2*pbx*pmissx-2*pby*pmissy+mbsq;
426 Deltasq_high22 = 2*Ea*mn+masq;
428 if ( Deltasq_high21 < Deltasq_high22 ) Deltasq_high2 = Deltasq_high22;
429 else Deltasq_high2 = Deltasq_high21;
433 if(Deltasq_high1 < Deltasq_high2) Deltasq_high = Deltasq_high1;
434 else Deltasq_high = Deltasq_high2;
438 Deltasq_low = Deltasq0;
441 if( nsols(Deltasq_low) > 0 )
444 mt2_b = (double)
sqrt(mnsq+Deltasq0);
448 int nsols_high, nsols_low;
450 nsols_low = nsols(Deltasq_low);
457 nsols_high = nsols(Deltasq_high);
459 if(nsols_high == nsols_low || nsols_high == 4)
462 foundhigh = find_high(Deltasq_high);
465 if(
verbose > 0)
cout <<
"Davismt2::mt2_bisect() ==> Deltasq_high not found at event " <<
nevt << endl;
466 mt2_b =
sqrt( Deltasq_low + mnsq );
474 double Deltasq_mid,nsols_mid;
476 Deltasq_mid = (Deltasq_high+Deltasq_low)/2.;
477 nsols_mid = nsols(Deltasq_mid);
479 if ( nsols_mid == 4 )
481 Deltasq_high = Deltasq_mid;
483 find_high(Deltasq_high);
488 if(nsols_mid != nsols_low) Deltasq_high = Deltasq_mid;
489 if(nsols_mid == nsols_low) Deltasq_low = Deltasq_mid;
491 mt2_b = (double)
sqrt( mnsq + Deltasq_high);
495 int Davismt2::find_high(
double & Deltasq_high){
497 x0 = (
c1*d1-b1*
e1)/(b1*b1-a1*
c1);
498 y0 = (a1*
e1-b1*d1)/(b1*b1-a1*c1);
499 double Deltasq_low = (mn + ma)*(mn + ma) - mnsq;
502 double Deltasq_mid = (Deltasq_high + Deltasq_low)/2.;
503 int nsols_mid = nsols(Deltasq_mid);
504 if ( nsols_mid == 2 )
506 Deltasq_high = Deltasq_mid;
509 else if (nsols_mid == 4)
511 Deltasq_high = Deltasq_mid;
514 else if (nsols_mid ==0)
516 d1 = -pax*(Deltasq_mid-masq)/(2*Easq);
517 e1 = -pay*(Deltasq_mid-masq)/(2*Easq);
518 d2 = -pmissx + pbx*(Deltasq_mid - mbsq)/(2*Ebsq)
519 + pbx*(pbx*pmissx+pby*pmissy)/(Ebsq);
520 e2 = -pmissy + pby*(Deltasq_mid - mbsq)/(2*Ebsq)
521 + pby*(pbx*pmissx+pby*pmissy)/(Ebsq);
522 f2 = pmissx*pmissx+pmissy*pmissy-((Deltasq_mid-mbsq)/(2*Eb)+
523 (pbx*pmissx+pby*pmissy)/Eb)*((Deltasq_mid-mbsq)/(2*Eb)+
524 (pbx*pmissx+pby*pmissy)/Eb)+mnsq;
526 double dis = a2*x0*x0 + 2*b2*x0*y0 + c2*y0*y0 + 2*d2*x0 + 2*
e2*y0 +
f2;
527 if (dis < 0) Deltasq_high = Deltasq_mid;
528 else Deltasq_low = Deltasq_mid;
531 }
while ( Deltasq_high - Deltasq_low > 0.001);
535 int Davismt2::scan_high(
double & Deltasq_high){
541 double tempmass, maxmass;
543 maxmass =
sqrt(mnsq + Deltasq_high);
544 if (
nevt == 32334)
cout <<
"Davismt2::scan_high() ==> Deltasq_high = " << Deltasq_high << endl;
545 for(
double mass = tempmass + SCANSTEP;
mass < maxmass;
mass += SCANSTEP)
548 nsols_high = nsols(Deltasq_high);
560 int Davismt2::nsols(
double Dsq){
561 double delta = (Dsq-masq)/(2*Easq);
566 f1 = f12*delta*delta+f10;
569 f2 = f22*delta*delta+f21*delta+f20;
573 long double A4, A3, A2, A1, A0;
576 -4*a2*b1*b2*
c1 + 4*a1*b2*b2*
c1 +a2*a2*
c1*
c1 +
577 4*a2*b1*b1*c2 - 4*a1*b1*b2*c2 - 2*a1*a2*
c1*c2 +
581 (-4*a2*b2*
c1*d1 + 8*a2*b1*c2*d1 - 4*a1*b2*c2*d1 - 4*a2*b1*
c1*d2 +
582 8*a1*b2*
c1*d2 - 4*a1*b1*c2*d2 - 8*a2*b1*b2*
e1 + 8*a1*b2*b2*
e1 +
583 4*a2*a2*
c1*
e1 - 4*a1*a2*c2*
e1 + 8*a2*b1*b1*
e2 - 8*a1*b1*b2*
e2 -
584 4*a1*a2*
c1*
e2 + 4*a1*a1*c2*
e2)/Ea;
588 (4*a2*c2*d1*d1 - 4*a2*
c1*d1*d2 - 4*a1*c2*d1*d2 + 4*a1*
c1*d2*d2 -
589 8*a2*b2*d1*
e1 - 8*a2*b1*d2*
e1 + 16*a1*b2*d2*
e1 +
590 4*a2*a2*
e1*
e1 + 16*a2*b1*d1*
e2 - 8*a1*b2*d1*
e2 -
591 8*a1*b1*d2*
e2 - 8*a1*a2*
e1*
e2 + 4*a1*a1*
e2*
e2 - 4*a2*b1*b2*
f1 +
592 4*a1*b2*b2*
f1 + 2*a2*a2*
c1*
f1 - 2*a1*a2*c2*
f1 +
593 4*a2*b1*b1*
f2 - 4*a1*b1*b2*
f2 - 2*a1*a2*
c1*
f2 + 2*a1*a1*c2*
f2)/Easq;
596 (-8*a2*d1*d2*
e1 + 8*a1*d2*d2*
e1 + 8*a2*d1*d1*
e2 - 8*a1*d1*d2*
e2 -
597 4*a2*b2*d1*
f1 - 4*a2*b1*d2*
f1 + 8*a1*b2*d2*
f1 + 4*a2*a2*
e1*
f1 -
598 4*a1*a2*
e2*
f1 + 8*a2*b1*d1*
f2 - 4*a1*b2*d1*
f2 - 4*a1*b1*d2*
f2 -
599 4*a1*a2*
e1*
f2 + 4*a1*a1*
e2*
f2)/(Easq*Ea);
602 (-4*a2*d1*d2*
f1 + 4*a1*d2*d2*
f1 + a2*a2*
f1*
f1 +
603 4*a2*d1*d1*
f2 - 4*a1*d1*d2*
f2 - 2*a1*a2*
f1*
f2 +
604 a1*a1*
f2*
f2)/(Easq*Easq);
616 long double B3, B2, B1, B0;
622 long double C2, C1, C0;
623 C2 = -(A2/2 - 3*A3sq/(16*A4));
624 C1 = -(3*A1/4. -A2*A3/(8*A4));
625 C0 = -A0 + A1*A3/(16*A4);
628 D1 = -B1 - (B3*C1*C1/C2 - B3*C0 -B2*C1)/C2;
629 D0 = -B0 - B3 *C0 *C1/(C2*C2)+ B2*C0/C2;
632 E0 = -C0 - C2*D0*D0/(D1*
D1) + C1*D0/D1;
634 long double t1,
t2,t3,t4,t5;
645 nsol = signchange_n(t1,t2,t3,t4,t5) - signchange_p(t1,t2,t3,t4,t5);
648 if (nsol < 0) nsol = 0;
655 int Davismt2::signchange_n(
long double t1,
long double t2,
long double t3,
long double t4,
long double t5){
666 int Davismt2::signchange_p(
long double t1,
long double t2,
long double t3,
long double t4,
long double t5){
std::string print(const Track &, edm::Verbosity=edm::Concise)
Track print utility.
Sin< T >::type sin(const T &t)
Geom::Theta< T > theta() const
auto const T2 &decltype(t1.eta()) t2
Cos< T >::type cos(const T &t)
TAKEN FROM http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/CMSSW/ElectroWeakAnalysis/Utilities/src/PdfWeig...