User-friendly handling of input and output n-tuples.
A flow consists of input and output path to n-tuples and of a slice:
auto tIn = flow.GetInputTree(slice);
auto tOut = flow.GetOutputTree(output);
auto fOut = flow.GetOutputFile();
The last two lines can be condensed as follows:
auto [
fOut,
tOut] = flow.GetOutput(output);
The steering is use for the verbosity and the friendship. Setting up branches reduces to the following:
auto recEvent = flow.GetBranchReadOnly<RecEvent>("recEvent");
auto recJets = flow.GetBranchReadWrite<vector<RecJet>>("recJets");
auto recDijet = flow.GetBranchWriteOnly<
RecDijet>(
"recDijet");
Furthermore, as it is frequent to produce histograms along the n-tuple (e.g. control plots), a flow allows to sum on the fly a histogram:
auto hIn = flow.GetInputHist<TH2>("h");
auto hIns = flow.GetInputHists("h1", "h2");
- Note
- A one-liner is also possible:
|
std::string | DumpActiveBranches () const |
|
| Flow (int=none, const std::vector< std::filesystem::path > &={}) |
|
| ~Flow () |
|
ChainSlice * | GetInputTree (const Slice, const std::string &="events") |
|
ChainSlice * | GetInputTree (const std::string &="events") |
|
template<typename THX = TH1, size_t N> |
std::array< std::unique_ptr< THX >, N > | GetInputHists (const std::array< std::string, N > &names={}) |
|
template<typename THX = TH1, typename... Args> |
auto | GetInputHists (const Args... args) |
|
template<typename THX = TH1> |
std::unique_ptr< THX > | GetInputHist (const std::string &name) |
|
TTree * | GetOutputTree (std::shared_ptr< TFile >={}, const std::source_location=std::source_location::current()) |
|
TTree * | GetOutputTree (const std::filesystem::path &, const std::source_location=std::source_location::current()) |
|
void | SetOutputFile (std::shared_ptr< TFile > fOut) |
|
TFile * | GetOutputFile () |
|
std::pair< TFile *, TTree * > | GetOutput (const std::filesystem::path &, const std::source_location=std::source_location::current()) |
|
template<typename T > |
T * | GetBranchReadOnly (const std::string &name, BranchMode mode=mandatory) |
|
template<typename T > |
T * | GetBranchWriteOnly (const std::string &name) |
|
template<typename T > |
T * | GetBranchReadWrite (const std::string &name, BranchMode mode=mandatory) |
|
std::string | DumpActiveBranches () const |
|
| Flow (int=none, const std::vector< std::filesystem::path > &={}) |
|
| ~Flow () |
|
ChainSlice * | GetInputTree (const Slice, const std::string &="events") |
|
ChainSlice * | GetInputTree (const std::string &="events") |
|
template<typename THX = TH1, size_t N> |
std::array< std::unique_ptr< THX >, N > | GetInputHists (const std::array< std::string, N > &names={}) |
|
template<typename THX = TH1, typename... Args> |
auto | GetInputHists (const Args... args) |
|
template<typename THX = TH1> |
std::unique_ptr< THX > | GetInputHist (const std::string &name) |
|
TTree * | GetOutputTree (std::shared_ptr< TFile >={}, const std::source_location=std::source_location::current()) |
|
TTree * | GetOutputTree (const std::filesystem::path &, const std::source_location=std::source_location::current()) |
|
void | SetOutputFile (std::shared_ptr< TFile > fOut) |
|
TFile * | GetOutputFile () |
|
std::pair< TFile *, TTree * > | GetOutput (const std::filesystem::path &, const std::source_location=std::source_location::current()) |
|
template<typename T > |
T * | GetBranchReadOnly (const std::string &name, BranchMode mode=mandatory) |
|
template<typename T > |
T * | GetBranchWriteOnly (const std::string &name) |
|
template<typename T > |
T * | GetBranchReadWrite (const std::string &name, BranchMode mode=mandatory) |
|
Wrapper to initialise read-only branches.
The existence of the branch is checked before setting the address.
In practice, loading a branch whose contents should be accessed but not modified reduces to a single line:
auto recEvent = flow.GetBranchReadOnly<RecEvent>("recEvent");
< branch type (e.g. RecEvent
, vector<RecJet>
)
- Parameters
-
name | branch name |
mode | branch may not exist |
269 BOOST_THROW_EXCEPTION( invalid_argument(
"`GetInputTree()` should "
270 "be called before declaring a read-only branch") );
277 t = GetBranch<T>(
name);
279 t = make_shared<T*>();
281 cout <<
"Flow: loading branch `" <<
name <<
"`" << endl;
283 if (
tIn->GetBranch(
name.c_str()) ==
nullptr)
284 return NoBranch<T>(
name, mode);
286 int err =
tIn->SetBranchAddress(
name.c_str(), t.get());
288 cout <<
"Flow: `TTree::SetBranchAddress()` returned " << to_string(err)
289 <<
" (check `TTree::ESetBranchAddressStatus` for the meaning)."
292 string what =
"`"s +
name +
"` branch could not be set. "s;
295 cout <<
orange <<
"Flow: " << what <<
def << endl;
Wrapper to initialise read-only branches.
The existence of the branch is checked before setting the address.
In practice, loading a branch whose contents should be accessed but not modified reduces to a single line:
auto recEvent = flow.GetBranchReadOnly<RecEvent>("recEvent");
< branch type (e.g. RecEvent
, vector<RecJet>
)
- Parameters
-
name | branch name |
mode | branch may not exist |
269 BOOST_THROW_EXCEPTION( invalid_argument(
"`GetInputTree()` should "
270 "be called before declaring a read-only branch") );
277 t = GetBranch<T>(
name);
279 t = make_shared<T*>();
281 cout <<
"Flow: loading branch `" <<
name <<
"`" << endl;
283 if (
tIn->GetBranch(
name.c_str()) ==
nullptr)
284 return NoBranch<T>(
name, mode);
286 int err =
tIn->SetBranchAddress(
name.c_str(), t.get());
288 cout <<
"Flow: `TTree::SetBranchAddress()` returned " << to_string(err)
289 <<
" (check `TTree::ESetBranchAddressStatus` for the meaning)."
292 string what =
"`"s +
name +
"` branch could not be set. "s;
295 cout <<
orange <<
"Flow: " << what <<
def << endl;
TTree * GetOutputTree |
( |
std::shared_ptr< TFile > |
fOut = {} , |
|
|
const std::source_location |
location = std::source_location::current() |
|
) |
| |
Create an output TTree
object.
If the TTree
already exists, either clone the input TChain
or define the input TChain
as a friend of the new TTree
. Else a brand new TTree
is stored.
The title of the TTree
is used to store (retrieve) the name of the present (previous) command. When loading a tree with friends, one can refer to old versions of the branches by prefixing them with the corresponding command name.
- Todo:
TTree::BuildIndex()
to preserve the association despite skipped events?
upstream function
- Note
- We use the title to store the current command. When the present tree is used as a friend, this title will supsersede its name. Exceptions:
- no title was found,
- or the present name is the same as the last title (i.e. running twice the same command).
- Parameters
-
94 cout <<
"Flow: returning the existing output tree" << endl;
102 const auto title = fs::path(location.file_name()).stem().string();
106 cout <<
"Flow: creating a new output tree" << endl;
108 tOut = make_unique<TTree>(
"events", title.c_str());
117 cout <<
"Flow: creating a friend tree" << endl;
119 tOut = make_unique<TTree>(
"events", title.c_str());
123 string lastFunc =
tIn->GetTree()->GetTitle();
125 if (lastFunc ==
"") {
126 cerr <<
orange <<
"Unable to identify the command used to "
127 "obtain the input from the title.\n" <<
def;
128 lastFunc =
"previous";
130 else if (lastFunc == title) {
131 cerr <<
orange <<
"Running twice the same command in a row. "
132 "Adding `previous2` ahead of the title.\n" <<
def;
133 lastFunc =
"previous2"s + title;
140 TList * userinfo =
tIn->GetTree()->GetUserInfo();
141 tOut->GetUserInfo()->AddAll(userinfo);
147 cout <<
"Flow: creating a clone tree" << endl;
149 tOut = unique_ptr<TTree>(
tIn->CloneTree(0));
150 tOut->SetTitle(title.c_str());
TTree* GetOutputTree |
( |
std::shared_ptr< TFile > |
= {} , |
|
|
const std::source_location |
= std::source_location::current() |
|
) |
| |
Create an output TTree
object.
If the TTree
already exists, either clone the input TChain
or define the input TChain
as a friend of the new TTree
. Else a brand new TTree
is stored.
The title of the TTree
is used to store (retrieve) the name of the present (previous) command. When loading a tree with friends, one can refer to old versions of the branches by prefixing them with the corresponding command name.
- Todo:
TTree::BuildIndex()
to preserve the association despite skipped events?
upstream function