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 <cmath>
12 #include <vector>
13 
14 namespace Trk{
15 
16  //constructor
17  SecVertexMergingTool::SecVertexMergingTool ( const std::string& t, const std::string& n, const IInterface* p )
18  : AthAlgTool ( t,n,p ),
19  m_Compatidime(1),
20  m_minDist(3),
21  m_iVertexFitter("Trk::AdaptiveVertexFitter", this )
22  {
23  declareInterface<IVertexMergingTool> ( this );
24  declareProperty("VertexFitterTool", m_iVertexFitter);
25  declareProperty("CompatibilityDimension", m_Compatidime, "0 for z0, 1 for d0, 2 for all" ) ;
26  declareProperty("MininumDistance", m_minDist, "in sigma" ) ;
27  }
28 
29  //destructor
31 
32 //initialize
34  {
35 
36  if ( m_iVertexFitter.retrieve().isFailure() ) {
37  ATH_MSG_ERROR("Failed to retrieve tool " << m_iVertexFitter);
38  return StatusCode::FAILURE;
39  }
40 
41  ATH_MSG_DEBUG("Re-merging tool initialization successful");
42  return StatusCode::SUCCESS;
43  }
44 
46  {
47  return StatusCode::SUCCESS;
48  }
49 
50  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
52  const xAOD::VertexContainer& MyVxCont) const
53 
54  {
55 
56  ATH_MSG_DEBUG("Run vertex remerging");
57 
58  // new output containers to be filled
59  xAOD::VertexContainer* NewContainer = new xAOD::VertexContainer();
60  xAOD::VertexAuxContainer* auxNewContainer = new xAOD::VertexAuxContainer();
61  NewContainer->setStore(auxNewContainer);
62 
63  static const SG::Decorator<float> mDecor_sumPt2("sumPt2");
64  static const SG::Decorator<float> mDecor_mass("mass");
65  static const SG::Decorator<float> mDecor_energy("ee");
66  static const SG::Decorator<int> mDecor_nrobbed("nrobbed");
67  static const SG::Decorator<int> mDecor_intrk("NumInputTrk");
68 
69  static const SG::Accessor<float> mAcc_sumPt2("sumPt2");
70  static const SG::Accessor<int> mAcc_momdir ("MomentaDirection");
71  static const SG::Accessor<float> mAcc_mass("mass");
72  static const SG::Accessor<float> mAcc_energy("ee");
73  static const SG::Accessor<int> mAcc_intrk("NumInputTrk");
74  static const SG::Accessor<float> mAcc_radpat("radiiPattern");
75  static const SG::Accessor<std::vector<float> > mAcc_trkwt("trkWeight");
76  static const SG::Accessor<int> mAcc_numtav("NumTrkAtVtx");
77  static const SG::Accessor<std::vector<float> > mAcc_trkdoe("trkDistOverError");
78 
79  bool moreDeco = mAcc_momdir.isAvailable(*MyVxCont.front());
80 
81  if (!moreDeco)
82  ATH_MSG_DEBUG("Missing decoration !!! ");
83 
92  // add remerged flags to all
93  std::vector<bool> remerged(MyVxCont.size(), false);
94 
95  xAOD::VertexContainer::const_iterator beginIter = MyVxCont.begin();
96  xAOD::VertexContainer::const_iterator endIter = MyVxCont.end();
97  unsigned int Ni = 0;
98  for (xAOD::VertexContainer::const_iterator i = beginIter; i != endIter;
99  ++i, Ni++) {
100  xAOD::Vertex* vx = new xAOD::Vertex(**i);
101 
102  if (remerged[Ni])
103  continue; // skip vertices already merged into another
104 
105  std::vector<const xAOD::TrackParticle*> combinedTracks;
106  std::vector<ElementLink<xAOD::TrackParticleContainer>> tpLinks1 =
107  vx->trackParticleLinks();
108  if (!tpLinks1.empty()) {
109  for (const auto& tp_EL : tpLinks1) {
110  const xAOD::TrackParticle* trk = *tp_EL;
111  combinedTracks.push_back(trk);
112  }
113 
114  unsigned int Nj = Ni + 1;
115  bool newmerge = false;
116  for (xAOD::VertexContainer::const_iterator j = i + 1; j != endIter;
117  ++j, Nj++) {
118  const xAOD::Vertex* mergeCand = (*j);
119  if (remerged[Nj])
120  continue;
121 
122  if (newmerge) {
123  combinedTracks.clear();
124  tpLinks1 = vx->trackParticleLinks();
125  if (tpLinks1.empty())
126  break;
127  for (const auto& tp_EL : tpLinks1) {
128  const xAOD::TrackParticle* trk = *tp_EL;
129  combinedTracks.push_back(trk);
130  }
131  newmerge = false;
132  }
133 
134  // not dummy and not already merged into earlier vertex, so consider
135  // it as merging candidate
136  if (!checkCompatibility(vx, mergeCand))
137  continue;
138 
139  ATH_MSG_DEBUG("To merge vertices " << Ni << " and " << Nj);
140  // get all the track particles to fit
141 
142  const std::vector<ElementLink<xAOD::TrackParticleContainer>>
143  tpLinks2 = mergeCand->trackParticleLinks();
144  if (tpLinks2.empty())
145  continue;
146 
147  for (const auto& tp_EL : tpLinks2) {
148  const xAOD::TrackParticle* trk = *tp_EL;
149  combinedTracks.push_back(trk);
150  }
151 
152  ATH_MSG_DEBUG("Tracks input : " << tpLinks1.size() << " + "
153  << tpLinks2.size());
154 
155  // call the fitter -> using xAOD::TrackParticle it should set the
156  // track links for us
157  xAOD::Vertex* mergedVtx = nullptr;
158  // no interface for no constraint and no starting point, so use
159  // starting point of original vertex
160  Amg::Vector3D start(0.5 * (vx->position() + mergeCand->position()));
161  mergedVtx = m_iVertexFitter->fit(combinedTracks, start);
162 
163  ATH_MSG_DEBUG("Merged vertices " << mergedVtx->nTrackParticles());
164 
165  remerged[Nj] = true;
166  remerged[Ni] = true;
167  newmerge = true;
168 
169  // update the decors
170  float pt1 = sqrt(mAcc_sumPt2(*vx));
171  float pt2 = sqrt(mAcc_sumPt2(*mergeCand));
172  float ntrk1 = 1.0 * ((vx->trackParticleLinks()).size());
173  float ntrk2 = 1.0 * ((mergeCand->trackParticleLinks()).size());
174  float wght1 =
175  0.6 * pt1 / (pt1 + pt2) + 0.4 * ntrk1 / (ntrk1 + ntrk2);
176  float wght2 =
177  0.6 * pt2 / (pt1 + pt2) + 0.4 * ntrk2 / (ntrk1 + ntrk2);
178 
180  xAOD::VxType::VertexType typ2 = mergeCand->vertexType();
181  float mas1 = mAcc_mass(*vx);
182  float mas2 = mAcc_mass(*mergeCand);
183  float e1 = mAcc_energy(*vx);
184  float e2 = mAcc_energy(*mergeCand);
185  int inNtrk1 = mAcc_intrk(*vx);
186  int inNtrk2 = mAcc_intrk(*mergeCand);
187 
188  int ntrks = 0;
189  float md1 = 0., md2 = 0., hf1 = 0., hf2 = 0.;
190  std::vector<float> trkW1, trkW2, doe1, doe2;
191  if (moreDeco) {
192  doe1 = mAcc_trkdoe(*vx);
193  doe2 = mAcc_trkdoe(*mergeCand);
194  doe2.insert(doe2.end(), doe1.begin(), doe1.end());
195  md1 = mAcc_momdir(*vx);
196  md2 = mAcc_momdir(*mergeCand);
197  hf1 = mAcc_radpat(*vx);
198  hf2 = mAcc_radpat(*mergeCand);
199  trkW1 = mAcc_trkwt(*vx);
200  trkW2 = mAcc_trkwt(*mergeCand);
201  trkW2.insert(trkW2.end(), trkW1.begin(), trkW1.end());
202  ntrks = mAcc_numtav(*vx) + mAcc_numtav(*mergeCand);
203  }
204 
205  // delete copy of first vertex and then overwrite with merged vertex
206  delete vx;
207  vx = mergedVtx;
208 
209  if (wght1 >= wght2)
210  vx->setVertexType(typ1);
211  else
212  vx->setVertexType(typ2);
213 
214  if (moreDeco) {
215  mAcc_trkdoe(*vx) = doe2;
216  mAcc_momdir(*vx) = wght1 * md1 + wght2 * md2;
217  mAcc_radpat(*vx) = wght1 * hf1 + wght2 * hf2;
218  mAcc_trkwt(*vx) = trkW2;
219  mAcc_numtav(*vx) = ntrks;
220  }
221 
222  mDecor_sumPt2(*vx) = pt1 * pt1 + pt2 * pt2;
223  mDecor_mass(*vx) = wght1 * mas1 + wght2 * mas2;
224  mDecor_energy(*vx) = wght1 * e1 + wght2 * e2;
225  mDecor_nrobbed(*vx) = 0;
226  mDecor_intrk(*vx) = (int)(wght1 * inNtrk1 + wght1 * inNtrk2);
227 
228  } // loop over j
229  } // if vx found partner in compatibility
230 
231  ATH_MSG_DEBUG("Merged sumPt2 " << mAcc_sumPt2(*vx));
232 
233  // whether we merged or not, can add vx to the container
234  if (vx != nullptr)
235  NewContainer->push_back(vx);
236  }
237 
238  return std::make_pair(NewContainer, auxNewContainer);
239 
240  }
241 
242  bool
244  const xAOD::Vertex* v2) const
245  {
246 
247  float sigma = 100 ;
248 
249  Amg::Vector3D vdif = v1->position() - v2->position() ;
250  AmgSymMatrix(3) vErrs = v1->covariancePosition() + v2->covariancePosition() ;
251  vErrs = vErrs.inverse().eval();
252 
253  if ( m_Compatidime == 2 ) // 3 dimension
254  {
255  sigma = sqrt( vdif.dot( vErrs * vdif ) ) ;
256  } else if ( m_Compatidime == 1 ) // d0
257  {
258  sigma = vdif(0)*vdif(0)*vErrs(0,0) + vdif(1)*vdif(1)*vErrs(1,1) + 2*vdif(0)*vdif(1)*vErrs(0,1) ;
259  sigma = std::sqrt( sigma ) ;
260 
261  } else { // z0
262 
263  sigma = vdif(2)*sqrt( vErrs(2,2) );
264  }
265 
266 // ATH_MSG_DEBUG(" Compatibility/significance when merging vertices : " << sigma );
267  ATH_MSG_DEBUG(" Compatibility/significance when merging vertices : " << sigma );
268 
269  return sigma < m_minDist;
270 
271  }
272 
273 }
Trk::SecVertexMergingTool::mergeVertexContainer
virtual std::pair< xAOD::VertexContainer *, xAOD::VertexAuxContainer * > mergeVertexContainer(const xAOD::VertexContainer &MyVxCont) const override
Merging
Definition: SecVertexMergingTool.cxx:51
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
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
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
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:85
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:794
Trk::SecVertexMergingTool::checkCompatibility
bool checkCompatibility(const xAOD::Vertex *vx1, const xAOD::Vertex *vx2) const
Definition: SecVertexMergingTool.cxx:243
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:33
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
Trk::SecVertexMergingTool::finalize
virtual StatusCode finalize() override
EndOfInitialize.
Definition: SecVertexMergingTool.cxx:45
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:17