ATLAS Offline Software
RootOutputStreamTool.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 // RootOutputStreamTool.cxx
8 // Implementation file for class Athena::RootOutputStreamTool
9 // Author Peter van Gemmeren <gemmeren@anl.gov>
11 
12 // AthenaRootComps includes
13 #include "RootOutputStreamTool.h"
14 #include "RootSvc.h"
15 #include "RootConnection.h"
16 #include "RootBranchAddress.h"
17 
18 // Gaudi
19 #include "GaudiKernel/IConversionSvc.h"
20 #include "GaudiKernel/IOpaqueAddress.h"
21 #include "GaudiKernel/IRegistry.h"
22 #include "GaudiKernel/DataObject.h"
23 
24 // Athena
25 #include "GaudiKernel/IClassIDSvc.h"
26 #include "StoreGate/StoreGateSvc.h"
27 
28 // stl
29 #include <set>
30 
31 namespace Athena {
32 
33 RootOutputStreamTool::RootOutputStreamTool(const std::string& type, const std::string& name, const IInterface* parent) :
34  base_class(type, name, parent),
35  m_storeSvc("StoreGateSvc", name),
36  m_conversionSvc("Athena::RootCnvSvc/AthenaRootCnvSvc", name),
37  m_clidSvc("ClassIDSvc", name) {
38  // Properties
39  declareProperty("Store", m_storeSvc, "Store from which to stream out event data");
40  declareProperty("TreeName", m_treeName = "CollectionTree", "Name of the output event tree");
41  declareProperty("OutputFile", m_outputName, "Name of the output file");
42 }
43 
45 }
46 
48  ATH_MSG_INFO("Initializing " << name());
49 
50  // Get the ClassID service
51  ATH_CHECK(m_clidSvc.retrieve());
52  // Get the conversion service
53  ATH_CHECK(m_conversionSvc.retrieve());
54  return StatusCode::SUCCESS;
55 }
56 
58  // Release the data store service
59  if (m_storeSvc != 0) {
60  if (!m_storeSvc.release().isSuccess()) {
61  ATH_MSG_WARNING("Could not release " << m_storeSvc.type() << " store.");
62  }
63  }
64  // Release the conversion service
65  if (!m_conversionSvc.release().isSuccess()) {
66  ATH_MSG_WARNING("Cannot release conversion service.");
67  }
68  // Release the ClassID service
69  if (!m_clidSvc.release().isSuccess()) {
70  ATH_MSG_WARNING("Cannot release ClassID service.");
71  }
72  return StatusCode::SUCCESS;
73 }
74 
75 StatusCode RootOutputStreamTool::connectServices(const std::string& dataStore, const std::string& cnvSvc, bool extendProvenenceRecord) {
76  ATH_MSG_VERBOSE("connectServices dataStore = " << dataStore << ", cnvSvc = " << cnvSvc << ", extendProv = " << extendProvenenceRecord);
77  // Release the old data store service
78  if (m_storeSvc != 0) {
79  if (!m_storeSvc.release().isSuccess()) {
80  ATH_MSG_WARNING("Could not release " << m_storeSvc.type() << " store.");
81  }
82  }
83  m_storeSvc = ServiceHandle<StoreGateSvc>(dataStore, this->name());
84  // Get the data store service
85  ATH_CHECK(m_storeSvc.retrieve());
86  return StatusCode::SUCCESS;
87 }
88 
90  ATH_MSG_VERBOSE("connectOutput outputName = [" << outputName <<"]");
91  // Set output file name property
92  if (!outputName.empty()) {
94  } else {
95  return StatusCode::FAILURE;
96  }
97  // Connect the output file to the service
98  if (!m_conversionSvc->connectOutput(m_outputName + "(" + m_treeName + ")", "recreate").isSuccess()) {
99  ATH_MSG_ERROR("Unable to connect output " << m_outputName);
100  return StatusCode::FAILURE;
101  } else {
102  ATH_MSG_DEBUG("Connected to " << m_outputName);
103  }
104  return StatusCode::SUCCESS;
105 }
106 
108  ATH_MSG_VERBOSE("commitOutput");
109  if (m_outputName.empty()) {
110  ATH_MSG_ERROR("Unable to commit, no output connected.");
111  return StatusCode::FAILURE;
112  }
113  // Connect the output file to the service
114  if (!m_conversionSvc->commitOutput(m_outputName, false).isSuccess()) {
115  ATH_MSG_ERROR("Unable to commit output " << m_outputName);
116  return StatusCode::FAILURE;
117  } else {
118  ATH_MSG_DEBUG("Committed: " << m_outputName);
119  }
120  m_outputName.clear();
121  return StatusCode::SUCCESS;
122 }
123 
125  ATH_MSG_VERBOSE("finalizeOutput");
126  return StatusCode::SUCCESS;
127 }
128 
130  ATH_MSG_VERBOSE("streamObjects(type/keys)...");
131  // Now iterate over the type/key pairs and stream out each object
132  std::vector<DataObject*> dataObjects;
133  dataObjects.reserve(typeKeys.size());
134  for (IAthenaOutputStreamTool::TypeKeyPairs::const_iterator first = typeKeys.begin(), last = typeKeys.end();
135  first != last; ++first) {
136  const std::string& type = (*first).first;
137  const std::string& key = (*first).second;
138  // Find the clid for type name from the classIDSvc
139  CLID clid = 0;
140  if (!m_clidSvc->getIDOfTypeName(type, clid).isSuccess()) {
141  ATH_MSG_ERROR("Could not get clid for typeName " << type);
142  return StatusCode::FAILURE;
143  }
144  DataObject* dObj = 0;
145  // Two options: no key or explicit key
146  if (key.empty()) {
147  ATH_MSG_DEBUG("Get data object with no key");
148  // Get DataObject without key
149  dObj = m_storeSvc->accessData(clid);
150  } else {
151  ATH_MSG_DEBUG("Get data object with key");
152  // Get DataObjects with key
153  dObj = m_storeSvc->accessData(clid, key);
154  }
155  if (dObj == 0) {
156  // No object - print warning and continue with next object
157  ATH_MSG_WARNING("No object found for type " << type << " key " << key);
158  continue;
159  } else {
160  ATH_MSG_DEBUG("Found object for type " << type << " key " << key);
161  }
162  // Save the dObj
163  dataObjects.push_back(dObj);
164  }
165  return this->streamObjects(dataObjects, outputName);
166 }
167 
168 StatusCode RootOutputStreamTool::streamObjects(const DataObjectVec& dataObjects, const std::string&
169  /*outputName*/) {
170  ATH_MSG_VERBOSE("streamObjects(dobjs)");
171  if (m_outputName.empty()) {
172  ATH_MSG_ERROR("Unable to commit, no output connected.");
173  return StatusCode::FAILURE;
174  }
175  ATH_MSG_VERBOSE("streaming out... [" << m_conversionSvc.typeAndName() << "]");
176  std::set<DataObject*> written;
177  for (std::vector<DataObject*>::const_iterator doIter = dataObjects.begin(), doLast = dataObjects.end();
178  doIter != doLast; ++doIter) {
179  ATH_MSG_VERBOSE(" --> [" << (*doIter)->clID() << "/" << (*doIter)->name() << "]...");
180  // Do not stream out same object twice
181  if (written.find(*doIter) != written.end()) {
182  // Print warning and skip
183  ATH_MSG_DEBUG("Trying to write DataObject twice (clid/key): " << (*doIter)->clID() << ", " << (*doIter)->name());
184  ATH_MSG_DEBUG(" Skipping this one.");
185  } else {
186  written.insert(*doIter);
187  // Write object
188  IOpaqueAddress* addr = 0;
189  if ((m_conversionSvc->createRep(*doIter, addr)).isSuccess()) {
190  IRegistry* ireg = (*doIter)->registry();
191  // FIXME: that's a wild hack to handle RootBranchAddress's stickyness.
192  // if the transient address already has a RootBranchAddress (ie: it was
193  // read from a d3pd-file) calling setAddress will invalidate the
194  // previous RBA which will screw things up the next time around.
195  // The real fix would probably involve changing a bit the logic either
196  // in convsvc::createRep above, or -rather- have the side effect of
197  // properly setting up the RootConnection (in createRep) be explicitly
198  // written somewhere. (here?)
199  if (dynamic_cast<RootBranchAddress*>(ireg->address())) {
200  delete addr; addr = 0;
201  } else {
202  ireg->setAddress(addr);
203  }
204  // SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>((*doIter)->registry());
205  // if (!proxy) {
206  // ATH_MSG_WARNING("Could cast DataObject "
207  // << (*doIter)->clID() << " " << (*doIter)->name());
208  // }
209  } else {
210  ATH_MSG_ERROR("Could not create Rep for DataObject (clid/key): " << (*doIter)->clID() << ", " << (*doIter)->name());
211  return StatusCode::FAILURE;
212  }
213  }
214  }
215  return StatusCode::SUCCESS;
216 }
217 
219  ATH_MSG_VERBOSE("getInputItemList");
220  return StatusCode::SUCCESS;
221 }
222 
223 }//> namespace Athena
Athena::RootOutputStreamTool::finalize
virtual StatusCode finalize() override
Definition: RootOutputStreamTool.cxx:57
Athena::RootOutputStreamTool::~RootOutputStreamTool
virtual ~RootOutputStreamTool()
Destructor.
Definition: RootOutputStreamTool.cxx:44
IAthenaOutputStreamTool::TypeKeyPairs
std::vector< TypeKeyPair > TypeKeyPairs
Definition: IAthenaOutputStreamTool.h:100
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Athena::RootOutputStreamTool::getInputItemList
virtual StatusCode getInputItemList(SG::IFolder *m_p2BWrittenFromTool) override
Definition: RootOutputStreamTool.cxx:218
Athena::RootOutputStreamTool::RootOutputStreamTool
RootOutputStreamTool(const std::string &type, const std::string &name, const IInterface *parent)
Standard AlgTool Constructor.
Definition: RootOutputStreamTool.cxx:33
Athena::RootOutputStreamTool::commitOutput
virtual StatusCode commitOutput(bool doCommit=false) override
Commit the output stream after having streamed out objects Must commitOutput AFTER streaming.
Definition: RootOutputStreamTool.cxx:107
Athena::RootOutputStreamTool::m_outputName
std::string m_outputName
Name of the output file.
Definition: RootOutputStreamTool.h:86
Athena::RootOutputStreamTool::m_storeSvc
ServiceHandle< ::StoreGateSvc > m_storeSvc
ServiceHandle to the data store service.
Definition: RootOutputStreamTool.h:79
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::IFolder
a run-time configurable list of data objects
Definition: SGIFolder.h:21
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
Athena::RootOutputStreamTool::connectOutput
virtual StatusCode connectOutput(const std::string &outputName) override
Connect to the output stream Must connectOutput BEFORE streaming Only specify "outputName" if one wan...
Definition: RootOutputStreamTool.cxx:89
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Athena::RootOutputStreamTool::m_clidSvc
ServiceHandle< ::IClassIDSvc > m_clidSvc
ServiceHandle to clid service.
Definition: RootOutputStreamTool.h:83
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
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
test_pyathena.parent
parent
Definition: test_pyathena.py:15
RootSvc.h
This file contains the class definition for the RootSvc class.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Athena::RootOutputStreamTool::connectServices
virtual StatusCode connectServices(const std::string &dataStore, const std::string &cnvSvc, bool extendProvenenceRecord) override
Specify which data store and conversion service to use and whether to extend provenence Only use if o...
Definition: RootOutputStreamTool.cxx:75
CLID
uint32_t CLID
The Class ID type.
Definition: Event/xAOD/xAODCore/xAODCore/ClassID_traits.h:47
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
lumiFormat.outputName
string outputName
Definition: lumiFormat.py:65
RootOutputStreamTool.h
Athena::RootOutputStreamTool::streamObjects
virtual StatusCode streamObjects(const IAthenaOutputStreamTool::TypeKeyPairs &typeKeys, const std::string &outputName="") override
Stream out objects.
Definition: RootOutputStreamTool.cxx:129
RootBranchAddress.h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DeMoScan.first
bool first
Definition: DeMoScan.py:534
Athena::RootOutputStreamTool::m_treeName
std::string m_treeName
Name of the output tuple.
Definition: RootOutputStreamTool.h:89
RootConnection.h
This file contains the class definition for the Athena::RootConnection class.
Athena::RootOutputStreamTool::m_conversionSvc
ServiceHandle< ::IConversionSvc > m_conversionSvc
ServiceHandle to the data conversion service.
Definition: RootOutputStreamTool.h:81
Athena::RootOutputStreamTool::initialize
virtual StatusCode initialize() override
Gaudi AlgTool Interface method implementations:
Definition: RootOutputStreamTool.cxx:47
Athena::RootOutputStreamTool::finalizeOutput
virtual StatusCode finalizeOutput() override
Finalize the output stream after the last commit, e.g.
Definition: RootOutputStreamTool.cxx:124
StoreGateSvc.h
ServiceHandle< StoreGateSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37