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