CMS 3D CMS Logo

MultiProngTauSolver.cc
Go to the documentation of this file.
2 #include "TMatrixTSym.h"
3 #include "TVectorT.h"
5 
6 using namespace tauImpactParameter;
7 
8 void MultiProngTauSolver::quadratic(double& x_plus, double& x_minus, double a, double b, double c, bool& isReal) {
9  double R = b * b - 4 * a * c;
10  isReal = true;
11  if (R < 0) {
12  isReal = false;
13  } // flag cases when R<0 but compute quadratic equation with |R|
14  x_minus = (-b + sqrt(fabs(R))) / (2.0 * a); // opposite sign is smaller
15  x_plus = (-b - sqrt(fabs(R))) / (2.0 * a);
16 }
17 
18 void MultiProngTauSolver::analyticESolver(TLorentzVector& nu_plus,
19  TLorentzVector& nu_minus,
20  const TLorentzVector& A1,
21  bool& isReal) {
22  double a = (A1.Pz() * A1.Pz()) / (A1.E() * A1.E()) - 1.0;
23  double K = (PDGInfo::tau_mass() * PDGInfo::tau_mass() - A1.M2() - 2.0 * A1.Pt() * A1.Pt()) / (2.0 * A1.E());
24  double b = 2.0 * K * A1.Pz() / A1.E();
25  double c = K * K - A1.Pt() * A1.Pt();
26  double z_plus(0), z_minus(0);
27  quadratic(z_plus, z_minus, a, b, c, isReal);
28  nu_plus = TLorentzVector(-A1.Px(), -A1.Py(), z_plus, sqrt(z_plus * z_plus + A1.Pt() * A1.Pt()));
29  nu_minus = TLorentzVector(-A1.Px(), -A1.Py(), z_minus, sqrt(z_minus * z_minus + A1.Pt() * A1.Pt()));
30 }
31 
32 void MultiProngTauSolver::numericalESolver(TLorentzVector& nu_plus,
33  TLorentzVector& nu_minus,
34  const TLorentzVector& A1,
35  bool& isReal) {
36  double rmin(-100), rmax(100), step(0.01), mtau2(PDGInfo::tau_mass() * PDGInfo::tau_mass()), z1(-999), z2(-999),
37  zmin(-999), min(9999), prev(9999);
38  double z = rmin;
39  TLorentzVector nu, tau;
40  for (int i = 0; i <= (int)(rmax - rmin) / step; i++) {
41  nu.SetPxPyPzE(-A1.Px(), -A1.Py(), z, sqrt(z * z + A1.Pt() * A1.Pt()));
42  tau = A1 + nu;
43  double m2 = tau.M2();
44  if (m2 - mtau2 < 0 && prev - mtau2 >= 0)
45  z1 = z;
46  if (m2 - mtau2 > 0 && prev - mtau2 <= 0)
47  z2 = z;
48  if (min > m2) {
49  zmin = z;
50  min = m2;
51  }
52  prev = m2;
53  z += step;
54  }
55  if (z1 != -999 && z2 != -999) {
56  nu_plus = TLorentzVector(-A1.Px(), -A1.Py(), z1, sqrt(z1 * z1 + A1.Pt() * A1.Pt()));
57  nu_minus = TLorentzVector(-A1.Px(), -A1.Py(), z2, sqrt(z2 * z2 + A1.Pt() * A1.Pt()));
58  } else {
59  nu_plus = TLorentzVector(-A1.Px(), -A1.Py(), zmin, sqrt(zmin * zmin + A1.Pt() * A1.Pt()));
60  nu_minus = TLorentzVector(-A1.Px(), -A1.Py(), zmin, sqrt(zmin * zmin + A1.Pt() * A1.Pt()));
61  }
62 }
63 
64 void MultiProngTauSolver::solveByRotation(const TVector3& TauDir,
65  const TLorentzVector& A1,
66  TLorentzVector& Tau_plus,
67  TLorentzVector& Tau_minus,
68  TLorentzVector& nu_plus,
69  TLorentzVector& nu_minus,
70  bool& isReal,
71  bool rotateback) {
72  TLorentzVector A1rot = A1;
73  double phi(TauDir.Phi()), theta(TauDir.Theta());
74  A1rot.RotateZ(-phi);
75  A1rot.RotateY(-theta);
77  // NumericalESolver(nu_plus,nu_minus,A1rot); // for debugging analyticESolver (slow)
78  analyticESolver(nu_plus, nu_minus, A1rot, isReal);
80  if (rotateback) {
81  nu_plus.RotateY(theta);
82  nu_plus.RotateZ(phi);
83  Tau_plus = A1 + nu_plus;
84  //
85  nu_minus.RotateY(theta);
86  nu_minus.RotateZ(phi);
87  Tau_minus = A1 + nu_minus;
88  } else {
89  Tau_plus = A1rot + nu_plus;
90  Tau_minus = A1rot + nu_minus;
91  }
92 }
93 
95  double& theta,
96  double& phi,
97  double scale) {
98  double thetaGJMaxvar = thetaGJMax(a1);
99  TVector3 a1v(a1.Vect());
100  if (a1v.Mag() != 0)
101  a1v *= 1 / a1v.Mag();
102  TVector3 tau(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
103  double dphitheta = acos(a1v.Dot(tau) / (a1v.Mag() * tau.Mag()));
104  if (thetaGJMaxvar < dphitheta || scale < 0) {
105  if (scale < 0)
106  scale = 1.0;
107  double a = (thetaGJMaxvar / dphitheta) - (1 - scale);
108  double b = 1 - (thetaGJMaxvar / dphitheta) + (1 - scale);
109  edm::LogInfo("RecoTauTag/ImpactParameter")
110  << "SetTauDirectionatThetaGJMax before GF " << thetaGJMaxvar << " dot "
111  << acos(a1v.Dot(tau) / (a1v.Mag() * tau.Mag())) << " a1 phi " << a1v.Phi() << " tau phi " << tau.Phi()
112  << " a1 theta " << a1v.Theta() << " tau theta " << tau.Theta();
113  tau *= a;
114  a1v *= b;
115  tau += a1v;
116  theta = tau.Theta();
117  phi = tau.Phi();
118  edm::LogInfo("RecoTauTag/ImpactParameter")
119  << "SetTauDirectionatThetaGJMax GF " << thetaGJMaxvar << " dot " << acos(a1v.Dot(tau) / (a1v.Mag() * tau.Mag()))
120  << " phi " << phi << " theta " << theta;
121  return true;
122  }
123  return false;
124 }
125 
126 double MultiProngTauSolver::thetaGJMax(const TLorentzVector& a1) {
127  return asin((PDGInfo::tau_mass() * PDGInfo::tau_mass() - a1.M2()) / (2.0 * PDGInfo::tau_mass() * fabs(a1.P())));
128 }
129 
131  const TVector3& pv,
132  int ambiguity,
133  TLorentzVector& tau) {
134  TLorentzVector lorentzA1 = a1.p4();
135  TVector3 sv = a1.vertex();
136  TVector3 tauFlghtDir = sv - pv;
137  TLorentzVector nuGuess;
138 
139  TVector3 startingtauFlghtDir = tauFlghtDir.Unit();
140  if (ambiguity == zero) {
141  double theta = tauFlghtDir.Theta();
142  double phi = tauFlghtDir.Phi();
143  setTauDirectionatThetaGJMax(lorentzA1, theta, phi);
144  startingtauFlghtDir = TVector3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
145  }
146  TLorentzVector tau1, tau2, nu1, nu2;
147  bool isReal;
148  solveByRotation(startingtauFlghtDir, lorentzA1, tau1, tau2, nu1, nu2, isReal);
149  if (ambiguity == plus) {
150  nuGuess = nu1;
151  tau = tau1;
152  }
153  if (ambiguity == minus) {
154  nuGuess = nu2;
155  tau = tau1;
156  }
157  if (ambiguity == zero) {
158  nuGuess = nu1;
159  tau = tau1;
160  }
161  TVectorT<double> par(LorentzVectorParticle::NLorentzandVertexPar);
165  par(LorentzVectorParticle::px) = nuGuess.Px();
166  par(LorentzVectorParticle::py) = nuGuess.Py();
167  par(LorentzVectorParticle::pz) = nuGuess.Pz();
168  par(LorentzVectorParticle::m) = nuGuess.M();
169  TMatrixTSym<double> Cov(LorentzVectorParticle::NLorentzandVertexPar);
170  TMatrixTSym<double> pvCov = a1.vertexCov();
171  for (int i = 0; i < LorentzVectorParticle::NLorentzandVertexPar; i++) {
172  for (int j = 0; j <= i; j++) {
174  Cov(i, j) = pvCov(i, j);
175  else
176  Cov(i, j) = 0;
177  }
178  double v = 0;
180  v = 10 * par(i) * par(i);
181  if (v < 1000.0)
182  v = 1000.0; // try lowing to test impact
183  Cov(i, i) += v;
184  }
185  return LorentzVectorParticle(par, Cov, PDGInfo::nu_tau, 0, a1.bField());
186 }
187 
188 TVectorT<double> MultiProngTauSolver::rotateToTauFrame(const TVectorT<double>& inpar) {
189  TVectorT<double> outpar(3);
190  TVector3 res(inpar(0), inpar(1), inpar(2));
191  TVector3 Uz(sin(inpar(4)) * cos(inpar(3)), sin(inpar(4)) * sin(inpar(3)), cos(inpar(4)));
192  res.RotateUz(Uz);
193  /* double phi=inpar(3,0);
194  double theta=inpar(4,0);
195  res.RotateZ(-phi);
196  TVector3 Y(0,1,0);
197  TVector3 thetadir=res.Cross(Y);
198  thetadir.RotateY(-theta);
199  res.RotateY(-theta);
200  res.RotateZ(thetadir.Phi());*/
201  outpar(0) = res.X();
202  outpar(1) = res.Y();
203  outpar(2) = res.Z();
204  return outpar;
205 }
static void analyticESolver(TLorentzVector &nu_plus, TLorentzVector &nu_minus, const TLorentzVector &A1, bool &isReal)
virtual double bField() const
Definition: Particle.h:29
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
static TVectorT< double > rotateToTauFrame(const TVectorT< double > &inpar)
static bool setTauDirectionatThetaGJMax(const TLorentzVector &a1, double &theta, double &phi, double scale=1.0)
static double thetaGJMax(const TLorentzVector &a1)
Definition: Electron.h:6
T sqrt(T t)
Definition: SSEVec.h:19
static LorentzVectorParticle estimateNu(const LorentzVectorParticle &a1, const TVector3 &pv, int ambiguity, TLorentzVector &tau)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
def pv(vc)
Definition: MetAnalyzer.py:7
Log< level::Info, false > LogInfo
double b
Definition: hdecay.h:118
double a
Definition: hdecay.h:119
step
Definition: StallMonitor.cc:98
Geom::Theta< T > theta() const
static void solveByRotation(const TVector3 &TauDir, const TLorentzVector &A1, TLorentzVector &Tau_plus, TLorentzVector &Tau_minus, TLorentzVector &nu_plus, TLorentzVector &nu_minus, bool &isReal, bool rotateback=true)
static double tau_mass()
Definition: PDGInfo.h:14
static void numericalESolver(TLorentzVector &nu_plus, TLorentzVector &nu_minus, const TLorentzVector &A1, bool &isReal)
static void quadratic(double &x_plus, double &x_minus, double a, double b, double c, bool &isReal)