ATLAS Offline Software
InDetConversionFinderTools.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /***************************************************************************
6  InDetConversionFinderTools.cxx - Description
7  -------------------
8  begin : 28-08-2006
9  authors : Tatjana Lenz
10  email : tatjana.lenz@cern.ch
11  changes :
12 ***************************************************************************/
14 
15 #include "AthLinks/ElementLink.h"
16 #include "TrkTrack/LinkToTrack.h"
17 #include "AthContainers/Accessor.h"
18 
19 #include <vector>
20 #include <utility>
21 
22 namespace InDet
23 {
24 
26  const std::string& n,
27  const IInterface* p)
28  : AthAlgTool(t, n, p)
29  , m_mindR{ -350. }
30  , m_maxdR{ 250. }
31  , m_MinInitVtxR{ 0 }
32  , m_MinFlightAngle{ 0 }
33 {
34  declareInterface<IVertexFinder>(this);
35  // Remove standalone TRT tracks
36  declareProperty("RemoveTrtTracks", m_removeTrt);
37  // Conversion or V0s
38  declareProperty("IsConversion", m_isConversion);
39  // Decorate vertices with values used for vertex selection
40  declareProperty("DecorateVertices", m_decorateVertices = true);
41  declareProperty("MinDistVtxHit", m_mindR);
42  declareProperty("MaxDistVtxHit", m_maxdR);
43  declareProperty("MinInitVtxR", m_MinInitVtxR);
44  declareProperty("MinFlightAngle", m_MinFlightAngle);
45  }
46 
47  InDetConversionFinderTools::~InDetConversionFinderTools()= default;
48 
50  {
52  if (sc.isFailure()) {
53  ATH_MSG_FATAL("Unable to initialize InDetConversionFinderTools");
54  return StatusCode::FAILURE;
55  }
56  /* Get the right vertex fitting tool from ToolSvc */
57  if (m_iVertexFitter.retrieve().isFailure()) {
58  ATH_MSG_FATAL("Failed to retrieve tool " << m_iVertexFitter);
59  return StatusCode::FAILURE;
60  }
61  ATH_MSG_DEBUG("Retrieved tool " << m_iVertexFitter);
62 
63  /* Get the track pairs selector tool from ToolSvc */
64  if (m_trackPairsSelector.retrieve().isFailure()) {
65  ATH_MSG_FATAL("Failed to retrieve tool " << m_trackPairsSelector);
66  return StatusCode::FAILURE;
67  }
68  ATH_MSG_DEBUG("Retrieved tool " << m_trackPairsSelector);
69 
70  /* Get the vertex point estimator tool from ToolSvc */
71  if (m_vertexEstimator.retrieve().isFailure()) {
72  ATH_MSG_FATAL("Failed to retrieve tool " << m_vertexEstimator);
73  return StatusCode::FAILURE;
74  }
75  ATH_MSG_DEBUG("Retrieved tool " << m_vertexEstimator);
76 
77  /* Get the postselector tool from ToolSvc */
78  if (m_postSelector.retrieve().isFailure()) {
79  ATH_MSG_FATAL("Failed to retrieve tool " << m_postSelector);
80  return StatusCode::FAILURE;
81  }
82  ATH_MSG_DEBUG("Retrieved tool " << m_postSelector);
83 
84  /* Get the single track conversion tool from ToolSvc */
85  if (m_singleTrkConvTool.retrieve().isFailure()) {
86  ATH_MSG_FATAL("Failed to retrieve tool " << m_singleTrkConvTool);
87  return StatusCode::FAILURE;
88  }
89  ATH_MSG_DEBUG("Retrieved tool " << m_singleTrkConvTool);
90 
91  /* Get the track selector tool from ToolSvc */
92  if (m_trkSelector.retrieve().isFailure()) {
93  ATH_MSG_FATAL("Failed to retrieve tool " << m_trkSelector);
94  return StatusCode::FAILURE;
95  }
96  ATH_MSG_DEBUG("Retrieved tool " << m_trkSelector);
97 
98  ATH_MSG_DEBUG("Initialization successful");
99  return StatusCode::SUCCESS;
100  }
101 
103  {
104  return StatusCode::SUCCESS;
105  }
106 
107  //TrackCollection
108  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
109  InDetConversionFinderTools::findVertex(const EventContext& /*ctx*/,
110  const TrackCollection* /*trk_coll*/) const
111  {
112 
113  ATH_MSG_ERROR("Using Track Container not currently supported returning an empty conatiner");
114 
115  // Make collection for conversions.
116  xAOD::VertexContainer* InDetConversionContainer = new xAOD::VertexContainer();
117  xAOD::VertexAuxContainer* InDetConversionContainerAux = new xAOD::VertexAuxContainer();
118  InDetConversionContainer->setStore( InDetConversionContainerAux );
119 
120  return std::make_pair(InDetConversionContainer,InDetConversionContainerAux);
121  }
122 
123  // TrackParticle Collection
124  std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
125  InDetConversionFinderTools::findVertex(const EventContext& ctx,
126  const xAOD::TrackParticleContainer* trk_coll) const
127  {
128  // Make collection for conversions.
129  xAOD::VertexContainer* InDetConversionContainer =
130  new xAOD::VertexContainer();
131  xAOD::VertexAuxContainer* InDetConversionContainerAux =
133  InDetConversionContainer->setStore(InDetConversionContainerAux);
134  // Count for number of successful conversions
135  int numConversions = 0;
136 
137  // have to be used for the vertex fit
138  Amg::Vector3D pos(0., 0., 0.);
139  Amg::Vector3D initPos(0., 0., 0.);
140 
141  // Make seperate lists of positive and negative tracks (after presection
142  // cuts)
143  std::vector<const xAOD::TrackParticle*> negSelectedTracks;
144  negSelectedTracks.clear();
145  std::vector<const xAOD::TrackParticle*> posSelectedTracks;
146  posSelectedTracks.clear();
147  std::vector<int> negIndx;
148  std::vector<int> posIndx;
149 
151  // track preselection -->pt-cut
153  for (iter = (*trk_coll).begin(); iter != (*trk_coll).end(); ++iter) {
154  if (m_trkSelector->decision(
155  **iter,
156  nullptr)) { // Only save if track passes the pt, d0, z0 and TRT PID cuts
157  ATH_MSG_DEBUG("Track passed preselection");
158  if ((*iter)->charge() < 0) {
159  negSelectedTracks.push_back(*iter);
160  negIndx.push_back(0);
161  } else {
162  posSelectedTracks.push_back(*iter);
163  posIndx.push_back(0);
164  }
165  } else
166  ATH_MSG_DEBUG("Track failed preselection");
167  } // end pt,d0.z0-cuts
168 
169  // Make track pairs. To be used for double leg conversions
170  std::vector<const xAOD::TrackParticle*>::const_iterator iter_pos;
171  std::vector<const xAOD::TrackParticle*>::const_iterator iter_neg;
172  std::vector<Amg::Vector3D> positionList;
173  positionList.clear();
174  std::vector<const xAOD::TrackParticle*> trackParticleList;
175  trackParticleList.clear();
176  std::vector<const xAOD::TrackParticle*> singleTrackConvList;
177  singleTrackConvList.clear();
178  int ipos = -1;
179  int ineg = -1;
180  // Outer loop: Loop over positive tracks
181  for (iter_pos = posSelectedTracks.begin();
182  iter_pos != posSelectedTracks.end();
183  ++iter_pos) {
184  ineg = -1;
185  ipos++;
186  // Inner loop: Loop over negative tracks
187  for (iter_neg = negSelectedTracks.begin();
188  iter_neg != negSelectedTracks.end();
189  ++iter_neg) {
190  ineg++;
191  int flag = 0;
192 
193  std::map<std::string, float> intersectionDecors;
194  if (!passPreSelection(cache,
195  *iter_pos,
196  *iter_neg,
197  positionList,
198  initPos,
199  flag,
200  intersectionDecors)) {
201  positionList.clear();
202  continue;
203  }
204 
205  // Do the fit
206  if (positionList.size() < 2) {
207  ATH_MSG_DEBUG("No tracks to fit ");
208  positionList.clear();
209  continue;
210  }
211 
212  trackParticleList.push_back(*iter_pos);
213  trackParticleList.push_back(*iter_neg);
214 
215  std::unique_ptr<xAOD::Vertex> myVertex =
216  m_iVertexFitter->fit(ctx, trackParticleList, initPos);
217  trackParticleList.clear();
218 
219  // We have a new vertex
220  if (myVertex) {
221  ATH_MSG_DEBUG("VertexFit successful!");
222  int type = -1;
223  if ((m_isConversion && m_postSelector->selectConversionCandidate(
224  myVertex.get(), flag, positionList)) ||
225  (!m_isConversion &&
226  m_postSelector->selectSecVtxCandidate(
227  myVertex.get(), flag, positionList, type))) {
228 
229  ATH_MSG_DEBUG(" Conversion passed postselection cuts");
230  // Remove old element links
231  myVertex->clearTracks();
232 
233  // If we do not have a valid type just reset
234  if (!m_isConversion && !(type == 101) && !(type == 110) &&
235  !(type == 11)) {
236  myVertex.reset();
237  }
238 
239  // If we have the right type (not reset above) lets fill information
240  // and then push to the containers
241  if (myVertex) {
242  if (m_decorateVertices) {
244  "Decorating vertex with values used in track pair selector");
245  for (const auto& kv :
246  m_trackPairsSelector->getLastValues(cache)) {
247  SG::Accessor<float> acc (kv.first);
248  acc (*myVertex) = kv.second;
249  }
250  ATH_MSG_DEBUG("Decorating vertex with values used in vertex "
251  "point estimator");
252  for (const auto& kv : intersectionDecors) {
253  SG::Accessor<float> acc (kv.first);
254  acc (*myVertex) = kv.second;
255  }
256  }
257 
258  ElementLink<xAOD::TrackParticleContainer> newLinkPos(*iter_pos,
259  *trk_coll);
260  ElementLink<xAOD::TrackParticleContainer> newLinkNeg(*iter_neg,
261  *trk_coll);
262  myVertex->addTrackAtVertex(newLinkPos);
263  myVertex->addTrackAtVertex(newLinkNeg);
264 
265  // Now fill in the containers depending on the 2 possible
266  // cases
267  if (m_isConversion) {
269  InDetConversionContainer->push_back(std::move(myVertex));
270  }
271  else if (type == 101 || type == 110 || type == 11) { // V0
273  InDetConversionContainer->push_back(std::move(myVertex));
274  }
275 
276  } // End if on right type
277 
278  negIndx[ineg] = 1;
279  posIndx[ipos] = 1;
280  ++numConversions;
281  } else {
282  ATH_MSG_DEBUG("VxCandidate failed the post selection cuts!");
283  myVertex.reset();
284  }
285  } else {
286  ATH_MSG_DEBUG("VertexFit was NOT successful!");
287  }
288  positionList.clear();
289  } // neg loop
290  } // pos loop
291  ATH_MSG_DEBUG("Number of conversions found passing post selection cuts: "
292  << numConversions);
293 
294  // single track conversions
295  if (m_isConversion) {
296  for (int ip = 0; ip < int(posIndx.size()); ++ip) {
297  if (posIndx[ip] == 0)
298  singleTrackConvList.push_back(posSelectedTracks[ip]);
299  }
300  for (int in = 0; in < int(negIndx.size()); ++in) {
301  if (negIndx[in] == 0)
302  singleTrackConvList.push_back(negSelectedTracks[in]);
303  }
304 
306  itke = singleTrackConvList.end();
307  int numSingle = 0;
308  for (itk = singleTrackConvList.begin(); itk != itke; ++itk) {
309  if (!m_singleTrkConvTool->selectSingleTrackParticleConversion((*itk)))
310  ATH_MSG_DEBUG("Track failed single track conversion selection");
311  else {
312  xAOD::Vertex* sConver(nullptr);
313  sConver = m_singleTrkConvTool->buildSingleTrackParticleConversion(
314  (*itk), InDetConversionContainer);
315  if (sConver) {
316  sConver->clearTracks();
317 
319  newLink.toContainedElement(*trk_coll, *itk);
320  sConver->addTrackAtVertex(newLink);
321  sConver->setVertexType(xAOD::VxType::ConvVtx);
322  numSingle++;
323 
324  if (m_decorateVertices) {
325  ATH_MSG_DEBUG("Decorating single track vertex with dummy values "
326  "used in track pair selector");
327  for (const auto& kv : m_trackPairsSelector->getLastValues(cache)) {
328  SG::Accessor<float> acc (kv.first);
329  acc (*sConver) = 0.;
330  }
331 
332  ATH_MSG_DEBUG("Decorating single track vertex with dummy values "
333  "used in vertex point estimator");
334  for (const std::string& k : m_vertexEstimator->decorKeys()) {
336  acc (*sConver) = 0.;
337  }
338 
339  ATH_MSG_DEBUG("Decorating single track vertex with dummy values "
340  "used in post selector");
341  m_postSelector->decorateVertex(*sConver, 0., 0., 0., 0., 0.);
342  }
343  }
344  }
345  }
346  ATH_MSG_DEBUG("Number successful reconstructed single track conversion: "
347  << numSingle);
348  }
349 
350  return std::make_pair(InDetConversionContainer,
351  InDetConversionContainerAux);
352  }
353 
354  bool
355  InDetConversionFinderTools::passPreSelection(
356  TrackPairsSelector::Cache& cache,
357  const xAOD::TrackParticle* track_pos,
358  const xAOD::TrackParticle* track_neg,
359  std::vector<Amg::Vector3D>& trackList,
360  Amg::Vector3D& initPos,
361  int& flag,
362  std::map<std::string, float>& intersectionDecors) const
363  {
364  //Track summary information
365 
366  uint8_t nclusPos(0);
367  uint8_t dummy(0);
368  if(track_pos->summaryValue(dummy,xAOD::numberOfSCTHits)){
369  nclusPos += dummy;
370  }
372  nclusPos += dummy;
373  }
374 
375  uint8_t nclusNeg(0);
376  if(track_neg->summaryValue(dummy,xAOD::numberOfSCTHits)){
377  nclusNeg += dummy;
378  }
380  nclusNeg += dummy;
381  }
382 
383 
384  if(nclusNeg>0 && nclusPos>0) flag= 0;
385  if((nclusNeg>0 && nclusPos==0) || (nclusNeg==0 && nclusPos>0)) flag = 1;
386  if(nclusNeg==0 && nclusPos==0) flag = 2;
387  if(m_removeTrt && (flag==1 || flag==2)) return false;
388 
389  if (m_trackPairsSelector->selectTrackParticlePair( track_pos,track_neg,cache)){
390 
391  const Trk::Perigee& perPos = track_pos->perigeeParameters();
392  const Trk::Perigee& perNeg = track_neg->perigeeParameters();
393  int errorcode = 0;
394  Amg::Vector3D startingPoint(
395  m_vertexEstimator->getCirclesIntersectionPoint(
396  &perPos, &perNeg, flag, errorcode, intersectionDecors));
397  if(m_isConversion && errorcode != 0) return false;
398  if(!m_isConversion){
399  Amg::Vector3D v_direction = perPos.momentum() + perNeg.momentum();
400  double d_alpha = (startingPoint.adjoint()*v_direction)[0]/(startingPoint.mag()*v_direction.mag());
401  if(d_alpha<m_MinFlightAngle) return false;
402  }
403  initPos = startingPoint;
404  double startingPointR = startingPoint.perp();
405  if(startingPointR<800.) {
406  //Get measured track parameters at first track measurement.
407 
408  //Position of first hit in track particle
409  Trk::CurvilinearParameters trkPar_pos;
410  Trk::CurvilinearParameters trkPar_neg;
411 
412  int index(-1);
413  for(unsigned int i(0); i< track_pos->numberOfParameters() ; ++i ){
414  if( xAOD::FirstMeasurement == track_pos->parameterPosition(i) ){
415  index = i;
416  break;
417  }
418  }
419  if(index!=-1){
420  trkPar_pos = track_pos->curvilinearParameters(index);
421  } else {
422  ATH_MSG_WARNING("Track Particle does not contain first Measurement track parameters");
423  return false;
424  }
425 
426  index = -1;
427  for(unsigned int i(0); i< track_neg->numberOfParameters() ; ++i ){
428  if( xAOD::FirstMeasurement == track_neg->parameterPosition(i) ){
429  index = i;
430  break;
431  }
432  }
433  if(index!=-1){
434  trkPar_neg = track_neg->curvilinearParameters(index);
435  } else {
436  ATH_MSG_WARNING("Track Particle does not contain first Measurement track parameters");
437  return false;
438  }
439 
440 
441  if(!m_isConversion){
442  double posR = trkPar_pos.position().perp();
443  double negR = trkPar_neg.position().perp();
444  double diffR = 1000.;
445  if((startingPointR-posR)<(startingPointR-negR)) diffR = startingPointR-posR;
446  else diffR = startingPointR-negR;
447  if(startingPointR<m_MinInitVtxR) return false;
448  if(diffR<m_mindR || diffR>m_maxdR) return false;
449  }
450 
451  //Alternative way to estimate the guess vertex
452  initPos = trkPar_pos.position() + trkPar_neg.position();
453  initPos *= 0.5;
454  // Not correct but will do for now
455  trackList.push_back(trkPar_pos.position());
456  trackList.push_back(trkPar_neg.position());
457 
458  }
459  }
460  return true;
461  }
462 }// end namespace InDet
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
xAOD::TrackParticle_v1::curvilinearParameters
const Trk::CurvilinearParameters curvilinearParameters(unsigned int index) const
Returns a curvilinear representation of the parameters at 'index'.
Definition: TrackParticle_v1.cxx:673
LinkToTrack.h
python.tests.PyTestsLib.finalize
def finalize(self)
_info( "content of StoreGate..." ) self.sg.dump()
Definition: PyTestsLib.py:53
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
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::uint8_t
uint8_t
Definition: Muon_v1.cxx:575
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
SG::Accessor< float >
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
index
Definition: index.py:1
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
InDet
DUMMY Primary Vertex Finder.
Definition: VP1ErrorUtils.h:36
xAOD::VxType::V0Vtx
@ V0Vtx
Vertex from V0 decay.
Definition: TrackingPrimitives.h:575
initialize
void initialize()
Definition: run_EoverP.cxx:894
xAOD::TrackParticle_v1::summaryValue
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
Definition: TrackParticle_v1.cxx:736
xAOD::numberOfPixelHits
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
Definition: TrackingPrimitives.h:259
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
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
xAOD::Vertex_v1::setVertexType
void setVertexType(VxType::VertexType vType)
Set the type of the vertex.
xAOD::Vertex_v1::addTrackAtVertex
void addTrackAtVertex(const ElementLink< TrackParticleContainer > &tr, float weight=1.0)
Add a new track to the vertex.
Definition: Vertex_v1.cxx:314
xAOD::TrackParticle_v1::perigeeParameters
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
Definition: TrackParticle_v1.cxx:485
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
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
xAOD::FirstMeasurement
@ FirstMeasurement
Parameter defined at the position of the 1st measurement.
Definition: TrackingPrimitives.h:213
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
master.flag
bool flag
Definition: master.py:29
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
AthenaPoolTestRead.acc
acc
Definition: AthenaPoolTestRead.py:16
python.xAODType.dummy
dummy
Definition: xAODType.py:4
xAOD::Vertex_v1::clearTracks
void clearTracks()
Remove all tracks from the vertex.
Definition: Vertex_v1.cxx:331
Trk::CurvilinearParametersT
Definition: CurvilinearParametersT.h:48
xAOD::TrackParticle_v1::parameterPosition
xAOD::ParameterPosition parameterPosition(unsigned int index) const
Return the ParameterPosition of the parameters at 'index'.
Definition: TrackParticle_v1.cxx:647
DataVector< Trk::Track >
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.
xAOD::TrackParticle_v1::numberOfParameters
size_t numberOfParameters() const
Returns the number of additional parameters stored in the TrackParticle.
Definition: TrackParticle_v1.cxx:553
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
InDet::TrackPairsSelector::Cache
Definition: TrackPairsSelector.h:31
DeMoScan.index
string index
Definition: DeMoScan.py:362
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
declareProperty
#define declareProperty(n, p, h)
Definition: BaseFakeBkgTool.cxx:15
xAOD::numberOfSCTHits
@ numberOfSCTHits
number of hits in SCT [unit8_t].
Definition: TrackingPrimitives.h:268
InDetConversionFinderTools.h
xAOD::VxType::ConvVtx
@ ConvVtx
Conversion vertex.
Definition: TrackingPrimitives.h:574
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
AthAlgTool
Definition: AthAlgTool.h:26
InDet::InDetConversionFinderTools::InDetConversionFinderTools
InDetConversionFinderTools(const std::string &t, const std::string &n, const IInterface *p)
Definition: InDetConversionFinderTools.cxx:32
fitman.k
k
Definition: fitman.py:528