ATLAS Offline Software
Loading...
Searching...
No Matches
TrkCascadeFitter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Header include
6#include "VxVertex/Vertex.h"
17#include "GaudiKernel/EventContext.h"
18
19//-------------------------------------------------
20// Other stuff
21#include <iostream>
22#include <stdexcept>
23
24namespace Trk {
25
27//-----------------------------------------------------------------------------------------
28// First vertex in cascade
29//
30//
31// Main structure description objects
32//
33// cascadeV - structure with cascade vertex description. It contains
34// vID - VertexID of the vertex
35// vector<int> trkInVrt - used tracks
36// vector<VertexID> inPointingV - used vertices (pseudo-tracks from them really) or vertices pointing to the current one.
37// VertexID outPointingV - vertex to which the current vertex points
38//
39// PartialMassConstraint - structure for mass constraint description. It contains
40// VRT - VertexID of corresponding vertex
41// trkInVrt - list of real tracks. It's vector<int> of indices to m_partListForCascade
42// pseudoInVrt - list of VertexID of the participating vertices
43//
44// vector<cascadeV> m_cascadeVList - main cascade defining vector with cascade vertices. Filled by cascade interface.
45// Should not be touched during fit.
46//
47// vector< TrackParticleBase* > m_partListForCascade - list of all REAL tracks used in cascade
48// vector< double > m_partMassForCascade - their masses
49// vector< PartialMassConstraint > m_partMassCnstForCascade - list of all mass constraints in cascade
50//
51//
52//---------- makeSimpleCascade transforms the full cascade definition m_cascadeVList into simplified structure with merging---------
53//---------- SimpleCascade may have LESS vertices than Cascade itself due to merging ---------
54//---------- SimpleCascade is defined by vertexDefinition and cascadeDefinition vectors. ---------
55//---------- Their sizes are SimpleCascade sise. ---------
56//
57// vector< vector <int> > vertexDefinition - list of pointers to REAL tracks (in m_partListForConstraints ) for SimpleCascade
58// vector< vector <int> > cascadeDefinition - simple vertices pointing to the current one. Contains indices (integer) to itself!
59//
60//
61//----------------------------------------------------------------------------------------
62
63VertexID TrkVKalVrtFitter::startVertex(const std::vector<const xAOD::TrackParticle*> & list,
64 std::span<const double> particleMass,
65 IVKalState& istate,
66 const double massConstraint) const
67{
68 assert(dynamic_cast<State*> (&istate)!=nullptr);
69 State& state = static_cast<State&> (istate);
70 state.m_cascadeState = std::make_unique<CascadeState>();
72
73 return nextVertex (list, particleMass, istate, massConstraint);
74}
75
76
77//
78// Calculate total number of degrees of freedom for cascade WITHOUT pointing to primary vertex
79//
81{
82
83// get Tracks, Vertices and Pointings in cascade
84//
85 int nTrack = cstate.m_partListForCascade.size();
86 int nVertex = cstate.m_cascadeVList.size();
87
88 int nPointing = 0;
89 for( int iv=0; iv<nVertex; iv++) nPointing += cstate.m_cascadeVList[iv].inPointingV.size();
90
91 int nMassCnst = cstate.m_partMassCnstForCascade.size(); // mass cnsts
92
93 return 2*nTrack - 3*nVertex + 2*nPointing + nMassCnst;
94}
95//
96// Next vertex in cascade
97//
98VertexID TrkVKalVrtFitter::nextVertex(const std::vector<const xAOD::TrackParticle*> & list,
99 std::span<const double> particleMass,
100 IVKalState& istate,
101 const double massConstraint) const
102{
103 assert(dynamic_cast<State*> (&istate)!=nullptr);
104 State& state = static_cast<State&> (istate);
105 CascadeState& cstate = *state.m_cascadeState;
106
107//----
108 int NV = cstate.m_cascadeSize++;
109 VertexID new_vID=10000+NV;
110//----
111 int NTRK = list.size();
112 int presentNT = cstate.m_partListForCascade.size();
113//----
114
115 double totMass=0;
116 for(int it=0; it<NTRK; it++){
117 cstate.m_partListForCascade.push_back(list[it]);
118 cstate.m_partMassForCascade.push_back(particleMass[it]);
119 totMass += particleMass[it];
120 }
121//---------------------- Fill complete vertex mass constraint
122 if(totMass < massConstraint) {
123 PartialMassConstraint tmpMcnst;
124 tmpMcnst.Mass = massConstraint;
125 tmpMcnst.VRT = new_vID;
126 for(int it=0; it<NTRK; it++)tmpMcnst.trkInVrt.push_back(it+presentNT);
127 cstate.m_partMassCnstForCascade.push_back(std::move(tmpMcnst));
128 }
129//
130//
131//-- New vertex structure-----------------------------------
132 cascadeV newV; newV.vID=new_vID;
133 for(int it=0; it<NTRK; it++){
134 newV.trkInVrt.push_back(it+presentNT);
135 }
136 cstate.m_cascadeVList.push_back(std::move(newV));
137//--------------------------------------------------------------
138 return new_vID;
139}
140
141
142//
143// Next vertex in cascade
144//
145VertexID TrkVKalVrtFitter::nextVertex(const std::vector<const xAOD::TrackParticle*> & list,
146 std::span<const double> particleMass,
147 const std::vector<VertexID> &precedingVertices,
148 IVKalState& istate,
149 const double massConstraint) const
150{
151 assert(dynamic_cast<State*> (&istate)!=nullptr);
152 State& state = static_cast<State&> (istate);
153 CascadeState& cstate = *state.m_cascadeState;
154
155 VertexID vID=nextVertex( list, particleMass, istate, massConstraint);
156//
157 int lastC=cstate.m_partMassCnstForCascade.size()-1; // Check if full vertex mass constraint exist
158 if( lastC>=0 ){ if( cstate.m_partMassCnstForCascade[lastC].VRT == vID ){
159 for(int iv=0; iv<(int)precedingVertices.size(); iv++){
160 cstate.m_partMassCnstForCascade[lastC].pseudoInVrt.push_back(precedingVertices[iv]); }
161 }
162 }
163//
164//-- New vertex structure-----------------------------------
165 int lastV=cstate.m_cascadeVList.size()-1;
166 for(int iv=0; iv<(int)precedingVertices.size(); iv++){
167 cstate.m_cascadeVList[lastV].inPointingV.push_back(precedingVertices[iv]); // fill preceding vertices list
168 }
169//--
170 return vID;
171}
172
173
174//--------------------------------------------------------------------------------
175// Convert complex (with vertex merging) structure into simple one for fitter
176// vrtDef[iv][it] - list of real tracks in vertex IV in cascade
177// cascadeDef[iv][ipv] - list of previous vertices pointing to vertex IV in cascade
178//
179// Vectors are filled with the indices (NOT VertexID!!!)
180//------------------------
181void TrkVKalVrtFitter::makeSimpleCascade(std::vector< std::vector<int> > & vrtDef,
182 std::vector< std::vector<int> > & cascadeDef,
183 CascadeState& cstate)
184{
185 int iv,ip,it, nVAdd, iva;
186 vrtDef.clear();
187 cascadeDef.clear();
188 int NVC=cstate.m_cascadeVList.size();
189 vrtDef.resize(NVC);
190 cascadeDef.resize(NVC);
191//
192//---- First set up position of each vertex in simple structure with merging(!!!)
193//
194 int vCounter=0;
195 for(iv=0; iv<NVC; iv++){
196 cascadeV &vrt=cstate.m_cascadeVList[iv];
197 vrt.indexInSimpleCascade=-1; // set to -1 for merged vertices not present in simple list
198 if(vrt.mergedTO) continue; // vertex is merged with another one;
199 vrt.indexInSimpleCascade=vCounter; // vertex position in simple cascade structure
200 vCounter++;
201 }
202//---- Fill vertices in simple structure
203 vCounter=0;
204 for(iv=0; iv<NVC; iv++){
205 const cascadeV &vrt=cstate.m_cascadeVList[iv];
206 if(vrt.mergedTO) continue; // vertex is merged with another one;
207 for(it=0; it<(int)vrt.trkInVrt.size(); it++) vrtDef[vCounter].push_back(vrt.trkInVrt[it]); //copy real tracks
208 for(ip=0; ip<(int)vrt.inPointingV.size(); ip++) {
209 //int indInFull=vrt.inPointingV[ip]; // pointing vertex in full list WRONG!!!
210 int indInFull = indexInV(vrt.inPointingV[ip], cstate); // pointing vertex in full list
211 if (indInFull < 0)[[unlikely]]{
212 throw std::runtime_error("TrkVKalVrtFitter::makeSimpleCascade: index into vector is negative.");
213 }
214 int indInSimple=cstate.m_cascadeVList[indInFull].indexInSimpleCascade; // its index in simple structure
215 if(indInSimple<0) continue; // merged out vertex. Will be added as tracks
216 cascadeDef[vCounter].push_back(indInSimple);
217 }
218 nVAdd=vrt.mergedIN.size();
219 if( nVAdd ) { //----------------------------- mergedIN(added) vertices exist
220 for(iva=0; iva<nVAdd; iva++){
221 const cascadeV &vrtM=cstate.m_cascadeVList[vrt.mergedIN[iva]]; // merged/added vertex itself
222 for(it=0; it<(int)vrtM.trkInVrt.size(); it++) vrtDef[vCounter].push_back(vrtM.trkInVrt[it]);
223 for(ip=0; ip<(int)vrtM.inPointingV.size(); ip++) {
224 //int indInFull=vrtM.inPointingV[ip]; // pointing vertex in full list WRONG!!!
225 int indInFull=indexInV(vrtM.inPointingV[ip], cstate); // pointing vertex in full list
226 int indInSimple=cstate.m_cascadeVList[indInFull].indexInSimpleCascade; // its index in simple structure
227 if(indInSimple<0) continue; // merged out vertex. Will be added as tracks
228 cascadeDef[vCounter].push_back(indInSimple);
229 }
230 }
231 }
232
233 vCounter++;
234 }
235 vrtDef.resize(vCounter);
236 cascadeDef.resize(vCounter);
237}
238//--------------------------------------------------------------------------------
239// Printing of cascade structure
240//
241void TrkVKalVrtFitter::printSimpleCascade(std::vector< std::vector<int> > & vrtDef,
242 std::vector< std::vector<int> > & cascadeDef,
243 const CascadeState& cstate)
244{
245 int kk,kkk;
246 for(kk=0; kk<(int)vrtDef.size(); kk++){
247 std::cout<<" Vertex("<<kk<<"):: trk=";
248 for(kkk=0; kkk<(int)vrtDef[kk].size(); kkk++){
249 std::cout<<vrtDef[kk][kkk]<<", ";} std::cout<<" pseu=";
250 for(kkk=0; kkk<(int)cascadeDef[kk].size(); kkk++){
251 std::cout<<cascadeDef[kk][kkk]<<", ";}
252 } std::cout<<'\n';
253//---
254 for(kk=0; kk<(int)vrtDef.size(); kk++){
255 std::cout<<" Vertex("<<kk<<"):: trkM=";
256 for(kkk=0; kkk<(int)vrtDef[kk].size(); kkk++){
257 std::cout<<cstate.m_partMassForCascade[vrtDef[kk][kkk]]<<", ";}
258 }std::cout<<'\n';
259//--
260 for (const PartialMassConstraint& c : cstate.m_partMassCnstForCascade) {
261 std::cout<<" MCnst vID=";
262 std::cout<<c.VRT<<" m="<<c.Mass<<" trk=";
263 for(int idx : c.trkInVrt) {
264 std::cout<<idx<<", ";
265 }
266 std::cout<<" pseudo=";
267 for (VertexID id : c.pseudoInVrt) {
268 std::cout<<id<<", ";
269 }
270 std::cout<<'\n';
271 }
272}
273
274
275inline int SymIndex(int it, int i, int j) { return (3*it+3+i)*(3*it+3+i+1)/2 + (3*it+3+j);}
276#define CLEANCASCADE() state.m_vkalFitControl.renewCascadeEvent(nullptr)
277
279 const Vertex* primVrt, bool FirstDecayAtPV ) const
280{
281 assert(dynamic_cast<State*> (&istate)!=nullptr);
282 State& state = static_cast<State&> (istate);
283 CascadeState& cstate = *state.m_cascadeState;
284
285 int iv,it,jt;
286 std::vector< Vect3DF > cVertices;
287 std::vector< std::vector<double> > covVertices;
288 std::vector< std::vector< VectMOM> > fittedParticles;
289 std::vector< std::vector<double> > fittedCovariance;
290 std::vector<double> fitFullCovariance;
291 std::vector<double> particleChi2;
292//
293 int ntrk=0;
294 StatusCode sc;
295 std::vector<const TrackParameters*> baseInpTrk;
296 if(m_firstMeasuredPoint){ //First measured point strategy
297 std::vector<const xAOD::TrackParticle*>::const_iterator i_ntrk;
298 //for (i_ntrk = cstate.m_partListForCascade.begin(); i_ntrk < cstate.m_partListForCascade.end(); ++i_ntrk) baseInpTrk.push_back(GetFirstPoint(*i_ntrk));
299 unsigned int indexFMP;
300 for (i_ntrk = cstate.m_partListForCascade.begin(); i_ntrk < cstate.m_partListForCascade.end(); ++i_ntrk) {
301 if ((*i_ntrk)->indexOfParameterAtPosition(indexFMP, xAOD::FirstMeasurement)){
302 ATH_MSG_DEBUG("FirstMeasuredPoint on track is discovered. Use it.");
303 baseInpTrk.push_back(new CurvilinearParameters((*i_ntrk)->curvilinearParameters(indexFMP)));
304 }else{
305 ATH_MSG_DEBUG("No FirstMeasuredPoint on track in CascadeFitter. Stop fit");
306 { CLEANCASCADE(); return nullptr; }
307 }
308 }
309 sc=CvtTrackParameters(baseInpTrk,ntrk,state);
310 if(sc.isFailure()){ntrk=0; sc=CvtTrackParticle(cstate.m_partListForCascade,ntrk,state);}
311 }else{
312 sc=CvtTrackParticle(cstate.m_partListForCascade,ntrk,state);
313 }
314 if(sc.isFailure()){ CLEANCASCADE(); return nullptr; }
315
316 VKalVrtConfigureFitterCore(ntrk, state);
317
318 std::vector< std::vector<int> > vertexDefinition; // track indices for vertex;
319 std::vector< std::vector<int> > cascadeDefinition; // cascade structure
320 makeSimpleCascade(vertexDefinition, cascadeDefinition, cstate);
321
322 double * partMass=new double[ntrk];
323 for(int i=0; i<ntrk; i++) partMass[i] = cstate.m_partMassForCascade[i];
324 int IERR = makeCascade(state.m_vkalFitControl, ntrk, state.m_ich, partMass, &state.m_apar[0][0], &state.m_awgt[0][0],
325 vertexDefinition,
326 cascadeDefinition,
327 m_cascadeCnstPrecision); delete[] partMass; if(IERR){ CLEANCASCADE(); return nullptr;}
328 CascadeEvent & refCascadeEvent=*(state.m_vkalFitControl.getCascadeEvent());
329//
330// Then set vertex mass constraints
331//
332 std::vector<int> indexT,indexV,indexTT,indexVV,tmpInd; // track indices for vertex;
333 for (const PartialMassConstraint& c : cstate.m_partMassCnstForCascade) {
334 //int index=c.VRT; // vertex position in simple structure
335 int index=getSimpleVIndex(c.VRT, cstate); // vertex position in simple structure
336 if (index < 0)[[unlikely]]{
337 throw std::runtime_error("TrkVKalVrtFitter::fitCascade: index into vector is negative.");
338 }
339 IERR = findPositions(c.trkInVrt, vertexDefinition[index], indexT);
340 if(IERR)break;
341 tmpInd.clear();
342 for (int idx : c.pseudoInVrt)
343 tmpInd.push_back( getSimpleVIndex(idx, cstate) );
344 IERR = findPositions( tmpInd, cascadeDefinition[index], indexV); if(IERR)break;
345 //IERR = findPositions(c.pseudoInVrt, cascadeDefinition[index], indexV); if(IERR)break; //VK 31.10.2011 ERROR!!!
346 IERR = setCascadeMassConstraint(refCascadeEvent,index, indexT, indexV, c.Mass);
347 if(IERR)break;
348 }
349 if(IERR){ CLEANCASCADE(); return nullptr;}
350 if(msgLvl(MSG::DEBUG)){
351 msg(MSG::DEBUG)<<"Standard cascade fit" << endmsg;
352 printSimpleCascade(vertexDefinition,cascadeDefinition, cstate);
353 }
354//
355// At last fit of cascade
356// primVrt == 0 - no primary vertex
357// primVrt is <Vertex*> - exact pointing to primary vertex
358// primVrt is <RecVertex*> - summary track pass near primary vertex
359//
360 if(primVrt){
361 double vertex[3] = {primVrt->position().x()-state.m_refFrameX, primVrt->position().y()-state.m_refFrameY,primVrt->position().z()-state.m_refFrameZ};
362 const RecVertex* primVrtRec=dynamic_cast< const RecVertex* > (primVrt);
363 if(primVrtRec){
364 double covari[6] = {primVrtRec->covariancePosition()(0,0),primVrtRec->covariancePosition()(0,1),
365 primVrtRec->covariancePosition()(1,1),primVrtRec->covariancePosition()(0,2),
366 primVrtRec->covariancePosition()(1,2),primVrtRec->covariancePosition()(2,2)};
367 if(FirstDecayAtPV) { IERR = processCascadePV(refCascadeEvent,vertex,covari);}
368 else { IERR = processCascade(refCascadeEvent,vertex,covari);}
369 }else{
370 IERR = processCascade(refCascadeEvent,vertex);
371 }
372 }else{
373 IERR = processCascade(refCascadeEvent);
374 }
375 if(IERR){ CLEANCASCADE(); return nullptr;}
376 getFittedCascade(refCascadeEvent, cVertices, covVertices, fittedParticles, fittedCovariance, particleChi2, fitFullCovariance );
377
378// for(int iv=0; iv<(int)cVertices.size(); iv++){ std::cout<<"iv="<<iv<<" masses=";
379// for(int it=0; it<(int)fittedParticles[iv].size(); it++){
380// double m=sqrt( fittedParticles[iv][it].E *fittedParticles[iv][it].E
381// -fittedParticles[iv][it].Pz*fittedParticles[iv][it].Pz
382// -fittedParticles[iv][it].Py*fittedParticles[iv][it].Py
383// -fittedParticles[iv][it].Px*fittedParticles[iv][it].Px);
384// std::cout<<m<<", "; } std::cout<<'\n'; }
385//-----------------------------------------------------------------------------
386//
387// Check cascade correctness
388//
389 int ip,ivFrom=0,ivTo;
390 double px,py,pz,Sign=10.;
391 for( ivTo=0; ivTo<(int)vertexDefinition.size(); ivTo++){ //Vertex to check
392 if(cascadeDefinition[ivTo].empty()) continue; //no pointing to it
393 for( ip=0; ip<(int)cascadeDefinition[ivTo].size(); ip++){
394 ivFrom=cascadeDefinition[ivTo][ip]; //pointing vertex
395 px=py=pz=0;
396 for(it=0; it<(int)fittedParticles[ivFrom].size(); it++){
397 px += fittedParticles[ivFrom][it].Px;
398 py += fittedParticles[ivFrom][it].Py;
399 pz += fittedParticles[ivFrom][it].Pz;
400 }
401 Sign= (cVertices[ivFrom].X-cVertices[ivTo].X)*px
402 +(cVertices[ivFrom].Y-cVertices[ivTo].Y)*py
403 +(cVertices[ivFrom].Z-cVertices[ivTo].Z)*pz;
404 if(Sign<0) break;
405 }
406 if(Sign<0) break;
407 }
408//
409//--------------- Wrong vertices in cascade precedence. Squeeze cascade and refit-----------
410//
411 int NDOFsqueezed=0;
412 if(Sign<0.){
413 int index,itmp;
414 std::vector< std::vector<int> > new_vertexDefinition; // track indices for vertex;
415 std::vector< std::vector<int> > new_cascadeDefinition; // cascade structure
416 cstate.m_cascadeVList[ivFrom].mergedTO=cstate.m_cascadeVList[ivTo].vID;
417 cstate.m_cascadeVList[ivTo].mergedIN.push_back(ivFrom);
418 makeSimpleCascade(new_vertexDefinition, new_cascadeDefinition, cstate);
419 if(msgLvl(MSG::DEBUG)){
420 msg(MSG::DEBUG)<<"Compressed cascade fit" << endmsg;
421 printSimpleCascade(new_vertexDefinition,new_cascadeDefinition, cstate);
422 }
423//-----------------------------------------------------------------------------------------
425 partMass=new double[ntrk];
426 for(int i=0; i<ntrk; i++) partMass[i] = cstate.m_partMassForCascade[i];
427 int IERR = makeCascade(state.m_vkalFitControl, ntrk, state.m_ich, partMass, &state.m_apar[0][0], &state.m_awgt[0][0],
428 new_vertexDefinition,
429 new_cascadeDefinition); delete[] partMass; if(IERR){ CLEANCASCADE(); return nullptr;}
430//------Set up mass constraints
431 for (const PartialMassConstraint& c : cstate.m_partMassCnstForCascade) {
432 indexT.clear(); indexV.clear();
433 index=getSimpleVIndex( c.VRT, cstate);
434 IERR = findPositions(c.trkInVrt, new_vertexDefinition[index], indexT); if(IERR)break;
435 for (VertexID inV : c.pseudoInVrt) { //cycle over pseudotracks
436 int icv=indexInV(inV, cstate); if(icv<0) break;
437 if(cstate.m_cascadeVList[icv].mergedTO == c.VRT){
438 IERR = findPositions(cstate.m_cascadeVList[icv].trkInVrt, new_vertexDefinition[index], indexTT);
439 if(IERR)break;
440 indexT.insert (indexT.end(), indexTT.begin(), indexTT.end());
441 }else{
442 std::vector<int> tmpI(1); tmpI[0]=inV;
443 IERR = findPositions(tmpI, new_cascadeDefinition[index], indexVV);
444 if(IERR)break;
445 indexV.insert (indexV.end(), indexVV.begin(), indexVV.end());
446 }
447 } if(IERR)break;
448 //std::cout<<"trk2="; for(int I=0; I<(int)indexT.size(); I++)std::cout<<indexT[I]; std::cout<<'\n';
449 //std::cout<<"pse="; for(int I=0; I<(int)indexV.size(); I++)std::cout<<indexV[I]; std::cout<<'\n';
450 IERR = setCascadeMassConstraint(*(state.m_vkalFitControl.getCascadeEvent()), index , indexT, indexV, c.Mass); if(IERR)break;
451 }
452 ATH_MSG_DEBUG("Setting compressed mass constraints ierr="<<IERR);
453 if(IERR){ CLEANCASCADE(); return nullptr;}
454//
455//--------------------------- Refit
456//
457 if(primVrt){
458 double vertex[3] = {primVrt->position().x()-state.m_refFrameX, primVrt->position().y()-state.m_refFrameY,primVrt->position().z()-state.m_refFrameZ};
459 const RecVertex* primVrtRec=dynamic_cast< const RecVertex* > (primVrt);
460 if(primVrtRec){
461 double covari[6] = {primVrtRec->covariancePosition()(0,0),primVrtRec->covariancePosition()(0,1),
462 primVrtRec->covariancePosition()(1,1),primVrtRec->covariancePosition()(0,2),
463 primVrtRec->covariancePosition()(1,2),primVrtRec->covariancePosition()(2,2)};
464 IERR = processCascade(*(state.m_vkalFitControl.getCascadeEvent()),vertex,covari);
465 }else{
467 }
468 }else{
470 }
471 if(IERR){ CLEANCASCADE(); return nullptr;}
472 NDOFsqueezed=getCascadeNDoF(cstate)+3-2; // Remove vertex (+3 ndf) and this vertex pointing (-2 ndf)
473//
474//-------------------- Get information according to old cascade structure
475//
476 std::vector< Vect3DF > t_cVertices;
477 std::vector< std::vector<double> > t_covVertices;
478 std::vector< std::vector< VectMOM> > t_fittedParticles;
479 std::vector< std::vector<double> > t_fittedCovariance;
480 std::vector<double> t_fitFullCovariance;
481 getFittedCascade(*(state.m_vkalFitControl.getCascadeEvent()), t_cVertices, t_covVertices, t_fittedParticles,
482 t_fittedCovariance, particleChi2, t_fitFullCovariance);
483 cVertices.clear(); covVertices.clear();
484//
485//------------------------- Real tracks
486//
487 if(msgLvl(MSG::DEBUG)){
488 msg(MSG::DEBUG)<<"Initial cascade momenta"<<endmsg;
489 for(int kv=0; kv<(int)fittedParticles.size(); kv++){
490 for(int kt=0; kt<(int)fittedParticles[kv].size(); kt++)
491 std::cout<<
492 " Px="<<fittedParticles[kv][kt].Px<<" Py="<<fittedParticles[kv][kt].Py<<";";
493 std::cout<<'\n';
494 }
495 msg(MSG::DEBUG)<<"Squized cascade momenta"<<endmsg;
496 for(int kv=0; kv<(int)t_fittedParticles.size(); kv++){
497 for(int kt=0; kt<(int)t_fittedParticles[kv].size(); kt++)
498 std::cout<<
499 " Px="<<t_fittedParticles[kv][kt].Px<<" Py="<<t_fittedParticles[kv][kt].Py<<";";
500 std::cout<<'\n';
501 }
502 }
503 for(iv=0; iv<(int)cstate.m_cascadeVList.size(); iv++){
504 index=getSimpleVIndex( cstate.m_cascadeVList[iv].vID, cstate ); //index of vertex in simplified structure
505 cVertices.push_back(t_cVertices[index]);
506 covVertices.push_back(t_covVertices[index]);
507 for(it=0; it<(int)cstate.m_cascadeVList[iv].trkInVrt.size(); it++){
508 int numTrk=cstate.m_cascadeVList[iv].trkInVrt[it]; //track itself
509 for(itmp=0; itmp<(int)new_vertexDefinition[index].size(); itmp++) if(numTrk==new_vertexDefinition[index][itmp])break;
510 fittedParticles[iv][it]=t_fittedParticles[index][itmp];
511//Update only particle covariance. Cross particle covariance remains old.
512 fittedCovariance[iv][SymIndex(it,0,0)]=t_fittedCovariance[index][SymIndex(itmp,0,0)];
513 fittedCovariance[iv][SymIndex(it,1,0)]=t_fittedCovariance[index][SymIndex(itmp,1,0)];
514 fittedCovariance[iv][SymIndex(it,1,1)]=t_fittedCovariance[index][SymIndex(itmp,1,1)];
515 fittedCovariance[iv][SymIndex(it,2,0)]=t_fittedCovariance[index][SymIndex(itmp,2,0)];
516 fittedCovariance[iv][SymIndex(it,2,1)]=t_fittedCovariance[index][SymIndex(itmp,2,1)];
517 fittedCovariance[iv][SymIndex(it,2,2)]=t_fittedCovariance[index][SymIndex(itmp,2,2)];
518 }
519 fittedCovariance[iv][SymIndex(0,0,0)]=t_fittedCovariance[index][SymIndex(0,0,0)]; // Update also vertex
520 fittedCovariance[iv][SymIndex(0,1,0)]=t_fittedCovariance[index][SymIndex(0,1,0)]; // covarinace
521 fittedCovariance[iv][SymIndex(0,1,1)]=t_fittedCovariance[index][SymIndex(0,1,1)];
522 fittedCovariance[iv][SymIndex(0,2,0)]=t_fittedCovariance[index][SymIndex(0,2,0)];
523 fittedCovariance[iv][SymIndex(0,2,1)]=t_fittedCovariance[index][SymIndex(0,2,1)];
524 fittedCovariance[iv][SymIndex(0,2,2)]=t_fittedCovariance[index][SymIndex(0,2,2)];
525 }
526// Pseudo-tracks. They are filled based on fitted results for nonmerged vertices
527// or as sum for merged vertices
528 VectMOM tmpMom{};
529 for(iv=0; iv<(int)cstate.m_cascadeVList.size(); iv++){
530 index=getSimpleVIndex( cstate.m_cascadeVList[iv].vID, cstate ); //index of current vertex in simplified structure
531 int NTrkInVrt=cstate.m_cascadeVList[iv].trkInVrt.size();
532 for(ip=0; ip<(int)cstate.m_cascadeVList[iv].inPointingV.size(); ip++){ //inPointing verties
533 int tmpIndexV=indexInV( cstate.m_cascadeVList[iv].inPointingV[ip], cstate); //index of inPointing vertex in full structure
534 if(cstate.m_cascadeVList[tmpIndexV].mergedTO){ //vertex is merged, so take pseudo-track as a sum
535 tmpMom.Px=tmpMom.Py=tmpMom.Pz=tmpMom.E=0.;
536 for(it=0; it<(int)(cstate.m_cascadeVList[tmpIndexV].trkInVrt.size()+
537 cstate.m_cascadeVList[tmpIndexV].inPointingV.size()); it++){
538 tmpMom.Px += fittedParticles[tmpIndexV][it].Px; tmpMom.Py += fittedParticles[tmpIndexV][it].Py;
539 tmpMom.Pz += fittedParticles[tmpIndexV][it].Pz; tmpMom.E += fittedParticles[tmpIndexV][it].E;
540 }
541 fittedParticles[iv][ip+NTrkInVrt]=tmpMom;
542 }else{
543 int indexS=getSimpleVIndex( cstate.m_cascadeVList[iv].inPointingV[ip], cstate ); //index of inPointing vertex in simplified structure
544 for(itmp=0; itmp<(int)new_cascadeDefinition[index].size(); itmp++) if(indexS==new_cascadeDefinition[index][itmp])break;
545 fittedParticles[iv][ip+NTrkInVrt]=t_fittedParticles[index][itmp+new_vertexDefinition[index].size()];
546 }
547 }
548 }
549 if(msgLvl(MSG::DEBUG)){
550 msg(MSG::DEBUG)<<"Refit cascade momenta"<<endmsg;
551 for(int kv=0; kv<(int)fittedParticles.size(); kv++){
552 for(int kt=0; kt<(int)fittedParticles[kv].size(); kt++)
553 std::cout<<
554 " Px="<<fittedParticles[kv][kt].Px<<" Py="<<fittedParticles[kv][kt].Py<<";";
555 std::cout<<'\n';
556 }
557 }
558// Covariance matrix for nonmerged vertices is updated.
559// For merged vertices (both IN and TO ) it's taken from old fit
560
561 for(iv=0; iv<(int)cstate.m_cascadeVList.size(); iv++){
562 bool isMerged=false;
563 if(cstate.m_cascadeVList[iv].mergedTO)isMerged=true; //vertex is merged
564 index=getSimpleVIndex( cstate.m_cascadeVList[iv].vID, cstate ); //index of current vertex in simplified structure
565 for(ip=0; ip<(int)cstate.m_cascadeVList[iv].inPointingV.size(); ip++){ //inPointing verties
566 int tmpIndexV=indexInV( cstate.m_cascadeVList[iv].inPointingV[ip], cstate); //index of inPointing vertex in full structure
567 if(cstate.m_cascadeVList[tmpIndexV].mergedTO)isMerged=true; //vertex is merged
568 }
569 if(!isMerged){
570 fittedCovariance[iv]=t_fittedCovariance[index]; //copy complete covarinace matrix for nonmerged vertices
571 }
572 }
573 }
574//
575//-------------------------------------Saving
576//
577 ATH_MSG_DEBUG("Now save results");
578 Amg::MatrixX VrtCovMtx(3,3);
579 Trk::Perigee * measPerigee;
580 std::vector<xAOD::Vertex*> xaodVrtList(0);
581 double phi, theta, invP, mom, fullChi2=0.;
582
583 int NDOF=getCascadeNDoF(cstate); if(NDOFsqueezed) NDOF=NDOFsqueezed;
584 if(primVrt){ if(FirstDecayAtPV){ NDOF+=3; }else{ NDOF+=2; } }
585
586 for(iv=0; iv<(int)cVertices.size(); iv++){
587 Amg::Vector3D FitVertex(cVertices[iv].X+state.m_refFrameX,cVertices[iv].Y+state.m_refFrameY,cVertices[iv].Z+state.m_refFrameZ);
588 VrtCovMtx(0,0) = covVertices[iv][0]; VrtCovMtx(0,1) = covVertices[iv][1];
589 VrtCovMtx(1,1) = covVertices[iv][2]; VrtCovMtx(0,2) = covVertices[iv][3];
590 VrtCovMtx(1,2) = covVertices[iv][4]; VrtCovMtx(2,2) = covVertices[iv][5];
591 VrtCovMtx(1,0) = VrtCovMtx(0,1);
592 VrtCovMtx(2,0) = VrtCovMtx(0,2);
593 VrtCovMtx(2,1) = VrtCovMtx(1,2);
594 double Chi2=0;
595 for(it=0; it<(int)vertexDefinition[iv].size(); it++) { Chi2 += particleChi2[vertexDefinition[iv][it]];};
596 fullChi2+=Chi2;
597
598//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-= xAOD::Vertex creation
599 xAOD::Vertex * tmpXAODVertex=new xAOD::Vertex();
600 tmpXAODVertex->makePrivateStore();
601 tmpXAODVertex->setPosition(FitVertex);
602 tmpXAODVertex->setFitQuality(Chi2, (float)NDOF);
603 std::vector<VxTrackAtVertex> & tmpVTAV=tmpXAODVertex->vxTrackAtVertex();
604 tmpVTAV.clear();
605
606 int NRealT=vertexDefinition[iv].size();
607 Amg::MatrixX genCOV( NRealT*3+3, NRealT*3+3 ); // Fill cov. matrix for vertex
608 for( it=0; it<NRealT*3+3; it++){ // (X,Y,Z,px1,py1,....pxn,pyn,pzn)
609 for( jt=0; jt<=it; jt++){ //
610 genCOV(it,jt) = genCOV(jt,it) = fittedCovariance[iv][it*(it+1)/2+jt]; // for real tracks only
611 } } // (first in the list)
612 Amg::MatrixX fullDeriv;
614 //VK fullDeriv=new CLHEP::HepMatrix( NRealT*3+3, NRealT*3+3, 0); // matrix is filled by zeros
615 fullDeriv=Amg::MatrixX::Zero(NRealT*3+3, NRealT*3+3); // matrix is filled by zeros
616 fullDeriv(0,0)=fullDeriv(1,1)=fullDeriv(2,2)=1.;
617 }
618 for( it=0; it<NRealT; it++) {
619 mom= sqrt( fittedParticles[iv][it].Pz*fittedParticles[iv][it].Pz
620 +fittedParticles[iv][it].Py*fittedParticles[iv][it].Py
621 +fittedParticles[iv][it].Px*fittedParticles[iv][it].Px);
622 double Px=fittedParticles[iv][it].Px;
623 double Py=fittedParticles[iv][it].Py;
624 double Pz=fittedParticles[iv][it].Pz;
625 double Pt= sqrt(Px*Px + Py*Py) ;
626 phi=atan2( Py, Px);
627 theta=acos( Pz/mom );
628 invP = - state.m_ich[vertexDefinition[iv][it]] / mom; // Change charge sign according to ATLAS
629// d(Phi,Theta,InvP)/d(Px,Py,Pz) - Perigee vs summary momentum
630 Amg::MatrixX tmpDeriv( 5, NRealT*3+3);
631 tmpDeriv.setZero(); // matrix is filled by zeros
632 tmpDeriv(0,1) = -sin(phi); // Space derivatives
633 tmpDeriv(0,2) = cos(phi);
634 tmpDeriv(1,1) = -cos(phi)/tan(theta);
635 tmpDeriv(1,2) = -sin(phi)/tan(theta);
636 tmpDeriv(1,3) = 1.;
637 tmpDeriv(2+0,3*it+3+0) = -Py/Pt/Pt; //dPhi/dPx
638 tmpDeriv(2+0,3*it+3+1) = Px/Pt/Pt; //dPhi/dPy
639 tmpDeriv(2+0,3*it+3+2) = 0; //dPhi/dPz
640 tmpDeriv(2+1,3*it+3+0) = Px*Pz/(Pt*mom*mom); //dTheta/dPx
641 tmpDeriv(2+1,3*it+3+1) = Py*Pz/(Pt*mom*mom); //dTheta/dPy
642 tmpDeriv(2+1,3*it+3+2) = -Pt/(mom*mom); //dTheta/dPz
643 tmpDeriv(2+2,3*it+3+0) = -Px/(mom*mom) * invP; //dInvP/dPx
644 tmpDeriv(2+2,3*it+3+1) = -Py/(mom*mom) * invP; //dInvP/dPy
645 tmpDeriv(2+2,3*it+3+2) = -Pz/(mom*mom) * invP; //dInvP/dPz
646//---------- Here for Eigen block(startrow,startcol,sizerow,sizecol)
647 if( m_makeExtendedVertex )fullDeriv.block<3,3>(3*it+3+0,3*it+3+0) = tmpDeriv.block<3,3>(2,3*it+3+0);
648//----------
649 AmgSymMatrix(5) tmpCovMtx ; // New Eigen based EDM
650 tmpCovMtx = genCOV.similarity(tmpDeriv); // New Eigen based EDM
651 measPerigee = new Perigee( 0.,0., phi, theta, invP, PerigeeSurface(FitVertex), std::move(tmpCovMtx) ); // New Eigen based EDM
652 tmpVTAV.emplace_back( particleChi2[vertexDefinition[iv][it]] , measPerigee ) ;
653 }
654 std::vector<float> floatErrMtx;
656 Amg::MatrixX tmpCovMtx(NRealT*3+3,NRealT*3+3); // New Eigen based EDM
657 tmpCovMtx=genCOV.similarity(fullDeriv);
658 floatErrMtx.resize((NRealT*3+3)*(NRealT*3+3+1)/2);
659 int ivk=0;
660 for(int i=0;i<NRealT*3+3;i++){
661 for(int j=0;j<=i;j++){
662 floatErrMtx.at(ivk++)=tmpCovMtx(i,j);
663 }
664 }
665 }else{
666 floatErrMtx.resize(6);
667 for(int i=0; i<6; i++) floatErrMtx[i]=covVertices[iv][i];
668 }
669 tmpXAODVertex->setCovariance(floatErrMtx);
670 for(int itvk=0; itvk<NRealT; itvk++) {
672 if(itvk < (int)cstate.m_cascadeVList[iv].trkInVrt.size()){
673 TEL.setElement( cstate.m_partListForCascade[ cstate.m_cascadeVList[iv].trkInVrt[itvk] ] );
674 }else{
675 TEL.setElement( nullptr );
676 }
677 tmpXAODVertex->addTrackAtVertex(TEL,1.);
678 }
679 xaodVrtList.push_back(tmpXAODVertex); //VK Save xAOD::Vertex
680//
681 }
682//
683// Save momenta of all particles including combined at vertex positions
684//
685 std::vector<TLorentzVector> tmpMoms;
686 std::vector<std::vector<TLorentzVector> > particleMoms;
687 std::vector<Amg::MatrixX> particleCovs;
688 int allFitPrt=0;
689 for(iv=0; iv<(int)cVertices.size(); iv++){
690 tmpMoms.clear();
691 int NTrkF=fittedParticles[iv].size();
692 for(it=0; it< NTrkF; it++) {
693 tmpMoms.emplace_back( fittedParticles[iv][it].Px, fittedParticles[iv][it].Py,
694 fittedParticles[iv][it].Pz, fittedParticles[iv][it].E );
695 }
696 //CLHEP::HepSymMatrix COV( NTrkF*3+3, 0 );
697 Amg::MatrixX COV(NTrkF*3+3,NTrkF*3+3); COV=Amg::MatrixX::Zero(NTrkF*3+3,NTrkF*3+3);
698 for( it=0; it<NTrkF*3+3; it++){
699 for( jt=0; jt<=it; jt++){
700 COV(it,jt) = COV(jt,it) = fittedCovariance[iv][it*(it+1)/2+jt];
701 } }
702 particleMoms.push_back( std::move(tmpMoms) );
703 particleCovs.push_back( std::move(COV) );
704 allFitPrt += NTrkF;
705 }
706//
707 int NAPAR=(allFitPrt+cVertices.size())*3; //Full size of complete covariance matrix
708 //CLHEP::HepSymMatrix FULL( NAPAR, 0 );
709 Amg::MatrixX FULL(NAPAR,NAPAR); FULL.setZero();
710 if( !NDOFsqueezed ){ //normal cascade
711 for( it=0; it<NAPAR; it++){
712 for( jt=0; jt<=it; jt++){
713 FULL(it,jt) = FULL(jt,it) = fitFullCovariance[it*(it+1)/2+jt];
714 } }
715 }else{ //squeezed cascade
716 //int mcount=1; //Indexing in SUB starts from 1 !!!!
717 int mcount=0; //Indexing in BLOCK starts from 0 !!!!
718 for(iv=0; iv<(int)cstate.m_cascadeVList.size(); iv++){
719 //FULL.sub(mcount,particleCovs[iv]); mcount += particleCovs[iv].num_col();
720 FULL.block(mcount,mcount,particleCovs[iv].rows(),particleCovs[iv].cols())=particleCovs[iv];
721 mcount += particleCovs[iv].rows();
722 }
723 }
724//
725//
726// VxCascadeInfo * recCascade= new VxCascadeInfo(vxVrtList,particleMoms,particleCovs, NDOF ,fullChi2);
727 VxCascadeInfo * recCascade= new VxCascadeInfo(std::move(xaodVrtList),std::move(particleMoms),std::move(particleCovs), NDOF ,fullChi2);
728 recCascade->setFullCascadeCovariance(FULL);
729 CLEANCASCADE();
730 return recCascade;
731}
732
733#undef CLEANCASCADE
734
735
737 const std::vector<const xAOD::TrackParticle*> & tracksInConstraint,
738 const std::vector<VertexID> &pseudotracksInConstraint,
739 IVKalState& istate,
740 double massConstraint ) const
741{
742 assert(dynamic_cast<State*> (&istate)!=nullptr);
743 State& state = static_cast<State&> (istate);
744 CascadeState& cstate = *state.m_cascadeState;
745
746 int ivc, it, itc;
747 //int NV=m_cstate.cascadeVList.size(); // cascade size
748//----
749 if(Vertex < 0) return StatusCode::FAILURE;
750 //if(Vertex >= NV) return StatusCode::FAILURE; //Now this check is WRONG. Use indexInV(..) instead
751//
752//---- real tracks
753//
754 int cnstNTRK=tracksInConstraint.size(); // number of real tracks in constraints
755 int indexV = indexInV(Vertex, cstate); // index of vertex in cascade structure
756 if(indexV<0) return StatusCode::FAILURE;
757 int NTRK = cstate.m_cascadeVList[indexV].trkInVrt.size(); // number of real tracks in chosen vertex
758 int totNTRK = cstate.m_partListForCascade.size(); // total number of real tracks
759 if( cnstNTRK > NTRK ) return StatusCode::FAILURE;
760//-
761 PartialMassConstraint tmpMcnst;
762 tmpMcnst.Mass = massConstraint;
763 tmpMcnst.VRT = Vertex;
764//
765 double totMass=0;
766 for(itc=0; itc<cnstNTRK; itc++) {
767 for(it=0; it<totNTRK; it++) if(tracksInConstraint[itc]==cstate.m_partListForCascade[it]) break;
768 if(it==totNTRK) return StatusCode::FAILURE; //track in constraint doesn't correspond to any track in vertex
769 tmpMcnst.trkInVrt.push_back(it);
770 totMass += cstate.m_partMassForCascade[it];
771 }
772 if(totMass > massConstraint)return StatusCode::FAILURE;
773//
774//---- pseudo tracks
775//
776 int cnstNVP = pseudotracksInConstraint.size(); // number of pseudo-tracks in constraints
777 int NVP = cstate.m_cascadeVList[indexV].inPointingV.size(); // number of pseudo-tracks in chosen vertex
778 if( cnstNVP > NVP ) return StatusCode::FAILURE;
779//-
780 for(ivc=0; ivc<cnstNVP; ivc++) {
781 int tmpV = indexInV(pseudotracksInConstraint[ivc], cstate); // index of vertex in cascade structure
782 if( tmpV< 0) return StatusCode::FAILURE; //pseudotrack in constraint doesn't correspond to any pseudotrack in vertex
783 tmpMcnst.pseudoInVrt.push_back( pseudotracksInConstraint[ivc] );
784 }
785
786 cstate.m_partMassCnstForCascade.push_back(std::move(tmpMcnst));
787
788 return StatusCode::SUCCESS;
789}
790
791
792//----------------------------------------------------------------------------------------
793// Looks for index of each element of inputList in refList
794//
795int TrkVKalVrtFitter::findPositions(const std::vector<int> &inputList,const std::vector<int> &refList, std::vector<int> &index)
796{
797 int R,I;
798 index.clear();
799 int nI=inputList.size(); if(nI==0) return 0; //all ok
800 int nR=refList.size(); if(nR==0) return 0; //all ok
801 //std::cout<<"inp="; for(I=0; I<nI; I++)std::cout<<inputList[I]; std::cout<<'\n';
802 //std::cout<<"ref="; for(R=0; R<nR; R++)std::cout<<refList[R]; std::cout<<'\n';
803 for(I=0; I<nI; I++){
804 for(R=0; R<nR; R++) if(inputList[I]==refList[R]){index.push_back(R); break;}
805 if(R==nR) return -1; //input element not found in reference list
806 }
807 return 0;
808}
809//-----------------------------------------------------------------
810// Get index of given vertex in simplified cascade structure
811//
813 const CascadeState& cstate)
814{
815 int NVRT=cstate.m_cascadeVList.size();
816
817 int iv=indexInV(vrt, cstate);
818 if(iv<0) return -1; //not found
819
820 int ivv=0;
821 if(cstate.m_cascadeVList[iv].mergedTO){
822 for(ivv=0; ivv<NVRT; ivv++) if(cstate.m_cascadeVList[iv].mergedTO == cstate.m_cascadeVList[ivv].vID) break;
823 if(iv==NVRT) return -1; //not found
824 iv=ivv;
825 }
826 return cstate.m_cascadeVList[iv].indexInSimpleCascade;
827}
828//-----------------------------------------------------------------
829// Get index of given vertex in full cascade structure
830//
832 const CascadeState& cstate)
833{ int icv; int NVRT=cstate.m_cascadeVList.size();
834 for(icv=0; icv<NVRT; icv++) if(vrt==cstate.m_cascadeVList[icv].vID)break;
835 if(icv==NVRT)return -1;
836 return icv;
837}
838
839} // End Of Namespace
#define endmsg
#define ATH_MSG_DEBUG(x)
#define AmgSymMatrix(dim)
Base class for VKal state object.
int Sign(int in)
static Double_t sc
#define I(x, y, z)
Definition MD5.cxx:116
#define CLEANCASCADE()
static const Attributes_t empty
Class describing the Line to which the Perigee refers to.
Trk::RecVertex inherits from Trk::Vertex.
Definition RecVertex.h:44
std::vector< const xAOD::TrackParticle * > m_partListForCascade
std::vector< double > m_partMassForCascade
std::vector< PartialMassConstraint > m_partMassCnstForCascade
std::vector< cascadeV > m_cascadeVList
double m_apar[NTrMaxVFit][5]
double m_awgt[NTrMaxVFit][15]
std::unique_ptr< CascadeState > m_cascadeState
static int getSimpleVIndex(const VertexID &, const CascadeState &cstate)
StatusCode CvtTrackParameters(const std::vector< const TrackParameters * > &InpTrk, int &ntrk, State &state) const
void VKalVrtConfigureFitterCore(int NTRK, State &state) const
Gaudi::Property< bool > m_makeExtendedVertex
VertexID nextVertex(const std::vector< const xAOD::TrackParticle * > &list, std::span< const double > particleMass, IVKalState &istate, double massConstraint=0.) const override final
static int indexInV(const VertexID &, const CascadeState &cstate)
static int findPositions(const std::vector< int > &, const std::vector< int > &, std::vector< int > &)
static void makeSimpleCascade(std::vector< std::vector< int > > &, std::vector< std::vector< int > > &, CascadeState &cstate)
VertexID startVertex(const std::vector< const xAOD::TrackParticle * > &list, std::span< const double > particleMass, IVKalState &istate, double massConstraint=0.) const override final
Interface for cascade fit.
Gaudi::Property< bool > m_firstMeasuredPoint
static void printSimpleCascade(std::vector< std::vector< int > > &, std::vector< std::vector< int > > &, const CascadeState &cstate)
Gaudi::Property< double > m_cascadeCnstPrecision
VxCascadeInfo * fitCascade(IVKalState &istate, const Vertex *primVertex=0, bool FirstDecayAtPV=false) const override final
StatusCode CvtTrackParticle(std::span< const xAOD::TrackParticle *const > list, int &ntrk, State &state) const
StatusCode addMassConstraint(VertexID Vertex, const std::vector< const xAOD::TrackParticle * > &tracksInConstraint, const std::vector< VertexID > &verticesInConstraint, IVKalState &istate, double massConstraint) const override final
static int getCascadeNDoF(const CascadeState &cstate)
void renewCascadeEvent(CascadeEvent *)
const CascadeEvent * getCascadeEvent() const
This class is a simplest representation of a vertex candidate.
const Amg::Vector3D & position() const
return position of vertex
Definition Vertex.cxx:63
void setFullCascadeCovariance(const Amg::MatrixX &)
void addTrackAtVertex(const ElementLink< TrackParticleContainer > &tr, float weight=1.0)
Add a new track to the vertex.
void setCovariance(const std::vector< float > &value)
Sets the covariance matrix as a simple vector of values.
void setPosition(const Amg::Vector3D &position)
Sets the 3-position.
std::vector< Trk::VxTrackAtVertex > & vxTrackAtVertex()
Non-const access to the VxTrackAtVertex vector.
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
int SymIndex(int it, int i, int j)
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
void getFittedCascade(CascadeEvent &cascadeEvent_, std::vector< Vect3DF > &cVertices, std::vector< std::vector< double > > &covVertices, std::vector< std::vector< VectMOM > > &fittedParticles, std::vector< std::vector< double > > &cascadeCovar, std::vector< double > &particleChi2, std::vector< double > &fullCovar)
int processCascade(CascadeEvent &cascadeEvent_)
int setCascadeMassConstraint(CascadeEvent &cascadeEvent_, long int IV, double Mass)
CurvilinearParametersT< TrackParametersDim, Charged, PlaneSurface > CurvilinearParameters
int makeCascade(VKalVrtControl &FitCONTROL, long int NTRK, const long int *ich, double *wm, double *inp_Trk5, double *inp_CovTrk5, const std::vector< std::vector< int > > &vertexDefinition, const std::vector< std::vector< int > > &cascadeDefinition, double definedCnstAccuracy)
@ pz
global momentum (cartesian)
Definition ParamDefs.h:61
@ theta
Definition ParamDefs.h:66
@ phi
Definition ParamDefs.h:75
@ px
Definition ParamDefs.h:59
@ py
Definition ParamDefs.h:60
int processCascadePV(CascadeEvent &cascadeEvent_, const double *primVrt, const double *primVrtCov)
Definition index.py:1
Vertex_v1 Vertex
Define the latest version of the vertex class.
@ FirstMeasurement
Parameter defined at the position of the 1st measurement.
#define unlikely(x)
std::vector< VertexID > pseudoInVrt
std::vector< int > trkInVrt
std::vector< VertexID > mergedIN
std::vector< VertexID > inPointingV
std::vector< int > trkInVrt
MsgStream & msg
Definition testRead.cxx:32