// D0 RedMET with CMG trees double getD0RedMet(double lpx1, double lpy1, double lpterr1, double lpx2, double lpy2, double lpterr2, double sumjpx, double sumjpy, double pfmet, double pfmetphi, int flav, int pickAFlav = 1) { if( flav==3 ) { if( pickAFlav!=1 && pickAFlav!=2 ) { cout << " *** ERROR *** " << endl; cout << " You need to pick a flavor in getD0RedMet(...)! " << endl; throw std::exception(); return -1.; } else { flav = pickAFlav; } } // double wPerpMu = 1.0; // double wRecMu = 2.0; // double wUncMu = 2.5; double wPerpMu = 1.0; double wRecMu = 1.5; double wUncMu = 2.75; // double wPerpEl = 1.5; // double wRecEl = 2.25; // double wUncEl = 0.0; double wPerpEl = 0.75; double wRecEl = 1.0; double wUncEl = 0.25; int seplep = 1; if (seplep == 0){ wPerpMu = 1.0; wRecMu = 1.25; wUncMu = 0.0; wPerpEl = wPerpMu; wRecEl = wRecMu; wUncEl = wUncMu; } double kPerp = 1.; double kRecoil_l = 1.; double kRecoil_t = 1.; double kSigmaPt_l = 1.; double kSigmaPt_t = 1.; if( flav==1 ) { // mm kPerp = wPerpMu; kRecoil_l = kRecoil_t = wRecMu; kSigmaPt_l = kSigmaPt_t = wUncMu; } else if( flav==2 ) { // ee kPerp = wPerpEl; kRecoil_l = kRecoil_t = wRecEl; kSigmaPt_l = kSigmaPt_t = wUncEl; } else {} double pt1 = sqrt(lpx1*lpx1 + lpy1*lpy1); double pt2 = sqrt(lpx2*lpx2 + lpy2*lpy2); TVector2 lead, subl; double leadpt, sublpt, leadpterr, sublpterr; if(pt1>pt2) { lead = TVector2(lpx1, lpy1); subl = TVector2(lpx2, lpy2); leadpt = pt1; leadpterr = lpterr1; sublpt = pt2; sublpterr = lpterr2; } else { lead = TVector2(lpx2, lpy2); subl = TVector2(lpx1, lpy1); leadpt = pt2; leadpterr = lpterr2; sublpt = pt1; sublpterr = lpterr1; } // Define the thrust and dilepton TVector2 dil = lead+subl; TVector2 thr = lead-subl; TVector2 longi; TVector2 perpe; double deltaPhi = fabs(lead.DeltaPhi(subl)); if( deltaPhi>(3.141592654/2.) ) { longi = thr.Unit(); perpe = longi.Rotate(3.141592654/2.); if(perpe*lead<0) perpe *= -1; } else { perpe = dil.Unit(); longi = perpe.Rotate(3.141592654/2.); if(longi*lead<0) longi *= -1; } // Dilepton double dileptProj_l = dil*longi; double dileptProj_t = dil*perpe; // Unclustered TVector2 uncl( pfmet*cos(pfmetphi), pfmet*sin(pfmetphi) ); uncl += dil; double unclProj_l = uncl*longi; double unclProj_t = uncl*perpe; // Sum of jets TVector2 sumjVec(sumjpx, sumjpy); double sumjetProj_l = sumjVec*longi; double sumjetProj_t = sumjVec*perpe; // Recoil double recoilProj_l = min( sumjetProj_l, -1.0*unclProj_l ); recoilProj_l = min( 0., recoilProj_l ); double recoilProj_t = min( sumjetProj_t, -1.0*unclProj_t ); recoilProj_t = min( 0., recoilProj_t ); // Case with 0 jets // double recoilProj_l = -1.0*unclProj_l; recoilProj_l = min( 0., recoilProj_l ); // double recoilProj_t = -1.0*unclProj_t; recoilProj_t = min( 0., recoilProj_t ); // Lepton uncertainty double relErrLead = min( leadpterr/leadpt, 1. ); double relErrSubl = min( sublpterr/sublpt, 1. ); TVector2 lowLead = lead*(1.0-relErrLead); TVector2 lowSubl = subl*(1.0-relErrSubl); TVector2 lowDil = lowLead + lowSubl; TVector2 lowThr = lowLead - lowSubl; double deltaDileptProj_t = lowDil*perpe - dileptProj_t; double deltaDileptProj_l = ( -relErrLead*lead + relErrSubl*subl )*longi; double redMET_l = max( (dileptProj_l + kRecoil_l*recoilProj_l + kSigmaPt_l*deltaDileptProj_l), 0.); double redMET_t = max( (dileptProj_t + kRecoil_t*recoilProj_t + kSigmaPt_t*deltaDileptProj_t), 0.); double redMET = sqrt( pow(redMET_l,2) + kPerp*pow(redMET_t,2) ); return redMET; }
void PMCSZCand::SetA(PMCSEMObj &elec1, PMCSEMObj &elec2) { // First we need to calculate the thrust axis // TVector2 e1(elec1.ppx(),elec1.ppy()); TVector2 e2(elec2.ppx(),elec2.ppy()); // Calculate the two phi angles double phi1=e1.Phi(); double phi2=e2.Phi(); // Order in phi if (phi1<phi2) { TVector2 dummy=e1; e1=e2; e2=dummy; double dummy2=phi1; phi1=phi2; phi2=dummy2; } // Calculate lengths as well double len1=e1.Mod(); double len2=e2.Mod(); // Good old Newton // // initial guess TVector2 bisector=(e1.Unit()+e2.Unit()).Unit(); double alpha=bisector.Phi()-TMath::Pi()/2.; double alphaBackup=alpha; int nIt=0; // iterate double oldAlpha=9999.; while (fabs(alpha-oldAlpha)>0.000001) { oldAlpha=alpha; double f=len2*sin(phi2-oldAlpha)+len1*sin(oldAlpha-phi1); double fp=-len2*cos(phi2-oldAlpha)+len1*cos(oldAlpha-phi1); alpha=oldAlpha-f/fp; nIt++; if (nIt>1000) { cout<<"Newton did not converge in search for thrust axis"<<endl; alpha=alphaBackup; break; } } // Build unit vector TVector2 r; r.SetMagPhi(1.,alpha); TVector2 rPerp=r.Rotate(TMath::Pi()/2.); // Checks if (fabs(e1*rPerp-e2*rPerp)>0.001) { cout<<"Looks like Newton was imprecise in calculation of thrust axis: "<<e1*rPerp<<" "<<e2*rPerp<<endl; } // now we can do the projections TVector2 Z=e1+e2; _pat=Z*rPerp; _pal=Z*r; }