ATLAS Offline Software
Loading...
Searching...
No Matches
RootConnection.cxx
Go to the documentation of this file.
1
2
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"
21
22// ROOT includes
23#include "TROOT.h"
24#include "TFile.h"
25#include "TTree.h"
26#include "TBranch.h"
27
28namespace {
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
60namespace Athena {
61
62RootConnection::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
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
85StatusCode RootConnection::connectWrite(const std::string& mode) {
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
126StatusCode RootConnection::read(void* const /*data*/, size_t /*len*/) {
127 return StatusCode::FAILURE;
128}
129
130StatusCode 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
148StatusCode 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
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE(LVL)
Report a message.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
This file contains the class definition for the Athena::RootConnection class.
TTypeAdapter RootType
Definition RootType.h:211
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
StatusCode disconnect()
Release data stream and release implementation dependent resources.
StatusCode connectRead()
Open data stream in read mode.
TFile * m_file
Age counter.
bool isConnected() const
Check if connected to data source.
StatusCode write(const void *data, unsigned long &len)
Write root byte buffer to output stream.
virtual ~RootConnection()
Standard destructor.
std::string m_fid
File ID of the connection.
StatusCode connectWrite(const std::string &mode)
Open data stream in write mode.
std::string m_pfn
Physical file name of the connection.
StatusCode read(void *const data, size_t len)
Read root byte buffer from input stream.
char m_branchTypeCode
Branch typecode for branch we are asked to write out.
StatusCode setContainer(const std::string &container, const std::string &type)
Set the container name and type, creating TTree and TBranch as needed.
RootConnection(const IInterface *own, const std::string &pfn)
Standard constructor.
StatusCode commit()
Commit data stream to ROOT.
TTree * m_tree
Pointer to the main event data tree.
TBranch * m_branch
Pointer to the current data branch.
static TScopeAdapter ByNameNoQuiet(const std::string &name, Bool_t load=kTRUE)
Definition RootType.cxx:586
const std::type_info & TypeInfo() const
Definition RootType.cxx:684
Some weak symbol referencing magic... These are declared in AthenaKernel/getMessageSvc....