ATLAS Offline Software
RootExCellWriter.icc
Go to the documentation of this file.
1 // Dear emacs, this is -*- c++ -*-
2 /*
3  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
4 */
5 
6 // This file was largely imported from the Acts testing framework
7 
8 #include <ios>
9 #include <stdexcept>
10 #include <forward_list>
11 #include "Acts/Utilities/Helpers.hpp"
12 #include "Acts/Geometry/GeometryIdentifier.hpp"
13 
14 template <class T>
15 void
16 RootExCellWriter<T>::write(
17  const Acts::ExtrapolationCell<T>& eCell, int eventNum)
18 {
19  using Acts::VectorHelpers::eta;
20  using Acts::VectorHelpers::phi;
21  using Acts::VectorHelpers::perp;
22 
23  // exclusive access to the tree
24  std::lock_guard<std::mutex> lock(m_writeMutex);
25 
26  // loop over all the extrapolation cells
27  // the event paramters
28  auto sMomentum = eCell.startParameters->momentum();
29  m_eta = eta(sMomentum);
30  m_phi = phi(sMomentum);
31  m_materialX0 = eCell.materialX0;
32  m_materialL0 = eCell.materialL0;
33 
34  m_eventNum = eventNum;
35 
36 
37  // clear the vectors & reserve
38  // - for main step information
39  m_s_positionX.clear();
40  m_s_positionY.clear();
41  m_s_positionZ.clear();
42  m_s_positionR.clear();
43  m_s_volumeID.clear();
44  m_s_layerID.clear();
45  m_s_surfaceID.clear();
46  m_s_positionX.reserve(MAXSTEPS);
47  m_s_positionY.reserve(MAXSTEPS);
48  m_s_positionZ.reserve(MAXSTEPS);
49  m_s_positionR.reserve(MAXSTEPS);
50  m_s_volumeID.reserve(MAXSTEPS);
51  m_s_layerID.reserve(MAXSTEPS);
52  m_s_surfaceID.reserve(MAXSTEPS);
53 
54  // - for the sensitive
55  if (m_cfg.writeSensitive) {
56  m_s_sensitive.clear();
57  m_s_localposition0.clear();
58  m_s_localposition1.clear();
59  m_s_sensitive.reserve(MAXSTEPS);
60  m_s_localposition0.reserve(MAXSTEPS);
61  m_s_localposition1.reserve(MAXSTEPS);
62  }
63  // - for the material
64  if (m_cfg.writeMaterial) {
65  m_s_material.clear();
66  m_s_materialX0.clear();
67  m_s_materialL0.clear();
68  m_s_material.reserve(MAXSTEPS);
69  m_s_materialX0.reserve(MAXSTEPS);
70  m_s_materialL0.reserve(MAXSTEPS);
71  }
72  // - for the boundary
73  if (m_cfg.writeBoundary) {
74  m_s_boundary.clear();
75  m_s_boundary.reserve(MAXSTEPS);
76  }
77  // the number of sensitive hits per event
78  m_hits = 0;
79  // loop over extrapolation steps
80  for (auto& es : eCell.extrapolationSteps) {
81  if (es.parameters) {
82  /// step parameters
83  const T& pars = (*es.parameters);
84  /// type information
85  int material = es.configuration.checkMode(
86  Acts::ExtrapolationMode::CollectMaterial);
87  int boundary = es.configuration.checkMode(
88  Acts::ExtrapolationMode::CollectBoundary);
89  int sensitive = es.configuration.checkMode(
90  Acts::ExtrapolationMode::CollectSensitive);
91  int passive = es.configuration.checkMode(
92  Acts::ExtrapolationMode::CollectPassive);
93 
94  /// check the layer, surface, volume ID
95  geo_id_value volumeID = pars.referenceSurface().geometryId().value(
96  Acts::GeometryIdentifier::volume_mask);
97  geo_id_value layerID = pars.referenceSurface().geometryId().value(
98  Acts::GeometryIdentifier::layer_mask);
99  geo_id_value surfaceID = pars.referenceSurface().geometryId().value(
100  Acts::GeometryIdentifier::sensitive_mask);
101 
102  ///
103  if ((m_cfg.writeSensitive && sensitive)
104  || (m_cfg.writeBoundary && boundary)
105  || (m_cfg.writeMaterial && material)
106  || (m_cfg.writePassive && passive)) {
107 
108  // the material steps
109  if (m_cfg.writeMaterial) {
110  // the material is being written out
111  double materialStepX0 = 0.;
112  double materialStepL0 = 0.;
113  if (es.material) {
114  // assign the material
115  materialStepX0
116  = es.materialScaling * es.material->thicknessInX0();
117  materialStepX0
118  = es.materialScaling * es.material->thicknessInL0();
119  }
120  m_s_materialX0.push_back(materialStepX0);
121  m_s_materialX0.push_back(materialStepL0);
122  }
123 
124  /// goblal position information
125  m_s_positionX.push_back(pars.position().x());
126  m_s_positionY.push_back(pars.position().y());
127  m_s_positionZ.push_back(pars.position().z());
128  m_s_positionR.push_back(perp(pars.position()));
129 
130  /// local position information - only makes sense for sensitive really
131  if (m_cfg.writeSensitive) {
132  m_s_localposition0.push_back(pars.parameters()[Acts::eLOC_X]);
133  m_s_localposition1.push_back(pars.parameters()[Acts::eLOC_Y]);
134  }
135  /// volume, layer and surface ID
136  m_s_volumeID.push_back(volumeID);
137  m_s_layerID.push_back(layerID);
138  m_s_surfaceID.push_back(surfaceID);
139  /// indicate what hit you have
140  m_s_material.push_back(material);
141  m_s_boundary.push_back(boundary);
142  m_s_sensitive.push_back(sensitive);
143  }
144  if (sensitive) m_hits++;
145  }
146  }
147  m_outputTree->Fill();
148 }
149 
150 template <class T>
151 RootExCellWriter<T>::RootExCellWriter(
152  const RootExCellWriter<T>::Config& cfg
153  //Acts::Logging::Level level
154  )
155  : m_cfg(cfg)
156  , m_outputFile(nullptr)
157  , m_outputTree(nullptr)
158 {
159  // Validate the configuration
160  /*if (m_cfg.collection.empty()) {
161  throw std::invalid_argument("Missing input collection");
162  } else*/ if (m_cfg.treeName.empty()) {
163  throw std::invalid_argument("Missing tree name");
164  }
165 
166  // Setup ROOT I/O
167  m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str());
168  if (!m_outputFile) {
169  throw std::ios_base::failure("Could not open '" + m_cfg.filePath);
170  }
171  m_outputFile->cd();
172  //not sure why I need this:
173  //cppcheck-suppress noCopyConstructor
174  m_outputTree
175  = new TTree(m_cfg.treeName.c_str(), "TTree from RootPlanarClusterWriter");
176  if (!m_outputTree) throw std::bad_alloc();
177 
178  // Initial parameters
179  m_outputTree->Branch("eta", &m_eta);
180  m_outputTree->Branch("phi", &m_phi);
181 
182  m_outputTree->Branch("evtNum", &m_eventNum);
183 
184  // Output the step information
185  m_outputTree->Branch("step_x", &m_s_positionX);
186  m_outputTree->Branch("step_y", &m_s_positionY);
187  m_outputTree->Branch("step_z", &m_s_positionZ);
188  m_outputTree->Branch("step_r", &m_s_positionR);
189 
190  // Identification
191  m_outputTree->Branch("volumeID", &m_s_volumeID);
192  m_outputTree->Branch("layerID", &m_s_layerID);
193  m_outputTree->Branch("surfaceID", &m_s_surfaceID);
194 
195  // Material section
196  if (m_cfg.writeMaterial) {
197  m_outputTree->Branch("material_X0", &m_materialX0);
198  m_outputTree->Branch("material_L0", &m_materialL0);
199  m_outputTree->Branch("step_material_X0", &m_s_materialX0);
200  m_outputTree->Branch("step_material_L0", &m_s_materialL0);
201  m_outputTree->Branch("material", &m_s_material);
202  }
203 
204 
205  // Sensitive section
206  if (m_cfg.writeSensitive) {
207  m_outputTree->Branch("sensitive", &m_s_sensitive);
208  m_outputTree->Branch("step_l0", &m_s_localposition0);
209  m_outputTree->Branch("step_l1", &m_s_localposition1);
210  }
211 
212  // Boundary section
213  if (m_cfg.writeBoundary) m_outputTree->Branch("boundary", &m_s_boundary);
214 
215  // Number of sensitive hits
216  m_outputTree->Branch("hits", &m_hits);
217 }
218 
219 template <class T>
220 RootExCellWriter<T>::~RootExCellWriter()
221 {
222  m_outputFile->Close();
223 }
224 
225 template <class T>
226 void
227 RootExCellWriter<T>::endRun()
228 {
229  m_outputFile->cd();
230  m_outputTree->Write();
231  // ACTS_INFO("Wrote particles to tree '" << m_cfg.treeName << "' in '"
232  // << m_cfg.filePath << "'");
233 }