ATLAS Offline Software
NeutrinoWeighting.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
3  */
4 
6 
7 #include "TopEvent/Event.h"
8 
9 #include <cmath>
10 
11 namespace top {
12  NeutrinoWeighting::NeutrinoWeighting() : sigmax(10), sigmay(10) {
13  double etaStep = 0.2;
14 
15  //construct the array of eta values to use (cosh and sinh them)
16  int index = 0;
17 
18  for (double eta = -5.0; eta < 5.0001; eta += etaStep) {
19  neutrinos[index][0] = eta;
20  neutrinos[index][1] = std::sinh(eta);
21  neutrinos[index][2] = std::cosh(eta);
22  ++index;
23  }
24 
25  etaSize = index;
26 
27  if (etaSize > 2000) {
28  std::cout << "ERROR TOO MANY SAMPLING POINT FOR neutrinos ARRAY" << std::endl;
29  exit(1);
30  }
31  }
32 
34  }
35 
37  TLorentzVector l1;
38  TLorentzVector l2;
39  TLorentzVector b1;
40  TLorentzVector b2;
41  double topMass = 172500.;
42 
43  const double met_ex = event.m_met->mpx();
44  const double met_ey = event.m_met->mpy();
45 
46  for (int i = 0; i < etaSize; ++i) {
47  for (int j = 0; j < etaSize; ++j) {
48  NWSolution ans1 = solveForNeutrinoEta(l1, b1, topMass, i);
49  NWSolution ans2 = solveForNeutrinoEta(l2, b2, topMass, j);
50 
51  if (ans1.getNumSolutions() > 0 && ans2.getNumSolutions() > 0) {
52  const double sol1 = neutrino_weight(ans1.getv1(), ans2.getv1(), met_ex, met_ey);
53  const double sol2 = neutrino_weight(ans1.getv1(), ans2.getv2(), met_ex, met_ey);
54  const double sol3 = neutrino_weight(ans1.getv2(), ans2.getv1(), met_ex, met_ey);
55  const double sol4 = neutrino_weight(ans1.getv2(), ans2.getv2(), met_ex, met_ey);
56 
57  if (std::isnan(sol1) || std::isnan(sol2) || std::isnan(sol3) ||
58  std::isnan(sol4)) std::cout << "One of the quadratic ans is NaN!" << std::endl;
59  }
60 
61  ans1 = solveForNeutrinoEta(l1, b2, topMass, i);
62  ans2 = solveForNeutrinoEta(l2, b1, topMass, j);
63 
64  if (ans1.getNumSolutions() > 0 && ans2.getNumSolutions() > 0) {
65  const double sol1 = neutrino_weight(ans1.getv1(), ans2.getv1(), met_ex, met_ey);
66  const double sol2 = neutrino_weight(ans1.getv1(), ans2.getv2(), met_ex, met_ey);
67  const double sol3 = neutrino_weight(ans1.getv2(), ans2.getv1(), met_ex, met_ey);
68  const double sol4 = neutrino_weight(ans1.getv2(), ans2.getv2(), met_ex, met_ey);
69 
70  if (std::isnan(sol1) || std::isnan(sol2) || std::isnan(sol3) ||
71  std::isnan(sol4)) std::cout << "One of the quadratic ans is NaN!" << std::endl;
72  }
73  }
74  }
75 
76  //normalise?
77 
78  return true;
79  }
80 
81  NWSolution NeutrinoWeighting::solveForNeutrinoEta(const TLorentzVector& lepton, const TLorentzVector& bJet,
82  double topMass, int index) const {
83  double Wmass2 = m_wmass * m_wmass;
84  double bmass = m_bmass;
85 
86  double Elprime = lepton.E() * neutrinos[index][2] - lepton.Pz() * neutrinos[index][1];
87  double Ebprime = bJet.E() * neutrinos[index][2] - bJet.Pz() * neutrinos[index][1];
88 
89  double A = (lepton.Py() * Ebprime - bJet.Py() * Elprime) / (bJet.Px() * Elprime - lepton.Px() * Ebprime);
90  double B = (Elprime * (topMass * topMass - Wmass2 - bmass * bmass - 2. * lepton * bJet) - Ebprime * Wmass2) /
91  (2. * (lepton.Px() * Ebprime - bJet.Px() * Elprime));
92 
93  double par1 = (lepton.Px() * A + lepton.Py()) / Elprime;
94  double C = A * A + 1. - par1 * par1;
95  double par2 = (Wmass2 / 2. + lepton.Px() * B) / Elprime;
96  double D = 2. * (A * B - par2 * par1);
97  double F = B * B - par2 * par2;
98  double det = D * D - 4. * C * F;
99 
100  NWSolution sol;
101 
102  sol.setSolutions(0);
103 
104  if (det > 0.) {
105  double tmp = std::sqrt(det) / (2. * C);
106  double py1 = -D / (2. * C) + tmp;
107  double py2 = -D / (2. * C) - tmp;
108  double px1 = A * py1 + B;
109  double px2 = A * py2 + B;
110  double pT2_1 = px1 * px1 + py1 * py1;
111  double pT2_2 = px2 * px2 + py2 * py2;
112  double pz1 = std::sqrt(pT2_1) * neutrinos[index][1];
113  double pz2 = std::sqrt(pT2_2) * neutrinos[index][1];
114 
115  TLorentzVector a1(px1, py1, pz1, sqrt(pT2_1 + pz1* pz1));
116  TLorentzVector a2(px2, py2, pz2, sqrt(pT2_2 + pz2* pz2));
117 
118  sol.setSolutions(2, a1, a2);
119  }
120 
121  return sol;
122  }
123 
124  double NeutrinoWeighting::neutrino_weight(const TLorentzVector& neutrino1, const TLorentzVector& neutrino2,
125  double met_ex, double met_ey) const {
126  const double dx = met_ex - neutrino1.Px() - neutrino2.Px();
127  const double dy = met_ey - neutrino1.Py() - neutrino2.Py();
128 
129  return exp(-dx * dx / (2. * sigmax * sigmax) - dy * dy / (2. * sigmay * sigmay));
130  }
131 }
top::NWSolution::getv1
TLorentzVector getv1() const
Definition: NeutrinoWeighting.h:35
top::NeutrinoWeighting::m_bmass
double m_bmass
B jet mass constraint.
Definition: NeutrinoWeighting.h:100
top::NeutrinoWeighting::NeutrinoWeighting
NeutrinoWeighting()
Definition: NeutrinoWeighting.cxx:12
top
TopConfig A simple configuration that is NOT a singleton.
Definition: AnalysisTrackingHelper.cxx:58
top::NWSolution::getNumSolutions
int getNumSolutions() const
Definition: NeutrinoWeighting.h:31
top::NeutrinoWeighting::apply
bool apply(const top::Event &) const override
This does stuff based on the information in an event.
Definition: NeutrinoWeighting.cxx:36
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
index
Definition: index.py:1
top::NeutrinoWeighting::neutrinos
double neutrinos[2000][3]
Sampling points.
Definition: NeutrinoWeighting.h:90
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
top::NWSolution::getv2
TLorentzVector getv2() const
Definition: NeutrinoWeighting.h:39
top::NeutrinoWeighting::~NeutrinoWeighting
virtual ~NeutrinoWeighting()
Definition: NeutrinoWeighting.cxx:33
skel.l2
l2
Definition: skel.GENtoEVGEN.py:426
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
lumiFormat.i
int i
Definition: lumiFormat.py:92
top::NeutrinoWeighting::neutrino_weight
double neutrino_weight(const TLorentzVector &, const TLorentzVector &, double, double) const
Calculate the weight for this combination of particles by comparing with Met.
Definition: NeutrinoWeighting.cxx:124
WritePulseShapeToCool.det
det
Definition: WritePulseShapeToCool.py:204
top::NeutrinoWeighting::sigmay
double sigmay
Definition: NeutrinoWeighting.h:109
top::NeutrinoWeighting::m_wmass
double m_wmass
W jet mass constraint.
Definition: NeutrinoWeighting.h:103
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
top::NeutrinoWeighting::sigmax
double sigmax
Definition: NeutrinoWeighting.h:106
Event.h
calibdata.exit
exit
Definition: calibdata.py:236
top::NeutrinoWeighting::etaSize
int etaSize
Delta eta sampling size. For the mass we don't need to sample so many points.
Definition: NeutrinoWeighting.h:93
NeutrinoWeighting.h
top::NWSolution
Holds the two solutions from the quadratic equation as TLorentVectors.
Definition: NeutrinoWeighting.h:19
top::NeutrinoWeighting::solveForNeutrinoEta
NWSolution solveForNeutrinoEta(const TLorentzVector &lepton, const TLorentzVector &bJet, double topMass, int index) const
Definition: NeutrinoWeighting.cxx:81
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
DeMoScan.index
string index
Definition: DeMoScan.py:362
F
#define F(x, y, z)
Definition: MD5.cxx:112
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
top::NWSolution::setSolutions
void setSolutions(int num, const TLorentzVector &a, const TLorentzVector &b)
Definition: NeutrinoWeighting.h:21
top::Event
Very simple class to hold event data after reading from a file.
Definition: Event.h:49
skel.l1
l1
Definition: skel.GENtoEVGEN.py:425