Belle II Software  release-08-01-10
CalibObjManager.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 #pragma once
9 
10 #include <string>
11 #include <memory>
12 
13 #include <TDirectory.h>
14 #include <TNamed.h>
15 #include <TTree.h>
16 
17 #include <framework/dataobjects/EventMetaData.h>
18 #include <framework/logging/Logger.h>
19 
20 #include <calibration/Utilities.h>
21 
22 namespace Belle2 {
30 
31  public:
33  CalibObjManager(TDirectory* dir = nullptr) : m_dir(dir) {};
34 
42  virtual ~CalibObjManager() {m_templateObjects.clear();}
43 
45  void setDirectory(TDirectory* dir) {m_dir = dir;}
46 
50  void addObject(const std::string& name, std::shared_ptr<TNamed> object);
51 
53  void writeCurrentObjects(const Calibration::ExpRun& expRun);
54 
56  void clearCurrentObjects(const Calibration::ExpRun& expRun);
57 
61  void createDirectories();
62 
64  void createExpRunDirectories(Calibration::ExpRun& expRun) const;
65 
67  unsigned int getHighestIndexObject(const std::string& name, const TDirectory* dir) const;
68 
70  void deleteHeldObjects();
71 
73  bool isRegistered(const std::string& name) const;
74 
79  template<class T>
80  T* getObject(const std::string& name, const Belle2::Calibration::ExpRun expRun)
81  {
82  std::string objectDirName = name + '/' + getObjectExpRunName(name, expRun);
83  TDirectory* objectDir = m_dir->GetDirectory(objectDirName.c_str());
84  // Does the object name have a directory available? (framework problem if not)
85  if (not objectDir) {
86  // Is the object name known to us? (user problem if not)
87  if (not isRegistered(name)) {
88  B2ERROR("The requested object name '" << name << "' isn't known to CalibObjManager!");
89  return nullptr;
90  }
91  B2FATAL("TDirectory for registered object " << name << " not found: " << objectDirName);
92  }
93  unsigned int highestIndex = getHighestIndexObject(name, objectDir);
94  std::string highestIndexName = name + "_" + std::to_string(highestIndex);
95  // First check if we currently have an object we're using.
96  T* obj = dynamic_cast<T*>(objectDir->FindObject(highestIndexName.c_str()));
97  if (!obj) {
98  B2DEBUG(100, "Highest index is only file resident for " << highestIndexName << " in " << objectDir->GetPath() <<
99  ". Will make a higher one");
100  std::string newName = name + "_" + std::to_string(highestIndex + 1);
101  obj = cloneObj<T>(dynamic_cast<T*>(m_templateObjects[name].get()), newName);
102  obj->SetDirectory(objectDir);
103  obj->Reset();
104  // Did SetDirectory work? Or was it a dummy class method?
105  T* objTest;
106  objectDir->GetObject(newName.c_str(), objTest);
107  if (!objTest) {
108  B2DEBUG(100, "SetDirectory was a dummy function. Adding to Object to TDirectory manually.");
109  objectDir->Add(obj);
110  }
111  }
112  return obj;
113  }
114 
115  private:
116 
118  template<class T>
119  T* cloneObj(T* source, const std::string& newName) const
120  {
121  B2DEBUG(100, "Held object " << source->GetName() << " will be treated as a generic TNamed and have Clone(newname) called.");
122  return dynamic_cast<T*>(source->Clone(newName.c_str()));
123  }
124 
126  TDirectory* m_dir;
127 
132  std::map<std::string, std::shared_ptr<TNamed>> m_templateObjects;
133 
135  std::string getSuffix(const Calibration::ExpRun& key) const;
136 
138  std::string getSuffix(const EventMetaData& emd) const;
139 
141  std::string getObjectExpRunName(const std::string& name, const Calibration::ExpRun& expRun) const;
142 
144  unsigned int extractKeyIndex(const std::string& keyName) const;
145  };
147  template<>
148  TTree* CalibObjManager::cloneObj(TTree* source, const std::string& newName) const;
150 }
Manager class for collector registered data. Handles much of the TDirectory/TObject manipulation.
virtual ~CalibObjManager()
Destructor: Every object we are managing is ultimately either saved into a file to write out,...
T * cloneObj(T *source, const std::string &newName) const
Clone object.
std::map< std::string, std::shared_ptr< TNamed > > m_templateObjects
The objects that we are managing, these are template objects for all future objects for each (Exp,...
T * getObject(const std::string &name, const Belle2::Calibration::ExpRun expRun)
Gets the collector object of this name for the given exprun.
TDirectory * m_dir
The TDirectory where all of our managed objects should be found, and where we should create new ones.
void setDirectory(TDirectory *dir)
Change the directory that we will be using to find/store all our objects, we don't own it.
CalibObjManager(TDirectory *dir=nullptr)
Constructor.
std::string getSuffix(const Calibration::ExpRun &key) const
We rename objects based on the Exp,Run that they contain so we need to generate a nice naming convent...
Store event, run, and experiment numbers.
Definition: EventMetaData.h:33
unsigned int extractKeyIndex(const std::string &keyName) const
Extract key index.
void clearCurrentObjects(const Calibration::ExpRun &expRun)
Deletes all in-memory objects in the exprun directories for all the collector objects we know about.
void writeCurrentObjects(const Calibration::ExpRun &expRun)
For each templated object we know about, we find an in memory object for this exprun and write to the...
std::string getObjectExpRunName(const std::string &name, const Calibration::ExpRun &expRun) const
Get object experiment and run name.
unsigned int getHighestIndexObject(const std::string &name, const TDirectory *dir) const
Scans the directory to get the highest "_i" index of an object with this name.
void deleteHeldObjects()
Clears the map of templated objects -> causing their destruction.
void addObject(const std::string &name, std::shared_ptr< TNamed > object)
Add a new object to manage, this is used as a template for creating future/missing objects.
bool isRegistered(const std::string &name) const
Checks for the existence of a name in the templated object map to see if we registered the object.
void createExpRunDirectories(Calibration::ExpRun &expRun) const
For each templated object, we create a new TDirectory for this exprun.
void createDirectories()
Each object gets its own TDirectory under the main manager directory to store its objects.
Abstract base class for different kinds of events.