Belle II Software development
RootMergeable.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#pragma once
10
11#include <framework/pcore/Mergeable.h>
12#include <framework/logging/Logger.h>
13
14#include <TROOT.h>
15#include <TFile.h>
16#include <TList.h>
17#include <TH1F.h>
18#include <TH1D.h>
19#include <TH2F.h>
20#include <TNtuple.h>
21
22namespace Belle2 {
61 template <class T> class RootMergeable : public Mergeable {
62 public:
64 RootMergeable() : m_wrapped(nullptr) { }
66 template<class ...Args> explicit RootMergeable(Args&& ... params) : m_wrapped(new T(std::forward<Args>(params)...))
67 {
68 m_wrapped->SetBit(TObject::kMustCleanup); //ensure RecursiveRemove() is called
69 gROOT->GetListOfCleanups()->Add(this);
70 }
71
72 virtual ~RootMergeable()
73 {
74 gROOT->GetListOfCleanups()->Remove(this);
75 delete m_wrapped;
76 }
77
79 void assign(T* p)
80 {
81 delete m_wrapped;
82 m_wrapped = p;
83 m_wrapped->SetBit(TObject::kMustCleanup);
84 }
85
87 T& get() { return *m_wrapped; }
88
90 const T& get() const { return *m_wrapped; }
91
98 void write(TDirectory* file)
99 {
100 if (m_wrapped->GetDirectory() != nullptr and m_wrapped->GetDirectory() != file) {
101 B2ERROR("RootMergeable: wrapped object belongs to other file, Write() might crash. Make sure your histogram/ntuple already belongs to the file you want to save it to before filling (e.g. in initialize())");
102 }
103 file->cd();
104 m_wrapped->Write(nullptr, TObject::kOverwrite);
106 }
107
115 virtual void merge(const Mergeable* other) override
116 {
117 auto* otherMergeable = const_cast<RootMergeable<T>*>(static_cast<const RootMergeable<T>*>(other));
118 TList list;
119 list.SetOwner(false);
120 list.Add(&otherMergeable->get());
121
122 m_wrapped->Merge(&list);
123 }
124
130 virtual void clear() override
131 {
132 m_wrapped->Reset();
133 }
134
140 virtual void removeSideEffects() override
141 {
142 if (!m_wrapped) return;
143
144 m_wrapped->SetDirectory(nullptr);
145 //if we are the only owner, this becomes unnecessary
146 gROOT->GetListOfCleanups()->Remove(this);
147 }
148
150 virtual void RecursiveRemove(TObject* obj) override
151 {
152 if (obj == m_wrapped)
153 m_wrapped = nullptr;
154 }
155
156 private:
159
161 };
163}
Abstract base class for objects that can be merged.
Definition: Mergeable.h:31
Wrap a root histogram or TNtuple to make it mergeable.
Definition: RootMergeable.h:61
void assign(T *p)
Replace wrapped object with p (takes ownership).
Definition: RootMergeable.h:79
virtual void merge(const Mergeable *other) override
Merge object 'other' into this one.
ClassDefOverride(RootMergeable, 2)
Wrap a root histogram or ntuple to make them mergeable.
virtual void removeSideEffects() override
An ugly little method that is called before event() for input and worker processes.
virtual void RecursiveRemove(TObject *obj) override
Called from ROOT if obj is deleted.
RootMergeable(Args &&... params)
Constructor, forwards all arguments to T constructor.
Definition: RootMergeable.h:66
virtual void clear() override
Clear content of this object (e.g.
const T & get() const
Get the wrapped root object.
Definition: RootMergeable.h:90
void write(TDirectory *file)
Write the wrapped object into 'file', overwriting existing objects of same name.
Definition: RootMergeable.h:98
T * m_wrapped
Wrapped root object.
RootMergeable()
default constructor for root.
Definition: RootMergeable.h:64
T & get()
Get the wrapped root object.
Definition: RootMergeable.h:87
Abstract base class for different kinds of events.
STL namespace.