ATLAS Offline Software
NewVrtSecInclusiveAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3  */
4 
6  // NewVrtSecInclusiveAlg.cxx, (c) ATLAS Detector software
7  // Author: Vadim Kostyukhin (vadim.kostyukhin@cern.ch)
14 
15 #include "TLorentzVector.h"
16 #include "CxxUtils/sincos.h"
17 
18 namespace Rec {
19 
20  static const SG::AuxElement::Decorator<float> bvrtM("bvrtM");
21  static const SG::AuxElement::Decorator<float> bvrtPt("bvrtPt");
22  static const SG::AuxElement::Decorator<float> bvrtPhi("bvrtPhi");
23  static const SG::AuxElement::Decorator<float> bvrtEta("bvrtEta");
24  static const SG::AuxElement::Decorator<float> mindRjetP("mindRjetP");
25  static const SG::AuxElement::Decorator<float> mindRjetV("mindRjetV");
26  static const SG::AuxElement::Decorator<float> mindRBTagSV("mindRBTagSV");
27 
28  NewVrtSecInclusiveAlg::NewVrtSecInclusiveAlg(const std::string& name, ISvcLocator* pSvcLocator) :
29  AthReentrantAlgorithm( name, pSvcLocator )
30  {
31  }
32 
34  {
39  ATH_CHECK( m_pvContainerKey.initialize() );
41  ATH_CHECK( m_btsvContainerKey.initialize() );
42  ATH_CHECK( m_foundVerticesKey.initialize() );
43  ATH_CHECK( m_bvertextool.retrieve() );
44  return StatusCode::SUCCESS;
45  }
46 
48  {
49  return StatusCode::SUCCESS;
50  }
51 
52  StatusCode NewVrtSecInclusiveAlg::execute(const EventContext &ctx) const
53  {
54 
55  const xAOD::Vertex* pv = nullptr;
56  std::unordered_set<const xAOD::TrackParticle*> tp_set{};
57  if (m_addIDTracks) addInDetTracks(ctx, tp_set);
58  if (m_addMuonTracks) addMuonTracks(ctx, tp_set);
59  if (m_addGSFTracks) addGSFTracks(ctx, tp_set);
60  if (m_addElectronTracks) addElectronTracks(ctx, tp_set);
61  ATH_MSG_DEBUG("Found " << tp_set.size() << " useful tracks in this event" );
62 
63  std::vector<const xAOD::TrackParticle*> trkparticles(tp_set.begin(), tp_set.end());
64 
65  //-- Extract Primary Vertex
67  if ( !pv_cont.isValid() ) {
68  ATH_MSG_WARNING( "No Primary Vertices container found in TDS" );
69  }else{
70  //-- Extract PV itself
71  for ( const auto *v : *pv_cont ) {
72  if (v->vertexType()==xAOD::VxType::PriVtx) { pv = v; break; }
73  }
74  }
75 
76  //-- Extract SV from b-jets Vertices
78  if ( !btsv_cont.isValid() ) {
79  ATH_MSG_WARNING( "No BTagging Vertices container found in TDS" );
80  }
81 
82  //-- Extract Jets
84  if ( !jet_cont.isValid() ) {
85  ATH_MSG_WARNING( "No AntiKt4EMPFlowJet container found in TES" );
86  }
87 
88  //-- create container for new vertices
89  auto bVertexContainer = std::make_unique<xAOD::VertexContainer>();
90  auto bVertexAuxContainer = std::make_unique<xAOD::VertexAuxContainer>();
91  bVertexContainer->setStore(bVertexAuxContainer.get());
92 
93  if( pv && trkparticles.size()>1 ){
94  std::unique_ptr<Trk::VxSecVertexInfo> foundVrts = m_bvertextool->findAllVertices(trkparticles,*pv);
95  if(foundVrts && !foundVrts->vertices().empty()){
96  const std::vector<xAOD::Vertex*> vtmp=foundVrts->vertices();
97  double mindRSVPV=1.e3; // Check coincidence with existing SV1 vertex
98  for(const auto & iv : vtmp) {
99  if( btsv_cont.isValid() ){
100  for ( const auto *btsv : *btsv_cont ) mindRSVPV=std::min(Amg::deltaR(btsv->position()-pv->position(),iv->position()-pv->position()),mindRSVPV);
101  }
102  if (m_removeNonLepVerts && vertexHasNoLep(ctx, iv)) {
103  delete iv;
104  continue;
105  }
106  bVertexContainer->push_back(iv);
107  std::vector< Trk::VxTrackAtVertex > & vtrk = iv->vxTrackAtVertex();
108  TLorentzVector VSUM(0.,0.,0.,0.);
109  TLorentzVector tmp;
110  for(auto & it : vtrk){
111  const Trk::Perigee* mPer = dynamic_cast<const Trk::Perigee*>(it.perigeeAtVertex());
112  CxxUtils::sincos phi(mPer->parameters()[Trk::phi]);
113  CxxUtils::sincos theta(mPer->parameters()[Trk::theta]);
114  double absP = 1./std::abs(mPer->parameters()[Trk::qOverP]);
115  tmp.SetXYZM( phi.cs*theta.sn*absP, phi.sn*theta.sn*absP, theta.cs*absP, Trk::ParticleMasses::mass[Trk::pion]);
116  VSUM+=tmp;
117  }
118  bvrtM(*iv) =VSUM.M();
119  bvrtPt(*iv) =VSUM.Pt();
120  bvrtEta(*iv)=VSUM.Eta();
121  bvrtPhi(*iv)=VSUM.Phi();
122  TVector3 SVmPV(iv->x()-pv->x(),iv->y()-pv->y(),iv->z()-pv->z());
123  double mindRMOM=1.e3, mindRSV=1.e3;
124  if( jet_cont.isValid() ){
125  for(const auto *jet : (*jet_cont)) {
126  mindRMOM=std::min(VSUM.DeltaR(jet->p4()),mindRMOM);
127  mindRSV =std::min(SVmPV.DeltaR(jet->p4().Vect()),mindRSV);
128  }
129  }
130  mindRBTagSV(*iv) =mindRSVPV;
131  mindRjetP(*iv) =mindRMOM;
132  mindRjetV(*iv) =mindRSV;
133  }
134  }
135  }
136  ATH_MSG_DEBUG("Found Vertices in this event: " << bVertexContainer->size());
137  //
138  //--Update track ElementLinks
139  for(auto iv : (*bVertexContainer)){
140  std::vector< ElementLink< xAOD::TrackParticleContainer > > newLinkVec;
141  for(auto &it : iv->trackParticleLinks()){
143  const xAOD::TrackParticleContainer* tp_cont = dynamic_cast<const xAOD:: TrackParticleContainer*>((*it)->container());
144  tmpLnk.setStorableObject(*tp_cont);
145  newLinkVec.push_back(tmpLnk);
146  }
147  iv->setTrackParticleLinks(newLinkVec);
148  }
149 
151  ATH_CHECK( vrtInThisEvent.record (std::move(bVertexContainer),
152  std::move(bVertexAuxContainer)) );
153  return StatusCode::SUCCESS;
154  }
155 
156  void NewVrtSecInclusiveAlg::addInDetTracks(const EventContext &ctx, std::unordered_set<const xAOD::TrackParticle*> &trkparticles) const {
157  //-- Extract IDTrackParticles
159  if ( !tp_cont.isValid() ) {
160  ATH_MSG_WARNING( "No TrackParticle container found in TES" );
161  return;
162  }
163  trkparticles.reserve(trkparticles.size() + tp_cont->size());
164 
165  for (const auto *tp : (*tp_cont)) { trkparticles.insert(tp); }
166  }
167 
168  void NewVrtSecInclusiveAlg::addMuonTracks(const EventContext &ctx, std::unordered_set<const xAOD::TrackParticle*> &trkparticles) const {
169  //-- Extract Muons
171  if ( !muon_cont.isValid() ) {
172  ATH_MSG_WARNING( "No muon container found in TES" );
173  return;
174  }
175  trkparticles.reserve(trkparticles.size() + muon_cont->size());
176 
177  for (const auto *muon : (*muon_cont)) {
178  const auto *tp = muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
179  if (!tp) { continue; }
180  trkparticles.insert(tp);
181  }
182  }
183 
184  void NewVrtSecInclusiveAlg::addGSFTracks(const EventContext &ctx, std::unordered_set<const xAOD::TrackParticle*> &trkparticles) const {
185  //-- Extract GSFTrackParticles
187  if ( !gsf_cont.isValid() ) {
188  ATH_MSG_WARNING( "No GSF container found in TES" );
189  return;
190  }
191  trkparticles.reserve(trkparticles.size() + gsf_cont->size());
192 
193  for (const auto *gsf : (*gsf_cont)) {
194  trkparticles.insert(gsf);
195  // remove the corresponding ID track from the list if it exists already.
197  }
198  }
199 
200  void NewVrtSecInclusiveAlg::addElectronTracks(const EventContext &ctx, std::unordered_set<const xAOD::TrackParticle*> &trkparticles) const {
201  //-- Extract Electrons
203  if ( !electron_cont.isValid() ) {
204  ATH_MSG_WARNING( "No electron container found in TES" );
205  return;
206  }
207  trkparticles.reserve(trkparticles.size() + electron_cont->size());
208 
209  for(const auto *electron : (*electron_cont)) {
210  if( 0 == electron->nTrackParticles() ) continue;
211  // the 0th GSF TP is the best matched one.
212  const auto *gsf = electron->trackParticle(0);
213  if (!gsf) continue;
214  trkparticles.insert(gsf);
215  // remove the corresponding ID track from the list if it exists already.
217  }
218  }
219 
220  bool NewVrtSecInclusiveAlg::vertexHasNoLep(const EventContext &ctx, const xAOD::Vertex* vertex) const {
221  std::unordered_set<const xAOD::TrackParticle*> trkparts{};
222  trkparts.reserve(vertex->nTrackParticles());
223  for (const auto &trk : vertex->trackParticleLinks()) {
224  trkparts.insert(*trk);
225  }
226 
227  //-- Extract Muons
229  if ( muon_cont.isValid() ) {
230  for (const auto *muon : (*muon_cont)) {
231  const auto *tp = muon->trackParticle( xAOD::Muon::InnerDetectorTrackParticle );
232  if (!tp) { continue; }
233  if(trkparts.count(tp)) return false;
234  }
235  }
236 
237  //-- Extract Electrons
239  if ( electron_cont.isValid() ) {
240  for(const auto *electron : (*electron_cont)) {
241  if( 0 == electron->nTrackParticles() ) continue;
242  // the 0th GSF TP is the best matched one.
243  const auto *gsf = electron->trackParticle(0);
244  if (!gsf) continue;
245  if(trkparts.count(gsf)) return false;
246  if(trkparts.count(xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF(gsf))) return false;
247  }
248  }
249  // If both containers are missing, or no leptons are found in the vertex, return true.
250  return true;
251  }
252 }
253 
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:196
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
Rec::NewVrtSecInclusiveAlg::execute
StatusCode execute(const EventContext &ctx) const override
Definition: NewVrtSecInclusiveAlg.cxx:52
Rec::NewVrtSecInclusiveAlg::vertexHasNoLep
bool vertexHasNoLep(const EventContext &, const xAOD::Vertex *) const
Definition: NewVrtSecInclusiveAlg.cxx:220
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
Trk::VxSecVertexInfo::vertices
const std::vector< xAOD::Vertex * > & vertices() const
Definition: VxSecVertexInfo.cxx:100
skel.it
it
Definition: skel.GENtoEVGEN.py:407
Rec::NewVrtSecInclusiveAlg::m_btsvContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_btsvContainerKey
Definition: NewVrtSecInclusiveAlg.h:51
sincos.h
Helper to simultaneously calculate sin and cos of the same angle.
ElectronxAODHelpers.h
ParticleTest.tp
tp
Definition: ParticleTest.py:25
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
Rec::NewVrtSecInclusiveAlg::m_gsfContainerKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_gsfContainerKey
Definition: NewVrtSecInclusiveAlg.h:46
Rec::NewVrtSecInclusiveAlg::finalize
StatusCode finalize() override
Definition: NewVrtSecInclusiveAlg.cxx:47
Rec::NewVrtSecInclusiveAlg::m_muonContainerKey
SG::ReadHandleKey< xAOD::MuonContainer > m_muonContainerKey
Definition: NewVrtSecInclusiveAlg.h:47
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:74
Rec::NewVrtSecInclusiveAlg::m_pvContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_pvContainerKey
Definition: NewVrtSecInclusiveAlg.h:49
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:59
Rec::NewVrtSecInclusiveAlg::m_electronContainerKey
SG::ReadHandleKey< xAOD::ElectronContainer > m_electronContainerKey
Definition: NewVrtSecInclusiveAlg.h:48
Rec
Name: MuonSpContainer.h Package : offline/Reconstruction/MuonIdentification/muonEvent.
Definition: FakeTrackBuilder.h:10
Trk::theta
@ theta
Definition: ParamDefs.h:66
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
Trk::pion
@ pion
Definition: ParticleHypothesis.h:32
xAOD::VxType::PriVtx
@ PriVtx
Primary vertex.
Definition: TrackingPrimitives.h:572
Rec::NewVrtSecInclusiveAlg::addElectronTracks
void addElectronTracks(const EventContext &, std::unordered_set< const xAOD::TrackParticle * > &) const
Definition: NewVrtSecInclusiveAlg.cxx:200
Rec::NewVrtSecInclusiveAlg::m_bvertextool
ToolHandle< Rec::IVrtInclusive > m_bvertextool
Definition: NewVrtSecInclusiveAlg.h:54
Rec::NewVrtSecInclusiveAlg::m_addElectronTracks
Gaudi::Property< bool > m_addElectronTracks
Definition: NewVrtSecInclusiveAlg.h:59
Rec::NewVrtSecInclusiveAlg::m_jetContainerKey
SG::ReadHandleKey< xAOD::JetContainer > m_jetContainerKey
Definition: NewVrtSecInclusiveAlg.h:50
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Trk::ParticleMasses::mass
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:56
NewVrtSecInclusiveAlg.h
Rec::NewVrtSecInclusiveAlg::NewVrtSecInclusiveAlg
NewVrtSecInclusiveAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: NewVrtSecInclusiveAlg.cxx:28
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
Rec::TrackParticleContainer
Definition: Reconstruction/Particle/Particle/TrackParticleContainer.h:33
Rec::NewVrtSecInclusiveAlg::m_addGSFTracks
Gaudi::Property< bool > m_addGSFTracks
Definition: NewVrtSecInclusiveAlg.h:57
xAOD::EgammaHelpers::getOriginalTrackParticleFromGSF
const xAOD::TrackParticle * getOriginalTrackParticleFromGSF(const xAOD::TrackParticle *trkPar)
Helper function for getting the "Original" Track Particle (i.e before GSF) via the GSF Track Particle...
Definition: ElectronxAODHelpers.cxx:22
EventInfo.h
python.PyAthena.v
v
Definition: PyAthena.py:154
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
Amg::deltaR
double deltaR(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
Definition: GeoPrimitivesHelpers.h:122
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
Rec::NewVrtSecInclusiveAlg::addGSFTracks
void addGSFTracks(const EventContext &, std::unordered_set< const xAOD::TrackParticle * > &) const
Definition: NewVrtSecInclusiveAlg.cxx:184
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
GeoPrimitivesHelpers.h
Rec::NewVrtSecInclusiveAlg::m_removeNonLepVerts
Gaudi::Property< bool > m_removeNonLepVerts
Definition: NewVrtSecInclusiveAlg.h:60
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:67
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
python.changerun.pv
pv
Definition: changerun.py:79
CxxUtils::sincos
Helper to simultaneously calculate sin and cos of the same angle.
Definition: sincos.h:39
Rec::NewVrtSecInclusiveAlg::m_addMuonTracks
Gaudi::Property< bool > m_addMuonTracks
Definition: NewVrtSecInclusiveAlg.h:58
Trk::phi
@ phi
Definition: ParamDefs.h:75
Rec::NewVrtSecInclusiveAlg::initialize
StatusCode initialize() override
Definition: NewVrtSecInclusiveAlg.cxx:33
Rec::NewVrtSecInclusiveAlg::addMuonTracks
void addMuonTracks(const EventContext &, std::unordered_set< const xAOD::TrackParticle * > &) const
Definition: NewVrtSecInclusiveAlg.cxx:168
Rec::NewVrtSecInclusiveAlg::m_addIDTracks
Gaudi::Property< bool > m_addIDTracks
Definition: NewVrtSecInclusiveAlg.h:56
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
Rec::NewVrtSecInclusiveAlg::m_tpContainerKey
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_tpContainerKey
Definition: NewVrtSecInclusiveAlg.h:45
Rec::NewVrtSecInclusiveAlg::addInDetTracks
void addInDetTracks(const EventContext &, std::unordered_set< const xAOD::TrackParticle * > &) const
Definition: NewVrtSecInclusiveAlg.cxx:156
VertexAuxContainer.h
Rec::NewVrtSecInclusiveAlg::m_foundVerticesKey
SG::WriteHandleKey< xAOD::VertexContainer > m_foundVerticesKey
Definition: NewVrtSecInclusiveAlg.h:53