ATLAS Offline Software
RootOutputStreamTool.cxx
Go to the documentation of this file.
1 
3 /*
4  Copyright (C) 2002-2017 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) :
35  m_storeSvc("StoreGateSvc", name),
36  m_conversionSvc("Athena::RootCnvSvc/AthenaRootCnvSvc", name),
37  m_clidSvc("ClassIDSvc", name) {
38  // Declare IAthenaOutputStreamTool interface
39  declareInterface<IAthenaOutputStreamTool>(this);
40  // Properties
41  declareProperty("Store", m_storeSvc, "Store from which to stream out event data");
42  declareProperty("TreeName", m_treeName = "CollectionTree", "Name of the output event tree");
43  declareProperty("OutputFile", m_outputName, "Name of the output file");
44 }
45 
47 }
48 
50  ATH_MSG_INFO("Initializing " << name());
51  if (!::AthAlgTool::initialize().isSuccess()) {
52  ATH_MSG_FATAL("Cannot initialize AlgTool base class.");
53  return StatusCode::FAILURE;
54  }
55  // Get the ClassID service
56  ATH_CHECK(m_clidSvc.retrieve());
57  // Get the conversion service
58  ATH_CHECK(m_conversionSvc.retrieve());
59  return StatusCode::SUCCESS;
60 }
61 
63  // Release the data store service
64  if (m_storeSvc != 0) {
65  if (!m_storeSvc.release().isSuccess()) {
66  ATH_MSG_WARNING("Could not release " << m_storeSvc.type() << " store.");
67  }
68  }
69  // Release the conversion service
70  if (!m_conversionSvc.release().isSuccess()) {
71  ATH_MSG_WARNING("Cannot release conversion service.");
72  }
73  // Release the ClassID service
74  if (!m_clidSvc.release().isSuccess()) {
75  ATH_MSG_WARNING("Cannot release ClassID service.");
76  }
78 }
79 
80 StatusCode RootOutputStreamTool::connectServices(const std::string& dataStore, const std::string& cnvSvc, bool extendProvenenceRecord) {
81  ATH_MSG_VERBOSE("connectServices dataStore = " << dataStore << ", cnvSvc = " << cnvSvc << ", extendProv = " << extendProvenenceRecord);
82  // Release the old data store service
83  if (m_storeSvc != 0) {
84  if (!m_storeSvc.release().isSuccess()) {
85  ATH_MSG_WARNING("Could not release " << m_storeSvc.type() << " store.");
86  }
87  }
88  m_storeSvc = ServiceHandle<StoreGateSvc>(dataStore, this->name());
89  // Get the data store service
90  ATH_CHECK(m_storeSvc.retrieve());
91  return StatusCode::SUCCESS;
92 }
93 
95  ATH_MSG_VERBOSE("connectOutput outputName = [" << outputName <<"]");
96  // Set output file name property
97  if (!outputName.empty()) {
99  } else {
100  return StatusCode::FAILURE;
101  }
102  // Connect the output file to the service
103  if (!m_conversionSvc->connectOutput(m_outputName + "(" + m_treeName + ")", "recreate").isSuccess()) {
104  ATH_MSG_ERROR("Unable to connect output " << m_outputName);
105  return StatusCode::FAILURE;
106  } else {
107  ATH_MSG_DEBUG("Connected to " << m_outputName);
108  }
109  return StatusCode::SUCCESS;
110 }
111 
113  ATH_MSG_VERBOSE("commitOutput");
114  if (m_outputName.empty()) {
115  ATH_MSG_ERROR("Unable to commit, no output connected.");
116  return StatusCode::FAILURE;
117  }
118  // Connect the output file to the service
119  if (!m_conversionSvc->commitOutput(m_outputName, false).isSuccess()) {
120  ATH_MSG_ERROR("Unable to commit output " << m_outputName);
121  return StatusCode::FAILURE;
122  } else {
123  ATH_MSG_DEBUG("Committed: " << m_outputName);
124  }
125  m_outputName.clear();
126  return StatusCode::SUCCESS;
127 }
128 
130  ATH_MSG_VERBOSE("finalizeOutput");
131  return StatusCode::SUCCESS;
132 }
133 
135  ATH_MSG_VERBOSE("streamObjects(type/keys)...");
136  // Now iterate over the type/key pairs and stream out each object
137  std::vector<DataObject*> dataObjects;
138  dataObjects.reserve(typeKeys.size());
139  for (IAthenaOutputStreamTool::TypeKeyPairs::const_iterator first = typeKeys.begin(), last = typeKeys.end();
140  first != last; ++first) {
141  const std::string& type = (*first).first;
142  const std::string& key = (*first).second;
143  // Find the clid for type name from the classIDSvc
144  CLID clid = 0;
145  if (!m_clidSvc->getIDOfTypeName(type, clid).isSuccess()) {
146  ATH_MSG_ERROR("Could not get clid for typeName " << type);
147  return StatusCode::FAILURE;
148  }
149  DataObject* dObj = 0;
150  // Two options: no key or explicit key
151  if (key.empty()) {
152  ATH_MSG_DEBUG("Get data object with no key");
153  // Get DataObject without key
154  dObj = m_storeSvc->accessData(clid);
155  } else {
156  ATH_MSG_DEBUG("Get data object with key");
157  // Get DataObjects with key
158  dObj = m_storeSvc->accessData(clid, key);
159  }
160  if (dObj == 0) {
161  // No object - print warning and continue with next object
162  ATH_MSG_WARNING("No object found for type " << type << " key " << key);
163  continue;
164  } else {
165  ATH_MSG_DEBUG("Found object for type " << type << " key " << key);
166  }
167  // Save the dObj
168  dataObjects.push_back(dObj);
169  }
170  return this->streamObjects(dataObjects, outputName);
171 }
172 
173 StatusCode RootOutputStreamTool::streamObjects(const DataObjectVec& dataObjects, const std::string&
174  /*outputName*/) {
175  ATH_MSG_VERBOSE("streamObjects(dobjs)");
176  if (m_outputName.empty()) {
177  ATH_MSG_ERROR("Unable to commit, no output connected.");
178  return StatusCode::FAILURE;
179  }
180  ATH_MSG_VERBOSE("streaming out... [" << m_conversionSvc.typeAndName() << "]");
181  std::set<DataObject*> written;
182  for (std::vector<DataObject*>::const_iterator doIter = dataObjects.begin(), doLast = dataObjects.end();
183  doIter != doLast; ++doIter) {
184  ATH_MSG_VERBOSE(" --> [" << (*doIter)->clID() << "/" << (*doIter)->name() << "]...");
185  // Do not stream out same object twice
186  if (written.find(*doIter) != written.end()) {
187  // Print warning and skip
188  ATH_MSG_DEBUG("Trying to write DataObject twice (clid/key): " << (*doIter)->clID() << ", " << (*doIter)->name());
189  ATH_MSG_DEBUG(" Skipping this one.");
190  } else {
191  written.insert(*doIter);
192  // Write object
193  IOpaqueAddress* addr = 0;
194  if ((m_conversionSvc->createRep(*doIter, addr)).isSuccess()) {
195  IRegistry* ireg = (*doIter)->registry();
196  // FIXME: that's a wild hack to handle RootBranchAddress's stickyness.
197  // if the transient address already has a RootBranchAddress (ie: it was
198  // read from a d3pd-file) calling setAddress will invalidate the
199  // previous RBA which will screw things up the next time around.
200  // The real fix would probably involve changing a bit the logic either
201  // in convsvc::createRep above, or -rather- have the side effect of
202  // properly setting up the RootConnection (in createRep) be explicitly
203  // written somewhere. (here?)
204  if (dynamic_cast<RootBranchAddress*>(ireg->address())) {
205  delete addr; addr = 0;
206  } else {
207  ireg->setAddress(addr);
208  }
209  // SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>((*doIter)->registry());
210  // if (!proxy) {
211  // ATH_MSG_WARNING("Could cast DataObject "
212  // << (*doIter)->clID() << " " << (*doIter)->name());
213  // }
214  } else {
215  ATH_MSG_ERROR("Could not create Rep for DataObject (clid/key): " << (*doIter)->clID() << ", " << (*doIter)->name());
216  return StatusCode::FAILURE;
217  }
218  }
219  }
220  return StatusCode::SUCCESS;
221 }
222 
224  ATH_MSG_VERBOSE("fillObjectRefs");
225  return StatusCode::SUCCESS;
226 }
227 
229  ATH_MSG_VERBOSE("getInputItemList");
230  return StatusCode::SUCCESS;
231 }
232 
233 }//> namespace Athena
Athena::RootBranchAddress
Definition: RootBranchAddress.h:33
python.tests.PyTestsLib.finalize
def finalize(self)
_info( "content of StoreGate..." ) self.sg.dump()
Definition: PyTestsLib.py:53
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Athena::RootOutputStreamTool::~RootOutputStreamTool
virtual ~RootOutputStreamTool()
Destructor.
Definition: RootOutputStreamTool.cxx:46
IAthenaOutputStreamTool::TypeKeyPairs
std::vector< TypeKeyPair > TypeKeyPairs
Definition: IAthenaOutputStreamTool.h:99
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Athena::RootOutputStreamTool::finalizeOutput
StatusCode finalizeOutput()
Finalize the output stream after the last commit, e.g.
Definition: RootOutputStreamTool.cxx:129
Athena::RootOutputStreamTool::initialize
StatusCode initialize()
Gaudi AlgTool Interface method implementations:
Definition: RootOutputStreamTool.cxx:49
initialize
void initialize()
Definition: run_EoverP.cxx:894
Athena::RootOutputStreamTool::finalize
StatusCode finalize()
Definition: RootOutputStreamTool.cxx:62
Athena::RootOutputStreamTool::m_outputName
std::string m_outputName
Name of the output file.
Definition: RootOutputStreamTool.h:96
Athena::RootOutputStreamTool::m_storeSvc
ServiceHandle< ::StoreGateSvc > m_storeSvc
ServiceHandle to the data store service.
Definition: RootOutputStreamTool.h:89
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:25
Athena::RootOutputStreamTool::getInputItemList
StatusCode getInputItemList(SG::IFolder *m_p2BWrittenFromTool)
Get ItemList from the OutputStreamTool (e.g. all input objects)
Definition: RootOutputStreamTool.cxx:228
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:93
Athena
Some weak symbol referencing magic...
Definition: AthLegacySequence.h:21
Athena::RootOutputStreamTool::fillObjectRefs
StatusCode fillObjectRefs(const IAthenaOutputStreamTool::DataObjectVec &dataObjects)
Fill refs of an object - done as second iteration over objects, after streamObject.
Definition: RootOutputStreamTool.cxx:223
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
Athena::RootOutputStreamTool::connectServices
StatusCode connectServices(const std::string &dataStore, const std::string &cnvSvc, bool extendProvenenceRecord)
Specify which data store and conversion service to use and whether to extend provenence Only use if o...
Definition: RootOutputStreamTool.cxx:80
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::RootOutputStreamTool
RootOutputStreamTool()
Default constructor:
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:192
lumiFormat.outputName
string outputName
Definition: lumiFormat.py:71
Athena::RootOutputStreamTool::commitOutput
StatusCode commitOutput(bool doCommit=false)
Commit the output stream after having streamed out objects Must commitOutput AFTER streaming.
Definition: RootOutputStreamTool.cxx:112
Athena::RootOutputStreamTool::streamObjects
StatusCode streamObjects(const IAthenaOutputStreamTool::TypeKeyPairs &typeKeys, const std::string &outputName="")
Stream out objects.
Definition: RootOutputStreamTool.cxx:134
RootOutputStreamTool.h
IAthenaOutputStreamTool::DataObjectVec
std::vector< DataObject * > DataObjectVec
Stream out a vector of objects Must convert to DataObject, e.g.
Definition: IAthenaOutputStreamTool.h:107
RootBranchAddress.h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DeMoScan.first
bool first
Definition: DeMoScan.py:534
Athena::RootOutputStreamTool::m_treeName
std::string m_treeName
Name of the output tuple.
Definition: RootOutputStreamTool.h:99
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:91
Athena::RootOutputStreamTool::connectOutput
StatusCode connectOutput(const std::string &outputName)
Connect to the output stream Must connectOutput BEFORE streaming Only specify "outputName" if one wan...
Definition: RootOutputStreamTool.cxx:94
AthAlgTool
Definition: AthAlgTool.h:26
StoreGateSvc.h
ServiceHandle< StoreGateSvc >
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37