CMS 3D CMS Logo

TauA1NuConstrainedFitter.cc
Go to the documentation of this file.
1 /* From SimpleFits Package
2  * Designed an written by
3  * author: Ian M. Nugent
4  * Humboldt Foundations
5  */
6 #include <functional>
7 #include <cmath>
11 #include <iostream>
12 
13 using namespace tauImpactParameter;
14 
16  const LorentzVectorParticle& A1,
17  const TVector3& PVertex,
18  const TMatrixTSym<double>& VertexCov)
19  : MultiProngTauSolver(), ambiguity_(ambiguity) {
20  TLorentzVector Tau(0, 0, 0, 0);
21  //dummy substitution not used later
22  TVectorT<double> nu_par(LorentzVectorParticle::NLorentzandVertexPar, 1);
23  TMatrixTSym<double> nu_cov(LorentzVectorParticle::NLorentzandVertexPar);
24  LorentzVectorParticle Nu(nu_par, nu_cov, PDGInfo::nu_tau, 0.0, A1.bField());
25  particles_.push_back(A1);
26  particles_.push_back(Nu);
27 
28  // setup 13 by 13 matrix
30  TVectorT<double> inpar(size);
31  TMatrixTSym<double> incov(size);
32 
33  // Get primary vertex information
34  if (VertexCov.GetNrows() != LorentzVectorParticle::NVertex)
35  return;
36  inpar(LorentzVectorParticle::vx) = PVertex.X();
37  inpar(LorentzVectorParticle::vy) = PVertex.Y();
38  inpar(LorentzVectorParticle::vz) = PVertex.Z();
39  for (int i = 0; i < LorentzVectorParticle::NVertex; i++) {
40  for (int j = 0; j < LorentzVectorParticle::NVertex; j++)
41  incov(i, j) = VertexCov(i, j);
42  }
43  int A1offset = LorentzVectorParticle::NVertex;
45  for (int i = 0; i < LorentzVectorParticle::NLorentzandVertexPar; i++) {
46  inpar(i + A1offset) = A1.parameter(i);
47  inpar(i + Nuoffset) = Nu.parameter(i) + 1.0; // offset by 1 GeV to prevent convergence on first iteration
48  for (int j = 0; j < LorentzVectorParticle::NLorentzandVertexPar; j++) {
49  incov(i + A1offset, j + A1offset) = A1.covariance(i, j);
50  incov(i + Nuoffset, j + Nuoffset) = Nu.covariance(i, j);
51  }
52  }
53 
54  exppar.ResizeTo(nexpandedpar, 1);
55  exppar = ComputeInitalExpPar(inpar);
56  expcov.ResizeTo(nexpandedpar, nexpandedpar);
58 
59  TVectorT<double> PAR_0(npar);
60  par_0.ResizeTo(npar);
61  cov_0.ResizeTo(npar, npar);
62  PAR_0 = ComputeExpParToPar(exppar);
63  for (int i = 0; i < npar; i++)
64  par_0(i) = PAR_0(i);
66 
67  for (int i = 0; i < npar; i++) {
68  for (int j = 0; j < npar; j++) {
69  cov_0(i, j) = expcov(i, j);
70  }
71  }
72 
73  par.ResizeTo(npar);
74  par = par_0;
75  cov.ResizeTo(npar, npar);
76  cov = cov_0;
77 }
78 
79 TVectorT<double> TauA1NuConstrainedFitter::ComputeInitalExpPar(const TVectorT<double>& inpar) {
80  TVectorT<double> outpar(nexpandedpar);
81  int offset = LorentzVectorParticle::NVertex; // for A1
83  TVector3 sv(inpar(LorentzVectorParticle::vx + offset),
86  TVector3 TauDir = sv - pv;
87  outpar(tau_phi) = TauDir.Phi();
88  outpar(tau_theta) = TauDir.Theta();
89  outpar(a1_px) = inpar(LorentzVectorParticle::px + offset);
90  outpar(a1_py) = inpar(LorentzVectorParticle::py + offset);
91  outpar(a1_pz) = inpar(LorentzVectorParticle::pz + offset);
92  outpar(a1_m) = inpar(LorentzVectorParticle::m + offset);
93  outpar(a1_vx) = inpar(LorentzVectorParticle::vx + offset);
94  outpar(a1_vy) = inpar(LorentzVectorParticle::vy + offset);
95  outpar(a1_vz) = inpar(LorentzVectorParticle::vz + offset);
97  outpar(nu_px) = inpar(LorentzVectorParticle::px + offset);
98  outpar(nu_py) = inpar(LorentzVectorParticle::py + offset);
99  outpar(nu_pz) = inpar(LorentzVectorParticle::pz + offset);
100  return outpar;
101 }
102 
103 TVectorT<double> TauA1NuConstrainedFitter::ComputeExpParToPar(const TVectorT<double>& inpar) {
104  TVectorT<double> outpar(npar);
105  for (int i = 0; i < npar; i++) {
106  outpar(i) = inpar(i);
107  }
108  return outpar;
109 }
110 
111 TVectorT<double> TauA1NuConstrainedFitter::ComputeNuLorentzVectorPar(const TVectorT<double>& inpar) {
112  TVectorT<double> outpar(LorentzVectorParticle::NLorentzandVertexPar);
113  outpar(LorentzVectorParticle::vx) = inpar(a1_vx);
114  outpar(LorentzVectorParticle::vy) = inpar(a1_vy);
115  outpar(LorentzVectorParticle::vz) = inpar(a1_vz);
116  outpar(LorentzVectorParticle::px) = inpar(nu_px);
117  outpar(LorentzVectorParticle::py) = inpar(nu_py);
118  outpar(LorentzVectorParticle::pz) = inpar(nu_pz);
119  outpar(LorentzVectorParticle::m) = 0;
120  return outpar;
121 }
122 
123 TVectorT<double> TauA1NuConstrainedFitter::ComputeA1LorentzVectorPar(const TVectorT<double>& inpar) {
124  TVectorT<double> outpar(LorentzVectorParticle::NLorentzandVertexPar);
125  outpar(LorentzVectorParticle::vx) = inpar(a1_vx);
126  outpar(LorentzVectorParticle::vy) = inpar(a1_vy);
127  outpar(LorentzVectorParticle::vz) = inpar(a1_vz);
128  outpar(LorentzVectorParticle::px) = inpar(a1_px);
129  outpar(LorentzVectorParticle::py) = inpar(a1_py);
130  outpar(LorentzVectorParticle::pz) = inpar(a1_pz);
131  outpar(LorentzVectorParticle::m) = inpar(a1_m);
132  return outpar;
133 }
134 
135 TVectorT<double> TauA1NuConstrainedFitter::ComputeMotherLorentzVectorPar(const TVectorT<double>& inpar) {
136  TVectorT<double> outpar(LorentzVectorParticle::NLorentzandVertexPar);
137  TVectorT<double> nupar = ComputeNuLorentzVectorPar(inpar);
138  TVectorT<double> a1par = ComputeA1LorentzVectorPar(inpar);
139  for (int i = 0; i < LorentzVectorParticle::NLorentzandVertexPar; i++) {
141  outpar(i) = a1par(i);
142  } else {
143  outpar(i) = nupar(i) + a1par(i);
144  }
145  //if(i==LorentzVectorParticle::m) outpar(i,0)=PDGInfo::tau_mass();
146  }
147  double nu_px = nupar(LorentzVectorParticle::px);
148  double nu_py = nupar(LorentzVectorParticle::py);
149  double nu_pz = nupar(LorentzVectorParticle::pz);
150  double Enu2 = nu_px * nu_px + nu_py * nu_py + nu_pz * nu_pz;
151  double a1_px = a1par(LorentzVectorParticle::px);
152  double a1_py = a1par(LorentzVectorParticle::py);
153  double a1_pz = a1par(LorentzVectorParticle::pz);
154  double a1_m = a1par(LorentzVectorParticle::m);
155  double Ea12 = a1_px * a1_px + a1_py * a1_py + a1_pz * a1_pz + a1_m * a1_m;
156  double outpar_px = outpar(LorentzVectorParticle::px);
157  double outpar_py = outpar(LorentzVectorParticle::py);
158  double outpar_pz = outpar(LorentzVectorParticle::pz);
159  double P2 = outpar_px * outpar_px + outpar_py * outpar_py + outpar_pz * outpar_pz;
160  outpar(LorentzVectorParticle::m) = sqrt(std::fabs(Enu2 + Ea12 + 2 * sqrt(Enu2 * Ea12) - P2));
161  return outpar;
162 }
163 
165  // assumes changes to a1 correlation to vertex is small
166  if (par.GetNrows() == npar && cov.GetNrows() == npar && exppar.GetNrows() == npar && expcov.GetNrows() == npar)
167  return;
168  for (int i = 0; i < npar; i++) {
169  exppar(i) = par(i);
170  for (int j = 0; j < npar; j++) {
171  expcov(i, j) = cov(i, j);
172  }
173  }
174 }
175 
176 std::vector<LorentzVectorParticle> TauA1NuConstrainedFitter::getRefitDaughters() {
177  std::vector<LorentzVectorParticle> refitParticles;
179  double c(0), b(0);
180  for (unsigned int i = 0; i < particles_.size(); i++) {
181  c += particles_[i].charge();
182  b = particles_[i].bField();
183  }
184  TVectorT<double> a1 = ComputeA1LorentzVectorPar(exppar);
185  TMatrixTSym<double> a1cov =
187  refitParticles.push_back(LorentzVectorParticle(a1, a1cov, particles_[0].pdgId(), c, b));
188  TVectorT<double> nu = ComputeNuLorentzVectorPar(exppar);
189  TMatrixTSym<double> nucov =
191  refitParticles.push_back(LorentzVectorParticle(nu, nucov, PDGInfo::nu_tau, 0.0, b));
192  return refitParticles;
193 }
194 
197  double c(0), b(0);
198  for (unsigned int i = 0; i < particles_.size(); i++) {
199  c += particles_[i].charge();
200  b = particles_[i].bField();
201  }
202  TVectorT<double> m = ComputeMotherLorentzVectorPar(exppar);
203  TMatrixTSym<double> mcov =
205  LorentzVectorParticle mymother = LorentzVectorParticle(m, mcov, (int)(-1.0 * std::abs(PDGInfo::tau_minus) * c), c, b);
206  return mymother;
207 }
208 
210  const TVectorD& v, TLorentzVector& a1, TLorentzVector& nu, double& phi, double& theta, TVector3& TauDir) {
211  a1 = TLorentzVector(v(a1_px),
212  v(a1_py),
213  v(a1_pz),
214  sqrt(v(a1_m) * v(a1_m) + v(a1_px) * v(a1_px) + v(a1_py) * v(a1_py) + v(a1_pz) * v(a1_pz)));
215  nu = TLorentzVector(
216  v(nu_px), v(nu_py), v(nu_pz), sqrt(v(nu_px) * v(nu_px) + v(nu_py) * v(nu_py) + v(nu_pz) * v(nu_pz)));
217  phi = v(tau_phi);
218  theta = v(tau_theta);
219  TauDir.SetMagThetaPhi(1.0, theta, phi);
220 }
221 
224  // Check if Tau Direction is unphysical and if nessicary set the starting point to Theta_{GJ-Max}
225  TLorentzVector a1(
226  par(a1_px),
227  par(a1_py),
228  par(a1_pz),
229  sqrt(par(a1_m) * par(a1_m) + par(a1_px) * par(a1_px) + par(a1_py) * par(a1_py) + par(a1_pz) * par(a1_pz)));
230  double phi(par(tau_phi)), theta(par(tau_theta));
231  TLorentzVector Tau_plus, Tau_minus, nu_plus, nu_minus;
232  TVector3 TauDir(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
233  bool isReal;
234  solveByRotation(TauDir, a1, Tau_plus, Tau_minus, nu_plus, nu_minus, isReal);
235 
236  //check that the do product of the a1 and tau is positive, otherwise there is no information for tau direction -> use zero solution
237  if (TauDir.Dot(a1.Vect()) < 0) {
238  isReal = false;
239  }
240 
241  //case 1: is real then solve analytically
242  if (isReal && (ambiguity_ == plus || ambiguity_ == minus)) {
243  // popogate errors
246  std::bind(TauA1NuConstrainedFitter::SolveAmbiguityAnalytically, std::placeholders::_1, ambiguity_), par, cov_0);
247  for (int i = 0; i < npar; i++)
248  par(i) = par_tmp(i);
249  return true;
250  }
251  // case 2 is in unphsyical region - rotate and substitue \theta_{GJ} with \theta_{GJ}^{Max} and then solve analytically
252  else if (!isReal && ambiguity_ == zero) {
256  par,
257  cov_0);
258  for (int i = 0; i < npar; i++)
259  par(i) = par_tmp(i);
260  return true;
261  }
262  return false;
263 }
264 
265 TVectorT<double> TauA1NuConstrainedFitter::SolveAmbiguityAnalytically(const TVectorT<double>& inpar, unsigned int amb) {
266  // Solve equation quadratic equation
267  TVectorT<double> outpar(inpar.GetNrows());
268  TLorentzVector a1, nu;
269  double phi(0), theta(0);
270  TVector3 TauDir;
271  CovertParToObjects(inpar, a1, nu, phi, theta, TauDir);
272  TLorentzVector a1_d = a1;
273  TLorentzVector nu_d = nu;
274  TLorentzVector Tau_plus, Tau_minus, nu_plus, nu_minus;
275  bool isReal;
276  solveByRotation(TauDir, a1_d, Tau_plus, Tau_minus, nu_plus, nu_minus, isReal, true);
277  if (amb == plus)
278  nu = nu_plus;
279  else
280  nu = nu_minus;
281  for (int i = 0; i < outpar.GetNrows(); i++) {
282  outpar(i) = inpar(i);
283  }
284  outpar(nu_px) = nu.Px();
285  outpar(nu_py) = nu.Py();
286  outpar(nu_pz) = nu.Pz();
287  return outpar;
288 }
289 
290 TVectorT<double> TauA1NuConstrainedFitter::SolveAmbiguityAnalyticallywithRot(const TVectorT<double>& inpar,
291  unsigned int ambiguity) {
292  // Rotate and subsitute \theta_{GJ} with \theta_{GJ}^{Max} - assumes uncertianty on thata and phi of the a1 or small compared to the tau direction.
293  TVectorT<double> outpar(inpar.GetNrows());
294  TLorentzVector a1, nu;
295  double phi(0), theta(0);
296  TVector3 TauDir;
297  CovertParToObjects(inpar, a1, nu, phi, theta, TauDir);
298  double theta_a1(a1.Theta()), phi_a1(a1.Phi()), theta_GJMax(thetaGJMax(a1));
299  TauDir.RotateZ(-phi_a1);
300  TauDir.RotateY(-theta_a1);
301  double phiprime(TauDir.Phi());
302  TauDir = TVector3(sin(theta_GJMax) * cos(phiprime), sin(theta_GJMax) * sin(phiprime), cos(theta_GJMax));
303  TauDir.RotateY(theta_a1);
304  TauDir.RotateZ(phi_a1);
305  for (int i = 0; i < outpar.GetNrows(); i++)
306  outpar(i) = inpar(i);
307  outpar(tau_phi) = TauDir.Phi();
308  outpar(tau_theta) = TauDir.Theta();
309  return SolveAmbiguityAnalytically(outpar, ambiguity);
310 }
311 
312 // Return the significance of the rotation when the tau direction is in the unphysical region
314  TVectorT<double> par_tmp = TauA1NuConstrainedFitter::TauRot(par);
316  if (!(cov_tmp(0, 0) > 0))
317  return -999; // return invalid value if the covariance is unphysical (safety flag)
318  if (par_tmp(0) > 0)
319  return par_tmp(0) / sqrt(cov_tmp(0, 0)); // return the significance if the value is in the unphysical region
320  return 0; // reutrn 0 for the rotation significance if the tau is in the physical region
321 }
322 
323 TVectorT<double> TauA1NuConstrainedFitter::TauRot(const TVectorT<double>& inpar) {
324  TVectorT<double> outpar(1);
325  TLorentzVector a1, nu;
326  double phi(0), theta(0);
327  TVector3 TauDir;
328  CovertParToObjects(inpar, a1, nu, phi, theta, TauDir);
329  double theta_a1(a1.Theta()), phi_a1(a1.Phi()), theta_GJMax(thetaGJMax(a1));
330  TauDir.RotateZ(-phi_a1);
331  TauDir.RotateY(-theta_a1);
332  outpar(0) = (TauDir.Theta() - theta_GJMax);
333  return outpar;
334 }
size
Write out results.
virtual double bField() const
Definition: Particle.h:29
static const std::string Nu
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
static TVectorT< double > ComputeInitalExpPar(const TVectorT< double > &inpar)
static double thetaGJMax(const TLorentzVector &a1)
static TVectorT< double > ComputeA1LorentzVectorPar(const TVectorT< double > &inpar)
static TVectorT< double > ComputeMotherLorentzVectorPar(const TVectorT< double > &inpar)
std::vector< LorentzVectorParticle > getRefitDaughters()
virtual double covariance(int i, int j) const
Definition: Particle.h:24
T sqrt(T t)
Definition: SSEVec.h:19
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
TauA1NuConstrainedFitter(unsigned int ambiguity, const LorentzVectorParticle &A1, const TVector3 &PVertex, const TMatrixTSym< double > &VertexCov)
def pv(vc)
Definition: MetAnalyzer.py:7
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static TVectorT< double > TauRot(const TVectorT< double > &inpar)
static TVectorT< double > SolveAmbiguityAnalyticallywithRot(const TVectorT< double > &inpar, unsigned int ambiguity)
std::vector< LorentzVectorParticle > particles_
double b
Definition: hdecay.h:118
static void CovertParToObjects(const TVectorD &v, TLorentzVector &a1, TLorentzVector &nu, double &phi, double &theta, TVector3 &TauDir)
static TVectorT< double > ComputeNuLorentzVectorPar(const TVectorT< double > &inpar)
double amb
Definition: hdecay.h:21
static TVectorT< double > ComputeExpParToPar(const TVectorT< double > &inpar)
static TVectorT< double > SolveAmbiguityAnalytically(const TVectorT< double > &inpar, unsigned int ambiguity)
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 TMatrixTSym< double > propagateError(std::function< TVectorT< double >(const TVectorT< double > &)> f, const TVectorT< double > &inPar, TMatrixTSym< double > &inCov, double epsilon=0.001, double errorEpsilonRatio=1000)