CMS 3D CMS Logo

ConstrainedTreeBuilderT.h
Go to the documentation of this file.
1 #ifndef ConstrainedTreeBuilderT_H
2 #define ConstrainedTreeBuilderT_H
3 
7 
16 {
17 
18 public:
19 
21 
23 
29  template<int nTrk>
31  buildTree(const std::vector<RefCountedKinematicParticle> & initialParticles,
32  const std::vector<KinematicState> & finalStates,
34  const ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> >& fCov) const;
35 
36 private:
37 
39  const RefCountedKinematicVertex vtx, const std::vector<RefCountedKinematicParticle> & particles) const;
40 
44  template<int nTrk>
45  static AlgebraicSymMatrix77
46  covarianceMatrix(const std::vector<RefCountedKinematicParticle> &rPart,
47  const AlgebraicVector7& newPar,
48  const ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> >& fitCov);
49 
52 };
53 
54 
57 
58 template<int nTrk>
60 ConstrainedTreeBuilderT::buildTree(const std::vector<RefCountedKinematicParticle> & initialParticles,
61  const std::vector<KinematicState> & finalStates,
62  const RefCountedKinematicVertex vertex,
63  const ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> >& fullCov) const
64 {
65  if (!vertex->vertexIsValid()) {
66  LogDebug("RecoVertex/ConstrainedTreeBuilder")
67  << "Vertex is invalid\n";
69  }
71  vtx(0) = vertex->position().x();
72  vtx(1) = vertex->position().y();
73  vtx(2) = vertex->position().z();
74  AlgebraicMatrix33 vertexCov = fullCov.template Sub<ROOT::Math::SMatrix<double, 3> >(0,0);
75 
76 // cout << fullCov<<endl;
77 // cout << "RecoVertex/ConstrainedTreeBuilder"<<vtx<<endl;
78 
79  double ent = 0.;
80  int charge = 0;
81  AlgebraicVector7 virtualPartPar;
82  virtualPartPar(0) = vertex->position().x();
83  virtualPartPar(1) = vertex->position().y();
84  virtualPartPar(2) = vertex->position().z();
85 
86 //making refitted particles out of refitted states.
87 //none of the operations above violates the order of particles
88 
89  ROOT::Math::SMatrix<double,7,7,ROOT::Math::MatRepStd<double,7,7> > aMatrix;
90  ROOT::Math::SMatrix<double,7,7,ROOT::Math::MatRepStd<double,7,7> > aMatrixT;
91  aMatrix(3,3) = aMatrixT(3,3) = 1;
92  aMatrix(4,4) = aMatrixT(4,4) = 1;
93  aMatrix(5,5) = aMatrixT(5,5) = 1;
94  aMatrix(6,6) = aMatrixT(6,6) = 1;
95  ROOT::Math::SMatrix<double,7,3,ROOT::Math::MatRepStd<double,7,3> > bMatrix;
96  ROOT::Math::SMatrix<double,3,7,ROOT::Math::MatRepStd<double,3,7> > bMatrixT;
97  bMatrix(0,0) = bMatrixT(0,0) = 1;
98  bMatrix(1,1) = bMatrixT(1,1) = 1;
99  bMatrix(2,2) = bMatrixT(2,2) = 1;
100  AlgebraicSymMatrix77 trackParCov;
101  ROOT::Math::SMatrix<double,3,7,ROOT::Math::MatRepStd<double,3,7> > vtxTrackCov;
102  AlgebraicSymMatrix77 nCovariance;
103  // AlgebraicSymMatrix77 tmp;
104 
105  std::vector<RefCountedKinematicParticle>::const_iterator i = initialParticles.begin();
106  std::vector<KinematicState>::const_iterator iStates = finalStates.begin();
107  std::vector<RefCountedKinematicParticle> rParticles;
108  int n=0;
109  // assert(initialParticles.size()==nTrk);
110  for( ; i != initialParticles.end() && iStates != finalStates.end(); ++i,++iStates)
111  {
112  AlgebraicVector7 p = iStates->kinematicParameters().vector();
113  double a = - iStates->particleCharge() *
114  iStates->magneticField()->inInverseGeV(iStates->globalPosition()).z();
115 
116  aMatrix(4,0) = aMatrixT(0,4) = -a;
117  aMatrix(3,1) = aMatrixT(1,3) = a;
118  bMatrix(4,0) = bMatrixT(0,4) = a;
119  bMatrix(3,1) = bMatrixT(1,3) = -a;
120 
121  AlgebraicVector7 par = aMatrix*p + bMatrix * vtx;
122 
123  trackParCov = fullCov.template Sub<AlgebraicSymMatrix77>(3+n*7,3+n*7);
124  vtxTrackCov = fullCov.template Sub<ROOT::Math::SMatrix<double, 3, 7> >(0,3+n*7);
125  ROOT::Math::AssignSym::Evaluate(nCovariance,
126  aMatrix * trackParCov * aMatrixT
127  + aMatrix * ROOT::Math::Transpose(vtxTrackCov) * bMatrixT
128  + bMatrix * vtxTrackCov * aMatrixT
129  + bMatrix * vertexCov * bMatrixT
130  );
131  /*
132  ROOT::Math::AssignSym::Evaluate(tmp, aMatrix * ROOT::Math::Transpose(vtxTrackCov) * bMatrixT);
133  nCovariance+=tmp;
134  ROOT::Math::AssignSym::Evaluate(tmp, bMatrix * vtxTrackCov * aMatrixT);
135  nCovariance+=tmp;
136  ROOT::Math::AssignSym::Evaluate(tmp, bMatrix * vertexCov * bMatrixT);
137  nCovariance+=tmp;
138  */
139 
140  KinematicState stateAtVertex(KinematicParameters(par),
141  KinematicParametersError(nCovariance),
142  iStates->particleCharge(), iStates->magneticField());
143  rParticles.push_back((*i)->refittedParticle(stateAtVertex, vertex->chiSquared(), vertex->degreesOfFreedom()));
144 
145  virtualPartPar(3) += par(3);
146  virtualPartPar(4) += par(4);
147  virtualPartPar(5) += par(5);
148  ent += sqrt(par(6)*par(6) + par(3)*par(3)+par(4)*par(4)+par(5)*par(5) );
149  charge += iStates->particleCharge();
150 
151  ++n;
152 
153  }
154 
155  //total reconstructed mass
156  double differ = ent*ent - (virtualPartPar(3)*virtualPartPar(3) + virtualPartPar(5)*virtualPartPar(5) + virtualPartPar(4)*virtualPartPar(4));
157  if(differ>0.) {
158  virtualPartPar(6) = sqrt(differ);
159  } else {
160  LogDebug("ConstrainedTreeBuilder")
161  << "Fit failed: Current precision does not allow to calculate the mass\n";
163  }
164 
165  // covariance matrix:
166 
167  AlgebraicSymMatrix77 cov = this->covarianceMatrix<nTrk>(rParticles,virtualPartPar,fullCov);
168 
169  KinematicState nState(KinematicParameters(virtualPartPar),
171  charge, initialParticles[0]->magneticField());
172 
173  //newborn kinematic particle
174  float chi2 = vertex->chiSquared();
175  float ndf = vertex->degreesOfFreedom();
176  KinematicParticle * zp = nullptr;
177  RefCountedKinematicParticle virtualParticle = pFactory.particle(nState,chi2,ndf,zp);
178 
179  return buildRealTree(virtualParticle, vertex, rParticles);
180 }
181 
182 template<int nTrk>
184 ConstrainedTreeBuilderT::covarianceMatrix(const std::vector<RefCountedKinematicParticle> &rPart,
185  const AlgebraicVector7& newPar,
186  const ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> >& fitCov)
187  {
188 
189  typedef ROOT::Math::SMatrix<double,3+7*nTrk,3+7*nTrk,ROOT::Math::MatRepSym<double,3+7*nTrk> > FitCov;
190  //constructing the full matrix using the simple fact
191  //that we have never broken the order of tracks
192  // during our fit.
193 
194  int size = nTrk;
195 
196  if ( int(rPart.size())!=size) throw "error in ConstrainedTreeBuilderT ";
197 
198  //global propagation to the vertex position
199  //Jacobian is done for all the parameters together
200  ROOT::Math::SMatrix<double,3+7*nTrk> jac;
201  jac(0,0) = 1;
202  jac(1,1) = 1;
203  jac(2,2) = 1;
204  ROOT::Math::SMatrix<double,3,7> upper;
205  ROOT::Math::SMatrix<double,7> diagonal;
206  for( int i_int=0; i_int!=size; ++i_int) {
207  RefCountedKinematicParticle const & i = rPart[i_int];
208  //vertex position related components of the matrix
209  double a_i = - (i)->currentState().particleCharge() *
210  (i)->magneticField()->inInverseGeV((i)->currentState().globalPosition()).z();
211  upper(0,0) = 1;
212  upper(1,1) = 1;
213  upper(2,2) = 1;
214  upper(1,3) = -a_i;
215  upper(0,4) = a_i;
216  jac.Place_at(upper,0,3+i_int*7);
217 
218  diagonal(3,3) = 1;
219  diagonal(4,4) = 1;
220  diagonal(5,5) = 1;
221  diagonal(6,6) = 1;
222  diagonal(1,3) = a_i;
223  diagonal(0,4) = -a_i;
224  jac.Place_at(diagonal,3+i_int*7,3+i_int*7);
225  }
226 
227  // jacobian is constructed in such a way, that
228  // right operation for transformation will be
229  // fitCov.similarityT(jac)
230  // WARNING: normal similarity operation is
231  // not valid in this case
232  //now making reduced matrix:
233  // int vSize = rPart.size();
234  FitCov const & fit_cov_sym = fitCov;
235  /*
236  for(int i = 0; i<7*vSize+3; ++i)
237  {
238  for(int j = 0; j<7*vSize+3; ++j)
239  {if(i<=j) fit_cov_sym(i,j) = fitCov(i,j);}
240  }
241  */
242 
243  ROOT::Math::SMatrix<double,4*nTrk+3,4*nTrk+3, ROOT::Math::MatRepSym<double,4*nTrk+3> > reduced;
244  FitCov transform=ROOT::Math::SimilarityT(jac,fit_cov_sym); // similarityT???
245 
246  //jacobian to add matrix components
247  ROOT::Math::SMatrix<double,7,4*nTrk+3> jac_t;
248  jac_t(0,0) = 1.;
249  jac_t(1,1) = 1.;
250  jac_t(2,2) = 1.;
251 
252 
253 
254  double energy_global = sqrt(newPar(3)*newPar(3)+newPar(4)*newPar(4) + newPar(5)*newPar(5)+newPar(6)*newPar(6));
255  for(int il_int = 0; il_int!=size; ++il_int) {
256  RefCountedKinematicParticle const & rs = rPart[il_int];
257  //jacobian components:
258  int off1=3; int off2=il_int*4+3;
259  jac_t(off1+0,off2+0) = 1.;
260  jac_t(off1+1,off2+1) = 1.;
261  jac_t(off1+2,off2+2) = 1.;
262 
263  //non-trival elements: mass correlations:
264  AlgebraicVector7 l_Par = (rs)->currentState().kinematicParameters().vector();
265  double energy_local = sqrt(l_Par(6)*l_Par(6) + l_Par(3)*l_Par(3) + l_Par(4)*l_Par(4) + l_Par(5)*l_Par(5));
266  jac_t(off1+3,off2+3) = energy_global*l_Par(6)/(newPar(6)*energy_local);
267  jac_t(off1+3,off2+0) = ((energy_global*l_Par(3)/energy_local) - newPar(3))/newPar(6);
268  jac_t(off1+3,off2+1) = ((energy_global*l_Par(4)/energy_local) - newPar(4))/newPar(6);
269  jac_t(off1+3,off2+2) = ((energy_global*l_Par(5)/energy_local) - newPar(5))/newPar(6);
270  }
271 
272  for(int i = 0; i<7;++i)
273  for(int j =0; j<7; ++j)
274  reduced(i,j) = transform(i+3, j+3);
275 
276  for(int i = 1; i<size; i++) {
277  //non-trival elements: mass correlations:
278  //upper row and right column
279 
280  int off1=0;
281  int off2=3+4*i;
282  for(int l1 = 0; l1<3;++l1)
283  for(int l2 = 0; l2<4;++l2)
284  reduced(off1+l1,off2+l2) = transform(3+l1,6+7*i +l2);
285 
286  //diagonal elements
287  off1=off2=3+4*i;
288  for(int l1 = 0; l1<4;++l1)
289  for(int l2 = 0; l2<4;++l2)
290  reduced(off1+l1,off2+l2) = transform(6+7*i+l1, 6+7*i+l2);
291 
292  //off diagonal elements
293  for(int j = 1; j<size; j++) {
294  off1 = 3+4*(i-1); off2=3+4*j;
295  for(int l1 = 0; l1<4;++l1)
296  for(int l2 = 0; l2<4;++l2)
297  reduced(off1+l1,off2+l2) = transform(6+7*(i-1)+l1,6+7*j+l2);
298  }
299 
300  }
301 
303  ROOT::Math::AssignSym::Evaluate(ret, jac_t*reduced*ROOT::Math::Transpose(jac_t));
304  return ret;
305 }
306 
307 
308 
309 
310 
311 
312 
313 #endif
#define LogDebug(id)
size
Write out results.
VirtualKinematicParticleFactory pFactory
RefCountedKinematicParticle particle(const KinematicState &kineState, float &chiSquared, float &degreesOfFr, ReferenceCountingPointer< KinematicParticle > previousParticle, KinematicConstraint *lastConstraint=0) const
static AlgebraicSymMatrix77 covarianceMatrix(const std::vector< RefCountedKinematicParticle > &rPart, const AlgebraicVector7 &newPar, const ROOT::Math::SMatrix< double, 3+7 *nTrk, 3+7 *nTrk, ROOT::Math::MatRepSym< double, 3+7 *nTrk > > &fitCov)
KinematicVertexFactory vFactory
RefCountedKinematicTree buildTree(const std::vector< RefCountedKinematicParticle > &initialParticles, const std::vector< KinematicState > &finalStates, const RefCountedKinematicVertex vtx, const ROOT::Math::SMatrix< double, 3+7 *nTrk, 3+7 *nTrk, ROOT::Math::MatRepSym< double, 3+7 *nTrk > > &fCov) const
ROOT::Math::SMatrix< double, 7, 7, ROOT::Math::MatRepSym< double, 7 > > AlgebraicSymMatrix77
Definition: Matrices.h:9
ROOT::Math::SVector< double, 7 > AlgebraicVector7
Definition: Matrices.h:8
T sqrt(T t)
Definition: SSEVec.h:18
ROOT::Math::SVector< double, 3 > AlgebraicVector3
RefCountedKinematicTree buildRealTree(const RefCountedKinematicParticle virtualParticle, const RefCountedKinematicVertex vtx, const std::vector< RefCountedKinematicParticle > &particles) const
double a
Definition: hdecay.h:121
ROOT::Math::SMatrix< double, 3, 3, ROOT::Math::MatRepStd< double, 3, 3 > > AlgebraicMatrix33