ATLAS Offline Software
SecVertexMergingTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 //Author: Lianyou Shan <lianyou.shan@cern.ch>
5 
11 #include <vector>
12 
13 namespace Trk{
14 
15  //constructor
16  SecVertexMergingTool::SecVertexMergingTool ( const std::string& t, const std::string& n, const IInterface* p )
17  : AthAlgTool ( t,n,p ),
18  m_Compatidime(1),
19  m_minDist(3),
20  m_iVertexFitter("Trk::AdaptiveVertexFitter", this )
21  {
22  declareInterface<IVertexMergingTool> ( this );
23  declareProperty("VertexFitterTool", m_iVertexFitter);
24  declareProperty("CompatibilityDimension", m_Compatidime, "0 for z0, 1 for d0, 2 for all" ) ;
25  declareProperty("MininumDistance", m_minDist, "in sigma" ) ;
26  }
27 
28  //destructor
30 
31 //initialize
33  {
34 
35  if ( m_iVertexFitter.retrieve().isFailure() ) {
36  ATH_MSG_ERROR("Failed to retrieve tool " << m_iVertexFitter);
37  return StatusCode::FAILURE;
38  }
39 
40  ATH_MSG_DEBUG("Re-merging tool initialization successful");
41  return StatusCode::SUCCESS;
42  }
43 
45  {
46  return StatusCode::SUCCESS;
47  }
48 
49  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
51  const xAOD::VertexContainer& MyVxCont) const
52 
53  {
54 
55  ATH_MSG_DEBUG("Run vertex remerging");
56 
57  // new output containers to be filled
58  xAOD::VertexContainer* NewContainer = new xAOD::VertexContainer();
59  xAOD::VertexAuxContainer* auxNewContainer = new xAOD::VertexAuxContainer();
60  NewContainer->setStore(auxNewContainer);
61 
62  static const SG::Decorator<float> mDecor_sumPt2("sumPt2");
63  static const SG::Decorator<float> mDecor_mass("mass");
64  static const SG::Decorator<float> mDecor_energy("ee");
65  static const SG::Decorator<int> mDecor_nrobbed("nrobbed");
66  static const SG::Decorator<int> mDecor_intrk("NumInputTrk");
67 
68  static const SG::Accessor<float> mAcc_sumPt2("sumPt2");
69  static const SG::Accessor<int> mAcc_momdir ("MomentaDirection");
70  static const SG::Accessor<float> mAcc_mass("mass");
71  static const SG::Accessor<float> mAcc_energy("ee");
72  static const SG::Accessor<int> mAcc_intrk("NumInputTrk");
73  static const SG::Accessor<float> mAcc_radpat("radiiPattern");
74  static const SG::Accessor<std::vector<float> > mAcc_trkwt("trkWeight");
75  static const SG::Accessor<int> mAcc_numtav("NumTrkAtVtx");
76  static const SG::Accessor<std::vector<float> > mAcc_trkdoe("trkDistOverError");
77 
78  bool moreDeco = mAcc_momdir.isAvailable(*MyVxCont.front());
79 
80  if (!moreDeco)
81  ATH_MSG_DEBUG("Missing decoration !!! ");
82 
91  // add remerged flags to all
92  std::vector<bool> remerged(MyVxCont.size(), false);
93 
94  xAOD::VertexContainer::const_iterator beginIter = MyVxCont.begin();
95  xAOD::VertexContainer::const_iterator endIter = MyVxCont.end();
96  unsigned int Ni = 0;
97  for (xAOD::VertexContainer::const_iterator i = beginIter; i != endIter;
98  ++i, Ni++) {
99  xAOD::Vertex* vx = new xAOD::Vertex(**i);
100 
101  if (remerged[Ni])
102  continue; // skip vertices already merged into another
103 
104  std::vector<const xAOD::TrackParticle*> combinedTracks;
105  std::vector<ElementLink<xAOD::TrackParticleContainer>> tpLinks1 =
106  vx->trackParticleLinks();
107  if (!tpLinks1.empty()) {
108  for (const auto& tp_EL : tpLinks1) {
109  const xAOD::TrackParticle* trk = *tp_EL;
110  combinedTracks.push_back(trk);
111  }
112 
113  unsigned int Nj = Ni + 1;
114  bool newmerge = false;
115  for (xAOD::VertexContainer::const_iterator j = i + 1; j != endIter;
116  ++j, Nj++) {
117  const xAOD::Vertex* mergeCand = (*j);
118  if (remerged[Nj])
119  continue;
120 
121  if (newmerge) {
122  combinedTracks.clear();
123  tpLinks1 = vx->trackParticleLinks();
124  if (tpLinks1.empty())
125  break;
126  for (const auto& tp_EL : tpLinks1) {
127  const xAOD::TrackParticle* trk = *tp_EL;
128  combinedTracks.push_back(trk);
129  }
130  newmerge = false;
131  }
132 
133  // not dummy and not already merged into earlier vertex, so consider
134  // it as merging candidate
135  if (!checkCompatibility(vx, mergeCand))
136  continue;
137 
138  ATH_MSG_DEBUG("To merge vertices " << Ni << " and " << Nj);
139  // get all the track particles to fit
140 
141  const std::vector<ElementLink<xAOD::TrackParticleContainer>>
142  tpLinks2 = mergeCand->trackParticleLinks();
143  if (tpLinks2.empty())
144  continue;
145 
146  for (const auto& tp_EL : tpLinks2) {
147  const xAOD::TrackParticle* trk = *tp_EL;
148  combinedTracks.push_back(trk);
149  }
150 
151  ATH_MSG_DEBUG("Tracks input : " << tpLinks1.size() << " + "
152  << tpLinks2.size());
153 
154  // call the fitter -> using xAOD::TrackParticle it should set the
155  // track links for us
156  xAOD::Vertex* mergedVtx = nullptr;
157  // no interface for no constraint and no starting point, so use
158  // starting point of original vertex
159  Amg::Vector3D start(0.5 * (vx->position() + mergeCand->position()));
160  mergedVtx = m_iVertexFitter->fit(combinedTracks, start);
161 
162  ATH_MSG_DEBUG("Merged vertices " << mergedVtx->nTrackParticles());
163 
164  remerged[Nj] = true;
165  remerged[Ni] = true;
166  newmerge = true;
167 
168  // update the decors
169  float pt1 = sqrt(mAcc_sumPt2(*vx));
170  float pt2 = sqrt(mAcc_sumPt2(*mergeCand));
171  float ntrk1 = 1.0 * ((vx->trackParticleLinks()).size());
172  float ntrk2 = 1.0 * ((mergeCand->trackParticleLinks()).size());
173  float wght1 =
174  0.6 * pt1 / (pt1 + pt2) + 0.4 * ntrk1 / (ntrk1 + ntrk2);
175  float wght2 =
176  0.6 * pt2 / (pt1 + pt2) + 0.4 * ntrk2 / (ntrk1 + ntrk2);
177 
179  xAOD::VxType::VertexType typ2 = mergeCand->vertexType();
180  float mas1 = mAcc_mass(*vx);
181  float mas2 = mAcc_mass(*mergeCand);
182  float e1 = mAcc_energy(*vx);
183  float e2 = mAcc_energy(*mergeCand);
184  int inNtrk1 = mAcc_intrk(*vx);
185  int inNtrk2 = mAcc_intrk(*mergeCand);
186 
187  int ntrks = 0;
188  float md1 = 0., md2 = 0., hf1 = 0., hf2 = 0.;
189  std::vector<float> trkW1, trkW2, doe1, doe2;
190  if (moreDeco) {
191  doe1 = mAcc_trkdoe(*vx);
192  doe2 = mAcc_trkdoe(*mergeCand);
193  doe2.insert(doe2.end(), doe1.begin(), doe1.end());
194  md1 = mAcc_momdir(*vx);
195  md2 = mAcc_momdir(*mergeCand);
196  hf1 = mAcc_radpat(*vx);
197  hf2 = mAcc_radpat(*mergeCand);
198  trkW1 = mAcc_trkwt(*vx);
199  trkW2 = mAcc_trkwt(*mergeCand);
200  trkW2.insert(trkW2.end(), trkW1.begin(), trkW1.end());
201  ntrks = mAcc_numtav(*vx) + mAcc_numtav(*mergeCand);
202  }
203 
204  // delete copy of first vertex and then overwrite with merged vertex
205  delete vx;
206  vx = mergedVtx;
207 
208  if (wght1 >= wght2)
209  vx->setVertexType(typ1);
210  else
211  vx->setVertexType(typ2);
212 
213  if (moreDeco) {
214  mAcc_trkdoe(*vx) = doe2;
215  mAcc_momdir(*vx) = wght1 * md1 + wght2 * md2;
216  mAcc_radpat(*vx) = wght1 * hf1 + wght2 * hf2;
217  mAcc_trkwt(*vx) = trkW2;
218  mAcc_numtav(*vx) = ntrks;
219  }
220 
221  mDecor_sumPt2(*vx) = pt1 * pt1 + pt2 * pt2;
222  mDecor_mass(*vx) = wght1 * mas1 + wght2 * mas2;
223  mDecor_energy(*vx) = wght1 * e1 + wght2 * e2;
224  mDecor_nrobbed(*vx) = 0;
225  mDecor_intrk(*vx) = (int)(wght1 * inNtrk1 + wght1 * inNtrk2);
226 
227  } // loop over j
228  } // if vx found partner in compatibility
229 
230  ATH_MSG_DEBUG("Merged sumPt2 " << mAcc_sumPt2(*vx));
231 
232  // whether we merged or not, can add vx to the container
233  if (vx != nullptr)
234  NewContainer->push_back(vx);
235  }
236 
237  return std::make_pair(NewContainer, auxNewContainer);
238 
239  }
240 
241  bool
243  const xAOD::Vertex* v2) const
244  {
245 
246  float sigma = 100 ;
247 
248  Amg::Vector3D vdif = v1->position() - v2->position() ;
249  AmgSymMatrix(3) vErrs = v1->covariancePosition() + v2->covariancePosition() ;
250  vErrs = vErrs.inverse().eval();
251 
252  if ( m_Compatidime == 2 ) // 3 dimension
253  {
254  sigma = sqrt( vdif.dot( vErrs * vdif ) ) ;
255  } else if ( m_Compatidime == 1 ) // d0
256  {
257  sigma = vdif(0)*vdif(0)*vErrs(0,0) + vdif(1)*vdif(1)*vErrs(1,1) + 2*vdif(0)*vdif(1)*vErrs(0,1) ;
258  sigma = sqrt( sigma ) ;
259 
260  } else { // z0
261 
262  sigma = vdif(2)*sqrt( vErrs(2,2) );
263  }
264 
265 // ATH_MSG_DEBUG(" Compatibility/significance when merging vertices : " << sigma );
266  ATH_MSG_DEBUG(" Compatibility/significance when merging vertices : " << sigma );
267 
268  return sigma < m_minDist;
269 
270  }
271 
272 }
Trk::SecVertexMergingTool::mergeVertexContainer
virtual std::pair< xAOD::VertexContainer *, xAOD::VertexAuxContainer * > mergeVertexContainer(const xAOD::VertexContainer &MyVxCont) const override
Merging
Definition: SecVertexMergingTool.cxx:50
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
xAOD::Vertex_v1::nTrackParticles
size_t nTrackParticles() const
Get the number of tracks associated with this vertex.
Definition: Vertex_v1.cxx:270
xAOD::VertexAuxContainer_v1
Temporary container used until we have I/O for AuxStoreInternal.
Definition: VertexAuxContainer_v1.h:32
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
xAOD::Vertex
Vertex_v1 Vertex
Define the latest version of the vertex class.
Definition: Event/xAOD/xAODTracking/xAODTracking/Vertex.h:16
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
SG::Accessor< float >
egammaEnergyPositionAllSamples::e1
double e1(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 1st sampling
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
xAOD::Vertex_v1::trackParticleLinks
const TrackParticleLinks_t & trackParticleLinks() const
Get all the particles associated with the vertex.
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
Trk::SecVertexMergingTool::m_minDist
float m_minDist
Definition: SecVertexMergingTool.h:66
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
xAOD::VertexContainer
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Definition: VertexContainer.h:14
IVertexWeightCalculator.h
xAOD::Vertex_v1::vertexType
VxType::VertexType vertexType() const
The type of the vertex.
xAOD::VxType::VertexType
VertexType
Vertex types.
Definition: TrackingPrimitives.h:569
Trk::AmgSymMatrix
AmgSymMatrix(5) &GXFTrackState
Definition: GXFTrackState.h:156
xAOD::Vertex_v1::setVertexType
void setVertexType(VxType::VertexType vType)
Set the type of the vertex.
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
Trk::SecVertexMergingTool::m_iVertexFitter
ToolHandle< Trk::IVertexFitter > m_iVertexFitter
Definition: SecVertexMergingTool.h:67
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::Decorator< float >
xAOD::VertexAuxContainer
VertexAuxContainer_v1 VertexAuxContainer
Definition of the current jet auxiliary container.
Definition: VertexAuxContainer.h:19
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
DataVector::front
const T * front() const
Access the first element in the collection as an rvalue.
VxTrackAtVertex.h
SecVertexMergingTool.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
Trk::SecVertexMergingTool::checkCompatibility
bool checkCompatibility(const xAOD::Vertex *vx1, const xAOD::Vertex *vx2) const
Definition: SecVertexMergingTool.cxx:242
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Accessor.h
Helper class to provide type-safe access to aux data.
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::SecVertexMergingTool::~SecVertexMergingTool
virtual ~SecVertexMergingTool()
destructor
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
ReadCellNoiseFromCoolCompare.v2
v2
Definition: ReadCellNoiseFromCoolCompare.py:364
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
egammaEnergyPositionAllSamples::e2
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Trk::SecVertexMergingTool::initialize
virtual StatusCode initialize() override
Definition: SecVertexMergingTool.cxx:32
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
Trk::SecVertexMergingTool::finalize
virtual StatusCode finalize() override
EndOfInitialize.
Definition: SecVertexMergingTool.cxx:44
AthAlgTool
Definition: AthAlgTool.h:26
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
Decorator.h
Helper class to provide type-safe access to aux data.
Trk::SecVertexMergingTool::m_Compatidime
int m_Compatidime
Definition: SecVertexMergingTool.h:65
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Trk::SecVertexMergingTool::SecVertexMergingTool
SecVertexMergingTool(const std::string &t, const std::string &n, const IInterface *p)
constructor
Definition: SecVertexMergingTool.cxx:16