Belle II Software  release-05-02-19
RootMergeable.h
1 #pragma once
2 /**************************************************************************
3  * BASF2 (Belle Analysis Framework 2) *
4  * Copyright(C) 2014 - Belle II Collaboration *
5  * *
6  * Author: The Belle II Collaboration *
7  * Contributors: Christian Pulvermacher *
8  * *
9  * This software is provided "as is" without any warranty. *
10  **************************************************************************/
11 
12 #include <framework/pcore/Mergeable.h>
13 #include <framework/logging/Logger.h>
14 
15 #include <TROOT.h>
16 #include <TFile.h>
17 #include <TList.h>
18 #include <TH1F.h>
19 #include <TH1D.h>
20 #include <TH2F.h>
21 #include <TNtuple.h>
22 
23 namespace Belle2 {
62  template <class T> class RootMergeable : public Mergeable {
63  public:
65  RootMergeable() : m_wrapped(nullptr) { }
67  template<class ...Args> explicit RootMergeable(Args&& ... params) : m_wrapped(new T(std::forward<Args>(params)...))
68  {
69  m_wrapped->SetBit(TObject::kMustCleanup); //ensure RecursiveRemove() is called
70  gROOT->GetListOfCleanups()->Add(this);
71  }
72 
73  virtual ~RootMergeable()
74  {
75  gROOT->GetListOfCleanups()->Remove(this);
76  delete m_wrapped;
77  }
78 
80  void assign(T* p)
81  {
82  delete m_wrapped;
83  m_wrapped = p;
84  m_wrapped->SetBit(TObject::kMustCleanup);
85  }
86 
88  T& get() { return *m_wrapped; }
89 
91  const T& get() const { return *m_wrapped; }
92 
99  void write(TDirectory* file)
100  {
101  if (m_wrapped->GetDirectory() != nullptr and m_wrapped->GetDirectory() != file) {
102  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())");
103  }
104  file->cd();
105  m_wrapped->Write(nullptr, TObject::kOverwrite);
107  }
108 
116  virtual void merge(const Mergeable* other) override
117  {
118  auto* otherMergeable = const_cast<RootMergeable<T>*>(static_cast<const RootMergeable<T>*>(other));
119  TList list;
120  list.SetOwner(false);
121  list.Add(&otherMergeable->get());
122 
123  m_wrapped->Merge(&list);
124  }
125 
131  virtual void clear() override
132  {
133  m_wrapped->Reset();
134  }
135 
141  virtual void removeSideEffects() override
142  {
143  if (!m_wrapped) return;
144 
145  m_wrapped->SetDirectory(NULL);
146  //if we are the only owner, this becomes unnecessary
147  gROOT->GetListOfCleanups()->Remove(this);
148  }
149 
151  virtual void RecursiveRemove(TObject* obj) override
152  {
153  if (obj == m_wrapped)
154  m_wrapped = nullptr;
155  }
156 
157  private:
160 
162  };
164 }
Belle2::RootMergeable
Wrap a root histogram or TNtuple to make it mergeable.
Definition: RootMergeable.h:70
Belle2::RootMergeable::get
T & get()
Get the wrapped root object.
Definition: RootMergeable.h:96
Belle2::RootMergeable::RootMergeable
RootMergeable()
default constructor for root.
Definition: RootMergeable.h:73
Belle2::RootMergeable::RecursiveRemove
virtual void RecursiveRemove(TObject *obj) override
Called from ROOT if obj is deleted.
Definition: RootMergeable.h:159
Belle2::RootMergeable::removeSideEffects
virtual void removeSideEffects() override
An ugly little method that is called before event() for input and worker processes.
Definition: RootMergeable.h:149
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::RootMergeable::clear
virtual void clear() override
Clear content of this object (e.g.
Definition: RootMergeable.h:139
Belle2::RootMergeable::m_wrapped
T * m_wrapped
Wrapped root object.
Definition: RootMergeable.h:167
Belle2::RootMergeable::merge
virtual void merge(const Mergeable *other) override
Merge object 'other' into this one.
Definition: RootMergeable.h:124
Belle2::RootMergeable::ClassDefOverride
ClassDefOverride(RootMergeable, 2)
Wrap a root histogram or ntuple to make them mergeable.
Belle2::RootMergeable::assign
void assign(T *p)
Replace wrapped object with p (takes ownership).
Definition: RootMergeable.h:88
Belle2::RootMergeable::write
void write(TDirectory *file)
Write the wrapped object into 'file', overwriting existing objects of same name.
Definition: RootMergeable.h:107
Belle2::Mergeable
Abstract base class for objects that can be merged.
Definition: Mergeable.h:33