CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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  */
9 #include <iostream>
10 
11 using namespace tauImpactParameter;
12 
13 TauA1NuConstrainedFitter::TauA1NuConstrainedFitter(unsigned int ambiguity,const LorentzVectorParticle& A1,const TVector3& PVertex, const TMatrixTSym<double>& VertexCov)
16  ambiguity_(ambiguity)
17 {
18  TLorentzVector Tau(0,0,0,0);
20  particles_.push_back(A1);
21  particles_.push_back(Nu);
22  isConfigured_=false;
23  // setup 13 by 13 matrix
25  TVectorT<double> inpar(size);
26  TMatrixTSym<double> incov(size);
27 
28  // Get primary vertex information
29  if(VertexCov.GetNrows()!=LorentzVectorParticle::NVertex)return;
30  inpar(LorentzVectorParticle::vx)=PVertex.X();
31  inpar(LorentzVectorParticle::vy)=PVertex.Y();
32  inpar(LorentzVectorParticle::vz)=PVertex.Z();
33  for(int i=0; i<LorentzVectorParticle::NVertex;i++){
34  for(int j=0; j<LorentzVectorParticle::NVertex;j++)incov(i,j)=VertexCov(i,j);
35  }
36  int A1offset=LorentzVectorParticle::NVertex;
39  inpar(i+A1offset)=A1.parameter(i);
40  inpar(i+Nuoffset)=Nu.parameter(i)+1.0;// offset by 1 GeV to prevent convergence on first iteration
42  incov(i+A1offset,j+A1offset)=A1.covariance(i,j);
43  incov(i+Nuoffset,j+Nuoffset)=Nu.covariance(i,j);
44  }
45  }
46  // store expanded par for computation of final par (assumes fit has neglegible impact on a1 correlations with vertex errors)
47  exppar_.ResizeTo(nexpandedpar);
51  // store linearization point
52  TVectorT<double> PAR_0(npar);
53  par_0_.ResizeTo(npar);
54  cov_0_.ResizeTo(npar,npar);
56  for(int i=0; i<npar;i++)par_0_(i)=PAR_0(i);
58  for(int i=0; i<npar;i++){
59  for(int j=0;j<npar;j++){cov_0_(i,j)=expcov_(i,j);}
60  }
61  // set up inital point for fit (cov handled in Fit() function)
62  par_.ResizeTo(npar);
63  par_=par_0_;
64  /*
65  if(ambiguity_==zero){
66  aolveAmbiguityAnalytically();
67  isConfigured_=true;
68  isFit_=true;
69  return;
70  }*/
72  // Check if Tau Direction is unphysical and if nessicary set the starting point to Theta_{GJ-Max}
74  double phi(par_(tau_phi)),theta(par_(tau_theta));
75  double scale=0.999;
76  if(ambiguity==zero)scale=-1.0;
77  if(setTauDirectionatThetaGJMax(a1,theta,phi,scale)){
78  TLorentzVector Tau_plus,Tau_minus,nu_plus,nu_minus;
79  TVector3 TauDir; TauDir.SetMagThetaPhi(1.0,theta,phi);
80  solveByRotation(TauDir,a1,Tau_plus,Tau_minus,nu_plus,nu_minus);
81  par_(tau_phi)=phi;
83  if(ambiguity_==plus){
84  par_(nu_px)=nu_plus.Px();
85  par_(nu_py)=nu_plus.Py();
86  par_(nu_pz)=nu_plus.Pz();
87  }
88  if(ambiguity_==minus){
89  par_(nu_px)=nu_minus.Px();
90  par_(nu_py)=nu_minus.Py();
91  par_(nu_pz)=nu_minus.Pz();
92  }
93  if(ambiguity_==zero){
94  par_(nu_px)=(nu_minus.Px()+nu_plus.Px())/2;
95  par_(nu_py)=(nu_minus.Py()+nu_plus.Py())/2;
96  par_(nu_pz)=(nu_minus.Pz()+nu_plus.Pz())/2;
97  }
99  }
100  isConfigured_=true;
101 }
102 
103 TVectorT<double> TauA1NuConstrainedFitter::computeInitalExpPar(const TVectorT<double>& inpar){
104  TVectorT<double> outpar(nexpandedpar);
107  TVector3 sv(inpar(LorentzVectorParticle::vx+offset),inpar(LorentzVectorParticle::vy+offset),inpar(LorentzVectorParticle::vz+offset));
108  TVector3 TauDir=sv-pv;
109  outpar(tau_phi)=TauDir.Phi();
110  outpar(tau_theta)=TauDir.Theta();
111  outpar(a1_px)=inpar(LorentzVectorParticle::px+offset);
112  outpar(a1_py)=inpar(LorentzVectorParticle::py+offset);
113  outpar(a1_pz)=inpar(LorentzVectorParticle::pz+offset);
114  outpar(a1_m)=inpar(LorentzVectorParticle::m+offset);
115  outpar(a1_vx)=inpar(LorentzVectorParticle::vx+offset);
116  outpar(a1_vy)=inpar(LorentzVectorParticle::vy+offset);
117  outpar(a1_vz)=inpar(LorentzVectorParticle::vz+offset);
119  outpar(nu_px)=inpar(LorentzVectorParticle::px+offset);
120  outpar(nu_py)=inpar(LorentzVectorParticle::py+offset);
121  outpar(nu_pz)=inpar(LorentzVectorParticle::pz+offset);
122  return outpar;
123 }
124 
125 TVectorT<double> TauA1NuConstrainedFitter::computeExpParToPar(const TVectorT<double>& inpar){
126  TVectorT<double> outpar(npar,1);
127  for(int i=0;i<npar;i++){outpar(i)=inpar(i);}
128  return outpar;
129 }
130 
131 
132 TVectorT<double> TauA1NuConstrainedFitter::computeNuLorentzVectorPar(const TVectorT<double>& inpar){
133  TVectorT<double> outpar(LorentzVectorParticle::NLorentzandVertexPar,1);
134  outpar(LorentzVectorParticle::vx)=inpar(a1_vx);
135  outpar(LorentzVectorParticle::vy)=inpar(a1_vy);
136  outpar(LorentzVectorParticle::vz)=inpar(a1_vz);
137  outpar(LorentzVectorParticle::px)=inpar(nu_px);
138  outpar(LorentzVectorParticle::py)=inpar(nu_py);
139  outpar(LorentzVectorParticle::pz)=inpar(nu_pz);
140  outpar(LorentzVectorParticle::m)=0;
141  return outpar;
142 }
143 
144 TVectorT<double> TauA1NuConstrainedFitter::computeA1LorentzVectorPar(const TVectorT<double>& inpar){
145  TVectorT<double> outpar(LorentzVectorParticle::NLorentzandVertexPar);
146  outpar(LorentzVectorParticle::vx)=inpar(a1_vx);
147  outpar(LorentzVectorParticle::vy)=inpar(a1_vy);
148  outpar(LorentzVectorParticle::vz)=inpar(a1_vz);
149  outpar(LorentzVectorParticle::px)=inpar(a1_px);
150  outpar(LorentzVectorParticle::py)=inpar(a1_py);
151  outpar(LorentzVectorParticle::pz)=inpar(a1_pz);
152  outpar(LorentzVectorParticle::m)=inpar(a1_m);
153  return outpar;
154 }
155 
156 TVectorT<double> TauA1NuConstrainedFitter::computeMotherLorentzVectorPar(const TVectorT<double>& inpar){
157  TVectorT<double> outpar(LorentzVectorParticle::NLorentzandVertexPar);
158  TVectorT<double> nupar=computeNuLorentzVectorPar(inpar);
159  TVectorT<double> a1par=computeA1LorentzVectorPar(inpar);
161  if(i==LorentzVectorParticle::m)continue;
162  if(i<LorentzVectorParticle::NVertex){outpar(i)=a1par(i);}
163  else{outpar(i)=nupar(i)+a1par(i);}
164  }
165  double nu_px = nupar(LorentzVectorParticle::px);
166  double nu_py = nupar(LorentzVectorParticle::py);
167  double nu_pz = nupar(LorentzVectorParticle::pz);
168  double Enu2 = nu_px*nu_px + nu_py*nu_py + nu_pz*nu_pz;
169  double a1_px = a1par(LorentzVectorParticle::px);
170  double a1_py = a1par(LorentzVectorParticle::py);
171  double a1_pz = a1par(LorentzVectorParticle::pz);
172  double Ea12 = a1_px*a1_px + a1_py*a1_py + a1_pz*a1_pz;
173  double outpar_px = outpar(LorentzVectorParticle::px);
174  double outpar_py = outpar(LorentzVectorParticle::py);
175  double outpar_pz = outpar(LorentzVectorParticle::pz);
176  double P2=outpar_px*outpar_px + outpar_py*outpar_py + outpar_pz*outpar_pz;
177  outpar(LorentzVectorParticle::m)=sqrt(fabs(Enu2 + Ea12 + 2*sqrt(Enu2*Ea12)-P2));
178  return outpar;
179 }
180 
182  // assumes changes to a1 correlation to vertex is small
183  if(par_.GetNrows()==npar && cov_.GetNrows() && exppar_.GetNrows()==npar && expcov_.GetNrows()) return;
184  for(int i=0; i<npar;i++){
185  exppar_(i)=par_(i);
186  for(int j=0; j<npar;j++){expcov_(i,j)=cov_(i,j);}
187  }
188 }
189 
190 std::vector<LorentzVectorParticle> TauA1NuConstrainedFitter::getRefitDaughters(){
191  std::vector<LorentzVectorParticle> refitParticles;
193  double c(0),b(0);
194  for(unsigned int i=0;i<particles_.size();i++){c+=particles_[i].charge();b=particles_[i].bField();}
195  TVectorT<double> a1=computeA1LorentzVectorPar(exppar_);
197  refitParticles.push_back(LorentzVectorParticle(a1,a1cov,fabs(PDGInfo::a_1_plus)*c,c,b));
198  TVectorT<double> nu=computeNuLorentzVectorPar(exppar_);
200  refitParticles.push_back(LorentzVectorParticle(nu,nucov,PDGInfo::nu_tau,0.0,b));
201  return refitParticles;
202 }
203 
206  double c(0),b(0);
207  for(unsigned int i=0;i<particles_.size();i++){c+=particles_[i].charge();b=particles_[i].bField();}
208  TVectorT<double> m=computeMotherLorentzVectorPar(exppar_);
210  return LorentzVectorParticle(m,mcov,-1.0*fabs(PDGInfo::tau_minus)*c,c,b);
211 }
212 
213 TVectorD TauA1NuConstrainedFitter::value(const TVectorD& v){
214  TLorentzVector a1,nu;
215  double phi(0),theta(0);
216  TVector3 TauDir;
217  covertParToObjects(v,a1,nu,phi,theta,TauDir);
218  TLorentzVector a1_d=a1;
219  TLorentzVector nu_d=nu;
220  TLorentzVector Tau_plus,Tau_minus,nu_plus,nu_minus;
221  solveByRotation(TauDir,a1_d,Tau_plus,Tau_minus,nu_plus,nu_minus,false);
222  a1.RotateZ(-phi);
223  a1.RotateY(-theta);
224  nu.RotateZ(-phi);
225  nu.RotateY(-theta);
226  TLorentzVector nufixed(-a1.Px(),-a1.Py(),nu.Pz(),sqrt(a1.Pt()*a1.Pt()+nu.Pz()*nu.Pz()));
227  TLorentzVector tau=a1+nufixed;
228  TVectorD d(3);
229  if(ambiguity_==minus){ d(0)=sqrt(pow(nu.Pz()-nu_minus.Pz(),4.0)+pow(tau.M2()-PDGInfo::tau_mass()*PDGInfo::tau_mass(),2.0));}
230  else if(ambiguity_==plus){d(0)=sqrt(pow(nu.Pz()-nu_plus.Pz(),4.0)+pow(tau.M2()-PDGInfo::tau_mass()*PDGInfo::tau_mass(),2.0));}
231  else {d(0) = tau.M2()-PDGInfo::tau_mass()*PDGInfo::tau_mass();}
232  d(1) = a1.Px()+nu.Px();
233  d(2) = a1.Py()+nu.Py();
234  return d;
235 }
236 
237 void TauA1NuConstrainedFitter::covertParToObjects(const TVectorD& v, TLorentzVector& a1, TLorentzVector& nu, double& phi,double& theta, TVector3& TauDir){
238  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)));
239  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)));
240  phi=v(tau_phi);
241  theta=v(tau_theta);
242  TauDir.SetMagThetaPhi(1.0,theta,phi);
243 }
244 
247  // Run Kicker to force +/- solution to avoid solution being stuck in the local minimum
248  if(ambiguity_==minus || ambiguity_==plus){
249  TLorentzVector a1,nu;
250  double phi(0),theta(0);
251  TVector3 TauDir;
252  covertParToObjects(par_,a1,nu,phi,theta,TauDir);
253  TLorentzVector Tau_plus,Tau_minus,nu_plus,nu_minus,nu_correct,nu_incorrect;
254  if(ambiguity_==minus) solveByRotation(TauDir,a1,Tau_plus,Tau_minus,nu_incorrect,nu_correct,false);
255  if(ambiguity_==plus) solveByRotation(TauDir,a1,Tau_plus,Tau_minus,nu_correct,nu_incorrect,false);
256  nu.RotateZ(-phi);
257  nu.RotateY(-theta);
258  if(fabs(nu_incorrect.Pz()-nu.Pz())<fabs(nu_correct.Pz()-nu.Pz())){
259  double pzkicked=nu_correct.Pz()-(nu_incorrect.Pz()-nu.Pz()); // minus sign is to make the kick a reflex about the ambiguity point
260  TLorentzVector nuKicked(nu.Px(),nu.Py(),pzkicked,sqrt(nu.Px()*nu.Px()+nu.Py()*nu.Py()+pzkicked*pzkicked));
261  nuKicked.RotateY(-theta);
262  nuKicked.RotateZ(-phi);
263  par_(nu_px)=nuKicked.Px();
264  par_(nu_py)=nuKicked.Py();
265  par_(nu_pz)=nuKicked.Pz();
266  }
267  }
269 }
270 
272  if(ambiguity_!=zero) return;
273  TVectorT<double> angles=TauA1NuConstrainedFitter::findThetaGJMax(par_0_);
275  TVectorT<double> thelpar(par_0_.GetNrows()+2,1);
276  TMatrixTSym<double> thelcov(par_0_.GetNrows()+2);
277  for(int i=0;i<par_0_.GetNrows();i++){
278  thelpar(i)=par_0_(i);
279  for(int j=0;j<par_0_.GetNrows();j++){thelcov(i,j)=cov_0_(i,j);}
280  }
281  thelpar(thelpar.GetNrows()-2)=anglescov(0,0);
282  thelpar(thelpar.GetNrows()-1)=anglescov(1,1);
284  cov_.ResizeTo(par_0_.GetNrows(),par_0_.GetNrows());
286 }
287 
288 TVectorT<double> TauA1NuConstrainedFitter::findThetaGJMax(const TVectorT<double>& inpar){
289  TVectorT<double> outpar(2);
290  TLorentzVector a1,nu;
291  TVector3 TauDir;
292  double phi,theta;
293  covertParToObjects(inpar,a1,nu,phi,theta,TauDir);
294  outpar(0)=thetaGJMax(a1);
295  outpar(1)=TauDir.Dot(a1.Vect());
296  return outpar;
297 }
298 
299 TVectorT<double> TauA1NuConstrainedFitter::setThetaGJMax(const TVectorT<double>& inpar){
300  TVectorT<double> outpar(inpar.GetNrows()-2);
301  TLorentzVector a1,nu;
302  TVector3 TauDir;
303  double phi,theta;
304  double ErrthetaTau=inpar(inpar.GetNrows()-2);
305  double ErrthetaA1=inpar(inpar.GetNrows()-1);
306  covertParToObjects(inpar,a1,nu,phi,theta,TauDir);
307  TVectorT<double> angles=TauA1NuConstrainedFitter::findThetaGJMax(inpar);
308  double delta=1;if(angles(1)!=0)delta=fabs(angles(0)/angles(1));
309  double dtheta=(theta-a1.Theta());
310  double dphi=fmod(fabs(phi-a1.Phi()),2*TMath::Pi());if(phi<a1.Phi())dphi*=-1.0;
311  double scale=dtheta*ErrthetaTau/(ErrthetaTau+ErrthetaA1);
312  outpar(tau_phi)=TauDir.Theta()+dtheta*delta*scale;
313  outpar(tau_theta)=TauDir.Phi()+dphi*delta*scale;
314  scale=dtheta*ErrthetaA1/(ErrthetaTau+ErrthetaA1);
315  double a1theta=a1.Theta()-dtheta*delta*scale;
316  double a1phi=a1.Phi()-dphi*delta*scale;
317  a1.SetTheta(a1theta);
318  a1.SetPhi(a1phi);
319  outpar(a1_px)=a1.Px();
320  outpar(a1_py)=a1.Py();
321  outpar(a1_pz)=a1.Pz();
322  TLorentzVector Tau_plus,Tau_minus,nu_plus,nu_minus;
323  solveByRotation(TauDir,a1,Tau_plus,Tau_minus,nu_plus,nu_minus);
324  outpar(nu_px)=nu_plus.Px();
325  outpar(nu_py)=nu_plus.Py();
326  outpar(nu_pz)=nu_plus.Pz();
327  return outpar;
328 }
329 
dbl * delta
Definition: mlp_gen.cc:36
virtual double covariance(int i, int j) const
Definition: Particle.h:25
const double Pi
int i
Definition: DBlmapReader.cc:9
static const std::string Nu
Geom::Theta< T > theta() const
static TVectorT< double > setThetaGJMax(const TVectorT< double > &inpar)
static bool setTauDirectionatThetaGJMax(const TLorentzVector &a1, double &theta, double &phi, double scale=1.0)
static double thetaGJMax(const TLorentzVector &a1)
static TVectorT< double > computeInitalExpPar(const TVectorT< double > &inpar)
static TVectorT< double > computeExpParToPar(const TVectorT< double > &inpar)
std::vector< LorentzVectorParticle > getRefitDaughters()
T sqrt(T t)
Definition: SSEVec.h:48
static LorentzVectorParticle estimateNu(const LorentzVectorParticle &a1, const TVector3 &pv, int ambiguity, TLorentzVector &tau)
TauA1NuConstrainedFitter(unsigned int ambiguity, const LorentzVectorParticle &A1, const TVector3 &PVertex, const TMatrixTSym< double > &VertexCov)
int j
Definition: DBlmapReader.cc:9
static TMatrixTSym< double > propagateError(TVectorT< double >(*f)(const TVectorT< double > &par), const TVectorT< double > &inPar, TMatrixTSym< double > &inCov, double epsilon=0.001, double errorEpsilonRatio=1000)
unsigned int offset(bool)
static TVectorT< double > computeMotherLorentzVectorPar(const TVectorT< double > &inpar)
static void solveByRotation(const TVector3 &TauDir, const TLorentzVector &A1, TLorentzVector &Tau_plus, TLorentzVector &Tau_minus, TLorentzVector &nu_plus, TLorentzVector &nu_minus, bool rotateback=true)
std::vector< LorentzVectorParticle > particles_
static void covertParToObjects(const TVectorD &v, TLorentzVector &a1, TLorentzVector &nu, double &phi, double &theta, TVector3 &TauDir)
double b
Definition: hdecay.h:120
static TVectorT< double > computeNuLorentzVectorPar(const TVectorT< double > &inpar)
static TVectorT< double > findThetaGJMax(const TVectorT< double > &inpar)
static TVectorT< double > computeA1LorentzVectorPar(const TVectorT< double > &inpar)
tuple size
Write out results.
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
static double tau_mass()
Definition: PDGInfo.h:14
Definition: DDAxes.h:10