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 
15 TauA1NuConstrainedFitter::TauA1NuConstrainedFitter(unsigned int ambiguity,const LorentzVectorParticle& A1,const TVector3& PVertex, const TMatrixTSym<double>& VertexCov):
17  ambiguity_(ambiguity)
18 {
19  TLorentzVector Tau(0,0,0,0);
20  //dummy substitution not used later
21  TVectorT<double> nu_par(LorentzVectorParticle::NLorentzandVertexPar,1);
22  TMatrixTSym<double> nu_cov(LorentzVectorParticle::NLorentzandVertexPar);
23  LorentzVectorParticle Nu(nu_par,nu_cov,PDGInfo::nu_tau,0.0,A1.bField());
24  particles_.push_back(A1);
25  particles_.push_back(Nu);
26 
27  // setup 13 by 13 matrix
29  TVectorT<double> inpar(size);
30  TMatrixTSym<double> incov(size);
31 
32  // Get primary vertex information
33  if(VertexCov.GetNrows()!=LorentzVectorParticle::NVertex)return;
34  inpar(LorentzVectorParticle::vx)=PVertex.X();
35  inpar(LorentzVectorParticle::vy)=PVertex.Y();
36  inpar(LorentzVectorParticle::vz)=PVertex.Z();
37  for(int i=0; i<LorentzVectorParticle::NVertex;i++){
38  for(int j=0; j<LorentzVectorParticle::NVertex;j++)incov(i,j)=VertexCov(i,j);
39  }
40  int A1offset=LorentzVectorParticle::NVertex;
43  inpar(i+A1offset)=A1.parameter(i);
44  inpar(i+Nuoffset)=Nu.parameter(i)+1.0;// offset by 1 GeV to prevent convergence on first iteration
46  incov(i+A1offset,j+A1offset)=A1.covariance(i,j);
47  incov(i+Nuoffset,j+Nuoffset)=Nu.covariance(i,j);
48  }
49  }
50 
51  exppar.ResizeTo(nexpandedpar,1);
55 
56  TVectorT<double> PAR_0(npar);
57  par_0.ResizeTo(npar);
58  cov_0.ResizeTo(npar,npar);
60  for(int i=0; i<npar;i++)par_0(i)=PAR_0(i);
62 
63  for(int i=0; i<npar;i++){
64  for(int j=0;j<npar;j++){cov_0(i,j)=expcov(i,j);}
65  }
66 
67  par.ResizeTo(npar);
68  par=par_0;
69  cov.ResizeTo(npar,npar);
70  cov=cov_0;
71 }
72 
73 TVectorT<double> TauA1NuConstrainedFitter::ComputeInitalExpPar(const TVectorT<double>& inpar){
74  TVectorT<double> outpar(nexpandedpar);
77  TVector3 sv(inpar(LorentzVectorParticle::vx+offset),inpar(LorentzVectorParticle::vy+offset),inpar(LorentzVectorParticle::vz+offset));
78  TVector3 TauDir=sv-pv;
79  outpar(tau_phi)=TauDir.Phi();
80  outpar(tau_theta)=TauDir.Theta();
81  outpar(a1_px)=inpar(LorentzVectorParticle::px+offset);
82  outpar(a1_py)=inpar(LorentzVectorParticle::py+offset);
83  outpar(a1_pz)=inpar(LorentzVectorParticle::pz+offset);
84  outpar(a1_m)=inpar(LorentzVectorParticle::m+offset);
85  outpar(a1_vx)=inpar(LorentzVectorParticle::vx+offset);
86  outpar(a1_vy)=inpar(LorentzVectorParticle::vy+offset);
87  outpar(a1_vz)=inpar(LorentzVectorParticle::vz+offset);
89  outpar(nu_px)=inpar(LorentzVectorParticle::px+offset);
90  outpar(nu_py)=inpar(LorentzVectorParticle::py+offset);
91  outpar(nu_pz)=inpar(LorentzVectorParticle::pz+offset);
92  return outpar;
93 }
94 
95 TVectorT<double> TauA1NuConstrainedFitter::ComputeExpParToPar(const TVectorT<double>& inpar){
96  TVectorT<double> outpar(npar);
97  for(int i=0;i<npar;i++){outpar(i)=inpar(i);}
98  return outpar;
99 }
100 
101 TVectorT<double> TauA1NuConstrainedFitter::ComputeNuLorentzVectorPar(const TVectorT<double>& inpar){
102  TVectorT<double> outpar(LorentzVectorParticle::NLorentzandVertexPar);
103  outpar(LorentzVectorParticle::vx)=inpar(a1_vx);
104  outpar(LorentzVectorParticle::vy)=inpar(a1_vy);
105  outpar(LorentzVectorParticle::vz)=inpar(a1_vz);
106  outpar(LorentzVectorParticle::px)=inpar(nu_px);
107  outpar(LorentzVectorParticle::py)=inpar(nu_py);
108  outpar(LorentzVectorParticle::pz)=inpar(nu_pz);
109  outpar(LorentzVectorParticle::m)=0;
110  return outpar;
111 }
112 
113 TVectorT<double> TauA1NuConstrainedFitter::ComputeA1LorentzVectorPar(const TVectorT<double>& inpar){
114  TVectorT<double> outpar(LorentzVectorParticle::NLorentzandVertexPar);
115  outpar(LorentzVectorParticle::vx)=inpar(a1_vx);
116  outpar(LorentzVectorParticle::vy)=inpar(a1_vy);
117  outpar(LorentzVectorParticle::vz)=inpar(a1_vz);
118  outpar(LorentzVectorParticle::px)=inpar(a1_px);
119  outpar(LorentzVectorParticle::py)=inpar(a1_py);
120  outpar(LorentzVectorParticle::pz)=inpar(a1_pz);
121  outpar(LorentzVectorParticle::m)=inpar(a1_m);
122  return outpar;
123 }
124 
125 TVectorT<double> TauA1NuConstrainedFitter::ComputeMotherLorentzVectorPar(const TVectorT<double>& inpar){
126  TVectorT<double> outpar(LorentzVectorParticle::NLorentzandVertexPar);
127  TVectorT<double> nupar=ComputeNuLorentzVectorPar(inpar);
128  TVectorT<double> a1par=ComputeA1LorentzVectorPar(inpar);
130  if(i<LorentzVectorParticle::NVertex){outpar(i)=a1par(i);}
131  else{outpar(i)=nupar(i)+a1par(i);}
132  //if(i==LorentzVectorParticle::m) outpar(i,0)=PDGInfo::tau_mass();
133  }
134  double nu_px = nupar(LorentzVectorParticle::px);
135  double nu_py = nupar(LorentzVectorParticle::py);
136  double nu_pz = nupar(LorentzVectorParticle::pz);
137  double Enu2 = nu_px*nu_px + nu_py*nu_py + nu_pz*nu_pz;
138  double a1_px = a1par(LorentzVectorParticle::px);
139  double a1_py = a1par(LorentzVectorParticle::py);
140  double a1_pz = a1par(LorentzVectorParticle::pz);
141  double a1_m = a1par(LorentzVectorParticle::m);
142  double Ea12 = a1_px*a1_px + a1_py*a1_py + a1_pz*a1_pz + a1_m*a1_m;
143  double outpar_px = outpar(LorentzVectorParticle::px);
144  double outpar_py = outpar(LorentzVectorParticle::py);
145  double outpar_pz = outpar(LorentzVectorParticle::pz);
146  double P2=outpar_px*outpar_px + outpar_py*outpar_py + outpar_pz*outpar_pz;
147  outpar(LorentzVectorParticle::m)=sqrt(std::fabs(Enu2 + Ea12 + 2*sqrt(Enu2*Ea12)-P2));
148  return outpar;
149 }
150 
152  // assumes changes to a1 correlation to vertex is small
153  if(par.GetNrows()==npar && cov.GetNrows()==npar && exppar.GetNrows()==npar && expcov.GetNrows()==npar) return;
154  for(int i=0; i<npar;i++){
155  exppar(i)=par(i);
156  for(int j=0; j<npar;j++){expcov(i,j)=cov(i,j);}
157  }
158 }
159 
160 std::vector<LorentzVectorParticle> TauA1NuConstrainedFitter::getRefitDaughters(){
161  std::vector<LorentzVectorParticle> refitParticles;
163  double c(0),b(0);
164  for(unsigned int i=0;i<particles_.size();i++){c+=particles_[i].charge();b=particles_[i].bField();}
165  TVectorT<double> a1=ComputeA1LorentzVectorPar(exppar);
167  refitParticles.push_back(LorentzVectorParticle(a1,a1cov,particles_[0].pdgId(),c,b));
168  TVectorT<double> nu=ComputeNuLorentzVectorPar(exppar);
170  refitParticles.push_back(LorentzVectorParticle(nu,nucov,PDGInfo::nu_tau,0.0,b));
171  return refitParticles;
172 }
173 
176  double c(0),b(0);
177  for(unsigned int i=0;i<particles_.size();i++){c+=particles_[i].charge();b=particles_[i].bField();}
178  TVectorT<double> m=ComputeMotherLorentzVectorPar(exppar);
180  LorentzVectorParticle mymother= LorentzVectorParticle(m,mcov,(int)(-1.0*std::abs(PDGInfo::tau_minus)*c),c,b);
181  return mymother;
182 }
183 
184 void TauA1NuConstrainedFitter::CovertParToObjects(const TVectorD &v,TLorentzVector &a1,TLorentzVector &nu,double &phi,double &theta,TVector3 &TauDir){
185  a1=TLorentzVector(v(a1_px),v(a1_py),v(a1_pz),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)));
186  nu=TLorentzVector(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)));
187  phi=v(tau_phi);
188  theta=v(tau_theta);
189  TauDir.SetMagThetaPhi(1.0,theta,phi);
190 }
191 
194  // Check if Tau Direction is unphysical and if nessicary set the starting point to Theta_{GJ-Max}
195  TLorentzVector a1(par(a1_px),par(a1_py),par(a1_pz),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)));
196  double phi(par(tau_phi)),theta(par(tau_theta));
197  TLorentzVector Tau_plus,Tau_minus,nu_plus,nu_minus;
198  TVector3 TauDir(cos(phi)*sin(theta),sin(phi)*sin(theta),cos(theta));
199  bool isReal;
200  solveByRotation(TauDir,a1,Tau_plus,Tau_minus,nu_plus,nu_minus,isReal);
201 
202  //check that the do product of the a1 and tau is positive, otherwise there is no information for tau direction -> use zero solution
203  if(TauDir.Dot(a1.Vect())<0){
204  isReal=false;
205  }
206 
207  //case 1: is real then solve analytically
208  if(isReal && (ambiguity_==plus || ambiguity_==minus)){
209  // popogate errors
212  for(int i=0; i<npar;i++) par(i)=par_tmp(i);
213  return true;
214  }
215  // case 2 is in unphsyical region - rotate and substitue \theta_{GJ} with \theta_{GJ}^{Max} and then solve analytically
216  else if(!isReal && ambiguity_==zero){
219  for(int i=0; i<npar;i++) par(i)=par_tmp(i);
220  return true;
221  }
222  return false;
223 }
224 
225 TVectorT<double> TauA1NuConstrainedFitter::SolveAmbiguityAnalytically(const TVectorT<double>& inpar, unsigned int amb){
226  // Solve equation quadratic equation
227  TVectorT<double> outpar(inpar.GetNrows());
228  TLorentzVector a1,nu;
229  double phi(0),theta(0);
230  TVector3 TauDir;
231  CovertParToObjects(inpar,a1,nu,phi,theta,TauDir);
232  TLorentzVector a1_d=a1;
233  TLorentzVector nu_d=nu;
234  TLorentzVector Tau_plus,Tau_minus,nu_plus,nu_minus;
235  bool isReal;
236  solveByRotation(TauDir,a1_d,Tau_plus,Tau_minus,nu_plus,nu_minus,isReal,true);
237  if(amb==plus)nu=nu_plus;
238  else nu=nu_minus;
239  for(int i=0; i<outpar.GetNrows();i++){ outpar(i)=inpar(i);}
240  outpar(nu_px)=nu.Px();
241  outpar(nu_py)=nu.Py();
242  outpar(nu_pz)=nu.Pz();
243  return outpar;
244 }
245 
246 TVectorT<double> TauA1NuConstrainedFitter::SolveAmbiguityAnalyticallywithRot(const TVectorT<double>& inpar, unsigned int ambiguity){
247  // 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.
248  TVectorT<double> outpar(inpar.GetNrows());
249  TLorentzVector a1,nu;
250  double phi(0),theta(0);
251  TVector3 TauDir;
252  CovertParToObjects(inpar,a1,nu,phi,theta,TauDir);
253  double theta_a1(a1.Theta()),phi_a1(a1.Phi()),theta_GJMax(thetaGJMax(a1));
254  TauDir.RotateZ(-phi_a1);
255  TauDir.RotateY(-theta_a1);
256  double phiprime(TauDir.Phi());
257  TauDir=TVector3(sin(theta_GJMax)*cos(phiprime),sin(theta_GJMax)*sin(phiprime),cos(theta_GJMax));
258  TauDir.RotateY(theta_a1);
259  TauDir.RotateZ(phi_a1);
260  for(int i=0; i<outpar.GetNrows();i++) outpar(i)=inpar(i);
261  outpar(tau_phi)=TauDir.Phi();
262  outpar(tau_theta)=TauDir.Theta();
263  return SolveAmbiguityAnalytically(outpar,ambiguity);
264 }
265 
266 // Return the significance of the rotation when the tau direction is in the unphysical region
268  TVectorT<double> par_tmp=TauA1NuConstrainedFitter::TauRot(par);
270  if(!(cov_tmp(0,0)>0)) return -999; // return invalid value if the covariance is unphysical (safety flag)
271  if(par_tmp(0)>0) return par_tmp(0)/sqrt(cov_tmp(0,0)); // return the significance if the value is in the unphysical region
272  return 0; // reutrn 0 for the rotation significance if the tau is in the physical region
273 }
274 
275 
276 TVectorT<double> TauA1NuConstrainedFitter::TauRot(const TVectorT<double>& inpar){
277  TVectorT<double> outpar(1);
278  TLorentzVector a1,nu;
279  double phi(0),theta(0);
280  TVector3 TauDir;
281  CovertParToObjects(inpar,a1,nu,phi,theta,TauDir);
282  double theta_a1(a1.Theta()),phi_a1(a1.Phi()),theta_GJMax(thetaGJMax(a1));
283  TauDir.RotateZ(-phi_a1);
284  TauDir.RotateY(-theta_a1);
285  outpar(0)=(TauDir.Theta()-theta_GJMax);
286  return outpar;
287 }
size
Write out results.
virtual double covariance(int i, int j) const
Definition: Particle.h:25
static const std::string Nu
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Geom::Theta< T > theta() const
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()
T sqrt(T t)
Definition: SSEVec.h:18
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:6
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:120
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
virtual double bField() const
Definition: Particle.h:26
static TVectorT< double > ComputeExpParToPar(const TVectorT< double > &inpar)
static TVectorT< double > SolveAmbiguityAnalytically(const TVectorT< double > &inpar, unsigned int ambiguity)
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)