InDetTrackSummaryHelperTool.cxx 22 KB
Newer Older
1
/*
2
  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3
4
5
*/

#include "InDetTrackSummaryHelperTool/InDetTrackSummaryHelperTool.h"
6

7
8
9
10
// forward declares
#include "InDetIdentifier/PixelID.h"
#include "InDetIdentifier/SCT_ID.h"
#include "InDetIdentifier/TRT_ID.h"
11
#include "TrkEventUtils/PRDtoTrackMap.h"
12
13
14
15
16
17
18
#include "TrkRIO_OnTrack/RIO_OnTrack.h"
#include "TrkTrack/Track.h"
#include "TrkTrack/TrackStateOnSurface.h"
// normal includes
#include "Identifier/Identifier.h"
#include "InDetRIO_OnTrack/PixelClusterOnTrack.h"
#include "InDetRIO_OnTrack/SCT_ClusterOnTrack.h"
19
#include "InDetRIO_OnTrack/TRT_DriftCircleOnTrack.h"
20
21
#include "TrkCompetingRIOsOnTrack/CompetingRIOsOnTrack.h"
#include "TrkParameters/TrackParameters.h"
22
#include "TrkTrackSummary/InDetTrackSummary.h"
23

24
25
#include <cassert>

26
//==========================================================================
27
28
29
30
31
32
InDet::InDetTrackSummaryHelperTool::InDetTrackSummaryHelperTool(
  const std::string& t,
  const std::string& n,
  const IInterface* p)
  : base_class(t, n, p)
{}
33
34
35

//==========================================================================

36
37
StatusCode
InDet::InDetTrackSummaryHelperTool::initialize()
38
{
39
40
41
  if (m_usePixel) {
    if (detStore()->retrieve(m_pixelId, "PixelID").isFailure()) {
      ATH_MSG_ERROR("Could not get PixelID helper !");
42
      return StatusCode::FAILURE;
43
44
    }
  }
45

46
47
48
  if (m_useSCT) {
    if (detStore()->retrieve(m_sctId, "SCT_ID").isFailure()) {
      ATH_MSG_ERROR("Could not get SCT_ID helper !");
49
      return StatusCode::FAILURE;
50
51
    }
  }
52

53
54
55
  if (m_useTRT) {
    if (detStore()->retrieve(m_trtId, "TRT_ID").isFailure()) {
      ATH_MSG_ERROR("Could not get TRT_ID helper !");
56
      return StatusCode::FAILURE;
57
58
    }
  }
59

60
61
62
63
64
65
66
  ATH_CHECK(
    m_assoTool.retrieve(DisableTool{ !m_doSharedHits || m_assoTool.empty() }));
  ATH_CHECK(m_pixeldedxtool.retrieve(DisableTool{ m_pixeldedxtool.empty() }));
  ATH_CHECK(m_holeSearchTool.retrieve(DisableTool{ m_holeSearchTool.empty() }));
  ATH_CHECK(m_testBLayerTool.retrieve(DisableTool{ m_testBLayerTool.empty() }));
  ATH_CHECK(m_TRTStrawSummaryTool.retrieve(
    DisableTool{ not m_useTRT or m_TRTStrawSummaryTool.empty() }));
67

68
69
  ATH_CHECK(m_clusterSplitProbContainer.initialize(
    !m_clusterSplitProbContainer.key().empty()));
70
71
72
73

  ATH_MSG_INFO("initialize() successful in " << name());

  return StatusCode::SUCCESS;
74
75
}

76
namespace {
77
78
79
80
81
82
83
84
85
86
87
88
bool
isShared(const Trk::PRDtoTrackMap* prd_to_track_map,
         const PublicToolHandle<Trk::IPRD_AssociationTool>& asso_tool,
         const Trk::PrepRawData& prd)
{
  if (prd_to_track_map) {
    return prd_to_track_map->isShared(prd);
  } else {
    if (!asso_tool.isEnabled()) {
      throw std::logic_error(
        "Shared hits to be computed but no PRDtoTrack provided "
        " (and no association tool configured (deprecated))");
89
    }
90
    return asso_tool->isShared(prd);
91
92
  }
}
93
}
94

95
//==========================================================================
96
97
98
99
100
101
102
103
104
void
InDet::InDetTrackSummaryHelperTool::analyse(
  const EventContext& ctx,
  const Trk::Track& track,
  const Trk::PRDtoTrackMap* prd_to_track_map,
  const Trk::RIO_OnTrack* rot,
  const Trk::TrackStateOnSurface* tsos,
  std::vector<int>& information,
  std::bitset<Trk::numberOfDetectorTypes>& hitPattern) const
105
{
106
  const Identifier& id = rot->identify();
107
108
  bool isOutlier = tsos->type(Trk::TrackStateOnSurface::Outlier);
  bool ispatterntrack = (track.info().trackFitter() == Trk::TrackInfo::Unknown);
109

110
  if (m_usePixel and m_pixelId->is_pixel(id)) {
111

112
113
114
    if (isOutlier and
        not ispatterntrack) { // ME: outliers on pattern tracks may be
                              // reintegrated by fitter, so count them as hits
115
      information[Trk::numberOfPixelOutliers]++;
116
      if (m_pixelId->layer_disk(id) == 0 and m_pixelId->is_barrel(id)) {
117
        information[Trk::numberOfInnermostPixelLayerOutliers]++;
118
      }
119
      if (m_pixelId->layer_disk(id) == 1 and m_pixelId->is_barrel(id)) {
120
        information[Trk::numberOfNextToInnermostPixelLayerOutliers]++;
121
      }
122
123
124
    } else {
      bool hitIsSplit(false);
      if (m_pixelId->is_dbm(id)) {
125
126
127
        int offset =
          static_cast<int>(Trk::DBM0); // get int value of first DBM layer
        offset += m_pixelId->layer_disk(id);
128
129
130
131
        hitPattern.set(offset);
        information[Trk::numberOfDBMHits]++;
      } else {
        information[Trk::numberOfPixelHits]++;
132
133
134
135
        if (m_pixelId->layer_disk(id) == 0 and m_pixelId->is_barrel(id))
          information[Trk::numberOfInnermostPixelLayerHits]++;
        if (m_pixelId->layer_disk(id) == 1 and m_pixelId->is_barrel(id))
          information[Trk::numberOfNextToInnermostPixelLayerHits]++;
136
        // check to see if there's an ambiguity with the ganged cluster.
137
138
139
140
        const PixelClusterOnTrack* pix = nullptr;
        if (rot->rioType(Trk::RIO_OnTrackType::PixelCluster)) {
          pix = static_cast<const PixelClusterOnTrack*>(rot);
        }
141
        if (not pix) {
142
143
144
          ATH_MSG_ERROR("Could not cast pixel RoT to PixelClusterOnTrack!");
        } else {
          const InDet::PixelCluster* pixPrd = pix->prepRawData();
145
          const Trk::ClusterSplitProbabilityContainer::ProbabilityInfo&
146
            splitProb = getClusterSplittingProbability(ctx, pixPrd);
147
148
149
150
          if (pixPrd and splitProb.isSplit()) {
            information[Trk::numberOfPixelSplitHits]++;
            hitIsSplit = true;
          }
151
          if (pixPrd and m_pixelId->is_barrel(id) and
152
              m_pixelId->layer_disk(id) == 0 and splitProb.isSplit())
153
154
            information[Trk::numberOfInnermostLayerSplitHits]++;
          if (pixPrd and m_pixelId->is_barrel(id) and
155
              m_pixelId->layer_disk(id) == 1 and splitProb.isSplit())
156
            information[Trk::numberOfNextToInnermostLayerSplitHits]++;
157
158
159
          if (pix->isBroadCluster())
            information[Trk::numberOfPixelSpoiltHits]++;
          if (pix->hasClusterAmbiguity()) {
160
            information[Trk::numberOfGangedPixels]++;
161
162
            if (pix->isFake())
              information[Trk::numberOfGangedFlaggedFakes]++;
163
164
165
          }
        }

166
        if ((m_pixelId->is_barrel(id))) {
167
          int offset = m_pixelId->layer_disk(id);
168
169
          if (not hitPattern.test(offset))
            information[Trk::numberOfContribPixelLayers]++;
170
171
          hitPattern.set(offset); // assumes numbered consecutively
        } else {
172
173
174
175
176
          int offset = static_cast<int>(
            Trk::pixelEndCap0); // get int value of first pixel endcap disc
          offset += m_pixelId->layer_disk(id);
          if (not hitPattern.test(offset))
            information[Trk::numberOfContribPixelLayers]++;
177
          hitPattern.set(offset); // assumes numbered consecutively
178
        }
179
      }
180

181
      if (m_doSharedHits && !isOutlier) {
182
        // If we are running the TIDE ambi don't count split hits as shared
183
        if (not(m_runningTIDE_Ambi and hitIsSplit)) {
184
          // used in more than one track ?
185
          if (isShared(prd_to_track_map, m_assoTool, *(rot->prepRawData()))) {
186
187
            ATH_MSG_DEBUG("shared Pixel hit found");
            information[Trk::numberOfPixelSharedHits]++;
188
            if ((m_pixelId->is_blayer(id))) {
189
190
191
              ATH_MSG_DEBUG("--> shared Pixel hit is in b-layer");
              information[Trk::numberOfBLayerSharedHits]++;
            }
192
            if ((m_pixelId->is_barrel(id) and m_pixelId->layer_disk(id) == 0)) {
193
194
              ATH_MSG_DEBUG("--> shared Pixel hit is in innermost layer");
              information[Trk::numberOfInnermostPixelLayerSharedHits]++;
195
            }
196
197
198
            if ((m_pixelId->is_barrel(id) and m_pixelId->layer_disk(id) == 1)) {
              ATH_MSG_DEBUG(
                "--> shared Pixel hit is in next to innermost layer");
199
200
201
202
203
204
              information[Trk::numberOfNextToInnermostPixelLayerSharedHits]++;
            }
          }
        }
      }
    }
205

206
207
208
209
  } else if (m_useSCT and m_sctId->is_sct(id)) {
    if (isOutlier and
        not ispatterntrack) { // ME: outliers on pattern tracks may be
                              // reintegrated by fitter, so count them as hits
210
      information[Trk::numberOfSCTOutliers]++;
211

212
213
    } else {
      information[Trk::numberOfSCTHits]++;
214
215
216
217
218

      const InDet::SCT_ClusterOnTrack* sctclus = nullptr;
      if (rot->rioType(Trk::RIO_OnTrackType::SCTCluster)) {
        sctclus = static_cast<const InDet::SCT_ClusterOnTrack*>(rot);
      }
219
      if (not sctclus) {
220
221
        ATH_MSG_ERROR("Could not cast SCT RoT to SCT_ClusterOnTrack!");
      } else {
222
223
        if (sctclus->isBroadCluster())
          information[Trk::numberOfSCTSpoiltHits]++;
224
      }
225

226
      if ((m_sctId->is_barrel(id))) {
227
        int offset = static_cast<int>(Trk::sctBarrel0);
228
229
        hitPattern.set(
          offset + m_sctId->layer_disk(id)); // assumes numbered consecutively
230
      } else {
231
232
233
234
        int offset = static_cast<int>(
          Trk::sctEndCap0); // get int value of first sct endcap disc
        hitPattern.set(
          offset + m_sctId->layer_disk(id)); // assumes numbered consecutively
235
      }
236

237
      if (m_doSharedHits && !isOutlier) {
238
        if (isShared(prd_to_track_map, m_assoTool, *(rot->prepRawData()))) {
239
240
241
242
243
          ATH_MSG_DEBUG("shared SCT hit found");
          information[Trk::numberOfSCTSharedHits]++;
        }
      }
    }
244
245
  } else if (m_useTRT and m_trtId->is_trt(id)) {
    bool isArgonStraw = false;
246
247
    bool isKryptonStraw = false;
    if (not m_TRTStrawSummaryTool.empty()) {
248
249
250
251
      int statusHT = m_TRTStrawSummaryTool->getStatusHT(id, ctx);
      if (statusHT == TRTCond::StrawStatus::Argon or
          statusHT == TRTCond::StrawStatus::Dead or
          statusHT == TRTCond::StrawStatus::EmulateArgon) {
252
253
        isArgonStraw = true;
      }
254
255
      if (statusHT == TRTCond::StrawStatus::Krypton or
          statusHT == TRTCond::StrawStatus::EmulateKrypton) {
256
257
258
        isKryptonStraw = true;
      }
    }
259
    if (not isArgonStraw and not isKryptonStraw) {
260
261
      information[Trk::numberOfTRTXenonHits]++;
    }
262

263
264
265
    if (isOutlier and not ispatterntrack) {
      // ME: outliers on pattern tracks may be
      // reintegrated by fitter, so count them as hits
266
267
      information[Trk::numberOfTRTOutliers]++;

268
269
270
271
272
      const InDet::TRT_DriftCircleOnTrack* trtDriftCircle = nullptr;
      if (rot->rioType(Trk::RIO_OnTrackType::TRT_DriftCircle)) {
        trtDriftCircle = static_cast<const InDet::TRT_DriftCircleOnTrack*>(rot);
      }
      if (not trtDriftCircle) {
273
274
        ATH_MSG_ERROR("Could not cast TRT RoT to TRT_DriftCircleOnTracknot ");
      } else {
275
        if (trtDriftCircle->highLevel() and not isArgonStraw and
276
277
            not isKryptonStraw)
          information[Trk::numberOfTRTHighThresholdOutliers]++;
278
279
280
      }
    } else {
      information[Trk::numberOfTRTHits]++;
281
282
283
      double error2 = rot->localCovariance()(0, 0);
      if (error2 > 1)
        information[Trk::numberOfTRTTubeHits]++;
284

285
286
287
288
289
      const InDet::TRT_DriftCircleOnTrack* trtDriftCircle = nullptr;
      if (rot->rioType(Trk::RIO_OnTrackType::TRT_DriftCircle)) {
        trtDriftCircle = static_cast<const InDet::TRT_DriftCircleOnTrack*>(rot);
      }
      if (not trtDriftCircle) {
290
291
        ATH_MSG_ERROR("Could not cast TRT RoT to TRT_DriftCircleOnTracknot ");
      } else {
292
        if (trtDriftCircle->highLevel()) {
293
294
295
          if (not isArgonStraw and not isKryptonStraw)
            information[Trk::numberOfTRTHighThresholdHits]++;
          assert(Trk::numberOfTRTHighThresholdHitsTotal < information.size());
296
297
          information[Trk::numberOfTRTHighThresholdHitsTotal]++;
        }
298
      }
299
300
    }

301
    if (m_doSharedHitsTRT && !isOutlier) {
302
303
304
305
306
307
      // used in more than one track ?
      assert(information[Trk::numberOfTRTSharedHits] >= 0);
      if (isShared(prd_to_track_map, m_assoTool, *(rot->prepRawData()))) {
        ATH_MSG_DEBUG("shared TRT hit found");
        information[Trk::numberOfTRTSharedHits]++;
      }
308
309
310
    }
  }
  return;
311
312
}

313
314
315
316
317
318
319
320
321
void
InDet::InDetTrackSummaryHelperTool::analyse(
  const EventContext& ctx,
  const Trk::Track& track,
  const Trk::PRDtoTrackMap* prd_to_track_map,
  const Trk::CompetingRIOsOnTrack* crot,
  const Trk::TrackStateOnSurface* tsos,
  std::vector<int>& information,
  std::bitset<Trk::numberOfDetectorTypes>& hitPattern) const
322
{
323
  // re-produce prior behaviour (i.e. just take most probable ROT)
324
325
326
327
328
329
330
  analyse(ctx,
          track,
          prd_to_track_map,
          &crot->rioOnTrack(crot->indexOfMaxAssignProb()),
          tsos,
          information,
          hitPattern);
331
332
}

333
334
335
336
337
void
InDet::InDetTrackSummaryHelperTool::searchForHoles(
  const Trk::Track& track,
  std::vector<int>& information,
  const Trk::ParticleHypothesis partHyp) const
338
{
339
340
  ATH_MSG_DEBUG("Do hole search within HELPER, PLEASE FIX THIS AFTER 16.0.X");
  m_holeSearchTool->countHoles(track, information, partHyp);
341

342
343
344
  // this is a hack, we need to run the TestBLayer Tool somewhere

  if (m_usePixel and not m_testBLayerTool.empty()) {
345

346
347
348
349
    if (information[Trk::numberOfContribPixelLayers] == 0) {
      ATH_MSG_DEBUG("No pxiels on track, so wo do not expect a B-Layer hit !");
      information[Trk::expectInnermostPixelLayerHit] = 0;
      information[Trk::expectNextToInnermostPixelLayerHit] = 0;
350
351
352
    } else {
      // innermost layer block
      if (information[Trk::numberOfInnermostPixelLayerHits] > 0) {
353
354
        information[Trk::expectInnermostPixelLayerHit] = 1;
      } else {
355
        if (m_testBLayerTool->expectHitInInnermostPixelLayer(&track)) {
356
357
358
359
360
          ATH_MSG_DEBUG("expect Pixel Layer 0 hit !");
          information[Trk::expectInnermostPixelLayerHit] = 1;
        } else {
          ATH_MSG_DEBUG("do not expect Pixel Layer 0 hit !");
          information[Trk::expectInnermostPixelLayerHit] = 0;
361
        }
362
      }
363

364
365
      // next to innermost block
      if (information[Trk::numberOfNextToInnermostPixelLayerHits] > 0) {
366
367
        information[Trk::expectNextToInnermostPixelLayerHit] = 1;
      } else {
368
        if (m_testBLayerTool->expectHitInNextToInnermostPixelLayer(&track)) {
369
370
371
372
373
          ATH_MSG_DEBUG("expect Pixel Layer 1 hit !");
          information[Trk::expectNextToInnermostPixelLayerHit] = 1;
        } else {
          ATH_MSG_DEBUG("do not expect Pixel Layer 1 hit !");
          information[Trk::expectNextToInnermostPixelLayerHit] = 0;
374
        }
375
      }
376
377
    }
  }
378

379
  return;
380
381
}

382
383
384
385
386
387
388
389
390
void
InDet::InDetTrackSummaryHelperTool::updateSharedHitCount(
  const Trk::Track& track,
  const Trk::PRDtoTrackMap* prd_to_track_map,
  Trk::TrackSummary& summary) const
{
  // loop over track states on surface and take pixel / sct to update the shared
  // hit count
  summary.m_information[Trk::numberOfPixelSharedHits] = 0;
391
392
  summary.m_information[Trk::numberOfInnermostPixelLayerSharedHits] = 0;
  summary.m_information[Trk::numberOfNextToInnermostPixelLayerSharedHits] = 0;
393
394
395
396
397
398
  summary.m_information[Trk::numberOfSCTSharedHits] = 0;
  summary.m_information[Trk::numberOfTRTSharedHits] = 0;
  if (m_runningTIDE_Ambi) {
    summary.m_information[Trk::numberOfPixelSplitHits] = 0;
    summary.m_information[Trk::numberOfInnermostLayerSplitHits] = 0;
    summary.m_information[Trk::numberOfNextToInnermostLayerSplitHits] = 0;
399
400
  }

401
  const EventContext& ctx = Gaudi::Hive::currentContext();
402
403
404
405
  const DataVector<const Trk::MeasurementBase>* measurements =
    track.measurementsOnTrack();
  if (measurements) {
    for (const auto* const ms : *measurements) {
406
      // check if it's a rot
407
408
409
410
      const Trk::RIO_OnTrack* rot = nullptr;
      if (ms->type(Trk::MeasurementBaseType::RIO_OnTrack)) {
        rot = static_cast<const Trk::RIO_OnTrack*>(ms);
      }
411
      if (rot) {
412
        const Identifier& id = rot->identify();
413
        if (m_doSharedHits and m_usePixel and m_pixelId->is_pixel(id)) {
414
          // check if shared
415
          bool hitIsSplit(false);
416
          if (m_runningTIDE_Ambi) {
417
            const PixelClusterOnTrack* pix = nullptr;
418
419
420
            if (rot->rioType(Trk::RIO_OnTrackType::PixelCluster)) {
              pix = static_cast<const PixelClusterOnTrack*>(rot);
            }
421
422
            if (pix) {
              const InDet::PixelCluster* pixPrd = pix->prepRawData();
423
424
              const Trk::ClusterSplitProbabilityContainer::ProbabilityInfo&
                splitProb = getClusterSplittingProbability(ctx, pixPrd);
425
              if (pixPrd and splitProb.isSplit()) {
426
                summary.m_information[Trk::numberOfPixelSplitHits]++;
427
428
429
                hitIsSplit = true;
                if (m_pixelId->is_barrel(id) and
                    m_pixelId->layer_disk(id) == 0) {
430
431
                  summary.m_information[Trk::numberOfInnermostLayerSplitHits]++;
                }
432
433
                if (m_pixelId->is_barrel(id) and
                    m_pixelId->layer_disk(id) == 1) {
434
435
436
                  summary.m_information
                    [Trk::numberOfNextToInnermostLayerSplitHits]++;
                }
437
438
439
              }
            }
          }
440
          // If we are running the TIDE ambi don't count split hits as shared
441
          if (not(m_runningTIDE_Ambi and hitIsSplit)) {
442
            if (isShared(prd_to_track_map, m_assoTool, *(rot->prepRawData()))) {
443
444
              ATH_MSG_DEBUG("shared Pixel hit found");
              summary.m_information[Trk::numberOfPixelSharedHits]++;
445
446
447
448
449
450
451
452
453
454
455
456
              if ((m_pixelId->is_barrel(id) and
                   m_pixelId->layer_disk(id) == 0)) {
                ATH_MSG_DEBUG(
                  "--> shared Pixel hit is in Innermost Pixel layer");
                summary
                  .m_information[Trk::numberOfInnermostPixelLayerSharedHits]++;
              } else if ((m_pixelId->is_barrel(id) and
                          m_pixelId->layer_disk(id) == 1)) {
                ATH_MSG_DEBUG(
                  "--> shared Pixel hit is in Next To Innermost Pixel layer");
                summary.m_information
                  [Trk::numberOfNextToInnermostPixelLayerSharedHits]++;
457
458
459
              }
            }
          }
460
        } else if (m_doSharedHits and m_useSCT and m_sctId->is_sct(id)) {
461
          // used in more than one track ?
462
          if (isShared(prd_to_track_map, m_assoTool, *(rot->prepRawData()))) {
463
464
465
466
467
468
            ATH_MSG_DEBUG("shared SCT hit found");
            summary.m_information[Trk::numberOfSCTSharedHits]++;
          }
        }
        if (m_doSharedHitsTRT and m_useTRT and m_trtId->is_trt(id)) {
          // used in more than one track ?
469
          if (isShared(prd_to_track_map, m_assoTool, *(rot->prepRawData()))) {
470
471
472
473
474
            ATH_MSG_DEBUG("shared TRT hit found");
            summary.m_information[Trk::numberOfTRTSharedHits]++;
          }
        }
      }
475
    }
476
477
  }
  return;
478
479
}

480
481
void
InDet::InDetTrackSummaryHelperTool::updateExpectedHitInfo(
482
  const EventContext& ctx,
483
484
485
  const Trk::Track& track,
  Trk::TrackSummary& summary) const
{
486

487
  if (m_usePixel and not m_testBLayerTool.empty()) {
488

489
    if (summary.m_information[Trk::numberOfContribPixelLayers] == 0) {
490
      ATH_MSG_DEBUG("No pxiels on track, so wo do not expect a B-Layer hit !");
491
      summary.m_information[Trk::expectInnermostPixelLayerHit] = 0;
492
      summary.m_information[Trk::expectNextToInnermostPixelLayerHit] = 0;
493
494
495
496
497
    } else {
      // innermost layer block
      if (summary.m_information[Trk::numberOfInnermostPixelLayerHits] > 0) {
        ATH_MSG_DEBUG("Innermost pixel Layer hit on track, so we expect a "
                      "innermost pixel layer hit !");
498
        summary.m_information[Trk::expectInnermostPixelLayerHit] = 1;
499
      } else {
500
        if (m_testBLayerTool->expectHitInInnermostPixelLayer(ctx, &track)) {
501
502
          ATH_MSG_DEBUG("expect Pixel Layer 0 hit !");
          summary.m_information[Trk::expectInnermostPixelLayerHit] = 1;
503
        } else {
504
505
          ATH_MSG_DEBUG("do not expect Pixel Layer 0 hit !");
          summary.m_information[Trk::expectInnermostPixelLayerHit] = 0;
506
        }
507
      }
508

509
510
511
      // next to innermost block
      if (summary.m_information[Trk::numberOfNextToInnermostPixelLayerHits] >
          0) {
512
        summary.m_information[Trk::expectNextToInnermostPixelLayerHit] = 1;
513
      } else {
514
515
        if (m_testBLayerTool->expectHitInNextToInnermostPixelLayer(ctx,
                                                                   &track)) {
516
517
518
519
520
521
          ATH_MSG_DEBUG("expect Pixel Layer 1 hit !");
          summary.m_information[Trk::expectNextToInnermostPixelLayerHit] = 1;
        } else {
          ATH_MSG_DEBUG("do not expect Pixel Layer 1 hit !");
          summary.m_information[Trk::expectNextToInnermostPixelLayerHit] = 0;
        }
522
523
      }
    }
524
  }
525

526
527
528
  return;
}

529
530
531
532
533
534
535
536
void
InDet::InDetTrackSummaryHelperTool::updateAdditionalInfo(
  Trk::TrackSummary& summary,
  std::vector<float>& eprob,
  float& dedx,
  int& nclus,
  int& noverflowclus) const
{
537
538
  summary.m_eProbability = eprob;
  summary.m_dedx = dedx;
539
  summary.m_nhitsdedx = nclus;
540
541
  summary.m_nhitsoverflowdedx = noverflowclus;

542
  return;
543
544
}

545
546
547
548
549
550
void
InDet::InDetTrackSummaryHelperTool::addDetailedTrackSummary(
  const EventContext& ctx,
  const Trk::Track& track,
  Trk::TrackSummary& summary) const
{
551
  if (summary.m_indetTrackSummary and not m_overwriteidsummary) {
552
553
    ATH_MSG_DEBUG("TrackSummary already has detailed indet track summary, not "
                  "adding a new one");
554
555
556
    return;
  }
  if (not m_usePixel) {
557
558
    ATH_MSG_DEBUG(
      "Pixels are off, so no need for an detailed indet track summary");
559
560
561
    return;
  }
  ATH_MSG_DEBUG("Adding detailed indet track summary");
562
  summary.m_indetTrackSummary.reset();
563
  Trk::InDetTrackSummary* indetTrackSummary = new Trk::InDetTrackSummary();
564
565
566
  Trk::InDetTrackSummary& trackSummary = *indetTrackSummary;
  if (m_usePixel and not m_pixeldedxtool.empty() and
      (track.perigeeParameters() or not track.trackParameters()->empty())) {
567
    const Trk::TrackParameters* par = track.perigeeParameters();
568

569
    if (par == nullptr) {
570
571
572
573
574
575
      par = *track.trackParameters()->begin();
    }
    double p = (par->parameters()[Trk::qOverP] != 0)
                 ? 1. / par->parameters()[Trk::qOverP]
                 : 1.e15;
    double dedx = summary.getPixeldEdx();
576
    int ngoodhits = summary.numberOfUsedHitsdEdx();
577
578
579
580
581
582
    if (ngoodhits > 0 and dedx > 0 and
        track.info().trackFitter() != Trk::TrackInfo::Unknown and p < 1.e15) {
      trackSummary.m_likelihoodspixeldedx =
        m_pixeldedxtool->getLikelihoods(ctx, dedx, p, ngoodhits);
      trackSummary.m_massdedx =
        m_pixeldedxtool->getMass(ctx, dedx, p, ngoodhits);
583
584
    }
  }
585
  summary.m_indetTrackSummary.reset(indetTrackSummary);
586
587
}

588
589
590
StatusCode
InDet::InDetTrackSummaryHelperTool::finalize()
{
591
  return StatusCode::SUCCESS;
592
}