CMS 3D CMS Logo

ConstrainedTreeBuilder.cc
Go to the documentation of this file.
4 
8 }
9 
11  delete pFactory;
12  delete vFactory;
13 }
14 
16  const std::vector<RefCountedKinematicParticle>& initialParticles,
17  const std::vector<KinematicState>& finalStates,
19  const AlgebraicMatrix& fullCov) const {
20  if (!vertex->vertexIsValid()) {
21  LogDebug("ConstrainedTreeBuilder") << "Vertex is invalid\n";
23  }
25  vtx(0) = vertex->position().x();
26  vtx(1) = vertex->position().y();
27  vtx(2) = vertex->position().z();
28  AlgebraicMatrix33 vertexCov = asSMatrix<3, 3>(fullCov.sub(1, 3, 1, 3));
29 
30  // cout << fullCov<<endl;
31  // cout << "RecoVertex/ConstrainedTreeBuilder"<<vtx<<endl;
32 
33  double ent = 0.;
34  int charge = 0;
35  AlgebraicVector7 virtualPartPar;
36  virtualPartPar(0) = vertex->position().x();
37  virtualPartPar(1) = vertex->position().y();
38  virtualPartPar(2) = vertex->position().z();
39 
40  //making refitted particles out of refitted states.
41  //none of the operations above violates the order of particles
42 
43  ROOT::Math::SMatrix<double, 7, 7, ROOT::Math::MatRepStd<double, 7, 7> > aMatrix;
44  aMatrix(3, 3) = 1;
45  aMatrix(4, 4) = 1;
46  aMatrix(5, 5) = 1;
47  aMatrix(6, 6) = 1;
48  ROOT::Math::SMatrix<double, 7, 3, ROOT::Math::MatRepStd<double, 7, 3> > bMatrix;
49  bMatrix(0, 0) = 1;
50  bMatrix(1, 1) = 1;
51  bMatrix(2, 2) = 1;
52  AlgebraicMatrix77 trackParCov;
53  ROOT::Math::SMatrix<double, 3, 7, ROOT::Math::MatRepStd<double, 3, 7> > vtxTrackCov;
54  AlgebraicMatrix77 nCovariance;
55 
56  std::vector<RefCountedKinematicParticle>::const_iterator i = initialParticles.begin();
57  std::vector<KinematicState>::const_iterator iStates = finalStates.begin();
58  std::vector<RefCountedKinematicParticle> rParticles;
59  int n = 0;
60  for (; i != initialParticles.end() && iStates != finalStates.end(); ++i, ++iStates) {
61  AlgebraicVector7 p = iStates->kinematicParameters().vector();
62  double a = -iStates->particleCharge() * iStates->magneticField()->inInverseGeV(iStates->globalPosition()).z();
63 
64  aMatrix(4, 0) = -a;
65  aMatrix(3, 1) = a;
66  bMatrix(4, 0) = a;
67  bMatrix(3, 1) = -a;
68 
69  AlgebraicVector7 par = aMatrix * p + bMatrix * vtx;
70 
71  trackParCov = asSMatrix<7, 7>(fullCov.sub(4 + n * 7, 10 + n * 7, 4 + n * 7, 10 + n * 7));
72  vtxTrackCov = asSMatrix<3, 7>(fullCov.sub(1, 3, 4 + n * 7, 10 + n * 7));
73  ;
74  nCovariance = aMatrix * trackParCov * ROOT::Math::Transpose(aMatrix) +
75  aMatrix * ROOT::Math::Transpose(vtxTrackCov) * ROOT::Math::Transpose(bMatrix) +
76  bMatrix * vtxTrackCov * ROOT::Math::Transpose(aMatrix) +
77  bMatrix * vertexCov * ROOT::Math::Transpose(bMatrix);
78 
79  KinematicState stateAtVertex(KinematicParameters(par),
80  KinematicParametersError(AlgebraicSymMatrix77(nCovariance.LowerBlock())),
81  iStates->particleCharge(),
82  iStates->magneticField());
83  rParticles.push_back((*i)->refittedParticle(stateAtVertex, vertex->chiSquared(), vertex->degreesOfFreedom()));
84 
85  virtualPartPar(3) += par(3);
86  virtualPartPar(4) += par(4);
87  virtualPartPar(5) += par(5);
88  ent += sqrt(par(6) * par(6) + par(3) * par(3) + par(4) * par(4) + par(5) * par(5));
89  charge += iStates->particleCharge();
90 
91  ++n;
92  }
93 
94  //total reconstructed mass
95  double differ = ent * ent - (virtualPartPar(3) * virtualPartPar(3) + virtualPartPar(5) * virtualPartPar(5) +
96  virtualPartPar(4) * virtualPartPar(4));
97  if (differ > 0.) {
98  virtualPartPar(6) = sqrt(differ);
99  } else {
100  LogDebug("ConstrainedTreeBuilder") << "Fit failed: Current precision does not allow to calculate the mass\n";
102  }
103 
104  // covariance matrix:
105 
106  AlgebraicMatrix77 cov = asSMatrix<7, 7>(covarianceMatrix(rParticles, virtualPartPar, fullCov));
107 
108  KinematicState nState(KinematicParameters(virtualPartPar),
110  charge,
111  initialParticles[0]->magneticField());
112 
113  //newborn kinematic particle
114  float chi2 = vertex->chiSquared();
115  float ndf = vertex->degreesOfFreedom();
116  KinematicParticle* zp = nullptr;
117  RefCountedKinematicParticle virtualParticle = pFactory->particle(nState, chi2, ndf, zp);
118 
119  return buildTree(virtualParticle, vertex, rParticles);
120 }
121 
123  const RefCountedKinematicParticle virtualParticle,
125  const std::vector<RefCountedKinematicParticle>& particles) const {
126  //making a resulting tree:
128 
129  //fake production vertex:
131  resTree->addParticle(fVertex, vtx, virtualParticle);
132 
133  //adding final state
134  for (std::vector<RefCountedKinematicParticle>::const_iterator il = particles.begin(); il != particles.end(); il++) {
135  if ((*il)->previousParticle()->correspondingTree() != nullptr) {
136  KinematicTree* tree = (*il)->previousParticle()->correspondingTree();
137  tree->movePointerToTheTop();
138  tree->replaceCurrentParticle(*il);
139  RefCountedKinematicVertex cdVertex = resTree->currentDecayVertex();
140  resTree->addTree(cdVertex, tree);
141  } else {
143  resTree->addParticle(vtx, ffVertex, *il);
144  }
145  }
146  return resTree;
147 }
148 
149 AlgebraicMatrix ConstrainedTreeBuilder::covarianceMatrix(const std::vector<RefCountedKinematicParticle>& rPart,
150  const AlgebraicVector7& newPar,
151  const AlgebraicMatrix& fitCov) const {
152  //constructing the full matrix using the simple fact
153  //that we have never broken the order of tracks
154  // during our fit.
155 
156  int size = rPart.size();
157  //global propagation to the vertex position
158  //Jacobian is done for all the parameters together
159  AlgebraicMatrix jac(3 + 7 * size, 3 + 7 * size, 0);
160  jac(1, 1) = 1;
161  jac(2, 2) = 1;
162  jac(3, 3) = 1;
163  int i_int = 0;
164  for (std::vector<RefCountedKinematicParticle>::const_iterator i = rPart.begin(); i != rPart.end(); i++) {
165  //vertex position related components of the matrix
166  double a_i = -(*i)->currentState().particleCharge() *
167  (*i)->magneticField()->inInverseGeV((*i)->currentState().globalPosition()).z();
168 
169  AlgebraicMatrix upper(3, 7, 0);
170  AlgebraicMatrix diagonal(7, 7, 0);
171  upper(1, 1) = 1;
172  upper(2, 2) = 1;
173  upper(3, 3) = 1;
174  upper(2, 4) = -a_i;
175  upper(1, 5) = a_i;
176  jac.sub(1, 4 + i_int * 7, upper);
177 
178  diagonal(4, 4) = 1;
179  diagonal(5, 5) = 1;
180  diagonal(6, 6) = 1;
181  diagonal(7, 7) = 1;
182  diagonal(2, 4) = a_i;
183  diagonal(1, 5) = -a_i;
184  jac.sub(4 + i_int * 7, 4 + i_int * 7, diagonal);
185  i_int++;
186  }
187 
188  // jacobian is constructed in such a way, that
189  // right operation for transformation will be
190  // fitCov.similarityT(jac)
191  // WARNING: normal similarity operation is
192  // not valid in this case
193  //now making reduced matrix:
194  int vSize = rPart.size();
195  AlgebraicSymMatrix fit_cov_sym(7 * vSize + 3, 0);
196  for (int i = 1; i < 7 * vSize + 4; ++i) {
197  for (int j = 1; j < 7 * vSize + 4; ++j) {
198  if (i <= j)
199  fit_cov_sym(i, j) = fitCov(i, j);
200  }
201  }
202 
203  AlgebraicMatrix reduced(3 + 4 * size, 3 + 4 * size, 0);
204  AlgebraicMatrix transform = fit_cov_sym.similarityT(jac);
205 
206  //jacobian to add matrix components
207  AlgebraicMatrix jac_t(7, 7 + 4 * (size - 1));
208  jac_t(1, 1) = 1.;
209  jac_t(2, 2) = 1.;
210  jac_t(3, 3) = 1.;
211 
212  //debug code:
213  //CLHEP bugs: avoiding the
214  // HepMatrix::sub method use
215  AlgebraicMatrix reduced_tm(7, 7, 0);
216  for (int i = 1; i < 8; ++i) {
217  for (int j = 1; j < 8; ++j) {
218  reduced_tm(i, j) = transform(i + 3, j + 3);
219  }
220  }
221 
222  //left top corner
223  // reduced.sub(1,1,transform.sub(4,10,4,10));
224 
225  //debug code:
226  //CLHEP bugs: avoiding the
227  // HepMatrix::sub method use
228  reduced.sub(1, 1, reduced_tm);
229 
230  // cout<<"reduced matrix"<<reduced<<endl;
231  int il_int = 0;
232  double energy_global =
233  sqrt(newPar(3) * newPar(3) + newPar(4) * newPar(4) + newPar(5) * newPar(5) + newPar(6) * newPar(6));
234  for (std::vector<RefCountedKinematicParticle>::const_iterator rs = rPart.begin(); rs != rPart.end(); rs++) {
235  //jacobian components:
236  AlgebraicMatrix jc_el(4, 4, 0);
237  jc_el(1, 1) = 1.;
238  jc_el(2, 2) = 1.;
239  jc_el(3, 3) = 1.;
240 
241  //non-trival elements: mass correlations:
242  AlgebraicVector7 l_Par = (*rs)->currentState().kinematicParameters().vector();
243  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));
244  jc_el(4, 4) = energy_global * l_Par(6) / (newPar(6) * energy_local);
245  jc_el(4, 1) = ((energy_global * l_Par(3) / energy_local) - newPar(3)) / newPar(6);
246  jc_el(4, 2) = ((energy_global * l_Par(4) / energy_local) - newPar(4)) / newPar(6);
247  jc_el(4, 3) = ((energy_global * l_Par(5) / energy_local) - newPar(5)) / newPar(6);
248  jac_t.sub(4, il_int * 4 + 4, jc_el);
249  il_int++;
250  }
251  // cout<<"jac_t"<<jac_t<<endl;
252  //debug code
253  //CLHEP bugs workaround
254  // cout<<"Transform matrix"<< transform<<endl;
255 
256  for (int i = 1; i < size; i++) {
257  //non-trival elements: mass correlations:
258  //upper row and right column
259  AlgebraicMatrix transform_sub1(3, 4, 0);
260  AlgebraicMatrix transform_sub2(4, 3, 0);
261  for (int l1 = 1; l1 < 4; ++l1) {
262  for (int l2 = 1; l2 < 5; ++l2) {
263  transform_sub1(l1, l2) = transform(3 + l1, 6 + 7 * i + l2);
264  }
265  }
266 
267  for (int l1 = 1; l1 < 5; ++l1) {
268  for (int l2 = 1; l2 < 4; ++l2) {
269  transform_sub2(l1, l2) = transform(6 + 7 * i + l1, 3 + l2);
270  }
271  }
272 
273  AlgebraicMatrix transform_sub3(4, 4, 0);
274  for (int l1 = 1; l1 < 5; ++l1) {
275  for (int l2 = 1; l2 < 5; ++l2) {
276  transform_sub3(l1, l2) = transform(6 + 7 * i + l1, 6 + 7 * i + l2);
277  }
278  }
279 
280  reduced.sub(1, 4 + 4 * i, transform_sub1);
281  reduced.sub(4 + 4 * i, 1, transform_sub2);
282 
283  //diagonal elements
284  reduced.sub(4 + 4 * i, 4 + 4 * i, transform_sub3);
285 
286  //off diagonal elements
287  for (int j = 1; j < size; j++) {
288  AlgebraicMatrix transform_sub4(4, 4, 0);
289  AlgebraicMatrix transform_sub5(4, 4, 0);
290  for (int l1 = 1; l1 < 5; ++l1) {
291  for (int l2 = 1; l2 < 5; ++l2) {
292  transform_sub4(l1, l2) = transform(6 + 7 * (i - 1) + l1, 6 + 7 * j + l2);
293  transform_sub5(l1, l2) = transform(6 + 7 * j + l1, 6 + 7 * (i - 1) + l2);
294  }
295  }
296  reduced.sub(4 + 4 * (i - 1), 4 + 4 * j, transform_sub4);
297  reduced.sub(4 + 4 * j, 4 + 4 * (i - 1), transform_sub5);
298  }
299  }
300 
301  return jac_t * reduced * jac_t.T();
302 }
size
Write out results.
ROOT::Math::SMatrix< double, 3, 3, ROOT::Math::MatRepStd< double, 3, 3 > > AlgebraicMatrix33
ROOT::Math::SVector< double, 7 > AlgebraicVector7
Definition: Matrices.h:8
RefCountedKinematicTree buildTree(const std::vector< RefCountedKinematicParticle > &initialParticles, const std::vector< KinematicState > &finalStates, const RefCountedKinematicVertex vtx, const AlgebraicMatrix &fCov) const
KinematicVertexFactory * vFactory
ROOT::Math::SMatrix< double, 7, 7, ROOT::Math::MatRepStd< double, 7, 7 > > AlgebraicMatrix77
Definition: Matrices.h:10
CLHEP::HepMatrix AlgebraicMatrix
T sqrt(T t)
Definition: SSEVec.h:19
AlgebraicMatrix covarianceMatrix(const std::vector< RefCountedKinematicParticle > &rPart, const AlgebraicVector7 &newPar, const AlgebraicMatrix &fitCov) const
ROOT::Math::SMatrix< double, 7, 7, ROOT::Math::MatRepSym< double, 7 > > AlgebraicSymMatrix77
Definition: Matrices.h:9
RefCountedKinematicParticle particle(const KinematicState &kineState, float &chiSquared, float &degreesOfFr, ReferenceCountingPointer< KinematicParticle > previousParticle, KinematicConstraint *lastConstraint=nullptr) const
double a
Definition: hdecay.h:119
ROOT::Math::SVector< double, 3 > AlgebraicVector3
CLHEP::HepSymMatrix AlgebraicSymMatrix
static RefCountedKinematicVertex vertex(const VertexState &state, float totalChiSq, float degreesOfFr)
VirtualKinematicParticleFactory * pFactory
Definition: tree.py:1
#define LogDebug(id)
unsigned transform(const HcalDetId &id, unsigned transformCode)