Belle II Software  release-05-02-19
RootFileInfo.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2019 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Martin Ritter *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <framework/io/RootFileInfo.h>
12 #include <framework/io/RootIOUtilities.h>
13 #include <framework/dataobjects/FileMetaData.h>
14 #include <framework/datastore/DataStore.h>
15 
16 #include <TTree.h>
17 #include <TFile.h>
18 
19 namespace Belle2::RootIOUtilities {
20  RootFileInfo::RootFileInfo(const std::string& filename)
21  {
22  // make sure TDirectory is reset after this function
23  TDirectory::TContext directoryGuard;
24  // Open the file
25  m_file.reset(TFile::Open(filename.c_str(), "READ"));
26  if (!m_file || !m_file->IsOpen()) throw std::invalid_argument("Could not open file");
27  // We want to get two trees the same way but only need that here ... lambda it is
28  auto getTree = [&file = this->m_file](const std::string & label, const std::string & name, std::unique_ptr<TTree>& destination) {
29  TTree* tmp{nullptr};
30  file->GetObject(name.c_str(), tmp);
31  if (!tmp) throw std::runtime_error("No " + label + " tree found");
32  destination.reset(tmp);
33  };
34  // So get the trees from the file and store them in the members
35  getTree("persistent", c_treeNames[DataStore::c_Persistent], m_persistent);
36  getTree("event", c_treeNames[DataStore::c_Event], m_events);
37  // And finally check the number of entries in the persistent tree
38  if (auto npersistent = m_persistent->GetEntries(); npersistent != 1) {
39  throw std::runtime_error("Expected exactly one entry in persistent tree, found " + std::to_string(npersistent));
40  }
41  }
42 
43  const FileMetaData& RootFileInfo::getFileMetaData()
44  {
45  if (!m_metadata) {
46  // object not set yet, get it from file
47  FileMetaData* metadata{nullptr};
48  auto branchStatus = m_persistent->SetBranchAddress("FileMetaData", &metadata);
49  if (branchStatus < 0) throw std::runtime_error("Error retrieving FileMetaData branch: " + std::to_string(branchStatus));
50  if (m_persistent->GetEntry(0) <= 0 || !metadata) throw std::runtime_error("Cannot read FileMetaData");
51  // and remembber
52  m_metadata.reset(metadata);
53  }
54  return *m_metadata;
55  }
56 
57  const std::set<std::string>& RootFileInfo::getBranchNames(bool persistent)
58  {
59  // which set of branches are we looking at?
60  std::optional<std::set<std::string>>& cache{persistent ? m_persistentBranches : m_eventBranches};
61  // if we didn't create the list already do it now
62  if (!cache) {
63  TTree& tree{persistent ? *m_persistent :* m_events};
64  std::set<std::string> result;
65  for (const TObject* obj : * (tree.GetListOfBranches())) {
66  const auto* branch = dynamic_cast<const TBranch*>(obj);
67  if (!branch) throw std::runtime_error("Entry in list of branches is no branch");
68  result.emplace(branch->GetName());
69  }
70  // and remember
71  cache.emplace(std::move(result));
72  }
73  // and just return the content
74  return *cache;
75  }
76 
77  void RootFileInfo::checkMissingBranches(const std::set<std::string>& required, bool persistent)
78  {
79  // So let's get the list of existing branches
80  const auto& existing = getBranchNames(persistent);
81  // and fill a list of branches which are in required but not existing
82  std::vector<std::string> missing;
83  std::set_difference(required.begin(), required.end(), existing.begin(), existing.end(),
84  std::inserter(missing, missing.begin()));
85  // and if that is not empty we complain
86  if (!missing.empty()) {
87  std::stringstream message;
88  message << "Branches missing from event tree: ";
89  for (const auto& name : missing) {
90  message << name << ", ";
91  }
92  throw std::runtime_error(message.str());
93  }
94  }
95 
96  /* Destructor. Declared here to allow forward declaration of TFile,TTree,... in header */
97  RootFileInfo::~RootFileInfo() = default;
98 }
Belle2::RootIOUtilities::RootFileInfo::checkMissingBranches
void checkMissingBranches(const std::set< std::string > &required, bool persistent=false)
Check if the event or persistent tree contain at least all the branches in the set of required branch...
Definition: RootFileInfo.cc:85
Belle2::RootIOUtilities::RootFileInfo::m_file
std::unique_ptr< TFile > m_file
Pointer to the file object.
Definition: RootFileInfo.h:56
Belle2::RootIOUtilities::RootFileInfo::m_persistent
std::unique_ptr< TTree > m_persistent
Pointer to the persistent tree.
Definition: RootFileInfo.h:58
Belle2::RootIOUtilities::RootFileInfo::m_eventBranches
std::optional< std::set< std::string > > m_eventBranches
Cached set of event branch names.
Definition: RootFileInfo.h:66
Belle2::RootIOUtilities::c_treeNames
const std::string c_treeNames[]
Names of trees.
Definition: RootIOUtilities.cc:20
Belle2::RootIOUtilities::RootFileInfo::m_persistentBranches
std::optional< std::set< std::string > > m_persistentBranches
Cached set of persistent branch names.
Definition: RootFileInfo.h:64
Belle2::RootIOUtilities::RootFileInfo::getFileMetaData
const FileMetaData & getFileMetaData()
Return the event metadata from the file.
Definition: RootFileInfo.cc:51
Belle2::RootIOUtilities::RootFileInfo::getBranchNames
const std::set< std::string > & getBranchNames(bool persistent=false)
Return a set of branch names for either the event or the persistent tree.
Definition: RootFileInfo.cc:65
Belle2::RootIOUtilities::RootFileInfo::RootFileInfo
RootFileInfo(const std::string &filename)
Create an object from a given filename or url.
Definition: RootFileInfo.cc:28
Belle2::RootIOUtilities::RootFileInfo::~RootFileInfo
~RootFileInfo()
Close the file and delete all structures associated with it.
Belle2::DataStore::c_Persistent
@ c_Persistent
Object is available during entire execution time.
Definition: DataStore.h:62
Belle2::RootIOUtilities
Some constants and helpers common to the RootInput and RootOutput modules.
Definition: RootFileInfo.h:24
alignment.constraints_generator.filename
filename
File name.
Definition: constraints_generator.py:224
Belle2::RootIOUtilities::RootFileInfo::m_events
std::unique_ptr< TTree > m_events
Pointer to the event tree.
Definition: RootFileInfo.h:60
Belle2::DataStore::c_Event
@ c_Event
Different object in each event, all objects/arrays are invalidated after event() function has been ca...
Definition: DataStore.h:61
Belle2::RootIOUtilities::RootFileInfo::m_metadata
std::unique_ptr< FileMetaData > m_metadata
Pointer to the file metadata once it has been read.
Definition: RootFileInfo.h:62