9#include <analysis/modules/VariablesToNtuple/VariablesToNtupleModule.h>
12#include <analysis/dataobjects/ParticleList.h>
13#include <analysis/VariableManager/Manager.h>
14#include <analysis/VariableManager/Utility.h>
15#include <analysis/dataobjects/StringWrapper.h>
18#include <framework/logging/Logger.h>
19#include <framework/pcore/ProcHandler.h>
20#include <framework/core/ModuleParam.templateDetails.h>
21#include <framework/core/Environment.h>
24#include <framework/utilities/MakeROOTCompatible.h>
25#include <framework/utilities/RootFileCreationManager.h>
40 setDescription(
"Calculate variables specified by the user for a given ParticleList and save them into a TNtuple. The TNtuple is candidate-based, meaning that the variables of each candidate are saved into separate rows.");
43 vector<string> emptylist;
45 "Name of particle list with reconstructed particles. If no list is provided the variables are saved once per event (only possible for event-type variables)",
48 "List of variables (or collections) to save. Variables are taken from Variable::Manager, and are identical to those available to e.g. ParticleSelector.",
51 addParam(
"fileName",
m_fileName,
"Name of ROOT file for output. Can be overridden using the -o argument of basf2.",
52 string(
"VariablesToNtuple.root"));
53 addParam(
"treeName",
m_treeName,
"Name of the NTuple in the saved file.",
string(
"ntuple"));
56 std::tuple<std::string, std::map<int, unsigned int>> default_sampling{
"", {}};
58 "Tuple of variable name and a map of integer values and inverse sampling rate. E.g. (signal, {1: 0, 0:10}) selects all signal candidates and every 10th background candidate.",
62 "Name of signal-side particle list to store the index of the signal-side particle when one calls the module in a for_each loop over the RestOfEvent",
69 "Use float type for floating-point numbers.",
false);
72 "If true, the branch __eventType__ is added. The eventType information is available from MC16 on.",
true);
75 "Ignore override of file name via command line argument -o. Useful if you have multiple output modules in one path.",
false);
89 if (!outputFileArgument.empty())
97 B2FATAL(
"Output root file name is not set. Please set a valid root output file name (\"fileName\" module parameter).");
103 B2ERROR(
"Could not create file \"" <<
m_fileName <<
104 "\". Please set a valid root output file name (\"fileName\" module parameter).");
108 TDirectory::TContext directoryGuard(
m_file.get());
113 <<
"\" already exists in the file \"" <<
m_fileName <<
"\"\n"
114 <<
"\nYou probably want to either set the output fileName or the treeName to something else:\n\n"
115 <<
" from modularAnalysis import variablesToNtuple\n"
116 <<
" variablesToNtuple('pi+:all', ['p'], treename='pions', filename='variablesToNtuple.root')\n"
117 <<
" variablesToNtuple('gamma:all', ['p'], treename='photons', filename='variablesToNtuple.root') # two trees, same file\n"
119 <<
" from modularAnalysis import variablesToNtuple\n"
120 <<
" variablesToNtuple('pi+:all', ['p'], filename='pions.root')\n"
121 <<
" variablesToNtuple('gamma:all', ['p'], filename='photons.root') # two files\n"
129 m_tree->get().SetCacheSize(100000);
133 m_tree->get().Branch(
"__run__", &
m_run,
"__run__/I");
145 if (not
m_roe.isOptional(
"RestOfEvent")) {
146 B2WARNING(
"The signalSideParticleList is set outside of a for_each loop over the RestOfEvent. "
147 <<
"__signalSideCandidates__ and __nSignalSideCandidate__ will be always -1 and 0, respectively.");
157 B2INFO(
"EventExtraInfo is not registered. __eventType__ will be empty. The eventType is available from MC16 on.");
161 if (Variable::isCounterVariable(variable)) {
162 B2WARNING(
"The counter '" << variable
163 <<
"' is handled automatically by VariablesToNtuple, you don't need to add it.");
169 unordered_set<string> seen;
171 if (seen.find(varStr) != std::end(seen)) return true;
187 size_t enumerate = 1;
197 B2ERROR(
"Variable '" << varStr <<
"' is not available in Variable::Manager!");
199 if (
m_particleList.empty() && var->description.find(
"[Eventbased]") == string::npos) {
200 B2ERROR(
"Variable '" << varStr <<
"' is not an event-based variable, "
201 "but you are using VariablesToNtuple without a decay string, i.e. in the event-wise mode.\n"
202 "If you have created an event-based alias you can wrap your alias with `eventCached` to "
203 "declare it as event based, which avoids this error.\n\n"
204 "vm.addAlias('myAliasName', 'eventCached(myAlias)')");
207 if (var->variabletype == Variable::Manager::VariableDataType::c_double) {
213 }
else if (var->variabletype == Variable::Manager::VariableDataType::c_int) {
215 }
else if (var->variabletype == Variable::Manager::VariableDataType::c_bool) {
218 m_functions.push_back(std::make_pair(var->function, var->variabletype));
230 B2FATAL(
"Couldn't find sample variable " <<
m_sampling_name <<
" via the Variable::Manager. Check the name!");
283 if (
m_roe.isValid()) {
302 for (
unsigned int iVar = 0; iVar <
m_variables.size(); iVar++) {
303 auto var_result = std::get<0>(
m_functions[iVar])(
nullptr);
305 if (std::holds_alternative<double>(var_result)) {
306 if (var_type != Variable::Manager::VariableDataType::c_double)
307 B2WARNING(
"Wrong registered data type for variable '" +
m_variables[iVar] +
308 "'. Expected Variable::Manager::VariableDataType::c_double. Exported data for this variable might be incorrect.");
314 }
else if (std::holds_alternative<int>(var_result)) {
315 if (var_type != Variable::Manager::VariableDataType::c_int)
316 B2WARNING(
"Wrong registered data type for variable '" +
m_variables[iVar] +
317 "'. Expected Variable::Manager::VariableDataType::c_int. Exported data for this variable might be incorrect.");
319 }
else if (std::holds_alternative<bool>(var_result)) {
320 if (var_type != Variable::Manager::VariableDataType::c_bool)
321 B2WARNING(
"Wrong registered data type for variable '" +
m_variables[iVar] +
322 "'. Expected Variable::Manager::VariableDataType::c_bool. Exported data for this variable might be incorrect.");
332 for (
unsigned int iPart = 0; iPart <
m_ncandidates; iPart++) {
334 const Particle* particle = particlelist->getParticle(iPart);
342 for (
unsigned int iVar = 0; iVar <
m_variables.size(); iVar++) {
343 auto var_result = std::get<0>(
m_functions[iVar])(particle);
345 if (std::holds_alternative<double>(var_result)) {
346 if (var_type != Variable::Manager::VariableDataType::c_double)
347 B2WARNING(
"Wrong registered data type for variable '" +
m_variables[iVar] +
348 "'. Expected Variable::Manager::VariableDataType::c_double. Exported data for this variable might be incorrect.");
354 }
else if (std::holds_alternative<int>(var_result)) {
355 if (var_type != Variable::Manager::VariableDataType::c_int)
356 B2WARNING(
"Wrong registered data type for variable '" +
m_variables[iVar] +
357 "'. Expected Variable::Manager::VariableDataType::c_int. Exported data for this variable might be incorrect.");
359 }
else if (std::holds_alternative<bool>(var_result)) {
360 if (var_type != Variable::Manager::VariableDataType::c_bool)
361 B2WARNING(
"Wrong registered data type for variable '" +
m_variables[iVar] +
362 "'. Expected Variable::Manager::VariableDataType::c_bool. Exported data for this variable might be incorrect.");
376 TDirectory::TContext directoryGuard(
m_file.get());
379 const bool writeError =
m_file->TestBit(TFile::kWriteError);
382 B2FATAL(
"A write error occurred while saving '" <<
m_fileName <<
"', please check if enough disk space is available.");
In the store you can park objects that have to be accessed by various modules.
@ c_DontWriteOut
Object/array should be NOT saved by output modules.
const std::string & getOutputFileOverride() const
Return overriden output file name, or "" if none was set.
static Environment & Instance()
Static method to get a reference to the Environment instance.
static std::string makeROOTCompatible(std::string str)
Remove special characters that ROOT dislikes in branch names, e.g.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
@ c_TerminateInAllProcesses
When using parallel processing, call this module's terminate() function in all processes().
Class to store reconstructed particles.
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.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
Type-safe access to single objects in the data store.
std::vector< std::string > resolveCollections(const std::vector< std::string > &variables)
Resolve Collection Returns variable names corresponding to the given collection or if it is not a col...
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
static Manager & Instance()
get singleton instance.
void checkDeprecatedVariable(const std::string &name)
Check if a variable is deprecated.
StoreObjPtr< RestOfEvent > m_roe
ROE object.
bool m_useFloat
Use float type for floating-point numbers.
std::vector< std::string > m_variables
List of variables to save.
std::vector< float > m_branchAddressesFloat
Branch addresses of variables of type float.
virtual void initialize() override
Initialises the module.
std::map< int, unsigned int > m_sampling_rates
Inverse sampling rates.
VariablesToNtupleModule()
Constructor.
virtual void event() override
Method called for each event.
unsigned int m_ncandidates
total n candidates
virtual void terminate() override
Write TTree to file, and close file if necessary.
StoreObjPtr< EventMetaData > m_eventMetaData
the event information
std::map< int, unsigned long int > m_sampling_counts
Current number of samples with this value.
std::string m_fileName
Name of ROOT file for output.
std::vector< std::pair< Variable::Manager::FunctionPtr, Variable::Manager::VariableDataType > > m_functions
List of pairs of function pointers and respective data type corresponding to given variables.
std::tuple< std::string, std::map< int, unsigned int > > m_sampling
Tuple of variable name and a map of integer values and inverse sampling rate.
std::vector< int > m_branchAddressesInt
Branch addresses of variables of type int (or bool)
int m_basketsize
Size of TBaskets in the output ROOT file in bytes.
int m_production
production ID (to distinguish MC samples)
unsigned int m_nSignalSideCandidates
total n signal-side candidates
StoreObjPtr< StringWrapper > m_stringWrapper
string wrapper storing the MCDecayString
int m_experiment
experiment number
bool m_storeEventType
If true, the branch eventType is added.
std::string m_particleList
Name of particle list with reconstructed particles.
bool m_ignoreCommandLineOverride
if true, ignore override of filename
std::string m_eventType
EventType to be filled.
StoreObjPtr< RootMergeable< TTree > > m_tree
The ROOT TNtuple for output.
std::shared_ptr< TFile > m_file
ROOT file for output.
std::vector< double > m_branchAddressesDouble
Branch addresses of variables of type double.
std::string m_sampling_name
Variable name of sampling variable.
float getInverseSamplingRateWeight(const Particle *particle)
Calculate inverse sampling rate weight.
StoreObjPtr< EventExtraInfo > m_eventExtraInfo
pointer to EventExtraInfo
std::string m_treeName
Name of the TTree.
std::string m_signalSideParticleList
Name of signal-side particle list
const Variable::Manager::Var * m_sampling_variable
Variable Pointer to target variable.
int m_signalSideCandidate
signal-side candidate counter
std::string m_fileNameSuffix
Suffix to be appended to the output file name.
int m_candidate
candidate counter
std::string m_MCDecayString
MC decay string to be filled.
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
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.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.
VariableDataType variabletype
data type of variable
A variable returning a floating-point value for a given Particle.
FunctionPtr function
Pointer to function.