Go to the documentation of this file.
16 #include <fmt/format.h>
18 #include <gsl/pointers>
25 auto getTypeName( std::string_view dependency ) {
26 auto unknownClassPos = dependency.find(
"UNKNOWN_CLASS:" );
27 return ( unknownClassPos != std::string::npos )
29 :
std::string( dependency );
33 auto getNameFromLoc( std::string_view loc ) {
34 auto lastSlashPos = loc.find_last_of(
'/' );
35 return std::string{ lastSlashPos != loc.npos ? loc.
substr( lastSlashPos + 1 ) : loc };
51 :
Algorithm(
n,
l ),
m_fileId( this,
"OutputFile",
"NTuple",
"Identifier for the TFile to write to." ) {}
59 if ( extraInputs.empty() ) {
60 error() <<
"No extra inputs locations specified. Please define extra inputs for the NTuple writer." <<
endmsg;
64 m_fileSvc = service<Gaudi::Interfaces::IFileSvc>(
"FileSvc" );
66 error() <<
"Failed to retrieve FileSvc." <<
endmsg;
72 error() <<
"Failed to retrieve TFile." <<
endmsg;
93 .
orThrow(
fmt::format(
"Failed to retrieve object for location '{}'. Ensure the location is correct and "
95 wrapper.getLocation() ),
100 std::scoped_lock lock{
m_mtx };
111 if (
m_tree->Write() <= 0 ) {
112 error() <<
"Failed to write TTree to ROOT file." <<
endmsg;
116 info() <<
"TTree written to ROOT file. File closed." <<
endmsg;
124 for (
const auto& dep : extraInputs ) {
125 auto typeName = getTypeName( dep.className() );
126 auto branchName = getNameFromLoc( dep.key() );
145 "Name of the TTree" };
159 # define BOOST_TEST_MODULE test_GenericNTupleWriter
160 # include <boost/test/unit_test.hpp>
178 return dummyServices;
181 virtual bool existsService( std::string_view )
const override {
return false; }
188 virtual unsigned long addRef()
override {
return 0; }
190 virtual unsigned long release()
override {
return 0; }
198 virtual unsigned long refCount()
const override {
return 1; }
202 BOOST_AUTO_TEST_CASE( testGetTypeName ) {
204 BOOST_CHECK_EQUAL( getTypeName(
"MyClass" ),
"MyClass" );
205 BOOST_CHECK_EQUAL( getTypeName(
"std::vector<double>" ),
"std::vector<double>" );
206 BOOST_CHECK_EQUAL( getTypeName(
"UNKNOWN_CLASS:MyCustomClass" ),
"MyCustomClass" );
209 BOOST_AUTO_TEST_CASE( testGetNameFromLoc ) {
211 BOOST_CHECK_EQUAL( getNameFromLoc(
"/Event/MyAlg/MyData" ),
"MyData" );
212 BOOST_CHECK_EQUAL( getNameFromLoc(
"MyAlg/MyData" ),
"MyData" );
213 BOOST_CHECK_EQUAL( getNameFromLoc(
"MyData" ),
"MyData" );
214 BOOST_CHECK_EQUAL( getNameFromLoc(
"" ),
"" );
218 BOOST_AUTO_TEST_CASE( testInit ) {
219 MockISvcLocator mockLocator;
223 BOOST_CHECK_EQUAL(
writer.name(),
"test_writer" );
227 BOOST_AUTO_TEST_CASE( testCreateBranches_EmptyDeps ) {
228 MockISvcLocator mockLocator;
236 BOOST_AUTO_TEST_CASE( testCreateBranches_InvalidType ) {
237 MockISvcLocator mockLocator;
238 auto tree = std::make_unique<TTree>(
"testTree",
"test tree" );
240 writer.setTree( tree.get() );
246 return e.message() ==
"Cannot create branch loc for unknown class: InvalidType. Provide a dictionary please.";
251 BOOST_AUTO_TEST_CASE( testCreateBranches_BasicTypes ) {
252 MockISvcLocator mockLocator;
253 auto tree = std::make_unique<TTree>(
"testTree",
"test tree" );
255 writer.setTree( tree.get() );
257 DataObjIDColl dependencies{ {
"int",
"loc1" }, {
"double",
"loc2" }, {
"std::string",
"loc3" } };
259 writer.createBranches( dependencies );
262 BOOST_CHECK_EQUAL(
writer.getBranchWrappersSize(), expectedTypes.size() );
263 BOOST_CHECK( expectedTypes ==
writer.getBranchesClassNames() );
267 BOOST_AUTO_TEST_CASE( testCreateBranches_ROOTKnownTypes ) {
268 MockISvcLocator mockLocator;
269 auto tree = std::make_unique<TTree>(
"testTree",
"test tree" );
271 writer.setTree( tree.get() );
273 DataObjIDColl dependencies{ {
"std::vector<double>",
"vectorDoubleLoc" }, {
"TH1D",
"hist1DLoc" } };
275 writer.createBranches( dependencies );
278 BOOST_CHECK_EQUAL(
writer.getBranchWrappersSize(), expectedTypes.size() );
279 BOOST_CHECK( expectedTypes ==
writer.getBranchesClassNames() );
size_t getBranchWrappersSize() const
virtual const std::list< IService * > & getServices() const =0
Get a reference to a service and create it if it does not exists.
StatusCode andThen(F &&f, ARGS &&... args) const
Chain code blocks making the execution conditional a success result.
const StatusCode & orThrow(std::string_view message, std::string_view tag) const
Throw a GaudiException in case of failures.
const std::string & name() const override
The identifying name of the algorithm object.
SmartIF< IDataProviderSvc > & eventSvc() const
The standard event data service.
StatusCode initialize() override
the default (empty) implementation of IStateful::initialize() method
std::vector< Gaudi::details::BranchWrapper > m_branchWrappers
std::shared_ptr< TFile > m_file
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
IDataProviderSvc * m_eventSvc
StatusCode finalize() override
virtual StatusCode getService(const Gaudi::Utils::TypeNameString &typeName, IService *&svc, const bool createIf=true)
Get a reference to the service given a service name.
StatusCode initialize() override
void createBranches(const DataObjIDColl &extraInputs)
Helper class to parse a string of format "type/name".
Gaudi::Property< std::string > m_fileId
virtual void * i_cast(const InterfaceID &) const =0
main cast function
Gaudi::Interfaces::IFileSvc * m_fileSvc
virtual StatusCode retrieveObject(IRegistry *pDirectory, std::string_view path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.
Base class from which all concrete algorithm classes should be derived.
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
const ValueType & value() const
virtual const DataObjIDColl & extraInputDeps() const override
void setTree(TTree *tree)
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
GenericWriter(const std::string &n, ISvcLocator *l)
StatusCode execute(const EventContext &) const override
Gaudi::Property< std::string > m_ntupleTname
T emplace_back(T... args)
StatusCode finalize() override
the default (empty) implementation of IStateful::finalize() method
constexpr static const auto SUCCESS
std::string typeName(const std::type_info &typ)
#define DECLARE_COMPONENT(type)
A Gaudi algorithm for writing data of any type from N locations in the event store to a TTree....
virtual std::vector< std::string > getInterfaceNames() const =0
Returns a vector of strings containing the names of all the implemented interfaces.
virtual std::shared_ptr< TFile > getFile(const std::string &identifier)=0
Interface for a component that manages file access within Gaudi applications.
constexpr static const auto FAILURE
virtual unsigned long refCount() const =0
Current reference count.
virtual unsigned long release()=0
Release Interface instance.
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
virtual bool existsService(std::string_view name) const =0
Check the existence of a service given a service name.
std::unordered_set< std::string > getBranchesClassNames() const