Belle II Software  release-08-01-10
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 
22 namespace 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
const T & get() const
Get the wrapped root object.
Definition: RootMergeable.h:90
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.
T & get()
Get the wrapped root object.
Definition: RootMergeable.h:87
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.
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
Abstract base class for different kinds of events.