ATLAS Offline Software
FPGATrackSimOutputHeaderTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
8 
9 FPGATrackSimOutputHeaderTool::FPGATrackSimOutputHeaderTool(std::string const & algname, std::string const & name, IInterface const * ifc) :
10  AthAlgTool(algname,name,ifc) {}
11 
12 
13 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
15 {
16  // close old file (I don't think we delete the pointer. Does ROOT handle that?)
17  if (m_infile && m_infile->IsOpen()) m_infile->Close();
18 
19  // open new file
20  ATH_MSG_DEBUG ("Opening file " << path.c_str() << " in " << m_rwoption.value() << " mode.");
21  m_infile = TFile::Open(path.c_str(), m_rwoption.value().c_str());
22 
23  if (!m_infile) {
24  ATH_MSG_FATAL("Could not open input file: " << path);
25  return StatusCode::FAILURE;
26  }
27 
28  if (m_rwoption.value() == std::string("READ")) {
29  // get the tree
30  m_EventTree = (TTree*) m_infile->Get(m_treeName.value().c_str());
31  if (!m_EventTree || m_EventTree->GetEntries() == -1) {
32  ATH_MSG_FATAL ("Input file: " << m_inpath.value() << " has no entries");
33  return StatusCode::FAILURE;
34  }
35 
36  ATH_MSG_INFO ("Input file: " << path << " has " << m_EventTree->GetEntries() << " event entries.");
37  }
38 
39  m_infile->cd();
40  m_event = 0;
41  return StatusCode::SUCCESS;
42 }
43 
44 // Since now the list of branches to read gets configured by algorithms, we can't do this in initialize().
45 // We could use properties to pass the branch names to this tool, but the algorithms would need to know those
46 // names too, so it may make more sense to store them as properties on individual algorithms.
47 
48 // Also... the properties would have to be a vector because we can have an arbitrary number of input and output headers.
49 // Perhaps we don't actually *need* an arbitrary number of input and output headers but I think it's best to allow for it.
50 
52 
53  // Don't do anything
54  if (m_rwoption.value() != std::string("READ")) {
55  ATH_MSG_FATAL("Called configureReadBranches() when ROOT file was not opened in READ mode.");
56  return StatusCode::FAILURE;
57  }
58 
59  // In read mode, we want to make sure the configured branches are actually available.
60  // Configuration is via a function call (to allow different algorithms to set up different numbers of branches).
61  for (unsigned i = 0; i < m_branchNameIns.size(); i++) {
62  std::string branchName = m_branchNameIns.at(i);
63  if (!m_EventTree->GetListOfBranches()->FindObject(branchName.c_str())) {
64  ATH_MSG_FATAL("Configured input branch: " << branchName << " not found!");
65  return StatusCode::FAILURE;
66  }
67  TBranch *branchIn = m_EventTree->GetBranch(branchName.c_str());
68  branchIn->SetAddress(&(m_eventInputHeaders.at(i)));
69  m_EventTree->SetBranchStatus(branchName.c_str(), 1);
70  }
71 
72  // Do the same thing for the output branches. In fact we could maybe combine these loops by making a function.
73  for (unsigned i = 0; i < m_branchNameOuts.size(); i++) {
74  std::string branchName = m_branchNameOuts.at(i);
75  if (!m_EventTree->GetListOfBranches()->FindObject(branchName.c_str())) {
76  ATH_MSG_FATAL("Configured output branch: " << branchName << " not found!");
77  return StatusCode::FAILURE;
78  }
79  TBranch *branchIn = m_EventTree->GetBranch(branchName.c_str());
80  branchIn->SetAddress(&(m_eventOutputHeaders.at(i)));
81  m_EventTree->SetBranchStatus(branchName.c_str(), 1);
82  }
83 
84  return StatusCode::SUCCESS;
85 }
86 
87 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
89 {
90  // Dump the configuration to make sure it propagated through right
91  const std::vector<Gaudi::Details::PropertyBase*> props = this->getProperties();
92  for( Gaudi::Details::PropertyBase* prop : props ) {
93  if (prop->ownerTypeName()==this->type()) {
94  ATH_MSG_DEBUG("Property:\t" << prop->name() << "\t : \t" << prop->toString());
95  }
96  }
97 
98  ATH_CHECK(m_tHistSvc.retrieve());
99 
100  if( m_rwoption.value()!=std::string("HEADER"))
101  {
102  if (m_inpath.value().empty())
103  {
104  ATH_MSG_ERROR("Empty input file list");
105  return StatusCode::FAILURE;
106  }
107  ATH_CHECK(openFile(m_inpath.value().front()));
108  }
109 
110  if (m_rwoption.value() == std::string("READ")) {
111  ATH_MSG_DEBUG ("Initialized in READ MODE");
112  } else if (m_rwoption.value()==std::string("RECREATE") || m_rwoption.value()==std::string("HEADER")) {
113 
114  // branches are NO LONGER created here, the user needs to do this.
115  m_EventTree = new TTree(m_treeName.value().c_str(), "data");
116 
117  // For HEADER-- use THistSvc explicitly to set things up.
118  if (m_rwoption.value() == std::string("HEADER")) {
119  ATH_CHECK(m_tHistSvc->regTree(Form("/FPGATRACKSIMOUTPUT/%s", m_treeName.value().c_str()), m_EventTree));
120  }
121 
122  } else {
123  ATH_MSG_ERROR ("RWstatus = " << m_rwoption.value() << " is not allowed!");
124  return StatusCode::FAILURE;
125  }
126 
127  m_event = 0; // in file
128  m_totevent = 0; // total counter
129  return StatusCode::SUCCESS;
130 }
131 
132 // Create a new input or output branch and return a pointer to the header object so code can write to it.
133 // These functions work for both reading and writing.
137  m_branchNameIns.push_back(branchName);
138  if (write) {
139  m_EventTree->Branch(branchName.c_str(), "FPGATrackSimLogicalEventInputHeader", inputHeader);
140  }
141  return inputHeader;
142 }
143 
147  m_branchNameOuts.push_back(branchName);
148  if (write) {
149  m_EventTree->Branch(branchName.c_str(), "FPGATrackSimLogicalEventOutputHeader", outputHeader);
150  }
151  return outputHeader;
152 }
153 
154 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
156 {
157  ATH_MSG_INFO ("finalize: closing files");
158 
159  if (m_rwoption.value() == std::string("RECREATE")) {
160  ATH_MSG_INFO ("Contains " << m_EventTree->GetEntries() << " entries, over " << m_event << " events run");
161  // close the output files, but check that it exists (for athenaMP)
162  m_infile->Write();
163  }
164 
165  if (m_rwoption.value() != std::string("HEADER")) {
166  m_infile->Close();
167  }
168 
169  // deleting pointers
170  for (auto* header : m_eventInputHeaders) delete header;
171  for (auto* header : m_eventOutputHeaders) delete header;
172 
173  return StatusCode::SUCCESS;
174 }
175 
176 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
177 // This version of writeData assumes that the header objects were created using addInputBranch and addOutputBranch
178 // and so don't need to be passed back to the tool.
180 
181  if (m_rwoption.value() == std::string("READ")) {
182  ATH_MSG_WARNING ("Asked to write file in READ mode");
183  return StatusCode::SUCCESS;
184  }
185 
186  ATH_MSG_DEBUG ("Writing data in TTree, event cnt=" << m_event << " limit=" << m_eventLimit << " activated" << m_activated);
187 
188  // Interpret -1 as no limit.
189  if ((m_event < static_cast<unsigned>(m_eventLimit) || m_eventLimit < 0) &&
191  m_EventTree->Fill();
192  m_event++;
193  m_activated=0;
194 
195  for (unsigned i = 0; i < m_eventInputHeaders.size(); i++) {
196  ATH_MSG_DEBUG("Wrote event " << m_event << " in input header (" << m_branchNameIns.at(i) << ") event " << m_eventInputHeaders.at(i)->event());
197  }
198  for (unsigned i = 0; i < m_eventOutputHeaders.size(); i++) {
199  ATH_MSG_DEBUG("Wrote event " << m_event << " in output header (" << m_branchNameOuts.at(i) << ")");
200  ATH_MSG_DEBUG("n.roads_1st = " << m_eventOutputHeaders.at(i)->nFPGATrackSimRoads_1st());
201  ATH_MSG_DEBUG("n.roads_2nd = " << m_eventOutputHeaders.at(i)->nFPGATrackSimRoads_2nd());
202  ATH_MSG_DEBUG("n.tracks_1st = " << m_eventOutputHeaders.at(i)->nFPGATrackSimTracks_1st());
203  ATH_MSG_DEBUG("n.tracks_2nd = " << m_eventOutputHeaders.at(i)->nFPGATrackSimTracks_2nd());
204  }
205  }
206 
207  // Reset any input headers that we wrote out (with debugging prints).
208  for (unsigned i = 0; i < m_eventInputHeaders.size(); i++) {
209  m_eventInputHeaders.at(i)->reset();
210  }
211 
212  // Reset any output headers that we wrote out (With debugging prints).
213  for (unsigned i = 0; i < m_eventOutputHeaders.size(); i++) {
214  m_eventOutputHeaders.at(i)->reset();
215  }
216 
217  // Only return FAILURe if there were no input AND output headers (i.e. something is misconfigured).
218  if (m_eventInputHeaders.size() == 0 and m_eventOutputHeaders.size() == 0) {
219  ATH_MSG_ERROR("Tried to fill output ROOT file with no configured input or output headers.");
220  return StatusCode::FAILURE;
221  }
222 
223  return StatusCode::SUCCESS;
224 }
225 
226 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
227 // Since the branches are now created using the same set of functions the user already has a pointer to the object.
228 // So in this function we just need to reset those objects, test last, and... call GetEntry I think.
230 {
231  if (m_rwoption.value() != std::string("READ")) {
232  ATH_MSG_WARNING ("Asked to read file that is not in READ mode");
233  return StatusCode::SUCCESS;
234  }
235 
236  for (auto* header : m_eventInputHeaders) {
237  header->reset();
238  }
239 
240  for (auto* header : m_eventOutputHeaders) {
241  header->reset();
242  }
243 
244  ATH_MSG_DEBUG ("Asked Event " << m_event << " in this file; current total is " << m_totevent);
245  last = false;
246  if (m_event >= m_EventTree->GetEntries()) {
247  if (++m_file < m_inpath.value().size()) {
248  ATH_CHECK(openFile(m_inpath.value().at(m_file)));
249  // If opening a new file we need to update the branch addresses.
251  }
252  else {
253  last = true;
254  return StatusCode::SUCCESS;
255  }
256  }
257 
258  // Read the objects. I removed some of the debug messages here, they could be readded.
259  for (const std::string& branchName : m_branchNameIns) {
260  int statIn = m_EventTree->GetBranch(branchName.c_str())->GetEntry(m_event);
261  if (statIn <= 0) ATH_MSG_WARNING("Error in reading from branch " << branchName);
262  }
263 
264  for (const std::string& branchName : m_branchNameOuts) {
265  int statOut = m_EventTree->GetBranch(branchName.c_str())->GetEntry(m_event);
266  if (statOut <= 0) ATH_MSG_WARNING("Error in reading from branch " << branchName);
267  }
268 
269  m_event++;
270  m_totevent++;
271 
272  return StatusCode::SUCCESS;
273 }
274 
FPGATrackSimOutputHeaderTool::m_tHistSvc
ServiceHandle< ITHistSvc > m_tHistSvc
Definition: FPGATrackSimOutputHeaderTool.h:72
FPGATrackSimOutputHeaderTool::readData
StatusCode readData(bool &last)
Definition: FPGATrackSimOutputHeaderTool.cxx:229
FPGATrackSimOutputHeaderTool::m_branchNameOuts
std::vector< std::string > m_branchNameOuts
Definition: FPGATrackSimOutputHeaderTool.h:91
getMenu.algname
algname
Definition: getMenu.py:54
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
FPGATrackSimLogicalEventInputHeader
Definition: FPGATrackSimLogicalEventInputHeader.h:21
header
Definition: hcg.cxx:527
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
FPGATrackSimOutputHeaderTool::openFile
StatusCode openFile(std::string const &path)
Definition: FPGATrackSimOutputHeaderTool.cxx:14
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ByteStreamConfig.write
def write
Definition: Event/ByteStreamCnvSvc/python/ByteStreamConfig.py:249
FPGATrackSimOutputHeaderTool::m_eventLimit
Gaudi::Property< int > m_eventLimit
Definition: FPGATrackSimOutputHeaderTool.h:75
FPGATrackSimOutputHeaderTool::finalize
virtual StatusCode finalize() override
Definition: FPGATrackSimOutputHeaderTool.cxx:155
FPGATrackSimOutputHeaderTool::m_branchNameIns
std::vector< std::string > m_branchNameIns
Definition: FPGATrackSimOutputHeaderTool.h:90
FPGATrackSimOutputHeaderTool::m_file
std::atomic< unsigned > m_file
Definition: FPGATrackSimOutputHeaderTool.h:83
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
FPGATrackSimOutputHeaderTool::configureReadBranches
StatusCode configureReadBranches()
Definition: FPGATrackSimOutputHeaderTool.cxx:51
lumiFormat.i
int i
Definition: lumiFormat.py:85
FPGATrackSimOutputHeaderTool::m_rwoption
Gaudi::Property< std::string > m_rwoption
Definition: FPGATrackSimOutputHeaderTool.h:66
FPGATrackSimLogicalEventOutputHeader.h
FPGATrackSimOutputHeaderTool::addInputBranch
FPGATrackSimLogicalEventInputHeader * addInputBranch(const std::string &branchName, bool write=true)
Definition: FPGATrackSimOutputHeaderTool.cxx:134
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
FPGATrackSimOutputHeaderTool::addOutputBranch
FPGATrackSimLogicalEventOutputHeader * addOutputBranch(const std::string &branchName, bool write=true)
Definition: FPGATrackSimOutputHeaderTool.cxx:144
FPGATrackSimOutputHeaderTool::m_infile
TFile * m_infile
Definition: FPGATrackSimOutputHeaderTool.h:93
FPGATrackSimOutputHeaderTool::m_EventTree
TTree * m_EventTree
Definition: FPGATrackSimOutputHeaderTool.h:94
FPGATrackSimOutputHeaderTool::m_treeName
Gaudi::Property< std::string > m_treeName
Definition: FPGATrackSimOutputHeaderTool.h:69
FPGATrackSimOutputHeaderTool::m_eventInputHeaders
std::vector< FPGATrackSimLogicalEventInputHeader * > m_eventInputHeaders
Definition: FPGATrackSimOutputHeaderTool.h:87
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
FPGATrackSimOutputHeaderTool::m_inpath
Gaudi::Property< std::vector< std::string > > m_inpath
Definition: FPGATrackSimOutputHeaderTool.h:62
FPGATrackSimOutputHeaderTool::m_activated
bool m_activated
Definition: FPGATrackSimOutputHeaderTool.h:84
FPGATrackSimOutputHeaderTool::m_event
std::atomic< unsigned > m_event
Definition: FPGATrackSimOutputHeaderTool.h:81
FPGATrackSimOutputHeaderTool.h
FPGATrackSimOutputHeaderTool::FPGATrackSimOutputHeaderTool
FPGATrackSimOutputHeaderTool(const std::string &, const std::string &, const IInterface *)
Definition: FPGATrackSimOutputHeaderTool.cxx:9
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
FPGATrackSimOutputHeaderTool::m_totevent
std::atomic< unsigned > m_totevent
Definition: FPGATrackSimOutputHeaderTool.h:82
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
FPGATrackSimOutputHeaderTool::m_requireActivation
Gaudi::Property< bool > m_requireActivation
Definition: FPGATrackSimOutputHeaderTool.h:78
FPGATrackSimOutputHeaderTool::writeData
StatusCode writeData()
Definition: FPGATrackSimOutputHeaderTool.cxx:179
FPGATrackSimLogicalEventOutputHeader
Definition: FPGATrackSimLogicalEventOutputHeader.h:12
FPGATrackSimOutputHeaderTool::m_eventOutputHeaders
std::vector< FPGATrackSimLogicalEventOutputHeader * > m_eventOutputHeaders
Definition: FPGATrackSimOutputHeaderTool.h:88
AthAlgTool
Definition: AthAlgTool.h:26
makeTOC.header
header
Definition: makeTOC.py:28
FPGATrackSimLogicalEventInputHeader.h
FPGATrackSimOutputHeaderTool::initialize
virtual StatusCode initialize() override
Definition: FPGATrackSimOutputHeaderTool.cxx:88