Belle II Software development
ConcreteVariablesToNtuplePersistenceManager.cc
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#include <reconstruction/persistenceManager/ConcreteVariablesToNtuplePersistenceManager.h>
10
11#include <framework/utilities/MakeROOTCompatible.h>
12#include <framework/utilities/RootFileCreationManager.h>
13#include <framework/pcore/ProcHandler.h>
14
15namespace {
16 using namespace Belle2::VariablePersistenceManager;
17
18 std::string typedVariableToLeafName(const TypedVariable& variable)
19 {
20 std::map<VariableDataType, std::string> suffix = {
21 {VariableDataType::c_double, "/D"},
22 {VariableDataType::c_int, "/I"},
23 {VariableDataType::c_bool, "/O"}
24 };
25
26 std::string branchName = Belle2::MakeROOTCompatible::makeROOTCompatible(variable.getName());
27 return branchName + suffix[variable.getDataType()];
28 }
29}
30
31namespace Belle2::VariablePersistenceManager {
37
39 const std::string& treeName,
40 Variables& variables)
41 {
42 m_fileName = fileName;
43 m_treeName = treeName;
44 m_variables = variables;
45
48 }
49
50 void ConcreteVariablesToNtuplePersistenceManager::addEntry(const EvaluatedVariables& evaluatedVariables)
51 {
52 for (const auto& [variableName, value] : evaluatedVariables) {
53 std::string branchName = Belle2::MakeROOTCompatible::makeROOTCompatible(variableName.c_str());
54 updateBranch(branchName, value);
55 }
56 m_tree->get().Fill();
57 }
58
60 {
62 B2INFO("Writing Ntuple: " << m_treeName);
63 TDirectory::TContext directoryGuard{m_file.get()};
64 m_tree->write(m_file.get());
65
66 const bool writeError = m_file->TestBit(TFile::kWriteError);
67 m_file.reset();
68 if (writeError) {
69 B2FATAL("A write error occurred while saving '" << m_fileName << "', please check if enough disk space is available.");
70 }
71 }
72 }
73
75 {
76 if (m_fileName.empty()) {
77 B2FATAL("Output root file name is not set.");
78 }
80
81 if (not m_file) {
82 B2FATAL("Could not create file: " << m_fileName << ".");
83 }
84
85 TDirectory::TContext directoryGuard{m_file.get()};
86
87 if (m_file->Get(m_treeName.c_str())) {
88 B2FATAL("A tree with the name: " << m_treeName << "already exists in the file: " << m_fileName << ".");
89 }
90
92 m_tree.construct(m_treeName.c_str(), "");
93 m_tree->get().SetCacheSize(100000);
94 }
95
97 {
98 for (const auto& variable : m_variables) {
99 std::visit([&](const auto & typedVariable) {
100 using T = std::decay_t<decltype(typedVariable)>;
101 if constexpr(std::is_same_v<T, TypedVariable>) {
102 std::string branchName = Belle2::MakeROOTCompatible::makeROOTCompatible(typedVariable.getName().c_str());
103 std::string leafName = typedVariableToLeafName(typedVariable);
104
105 switch (typedVariable.getDataType()) {
106 case VariableDataType::c_double:
107 m_branchesDouble[branchName] = double{};
108 m_tree->get().Branch(branchName.c_str(), &m_branchesDouble[branchName], leafName.c_str());
109 break;
110 case VariableDataType::c_int:
111 m_branchesInt[branchName] = int{};
112 m_tree->get().Branch(branchName.c_str(), &m_branchesInt[branchName], leafName.c_str());
113 break;
114 case VariableDataType::c_bool:
115 m_branchesBool[branchName] = bool{};
116 m_tree->get().Branch(branchName.c_str(), &m_branchesBool[branchName], leafName.c_str());
117 break;
118 default:
119 break;
120 }
121 } else {
122 B2WARNING("Incompatible variable type. Skipping branch registration.");
123 }
124 }, variable);
125 }
126 m_tree->get().SetBasketSize("*", m_basketSize);
127 }
128
130 const VariableType& evaluatedValue)
131 {
132 std::visit([&](auto&& value) {
133 using T = std::decay_t<decltype(value)>;
134
135 if constexpr(std::is_same_v<T, double>) {
136 m_branchesDouble[branchName] = value;
137 } else if constexpr(std::is_same_v<T, int>) {
138 m_branchesInt[branchName] = value;
139 } else if constexpr(std::is_same_v<T, bool>) {
140 m_branchesBool[branchName] = value;
141 }
142 }, evaluatedValue);
143 }
144}
In the store you can park objects that have to be accessed by various modules.
Definition DataStore.h:51
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
Definition DataStore.h:71
static std::string makeROOTCompatible(std::string str)
Remove special characters that ROOT dislikes in branch names, e.g.
static bool isOutputProcess()
Return true if the process is an output process.
static bool parallelProcessingUsed()
Returns true if multiple processes have been spawned, false in single-core mode.
void updateBranch(const std::string &variableName, const VariableType &value)
Updates the branch buffer for a given variable with a new value.
void addEntry(const EvaluatedVariables &evaluatedVariables) override
Adds a single event's worth of variable data to the TTree.
std::map< std::string, double > m_branchesDouble
Maps of variable names to storage for double, int, and bool TTree branches.
void initialize(const std::string &fileName, const std::string &treeName, Variables &variables) override
Initializes the manager by opening a ROOT file and preparing a TTree.
StoreObjPtr< RootMergeable< TTree > > m_tree
A store pointer to the RootMergeable wrapper for the TTree.
A variable with a specified data type.
Definition Types.h:57
std::shared_ptr< TFile > getFile(std::string, bool ignoreErrors=false)
Get a file with a specific name, if is does not exist it will be created.
static RootFileCreationManager & getInstance()
Interface for the FileManager.