11#ifndef FRAMEWORK_ROOTTREEREADER_H
12#define FRAMEWORK_ROOTTREEREADER_H
140template <
typename KeyType>
174 static_assert(std::is_same<KeyType, const char*>::value ==
false,
"the key type must not be const char*");
220 template <
typename DataT,
typename BASE>
227 static const size_t STAGE = BASE::STAGE + 1;
255 if constexpr (
STAGE > 1) {
256 PrevT::setupInstance(
tree, publishhook);
258 mPublishHook = publishhook;
261 mBranch =
tree.GetBranch(mName.c_str());
263 std::string sizebranchName = std::string(mName) +
"Size";
264 auto sizebranch =
tree.GetBranch(sizebranchName.c_str());
265 auto* classinfo = TClass::GetClass(mBranch->GetClassName());
266 if constexpr (not std::is_void<value_type>::value) {
268 auto* storedclass = TClass::GetClass(
typeid(
value_type));
269 if (classinfo != storedclass) {
270 throw std::runtime_error(std::string(
"Configured type ") +
271 (storedclass !=
nullptr ? storedclass->GetName() :
typeid(
value_type).
name()) +
272 " does not match the stored data type " +
273 (classinfo !=
nullptr ? classinfo->GetName() :
"") +
274 " in branch " + mName);
278 if (classinfo ==
nullptr) {
279 throw std::runtime_error(std::string(
"can not find class description for branch ") + mName);
281 LOG(info) <<
"branch set up: " << mName;
284 throw std::runtime_error(
"mismatching class type, expecting std::vector<char> for binary branch");
286 mSizeBranch = sizebranch;
287 LOG(info) <<
"binary branch set up: " << mName;
289 mClassInfo = classinfo;
291 throw std::runtime_error(std::string(
"can not find branch ") + mName);
300 if constexpr (
STAGE > 1) {
301 PrevT::process(context,
entry, stackcreator);
304 auto snapshot = [&context, &stackcreator](
const KeyType&
key,
const auto&
object) {
308 char*
data =
nullptr;
309 mBranch->SetAddress(&
data);
310 mBranch->GetEntry(
entry);
313 if (mPublishHook !=
nullptr && (*mPublishHook).
hook(mName, context,
Output{mKey.origin, mKey.description, mKey.subSpec, std::move(stackcreator())},
data)) {
318 if (mSizeBranch !=
nullptr) {
320 mSizeBranch->SetAddress(&datasize);
321 mSizeBranch->GetEntry(
entry);
323 if (
buffer->size() == datasize) {
324 LOG(
debug) <<
"branch " << mName <<
": publishing binary chunk of " << datasize <<
" bytes(s)";
325 snapshot(mKey, std::move(*
buffer));
327 LOG(error) <<
"branch " << mName <<
": inconsitent size of binary chunk "
328 <<
buffer->size() <<
" vs " << datasize;
330 snapshot(mKey,
empty);
333 if constexpr (std::is_void<value_type>::value ==
true) {
344 auto* delfunc = mClassInfo->GetDelete();
348 mBranch->DropBaskets(
"all");
354 TBranch* mBranch =
nullptr;
355 TBranch* mSizeBranch =
nullptr;
356 TClass* mClassInfo =
nullptr;
364 template <
typename T>
367 template <
typename U>
372 template <
typename U>
377 template <
typename U>
394 template <
typename... Args>
399 mInput.SetCacheSize(0);
400 parseConstructorArgs<0>(std::forward<Args>(args)...);
401 mBranchConfiguration->setup(mInput, mPublishHook);
407 mInput.AddFile(fileName);
408 mNEntries = mInput.GetEntries();
415 if ((mReadEntry + 1) >= mNEntries || mNEntries == 0) {
418 if (mReadEntry < mNEntries) {
419 mReadEntry = mNEntries;
426 if (mMaxEntries > 0 && (mNofPublished + 1) >= mMaxEntries) {
427 if (mReadEntry < mNEntries) {
428 mReadEntry = mNEntries;
457 template <
typename ContextType,
typename... HeaderTypes>
459 HeaderTypes&&... headers)
const
461 if (mReadEntry >= mNEntries || mNEntries == 0 || (mMaxEntries > 0 && mNofPublished >= mMaxEntries)) {
465 auto stackcreator = [&headers...]() {
469 mBranchConfiguration->exec(context, mReadEntry, stackcreator);
476 return mNofPublished + 1;
481 template <
typename T,
typename... Args>
482 const char* getCharArg(T arg, Args&&...)
484 static_assert(std::is_same<T, const char*>::value,
"missing branch name after publishing key, use const char* argument right after the key");
489 template <
size_t skip,
typename U,
typename... Args>
490 void parseConstructorArgs(U
key, Args&&... args)
493 mBranchConfiguration = createBranchConfiguration<0, BranchConfigurationInterface>({}, std::forward<U>(
key), std::forward<Args>(args)...);
499 template <
size_t skip,
typename BASE,
typename U,
typename... Args>
500 std::unique_ptr<BranchConfigurationInterface> createBranchConfiguration(
ConstructorArgs&& cargs, U def, Args&&... args)
502 if constexpr (skip > 0) {
503 return createBranchConfiguration<skip - 1,
BASE>(std::move(cargs), std::forward<Args>(args)...);
504 }
else if constexpr (std::is_same<U, const char*>::value) {
506 }
else if constexpr (std::is_same<U, int>::value) {
508 }
else if constexpr (std::is_same<U, PublishingMode>::value) {
509 mPublishingMode = def;
510 }
else if constexpr (std::is_same<U, SpecialPublishHook*>::value) {
512 }
else if constexpr (is_specialization_v<U, BranchDefinition>) {
513 cargs.emplace_back(
key_type(def.key), def.name);
514 using type = BranchConfigurationElement<typename U::type, BASE>;
515 return std::move(createBranchConfiguration<0, type>(std::move(cargs), std::forward<Args>(args)...));
516 }
else if constexpr (
sizeof...(Args) > 0) {
517 const char* arg = getCharArg(std::forward<Args>(args)...);
518 if (arg !=
nullptr && *arg != 0) {
519 cargs.emplace_back(
key_type(def), arg);
520 using type = BranchConfigurationElement<void, BASE>;
521 return std::move(createBranchConfiguration<1, type>(std::move(cargs), std::forward<Args>(args)...));
523 throw std::runtime_error(
"expecting valid branch name string after key");
525 static_assert(always_static_assert<U>::value,
"argument mismatch, define branches either as argument pairs of key and branchname or using the BranchDefinition helper struct");
527 return createBranchConfiguration<0, BASE>(std::move(cargs), std::forward<Args>(args)...);
532 template <
size_t skip,
typename T>
533 std::unique_ptr<BranchConfigurationInterface> createBranchConfiguration(
ConstructorArgs&& cargs)
535 static_assert(skip == 0);
536 return std::move(std::make_unique<T>(cargs));
542 std::unique_ptr<BranchConfigurationInterface> mBranchConfiguration;
548 int mNofPublished = -1;
550 int mMaxEntries = -1;
554 SpecialPublishHook* mPublishHook =
nullptr;
Class for time synchronization of RawReader instances.
void snapshot(const Output &spec, T const &object)
void process(ProcessingContext &context, int entry, std::function< o2::header::Stack()> &stackcreator)
Run the reader, first recursively for all lower stages, and then the current stage.
void exec(ProcessingContext &ctx, int entry, std::function< o2::header::Stack()> stackcreator) override
BranchConfigurationElement()=default
static const size_t STAGE
BranchConfigurationElement(ConstructorArgs const &args)
void setupInstance(TTree &tree, SpecialPublishHook *publishhook=nullptr)
~BranchConfigurationElement() override=default
void setup(TTree &tree, SpecialPublishHook *publishhook=nullptr) override
virtual ~BranchConfigurationInterface()=default
BranchConfigurationInterface(ConstructorArgs const &)
virtual void setup(TTree &, SpecialPublishHook *h=nullptr)
Setup the branch configuration, namely get the branch and class information from the tree.
static const size_t STAGE
virtual void exec(ProcessingContext &ctx, int entry, std::function< o2::header::Stack()> stackcreator)
BranchConfigurationInterface()=default
bool operator()(ContextType &context, HeaderTypes &&... headers) const
self_type & operator++(int)=delete
postfix increment forbidden
void addFile(const char *fileName)
add a file as source for the tree
self_type & operator++()
prefix increment, move to the next entry
o2::framework::ROOTSerialized< char, TClass > ROOTSerializedByClass
PublishingMode
Publishing mode determines what to do when the number of entries in the tree is reached.
@ Single
no more data after end of tree
@ Loop
start over at entry 0
GenericRootTreeReader(const char *treename, Args &&... args)
GenericRootTreeReader()
default constructor
int getCount() const
return the number of published entries
std::vector< ConstructorArg > ConstructorArgs
std::vector< char > BinaryDataStoreType
DataAllocator & outputs()
The data allocator is used to allocate memory for the output data.
GLuint const GLchar * name
GLint GLint GLsizei GLint GLenum GLenum type
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
Defining PrimaryVertex explicitly as messageable.
Lifetime
Possible Lifetime of objects being exchanged by the DPL.
BranchDefinition(U _key, std::string &&_name)
BranchDefinition(U _key, const char *_name)
BranchDefinition(U _key, std::string const &_name)
helper structure to hold the constructor arguments for BranchConfigurationElement stages
ConstructorArg(key_type _key, const char *_name)
ConstructorArg(key_type _key, std::string const &_name)
std::function< bool(std::string_view name, ProcessingContext &context, Output const &, char *data)> hook
header::DataOrigin origin
header::DataHeader::SubSpecificationType subSpec
header::DataOrigin origin
DefaultKey(const Output &desc)
header::DataDescription description
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))