ATLAS Offline Software
RootConnection.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // RootConnection.cxx
8 // Implementation file for class RootConnection
9 // Author: Peter van Gemmeren <gemmeren@anl.gov>
10 // Author: S.Binet<binet@cern.ch>
12 
13 // AthenaRootComps includes
14 #include "RootConnection.h"
15 
16 // fwk includes
17 #include "GaudiKernel/ServiceHandle.h"
20 #include "DataModelRoot/RootType.h"
21 
22 // ROOT includes
23 #include "TROOT.h"
24 #include "TFile.h"
25 #include "TTree.h"
26 #include "TBranch.h"
27 
28 namespace {
29  char typecode_from_typeid(const std::type_info& ti) {
30  if (ti == typeid(char*)) {
31  return 'C';
32  } else if (ti == typeid(Char_t)) {
33  return 'B';
34  } else if (ti == typeid(UChar_t)) {
35  return 'b';
36  } else if (ti == typeid(Short_t)) {
37  return 'S';
38  } else if (ti == typeid(UShort_t)) {
39  return 's';
40  } else if (ti == typeid(Int_t)) {
41  return 'I';
42  } else if (ti == typeid(UInt_t)) {
43  return 'i';
44  } else if (ti == typeid(Float_t)) {
45  return 'F';
46  } else if (ti == typeid(Double_t)) {
47  return 'D';
48  } else if (ti == typeid(Long64_t)) {
49  return 'L';
50  } else if (ti == typeid(ULong64_t)) {
51  return 'l';
52  } else if (ti == typeid(Bool_t)) {
53  return 'O';
54  } else {
55  return '\0';
56  }
57  }
58 } //> anon-namespace
59 
60 namespace Athena {
61 
62 RootConnection::RootConnection(const IInterface* /*own*/, const std::string& pfn) :
63  m_fid(),
64  m_pfn(pfn),
65  m_file(0),
66  m_tree(0),
67  m_branch(0),
68  m_branchTypeCode('\0') {
69 }
70 
72 }
73 
75  if (m_file == 0) {
76  m_file = TFile::Open(m_pfn.c_str());
77  }
78  if (m_file == 0 || m_file->IsZombie()) {
79  delete m_file; m_file = 0;
80  return StatusCode::FAILURE;
81  }
82  return StatusCode::SUCCESS;
83 }
84 
86  if (m_file == 0) {
87  m_file = TFile::Open(m_pfn.c_str(), mode.c_str(), "AthenaRoot event data file");
88  }
89  if (m_file == 0 || m_file->IsZombie()) {
90  delete m_file; m_file = 0;
91  return StatusCode::FAILURE;
92  }
93  return StatusCode::SUCCESS;
94 }
95 
97  if (m_file == 0) {
98  REPORT_MESSAGE (MSG::ERROR) << "commit: No file connected!";
99  return StatusCode::FAILURE;
100  }
101  if (m_tree !=0 && m_branch != 0) {
102  m_tree->SetEntries(m_branch->GetEntries());
103  }
104  //FIXME: call OptimizeBaskets()
105  //m_tree->AutoSave();
106  //m_tree->FlushBaskets();
107  return StatusCode::SUCCESS;
108 }
109 
111  if (!this->commit().isSuccess()) {
112  return StatusCode::FAILURE;
113  }
114  if (m_tree != 0 && m_file->IsWritable()) {
115  m_file->cd("/");
116  m_tree->Write(); m_tree = 0;
117  }
118  m_file->Close(); m_file = 0;
119  return StatusCode::SUCCESS;
120 }
121 
123  return false;
124 }
125 
126 StatusCode RootConnection::read(void* const /*data*/, size_t /*len*/) {
127  return StatusCode::FAILURE;
128 }
129 
130 StatusCode RootConnection::write(const void* data, unsigned long& len) {
131  void* address ATLAS_THREAD_SAFE = const_cast<void*>(data);
132  if (m_file == 0 || m_tree == 0 || m_branch == 0) {
133  return StatusCode::FAILURE;
134  }
135  if (m_branchTypeCode == '\0') {
136  m_branch->SetAddress(&address);
137  } else {
138  m_branch->SetAddress(address);
139  }
140  int32_t nbytes = m_branch->Fill();
141  if (nbytes < 0) {
142  return StatusCode::FAILURE;
143  }
144  len = m_branch->GetEntryNumber();
145  return StatusCode::SUCCESS;
146 }
147 
148 StatusCode RootConnection::setContainer(const std::string& container, const std::string& type) {
149  if (m_file == 0) {
150  return StatusCode::FAILURE;
151  }
152  std::string treeName(container), branchName;
153  for (std::string::iterator itr = treeName.begin(), iend = treeName.end(); itr != iend; ++itr) {
154  if (*itr == '/') *itr = '_';
155  }
156  std::string::size_type inx1 = container.find('(');
157  if (inx1 != std::string::npos) {
158  std::string::size_type inx2 = container.find(')');
159  if (inx2 == std::string::npos || inx2 != container.size() - 1) {
160  return StatusCode::FAILURE;
161  }
162  branchName = treeName.substr(inx1 + 1, inx2 - inx1 - 1);
163  treeName.resize(inx1);//inx1 was already checked
164  }
165  if (m_tree == 0) {
166  m_tree = (TTree*)m_file->Get(treeName.c_str());
167  }
168  if (m_tree == 0 && m_file->IsWritable()) {
169  int splitlevel = 0; //FIXME: Make configurable
170  m_file->cd("/");
171  m_tree = new TTree(treeName.c_str(), "Main event data tree", splitlevel);
172  m_tree->SetDirectory(m_file);
173  m_tree->Reset();
174  }
175  if (!m_tree)
176  return StatusCode::FAILURE;
177  m_branch = m_tree->GetBranch(branchName.c_str());
179  m_branchTypeCode = ::typecode_from_typeid(root_type.TypeInfo());
180  if (m_branch == 0 && m_file->IsWritable()) {
181  int bufsize = 32000; //FIXME: Make configurable
182  int splitlevel = 0; //FIXME: Make configurable
183  if (m_branchTypeCode == '\0') {
184  m_branch = m_tree->Bronch(branchName.c_str(),
185  type.c_str(),
186  0,
187  bufsize,
188  splitlevel);
189  } else {
190  m_branch = m_tree->Branch(branchName.c_str(),
191  0,
192  (branchName + "/" + m_branchTypeCode).c_str(),
193  bufsize);
194  }
195  if (m_branch != 0) {
196  // let the Athena framework deal with deletion
197  m_branch->SetAutoDelete(kFALSE);
198  int level = 1; //FIXME: Make configurable
199  m_branch->SetCompressionLevel(level);
200  }
201  }
202  if (m_branch == 0) {
203  return StatusCode::FAILURE;
204  }
205  return StatusCode::SUCCESS;
206 }
207 
208 }//> namespace Athena
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
Athena::RootConnection::disconnect
StatusCode disconnect()
Release data stream and release implementation dependent resources.
Definition: RootConnection.cxx:110
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
Athena::RootConnection::connectRead
StatusCode connectRead()
Open data stream in read mode.
Definition: RootConnection.cxx:74
TScopeAdapter::ByNameNoQuiet
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition: RootType.cxx:581
Athena::RootConnection::m_pfn
std::string m_pfn
Physical file name of the connection.
Definition: RootConnection.h:71
Athena::RootConnection::commit
StatusCode commit()
Commit data stream to ROOT.
Definition: RootConnection.cxx:96
Athena::RootConnection::~RootConnection
virtual ~RootConnection()
Standard destructor.
Definition: RootConnection.cxx:71
Athena::RootConnection::isConnected
bool isConnected() const
Check if connected to data source.
Definition: RootConnection.cxx:122
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
TScopeAdapter::TypeInfo
const std::type_info & TypeInfo() const
Definition: RootType.cxx:679
m_file
std::unique_ptr< TFile > m_file
description: this is a custom writer for the old-school drivers that don't use an actual writer
Definition: OutputStreamData.cxx:52
Athena::RootConnection::write
StatusCode write(const void *data, unsigned long &len)
Write root byte buffer to output stream.
Definition: RootConnection.cxx:130
Athena::RootConnection::m_file
TFile * m_file
Age counter.
Definition: RootConnection.h:78
Athena
Some weak symbol referencing magic...
Definition: AthLegacySequence.h:21
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
dumpFileToPlots.treeName
string treeName
Definition: dumpFileToPlots.py:20
Preparation.mode
mode
Definition: Preparation.py:95
Athena::RootConnection::RootConnection
RootConnection(const IInterface *own, const std::string &pfn)
Standard constructor.
Definition: RootConnection.cxx:62
Athena::RootConnection::connectWrite
StatusCode connectWrite(const std::string &mode)
Open data stream in write mode.
Definition: RootConnection.cxx:85
Athena::RootConnection::read
StatusCode read(void *const data, size_t len)
Read root byte buffer from input stream.
Definition: RootConnection.cxx:126
errorcheck.h
Helpers for checking error return status codes and reporting errors.
RTTAlgmain.address
address
Definition: RTTAlgmain.py:55
REPORT_MESSAGE
#define REPORT_MESSAGE(LVL)
Report a message.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:365
Athena::RootConnection::m_tree
TTree * m_tree
Pointer to the main event data tree.
Definition: RootConnection.h:80
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
RootConnection.h
This file contains the class definition for the Athena::RootConnection class.
Athena::RootConnection::setContainer
StatusCode setContainer(const std::string &container, const std::string &type)
Set the container name and type, creating TTree and TBranch as needed.
Definition: RootConnection.cxx:148
Athena::RootConnection::m_branch
TBranch * m_branch
Pointer to the current data branch.
Definition: RootConnection.h:82
Athena::RootConnection::m_branchTypeCode
char m_branchTypeCode
Branch typecode for branch we are asked to write out.
Definition: RootConnection.h:84
RootType.h
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
checker_macros.h
Define macros for attributes used to control the static checker.
TScopeAdapter
Definition: RootType.h:119