|
75 #ifndef LESTER_TESTWHETHERELLIPSESAREDISJOINT_H 76 #define LESTER_TESTWHETHERELLIPSESAREDISJOINT_H 131 struct EllipseParams { 153 if (c_xx<0 || c_yy<0) { 154 throw "precondition violation"; 161 det = (2.0*c_x*c_xy*c_y + c*c_xx*c_yy - c_yy*c_x*c_x - c*c_xy*c_xy - c_xx*c_y*c_y) ; 175 double lesterFactor( const EllipseParams & e2) const { 176 const EllipseParams & e1 = * this; 177 const double ans = e1.c_xx*e1.c_yy*e2.c + 2.0*e1.c_xy*e1.c_y*e2.c_x - 2.0*e1.c_x*e1.c_yy*e2.c_x + e1.c*e1.c_yy*e2.c_xx - 2.0*e1.c*e1.c_xy*e2.c_xy + 2.0*e1.c_x*e1.c_y*e2.c_xy + 2.0*e1.c_x*e1.c_xy*e2.c_y - 2.0*e1.c_xx*e1.c_y*e2.c_y + e1.c*e1.c_xx*e2.c_yy - e2.c_yy*(e1.c_x*e1.c_x) - e2.c*(e1.c_xy*e1.c_xy) - e2.c_xx*(e1.c_y*e1.c_y); 180 bool operator==( const EllipseParams & other) const { 182 c_xx == other.c_xx && 183 c_yy == other.c_yy && 184 c_xy == other.c_xy && 201 bool ellipsesAreDisjoint( const EllipseParams & e1, const EllipseParams & e2); 204 bool __private_ellipsesAreDisjoint( const double coeffLamPow3, const double coeffLamPow2, const double coeffLamPow1, const double coeffLamPow0); 206 bool ellipsesAreDisjoint( const EllipseParams & e1, const EllipseParams & e2) { 219 const double coeffLamPow3 = e1.det; 220 const double coeffLamPow2 = e1.lesterFactor(e2); 221 const double coeffLamPow1 = e2.lesterFactor(e1); 222 const double coeffLamPow0 = e2.det; 226 if (fabs(coeffLamPow3) >= fabs(coeffLamPow0)) { 227 return __private_ellipsesAreDisjoint(coeffLamPow3, coeffLamPow2, coeffLamPow1, coeffLamPow0); 229 return __private_ellipsesAreDisjoint(coeffLamPow0, coeffLamPow1, coeffLamPow2, coeffLamPow3); 232 bool __private_ellipsesAreDisjoint( const double coeffLamPow3, const double coeffLamPow2, const double coeffLamPow1, const double coeffLamPow0) { 237 if(coeffLamPow3==0) { 244 const double a = coeffLamPow2 / coeffLamPow3; 245 const double b = coeffLamPow1 / coeffLamPow3; 246 const double c = coeffLamPow0 / coeffLamPow3; 248 #ifdef LESTER_DEEP_FIDDLE 250 const double thing1 = -3.0*b + a*a; 251 const double thing2 = -27.0*c*c + 18.0*c*a*b + a*a*b*b - 4.0*a*a*a*c - 4.0*b*b*b; 253 << (thing1>0) << " && " << (thing2>0) << " && [[ " << (a>=0) << " " << (3.0*a*c + b*a*a - 4.0*b*b<0) << " ] or " 254 << "[ " << (a< 0) << " ] =("<< ((a >= 0 && 3.0*a*c + b*a*a - 4.0*b*b< 0 /*&& thing2 > 0*/) || 255 (a < 0 )) << ")] " << ( 256 ( (a >= 0 && thing1 > 0 && 3.0*a*c + b*a*a - 4.0*b*b< 0 && thing2 > 0) || 257 (a < 0 && thing1 > 0 && thing2 > 0)) 264 const double thing1 = -3.0*b + a*a; 265 if (thing1<=0) return false; 266 const double thing2 = -27.0*c*c + 18.0*c*a*b + a*a*b*b - 4.0*a*a*a*c - 4.0*b*b*b; 267 if (thing2<=0) return false; 270 const bool ans = ( (a >= 0 && 3.0*a*c + b*a*a - 4.0*b*b< 0 ) || 271 (a < 0 /*&& thing1 > 0*/ )); 287 #ifndef ASYMM_MT2_BISECT_H 288 #define ASYMM_MT2_BISECT_H 296 class asymm_mt2_lester_bisect { 299 static const int MT2_ERROR=-1; 301 static double get_mT2( 302 const double mVis1, const double pxVis1, const double pyVis1, 303 const double mVis2, const double pxVis2, const double pyVis2, 304 const double pxMiss, const double pyMiss, 305 const double mInvis1, const double mInvis2, 306 const double desiredPrecisionOnMT2=0, 307 const bool useDeciSectionsInitially= true 310 const double mT2_Sq = get_mT2_Sq( 311 mVis1, pxVis1, pyVis1, 312 mVis2, pxVis2, pyVis2, 315 desiredPrecisionOnMT2, 316 useDeciSectionsInitially); 317 if (mT2_Sq==MT2_ERROR) { 323 static void disableCopyrightMessage( const bool printIfFirst= false) { 324 static bool first = true; 325 if (first && printIfFirst) { 328 << "#=========================================================\n" 329 << "# To disable this message, place a call to \n" 331 << "# asymm_mt2_lester_bisect::disableCopyrightMessage();\n" 333 << "# somewhere before you begin to calculate your MT2 values.\n" 334 << "#=========================================================\n" 335 << "# You are calculating symmetric or asymmetric MT2 using\n" 336 << "# the implementation defined in:\n" 338 << "# http://arxiv.org/abs/1411.4312\n" 340 << "# Please cite the paper above if you use the MT2 values\n" 341 << "# for a scholarly purpose. For the variable MT2 itself,\n" 342 << "# please also cite:\n" 344 << "# http://arxiv.org/abs/hep-ph/9906349\n" 345 << "#=========================================================\n" 346 << "\n\n" << std::flush; 351 static double get_mT2_Sq( 352 const double mVis1, const double pxVis1, const double pyVis1, 353 const double mVis2, const double pxVis2, const double pyVis2, 354 const double pxMiss, const double pyMiss, 355 const double mInvis1, const double mInvis2, 356 const double desiredPrecisionOnMT2=0, 357 const bool useDeciSectionsInitially= true 361 disableCopyrightMessage( true); 363 const double m1Min = mVis1+mInvis1; 364 const double m2Min = mVis2+mInvis2; 368 return asymm_mt2_lester_bisect::get_mT2_Sq( 369 mVis2, pxVis2, pyVis2, 370 mVis1, pxVis1, pyVis1, 373 desiredPrecisionOnMT2 378 assert(m1Min<=m2Min); 380 const double mMin = m2Min; 384 const double msSq = mVis1*mVis1; 385 const double sx = pxVis1; 386 const double sy = pyVis1; 387 const double mpSq = mInvis1*mInvis1; 389 const double mtSq = mVis2*mVis2; 390 const double tx = pxVis2; 391 const double ty = pyVis2; 392 const double mqSq = mInvis2*mInvis2; 394 const double sSq = sx*sx + sy*sy; 395 const double tSq = tx*tx + ty*ty; 396 const double pMissSq = pxMiss*pxMiss + pyMiss*pyMiss; 397 const double massSqSum = msSq + mtSq + mpSq + mqSq; 398 const double scaleSq = (massSqSum + sSq + tSq + pMissSq)/8.0; 403 std::cout << "\nMOO "; 409 const double scale = sqrt(scaleSq); 412 double mLower = mMin; 413 double mUpper = mMin + scale; 414 unsigned int attempts=0; 415 const unsigned int maxAttempts=10000; 419 const double mUpperSq = mUpper*mUpper; 420 const Lester::EllipseParams & side1=helper(mUpperSq, msSq, -sx, -sy, mpSq, 0, 0 ); 421 const Lester::EllipseParams & side2=helper(mUpperSq, mtSq, +tx, +ty, mqSq, pxMiss, pyMiss); 425 disjoint = Lester::ellipsesAreDisjoint(side1, side2); 434 if (attempts>=maxAttempts) { 435 std::cerr << "MT2 algorithm failed to find upper bound to MT2" << std::endl; 448 bool goLow = useDeciSectionsInitially; 449 while(desiredPrecisionOnMT2<=0 || mUpper-mLower>desiredPrecisionOnMT2) { 451 const double trialM = ( goLow ? 452 (mLower*15+mUpper)/16 454 (mUpper + mLower)/2.0 457 if (trialM<=mLower || trialM>=mUpper) { 460 std::cout << " MACHINE_PREC " << std::setprecision(10) << mLower << " " << trialM << " " << mUpper << " " << mUpper-mLower << " " << desiredPrecisionOnMT2 << std::endl; 462 return trialM*trialM; 464 const double trialMSq = trialM * trialM; 465 const Lester::EllipseParams & side1 = helper(trialMSq, msSq, -sx, -sy, mpSq, 0, 0 ); 466 const Lester::EllipseParams & side2 = helper(trialMSq, mtSq, +tx, +ty, mqSq, pxMiss, pyMiss); 469 const bool disjoint = Lester::ellipsesAreDisjoint(side1, side2); 485 std::cout << " THROW " << std::endl; 487 return mLower*mLower; 491 const double mAns = (mLower+mUpper)/2.0; 494 std::cout << " USER_PREC " << std::endl; 499 static double lestermax( const double x, const double y) { 502 static const Lester::EllipseParams helper( const double mSq, 503 const double mtSq, const double tx, const double ty, 505 const double pxmiss, const double pymiss 507 const double txSq = tx*tx; 508 const double tySq = ty*ty; 509 const double pxmissSq = pxmiss*pxmiss; 510 const double pymissSq = pymiss*pymiss; 513 const double c_xx = +4.0* mtSq + 4.0* tySq; 515 const double c_yy = +4.0* mtSq + 4.0* txSq; 517 const double c_xy = -4.0* tx*ty; 519 const double c_x = -4.0* mtSq*pxmiss - 2.0* mqSq*tx + 2.0* mSq*tx - 2.0* mtSq*tx + 520 4.0* pymiss*tx*ty - 4.0* pxmiss*tySq; 522 const double c_y = -4.0* mtSq*pymiss - 4.0* pymiss*txSq - 2.0* mqSq*ty + 2.0* mSq*ty - 2.0* mtSq*ty + 525 const double c = - mqSq*mqSq + 2*mqSq*mSq - mSq*mSq + 2*mqSq*mtSq + 2*mSq*mtSq - mtSq*mtSq + 526 4.0* mtSq*pxmissSq + 4.0* mtSq*pymissSq + 4.0* mqSq*pxmiss*tx - 527 4.0* mSq*pxmiss*tx + 4.0* mtSq*pxmiss*tx + 4.0* mqSq*txSq + 528 4.0* pymissSq*txSq + 4.0* mqSq*pymiss*ty - 4.0* mSq*pymiss*ty + 529 4.0* mtSq*pymiss*ty - 8.0* pxmiss*pymiss*tx*ty + 4.0* mqSq*tySq + 532 return Lester::EllipseParams(c_xx, c_yy, c_xy, c_x, c_y, c); 538 std::cout << "Version is : 2014_11_13" << std::endl; 542 double MT( double px1, double px2, double py1, double py2, double m1 , double m2){ 543 double E1 = sqrt(px1*px1+py1*py1+m1*m1); 544 double E2 = sqrt(px2*px2+py2*py2+m2*m2); 545 double Msq = (E1+E2)*(E1+E2)-(px1+px2)*(px1+px2)-(py1+py2)*(py1+py2); 546 if (Msq < 0) Msq = 0; 550 std::pair <double,double> ben_findsols( double MT2, double px, double py, double visM, double Ma, double pxb, double pyb, double metx, double mety, double visMb, double Mb){ 553 std::pair <double,double> sols; 559 double Pt = sqrt(px*px+py*py); 560 double E = sqrt(Pt*Pt+visM*visM); 566 double Ma4 = Ma2*Ma2; 569 double px4 = px2*px2; 570 double py4 = py2*py2; 573 double TermA = E2*px-M2*px+Ma2*px-px2*px-px*py2; 574 double TermB = -2.*px*py; 575 double TermSqy0 = E4*E2-2.*E4*M2-2.*E4*Ma2-2.*E4*px2-2.*E4*py2+E2*M4-2.*E2*M2*Ma2+2.*E2*M2*px2+2.*E2*M2*py2+E2*Ma4+2.*E2*Ma2*px2-2.*E2*Ma2*py2+E2*px4+2.*E2*px2*py2+E2*py4; 576 double TermSqy1 = -4.*E4*py+4.*E2*M2*py-4.*E2*Ma2*py+4.*E2*px2*py+4.*E2*py3; 577 double TermSqy2 = -4.*E4+4.*E2*px2+4.*E2*py2; 582 if (TermSqy1*TermSqy1-4.*TermSqy0*TermSqy2 < 0){ 586 double sol1 = (-TermSqy1 - sqrt(TermSqy1*TermSqy1-4.*TermSqy0*TermSqy2))/(2.*TermSqy2); 587 double sol2 = (-TermSqy1 + sqrt(TermSqy1*TermSqy1-4.*TermSqy0*TermSqy2))/(2.*TermSqy2); 595 double myclose = 99999999.; 596 for ( double metpy = low; metpy<=high; metpy+=(high-low)/10000.){ 597 double metpx = -(TermB*metpy+TermA-sqrt(TermSqy0+TermSqy1*metpy+TermSqy2*metpy*metpy))*0.5/(E2-px2); 598 double metpx2 = -(TermB*metpy+TermA+sqrt(TermSqy0+TermSqy1*metpy+TermSqy2*metpy*metpy))*0.5/(E2-px2); 599 double mt1a = MT(px,metpx,py,metpy,visM,Ma); 600 double mt1b = MT(px,metpx2,py,metpy,visM,Ma); 601 double metpxb = metx-metpx; 602 double metpx2b = metx-metpx2; 603 double mt2a = MT(pxb,metpxb,pyb,mety-metpy,visMb,Mb); 604 double mt2b = MT(pxb,metpx2b,pyb,mety-metpy,visMb,Mb); 605 if (fabs(mt1a-mt2a) < myclose){ 606 myclose = fabs(mt1a-mt2a); 610 if (fabs(mt1b-mt2b) < myclose){ 611 myclose = fabs(mt1b-mt2b); bool operator==(const Cut &a, const Cut &b) Compare two cuts for equality, forwards to the cut-specific implementation. Definition: Cuts.hh:41
|