Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HitsPrinter.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file HitsPrinter.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include "HitsPrinter.hpp"
10 
18 
19 #include <algorithm>
20 #include <ostream>
21 #include <stdexcept>
22 #include <utility>
23 #include <vector>
24 
27  : IAlgorithm("HitsPrinter", level), m_cfg(cfg) {
28  if (m_cfg.inputClusters.empty()) {
29  throw std::invalid_argument("Input clusters collection is not configured");
30  }
31  if (m_cfg.inputMeasurementParticlesMap.empty()) {
32  throw std::invalid_argument(
33  "Input hit-particles map collection is not configured");
34  }
35  if (m_cfg.inputHitIds.empty()) {
36  throw std::invalid_argument("Input hit ids collection is not configured");
37  }
38 
42 }
43 
45  const ActsExamples::AlgorithmContext& ctx) const {
46  const auto& clusters = m_inputClusters(ctx);
47  const auto& hitParticlesMap = m_inputMeasurementParticlesMap(ctx);
48  const auto& hitIds = m_inputHitIds(ctx);
49 
50  if (clusters.size() != hitIds.size()) {
51  ACTS_ERROR(
52  "event "
53  << ctx.eventNumber
54  << " input clusters and hit ids collections have inconsistent size");
55  return ProcessCode::ABORT;
56  }
57  ACTS_INFO("event " << ctx.eventNumber << " collection '"
58  << m_cfg.inputClusters << "' contains " << clusters.size()
59  << " hits");
60 
61  // print hits selected by index
62  if (0 < m_cfg.selectIndexLength) {
63  size_t ihit = m_cfg.selectIndexStart;
64  // Saturated addition that does not overflow and exceed SIZE_MAX.
65  // From http://locklessinc.com/articles/sat_arithmetic/
66  size_t nend = ihit + m_cfg.selectIndexLength;
67  nend |= -static_cast<int>(nend < ihit);
68  // restrict to available hits
69  nend = std::min(clusters.size(), nend);
70 
71  if (nend <= ihit) {
72  ACTS_WARNING("event "
73  << ctx.eventNumber << " collection '" << m_cfg.inputClusters
74  << " hit index selection is outside the available range");
75  } else {
76  ACTS_INFO("event " << ctx.eventNumber << " collection '"
77  << m_cfg.inputClusters << "' contains "
78  << (nend - ihit) << " hits in index selection ["
79  << m_cfg.selectIndexStart << ", "
80  << m_cfg.selectIndexLength << ")");
81 
82  Acts::GeometryIdentifier prevGeoId;
83  for (; ihit < nend; ++ihit) {
84  // ihit is already known to be within the available cluster range.
85  // the `ic` iterator does not need to be checked for validity.
86  auto ic = clusters.nth(ihit);
87  Acts::GeometryIdentifier geoId = ic->first;
88  const Acts::PlanarModuleCluster& c = ic->second;
89  auto hitId = hitIds.at(ihit);
90 
91  if (geoId != prevGeoId) {
92  ACTS_INFO("on geometry id " << geoId);
93  prevGeoId = geoId;
94  }
95  ACTS_INFO(" cluster " << ihit << " hit " << hitId << " size "
96  << c.digitizationCells().size());
97  // get all contributing particles
98  for (auto [hid, pid] : makeRange(hitParticlesMap.equal_range(ihit))) {
99  ACTS_INFO(" generated by particle " << pid);
100  }
101  }
102  }
103  }
104 
105  // print hits within geometry selection
106  auto geoSelection = makeRange(clusters.begin(), clusters.begin());
107  if (m_cfg.selectModule != 0u) {
108  geoSelection = selectModule(clusters, m_cfg.selectVolume, m_cfg.selectLayer,
109  m_cfg.selectModule);
110  } else if (m_cfg.selectLayer != 0u) {
111  geoSelection = selectLayer(clusters, m_cfg.selectVolume, m_cfg.selectLayer);
112  } else if (m_cfg.selectVolume != 0u) {
113  geoSelection = selectVolume(clusters, m_cfg.selectVolume);
114  }
115  if (not geoSelection.empty()) {
116  ACTS_INFO("event " << ctx.eventNumber << " collection '"
117  << m_cfg.inputClusters << "' contains "
118  << geoSelection.size() << " hits in volume "
119  << m_cfg.selectVolume << " layer " << m_cfg.selectLayer
120  << " module " << m_cfg.selectModule);
121  // we could also use for (const Acts::PlanarModuleCluster& c : rangeModule)
122  // for simplicity, but then we could not get the hit index.
123  Acts::GeometryIdentifier prevGeoId;
124  for (auto ic = geoSelection.begin(); ic != geoSelection.end(); ++ic) {
125  auto ihit = clusters.index_of(ic);
126  auto hitId = hitIds[ihit];
127 
128  Acts::GeometryIdentifier geoId = ic->first;
129  const Acts::PlanarModuleCluster& c = ic->second;
130  if (geoId != prevGeoId) {
131  ACTS_INFO("on geometry id " << geoId);
132  prevGeoId = geoId;
133  }
134  ACTS_INFO(" cluster " << ihit << " hit " << hitId << " size "
135  << c.digitizationCells().size());
136  // get all contributing particles
137  for (auto [hid, pid] : makeRange(hitParticlesMap.equal_range(ihit))) {
138  ACTS_INFO(" generated by particle " << pid);
139  }
140  }
141  }
142 
143  return ProcessCode::SUCCESS;
144 }