DAS  3.0
Das Analysis System
Flow

Description

User-friendly handling of input and output n-tuples.

A flow consists of input and outputs 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"); // default is TH1
Note
A one-liner is also possible:

#include <Flow.h>

+ Collaboration diagram for Flow:

Public Member Functions

std::string DumpActiveBranches () const
 
 Flow (int=none, const std::vector< std::filesystem::path > &={})
 
 ~Flow ()
 
ChainSliceGetInputTree (std::vector< std::filesystem::path >, const Slice={1, 0}, const std::string &="events")
 
ChainSliceGetInputTree (const Slice={1, 0}, 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 ()
 
ChainSliceGetInputTree (std::vector< std::filesystem::path >, const Slice={1, 0}, const std::string &="events")
 
ChainSliceGetInputTree (const Slice={1, 0}, 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)
 

Private Member Functions

template<typename T >
std::shared_ptr< T * > GetBranch (const std::string &name) const
 
template<typename T >
T * NoBranch (const std::string &name, BranchMode mode)
 
template<typename T >
std::shared_ptr< T * > GetBranch (const std::string &name) const
 
template<typename T >
T * NoBranch (const std::string &name, BranchMode mode)
 

Private Attributes

int steering
 
std::vector< std::filesystem::path > inputs
 
std::unique_ptr< ChainSlicetIn
 
std::shared_ptr< TFile > fOut
 
std::unique_ptr< TTree > tOut
 
std::map< std::string, std::any > branches
 

Constructor & Destructor Documentation

◆ Flow() [1/2]

Flow ( int  steering = none,
const std::vector< std::filesystem::path > &  short_inputs = {} 
)

Constructor.

Determines the command in which Flow is called.

Parameters
steeringsteering bitfield
short_inputsROOT files or directories
12  : steering(steering), inputs(GetROOTfiles(short_inputs))
13 {
14  if (short_inputs.size() > 0 && inputs.size() == 0)
15  BOOST_THROW_EXCEPTION(fs::filesystem_error("No input was found!",
16  make_error_code(errc::no_such_file_or_directory)));
17 }

◆ ~Flow() [1/2]

~Flow ( )

Destructor.

Saves the output tree (if declared) to the output file (if open).

20 {
21  if (fOut) {
22  if (tOut) {
23  if (steering & verbose)
24  cout << "Flow: saving output tree" << endl;
25 
26  fOut->cd();
27  tOut->Write();
28  }
29  else if (steering & verbose)
30  cout << "Flow: no output tree to save" << endl;
31  }
32  else if (tOut && (steering & verbose))
33  cout << "Flow: no file to save the output tree" << endl;
34 
35  if (tIn) tIn->ResetBranchAddresses();
36  if (tOut) tOut->ResetBranchAddresses();
37 }

◆ Flow() [2/2]

Flow ( int  = none,
const std::vector< std::filesystem::path > &  = {} 
)

Constructor.

Determines the command in which Flow is called.

◆ ~Flow() [2/2]

~Flow ( )

Destructor.

Saves the output tree (if declared) to the output file (if open).

Member Function Documentation

◆ DumpActiveBranches() [1/2]

std::string DumpActiveBranches ( ) const
inline

Returns a list of all active branches, formatted as a string.

110  {
111  auto keys = branches | std::views::keys;
112  return std::accumulate(keys.begin(), keys.end(), std::string(),
113  [](const std::string& str, const std::string& branch_name) {
114  return str + ' ' + branch_name;
115  });
116  }

◆ DumpActiveBranches() [2/2]

std::string DumpActiveBranches ( ) const
inline

Returns a list of all active branches, formatted as a string.

110  {
111  auto keys = branches | std::views::keys;
112  return std::accumulate(keys.begin(), keys.end(), std::string(),
113  [](const std::string& str, const std::string& branch_name) {
114  return str + ' ' + branch_name;
115  });
116  }

◆ GetBranch() [1/2]

std::shared_ptr<T*> GetBranch ( const std::string &  name) const
inlineprivate

Get address of branch address in a shared pointer.

< branch type < branch name

85  {
86  using namespace std;
87  if (steering & verbose)
88  cout << "Flow: retrieving an existing branch" << endl;
89  auto& branch = branches.at(name);
90  return any_cast<shared_ptr<T*>>(branch);
91  }
92  catch (const std::bad_any_cast& e) {
93  BOOST_THROW_EXCEPTION(e);
94  }

◆ GetBranch() [2/2]

std::shared_ptr<T*> GetBranch ( const std::string &  name) const
inlineprivate

Get address of branch address in a shared pointer.

< branch type < branch name

85  {
86  using namespace std;
87  if (steering & verbose)
88  cout << "Flow: retrieving an existing branch" << endl;
89  auto& branch = branches.at(name);
90  return any_cast<shared_ptr<T*>>(branch);
91  }
92  catch (const std::bad_any_cast& e) {
93  BOOST_THROW_EXCEPTION(e);
94  }

◆ GetBranchReadOnly() [1/2]

T* GetBranchReadOnly ( const std::string &  name,
BranchMode  mode = mandatory 
)
inline

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
namebranch name
modebranch may not exist
259  {
260  using namespace std;
261 
262  if (!tIn)
263  BOOST_THROW_EXCEPTION( invalid_argument("`GetInputTree()` should "
264  "be called before declaring a read-only branch") );
265 
266  namespace DE = Darwin::Exceptions;
267 
268  shared_ptr<T*> t;
269 
270  if (branches.contains(name))
271  t = GetBranch<T>(name);
272  else {
273  t = make_shared<T*>();
274  if (steering & verbose)
275  cout << "Flow: loading branch `" << name << "`" << endl;
276 
277  if (tIn->GetBranch(name.c_str()) == nullptr)
278  return NoBranch<T>(name, mode);
279 
280  int err = tIn->SetBranchAddress(name.c_str(), t.get());
281  if (steering & verbose)
282  cout << "Flow: `TTree::SetBranchAddress()` returned " << to_string(err)
283  << " (check `TTree::ESetBranchAddressStatus` for the meaning)."
284  << endl;
285  if (err < 0) {
286  string what = "`"s + name + "` branch could not be set. "s;
287  if (mode == facultative) {
288  if (steering & verbose)
289  cout << orange << "Flow: " << what << def << endl;
290  return nullptr;
291  }
292  BOOST_THROW_EXCEPTION( DE::BadInput(what.c_str(), *tIn) );
293  }
294  branches.insert({name, t});
295  }
296  return *t;
297  }

◆ GetBranchReadOnly() [2/2]

T* GetBranchReadOnly ( const std::string &  name,
BranchMode  mode = mandatory 
)
inline

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
namebranch name
modebranch may not exist
259  {
260  using namespace std;
261 
262  if (!tIn)
263  BOOST_THROW_EXCEPTION( invalid_argument("`GetInputTree()` should "
264  "be called before declaring a read-only branch") );
265 
266  namespace DE = Darwin::Exceptions;
267 
268  shared_ptr<T*> t;
269 
270  if (branches.contains(name))
271  t = GetBranch<T>(name);
272  else {
273  t = make_shared<T*>();
274  if (steering & verbose)
275  cout << "Flow: loading branch `" << name << "`" << endl;
276 
277  if (tIn->GetBranch(name.c_str()) == nullptr)
278  return NoBranch<T>(name, mode);
279 
280  int err = tIn->SetBranchAddress(name.c_str(), t.get());
281  if (steering & verbose)
282  cout << "Flow: `TTree::SetBranchAddress()` returned " << to_string(err)
283  << " (check `TTree::ESetBranchAddressStatus` for the meaning)."
284  << endl;
285  if (err < 0) {
286  string what = "`"s + name + "` branch could not be set. "s;
287  if (mode == facultative) {
288  if (steering & verbose)
289  cout << orange << "Flow: " << what << def << endl;
290  return nullptr;
291  }
292  BOOST_THROW_EXCEPTION( DE::BadInput(what.c_str(), *tIn) );
293  }
294  branches.insert({name, t});
295  }
296  return *t;
297  }

◆ GetBranchReadWrite() [1/2]

T* GetBranchReadWrite ( const std::string &  name,
BranchMode  mode = mandatory 
)
inline

Wrapper to initialise read-write branches.

In practice, setting up a branch to modify its contents reduces to a single line:

auto recEvent = flow.GetBranchReadWrite<RecEvent>("recEvent");

< branch type (e.g. RecEvent, vector<RecJet>)

Parameters
namebranch name
modebranch may not exist
347  {
348  using namespace std;
349 
350  if (!tIn)
351  BOOST_THROW_EXCEPTION( invalid_argument("`GetInputTree()` should "
352  "be called before declaring a read-write branch") );
353 
354  if (!tOut)
355  BOOST_THROW_EXCEPTION( invalid_argument("`GetOutputTree()` should "
356  "be called before declaring a read-write branch") );
357 
358  shared_ptr<T*> t;
359 
360  if (branches.contains(name))
361  t = GetBranch<T>(name);
362  else {
363  if (GetBranchReadOnly<T>(name, mode) == nullptr)
364  return NoBranch<T>(name, mode);
365  if (steering & Friend)
366  GetBranchWriteOnly<T>(name);
367  t = any_cast<shared_ptr<T*>>(branches[name]);
368  }
369  return *t;
370  }

◆ GetBranchReadWrite() [2/2]

T* GetBranchReadWrite ( const std::string &  name,
BranchMode  mode = mandatory 
)
inline

Wrapper to initialise read-write branches.

In practice, setting up a branch to modify its contents reduces to a single line:

auto recEvent = flow.GetBranchReadWrite<RecEvent>("recEvent");

< branch type (e.g. RecEvent, vector<RecJet>)

Parameters
namebranch name
modebranch may not exist
347  {
348  using namespace std;
349 
350  if (!tIn)
351  BOOST_THROW_EXCEPTION( invalid_argument("`GetInputTree()` should "
352  "be called before declaring a read-write branch") );
353 
354  if (!tOut)
355  BOOST_THROW_EXCEPTION( invalid_argument("`GetOutputTree()` should "
356  "be called before declaring a read-write branch") );
357 
358  shared_ptr<T*> t;
359 
360  if (branches.contains(name))
361  t = GetBranch<T>(name);
362  else {
363  if (GetBranchReadOnly<T>(name, mode) == nullptr)
364  return NoBranch<T>(name, mode);
365  if (steering & Friend)
366  GetBranchWriteOnly<T>(name);
367  t = any_cast<shared_ptr<T*>>(branches[name]);
368  }
369  return *t;
370  }

◆ GetBranchWriteOnly() [1/2]

T* GetBranchWriteOnly ( const std::string &  name)
inline

Wrapper to initialise write-only branches.

In practice, setting up a new branch in a n-tuple reduces to a single line:

auto recEvent = flow.GetBranchWriteOnly<RecEvent>("recEvent");

< branch type (e.g. RecEvent, vector<RecJet>)

Parameters
namebranch name
309  {
310  using namespace std;
311 
312  if (!tOut)
313  BOOST_THROW_EXCEPTION( invalid_argument("`GetOutputTree()` should "
314  "be called before") );
315 
316  shared_ptr<T*> t;
317 
318  if (branches.contains(name))
319  t = GetBranch<T>(name);
320  else
321  t = make_shared<T*>();
322 
323  if (steering & verbose)
324  cout << "Flow: setting up new branch for `" << name << "`" << endl;
325  if (tOut->Branch(name.c_str(), t.get()) == nullptr) {
326  namespace DE = Darwin::Exceptions;
327  string what = name + " branch could not be set up";
328  BOOST_THROW_EXCEPTION( DE::BadInput(what.c_str(), *tOut) );
329  }
330 
331  if (!branches.contains(name))
332  branches.insert({name, t});
333  return *t;
334  }

◆ GetBranchWriteOnly() [2/2]

T* GetBranchWriteOnly ( const std::string &  name)
inline

Wrapper to initialise write-only branches.

In practice, setting up a new branch in a n-tuple reduces to a single line:

auto recEvent = flow.GetBranchWriteOnly<RecEvent>("recEvent");

< branch type (e.g. RecEvent, vector<RecJet>)

Parameters
namebranch name
309  {
310  using namespace std;
311 
312  if (!tOut)
313  BOOST_THROW_EXCEPTION( invalid_argument("`GetOutputTree()` should "
314  "be called before") );
315 
316  shared_ptr<T*> t;
317 
318  if (branches.contains(name))
319  t = GetBranch<T>(name);
320  else
321  t = make_shared<T*>();
322 
323  if (steering & verbose)
324  cout << "Flow: setting up new branch for `" << name << "`" << endl;
325  if (tOut->Branch(name.c_str(), t.get()) == nullptr) {
326  namespace DE = Darwin::Exceptions;
327  string what = name + " branch could not be set up";
328  BOOST_THROW_EXCEPTION( DE::BadInput(what.c_str(), *tOut) );
329  }
330 
331  if (!branches.contains(name))
332  branches.insert({name, t});
333  return *t;
334  }

◆ GetInputHist() [1/2]

std::unique_ptr<THX> GetInputHist ( const std::string &  name)
inline

Load a single ROOT histogram from a list of files.

Todo:
Can we rather use a node handle to extract the unique pointer?
Parameters
nameinternal path to ROOT histogram
205  {
206  auto hists = GetInputHists<THX,1>({name});
207  THX * hist = hists.front().release();
208  return std::unique_ptr<THX>(hist);
209  }

◆ GetInputHist() [2/2]

std::unique_ptr<THX> GetInputHist ( const std::string &  name)
inline

Load a single ROOT histogram from a list of files.

Todo:
Can we rather use a node handle to extract the unique pointer?
Parameters
nameinternal path to ROOT histogram
205  {
206  auto hists = GetInputHists<THX,1>({name});
207  THX * hist = hists.front().release();
208  return std::unique_ptr<THX>(hist);
209  }

◆ GetInputHists() [1/4]

auto GetInputHists ( const Args...  args)
inline

Load ROOT histograms from a list of files.

In many cases, this spares from running an intermediate hadd (which can be very slow if there is a TTree in the same ROOT file).

192  {
193  constexpr const size_t N = sizeof...(args);
194  std::array<std::string, N> names {{ args... }};
195  return GetInputHists<THX, N>(names);
196  }

◆ GetInputHists() [2/4]

auto GetInputHists ( const Args...  args)
inline

Load ROOT histograms from a list of files.

In many cases, this spares from running an intermediate hadd (which can be very slow if there is a TTree in the same ROOT file).

192  {
193  constexpr const size_t N = sizeof...(args);
194  std::array<std::string, N> names {{ args... }};
195  return GetInputHists<THX, N>(names);
196  }

◆ GetInputHists() [3/4]

std::array<std::unique_ptr<THX>, N> GetInputHists ( const std::array< std::string, N > &  names = {})
inline

Load ROOT histograms from a list of files.

In many cases, this spares from running an intermediate hadd (which can be very slow if there is a TTree in the same ROOT file).

Parameters
namespath to ROOT histograms
153  {}
154  )
155  {
156  using namespace std;
157  namespace fs = filesystem;
158 
159  if (inputs.size() == 0)
160  BOOST_THROW_EXCEPTION( runtime_error("Empty input list") );
161 
162  array<unique_ptr<THX>, N> sums;
163  for (const fs::path& input: inputs) {
164  auto fIn = make_unique<TFile>(input.c_str(), "READ");
165  for (size_t i = 0; i < N; ++i) {
166  const string& name = names[i];
167  unique_ptr<THX> h(fIn->Get<THX>(name.c_str()));
168  if (!h) {
169  namespace DE = Darwin::Exceptions;
170  BOOST_THROW_EXCEPTION(
171  DE::BadInput(Form("`%s` cannot be found in (one of) the "
172  " file(s).", name.c_str()), fIn));
173  }
174  if (sums[i])
175  sums[i]->Add(h.get());
176  else {
177  sums[i] = std::move(h);
178  sums[i]->SetDirectory(nullptr);
179  }
180  }
181  }
182  return sums;
183  }

◆ GetInputHists() [4/4]

std::array<std::unique_ptr<THX>, N> GetInputHists ( const std::array< std::string, N > &  names = {})
inline

Load ROOT histograms from a list of files.

In many cases, this spares from running an intermediate hadd (which can be very slow if there is a TTree in the same ROOT file).

Parameters
namespath to ROOT histograms
153  {}
154  )
155  {
156  using namespace std;
157  namespace fs = filesystem;
158 
159  if (inputs.size() == 0)
160  BOOST_THROW_EXCEPTION( runtime_error("Empty input list") );
161 
162  array<unique_ptr<THX>, N> sums;
163  for (const fs::path& input: inputs) {
164  auto fIn = make_unique<TFile>(input.c_str(), "READ");
165  for (size_t i = 0; i < N; ++i) {
166  const string& name = names[i];
167  unique_ptr<THX> h(fIn->Get<THX>(name.c_str()));
168  if (!h) {
169  namespace DE = Darwin::Exceptions;
170  BOOST_THROW_EXCEPTION(
171  DE::BadInput(Form("`%s` cannot be found in (one of) the "
172  " file(s).", name.c_str()), fIn));
173  }
174  if (sums[i])
175  sums[i]->Add(h.get());
176  else {
177  sums[i] = std::move(h);
178  sums[i]->SetDirectory(nullptr);
179  }
180  }
181  }
182  return sums;
183  }

◆ GetInputTree() [1/4]

ChainSlice * GetInputTree ( const Slice  slice = {1, 0},
const std::string &  name = "events" 
)

Load chain from a list of files.

internal path to TTree

Parameters
slicenumber and index of slice
40 {
41 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
42  return GetInputTree(inputs, slice, name);
43 _Pragma("GCC diagnostic pop")
44 }

◆ GetInputTree() [2/4]

ChainSlice* GetInputTree ( const  Slice = {1, 0},
const std::string &  = "events" 
)

Load chain from a list of files.

internal path to TTree

Parameters
Slicenumber and index of slice

◆ GetInputTree() [3/4]

ChainSlice * GetInputTree ( std::vector< std::filesystem::path >  inputs,
const Slice  slice = {1, 0},
const std::string &  name = "events" 
)

Load chain from a list of files.

internal path to TTree

Parameters
inputsROOT files or directories
slicenumber and index of slice
48 {
49  if (tIn) {
50  if (steering & verbose)
51  cout << "Flow: returning the existing input tree "
52  "(arguments are ignored)" << endl;
53  return tIn.get();
54  }
55 
56  if (inputs.size() == 0)
57  BOOST_THROW_EXCEPTION( runtime_error("Empty input list") );
58 
59  if (slice.first == 0 || slice.first <= slice.second)
60  BOOST_THROW_EXCEPTION(invalid_argument("The number of slices " + to_string(slice.first)
61  + " must be larger than the index of the current slice " + to_string(slice.second)));
62 
63  if (inputs.empty())
64  BOOST_THROW_EXCEPTION( invalid_argument("Empty list of input files") );
65 
66  tIn = make_unique<ChainSlice>(name.c_str());
67  for (const auto& input: inputs) {
68  int code = tIn->Add(input.c_str(), 0);
69  // "If nentries<=0 and wildcarding is not used,
70  // returns 1 if the file exists and contains the correct tree
71  // and 0 otherwise" (ROOT Doxygen)
72  if (code == 1) continue; // i.e. the tree was found successfully
73  tIn.reset();
74  auto fIn = make_unique<TFile>(input.c_str(), "READ");
75  BOOST_THROW_EXCEPTION(DE::BadInput("The tree cannot be "
76  "found in (one of) the input file(s).", fIn));
77  }
78  if (tIn->GetEntries() == 0) {
79  tIn.reset();
80  BOOST_THROW_EXCEPTION(invalid_argument("Empty trees in input!"));
81  }
82 
83  // Restrict the tIn to the entries for the slice
84  const auto entries = tIn->GetEntries();
85  tIn->SetBegin(entries * ((slice.second + 0.) / slice.first));
86  tIn->SetEnd(entries * ((slice.second + 1.) / slice.first));
87 
88  return tIn.get();
89 }

◆ GetInputTree() [4/4]

ChainSlice* GetInputTree ( std::vector< std::filesystem::path >  ,
const  Slice = {1, 0},
const std::string &  = "events" 
)

Load chain from a list of files.

internal path to TTree

Parameters
Slicenumber and index of slice

◆ GetOutput() [1/2]

std::pair< TFile *, TTree * > GetOutput ( const std::filesystem::path &  fOutName,
const std::source_location  location = std::source_location::current() 
)

Get both the output file and the output tree in one go.

upstream function

Parameters
fOutNameoutput directory
168 {
169  shared_ptr<TFile> fOut = Darwin::Tools::GetOutputFile(fOutName, location);
170  return {fOut.get(), GetOutputTree(fOut, location)};
171 }

◆ GetOutput() [2/2]

std::pair<TFile *, TTree *> GetOutput ( const std::filesystem::path &  ,
const std::source_location  = std::source_location::current() 
)

Get both the output file and the output tree in one go.

upstream function

◆ GetOutputFile() [1/2]

TFile* GetOutputFile ( )
inline

Get a raw pointer to the output file.

238 { return fOut.get(); }

◆ GetOutputFile() [2/2]

TFile* GetOutputFile ( )
inline

Get a raw pointer to the output file.

238 { return fOut.get(); }

◆ GetOutputTree() [1/4]

TTree* GetOutputTree ( const std::filesystem::path &  ,
const std::source_location  = std::source_location::current() 
)

Create an output TTree object.

upstream function

◆ GetOutputTree() [2/4]

TTree * GetOutputTree ( const std::filesystem::path &  fOutName,
const std::source_location  location = std::source_location::current() 
)

Create an output TTree object.

upstream function

Parameters
fOutNameoutput directory
161 {
162  shared_ptr<TFile> fOut = Darwin::Tools::GetOutputFile(fOutName, location);
163  return GetOutputTree(fOut, location);
164 }

◆ GetOutputTree() [3/4]

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
fOutoutput file
93 {
94  if (tOut) {
95  if (steering & verbose)
96  cout << "Flow: returning the existing output tree" << endl;
97 
98  return tOut.get();
99  }
100 
101  if (fOut)
103 
104  const char * title = fs::path(location.file_name()).stem().c_str();
105 
106  if (!tIn) {
107  if (steering & verbose)
108  cout << "Flow: creating a new output tree" << endl;
109 
110  tOut = make_unique<TTree>("events", title);
111  }
112  else if (steering & Friend) {
118  if (steering & verbose)
119  cout << "Flow: creating a friend tree" << endl;
120 
121  tOut = make_unique<TTree>("events", title);
122  tIn->GetEntry(0); // necessary to load a(ny) TTree
123 
124  // find the name of the previous command
125  string lastFunc = tIn->GetTree()->GetTitle();
126  // -> this is supposed to store the name of the last command
127  if (lastFunc == "") {
128  cerr << orange << "Unable to identify the command used to "
129  "obtain the input from the title.\n" << def;
130  lastFunc = "previous";
131  }
132  else if (lastFunc == title) {
133  cerr << orange << "Running twice the same command in a row. "
134  "Adding `previous2` ahead of the title.\n" << def;
135  lastFunc = "previous2"s + title;
136  }
137 
138  // add friend
139  SlicedFriendElement::AddTo(tOut.get(), tIn.get(), lastFunc.c_str());
140 
141  // copy metainfo
142  TList * userinfo = tIn->GetTree()->GetUserInfo();
143  tOut->GetUserInfo()->AddAll(userinfo);
144  userinfo->Clear(); // necessary to prevent the TTree destructor from deleting
145  // all elements in the list (avoid double deletion)
146  }
147  else {
148  if (steering & verbose)
149  cout << "Flow: creating a clone tree" << endl;
150 
151  tOut = unique_ptr<TTree>(tIn->CloneTree(0));
152  tOut->SetTitle(title);
153  }
154  if (fOut)
155  tOut->SetDirectory(fOut.get());
156  return tOut.get();
157 }

◆ GetOutputTree() [4/4]

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

◆ NoBranch() [1/2]

T* NoBranch ( const std::string &  name,
BranchMode  mode 
)
inlineprivate
97  {
98  if (mode == facultative)
99  return nullptr;
100 
101  namespace DE = Darwin::Exceptions;
102  std::string what = name + " branch could not be found";
103  BOOST_THROW_EXCEPTION( DE::BadInput(what.c_str(), *tIn) );
104  }

◆ NoBranch() [2/2]

T* NoBranch ( const std::string &  name,
BranchMode  mode 
)
inlineprivate
97  {
98  if (mode == facultative)
99  return nullptr;
100 
101  namespace DE = Darwin::Exceptions;
102  std::string what = name + " branch could not be found";
103  BOOST_THROW_EXCEPTION( DE::BadInput(what.c_str(), *tIn) );
104  }

◆ SetOutputFile() [1/2]

void SetOutputFile ( std::shared_ptr< TFile >  fOut)
inline

Set the output file where the output TTree should be saved.

234 { this->fOut = fOut; }

◆ SetOutputFile() [2/2]

void SetOutputFile ( std::shared_ptr< TFile >  fOut)
inline

Set the output file where the output TTree should be saved.

234 { this->fOut = fOut; }

Member Data Documentation

◆ branches

std::map< std::string, std::any > branches
private

pointers to mounted branches

◆ fOut

std::shared_ptr< TFile > fOut
private

output ROOT file

◆ inputs

std::vector< std::filesystem::path > inputs
private

ROOT files or directories.

◆ steering

int steering
private

steering from Options, mostly useful for friends

◆ tIn

std::unique_ptr< ChainSlice > tIn
private

input chain

◆ tOut

std::unique_ptr< TTree > tOut
private

output tree


The documentation for this class was generated from the following files:
DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.name
name
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:48
Darwin::Tools::Flow::branches
std::map< std::string, std::any > branches
pointers to mounted branches
Definition: Flow.h:79
prefix.diagnostic
None diagnostic(Exception exception)
Definition: prefix.py:354
Ntupliser_cfg.cerr
cerr
Definition: Ntupliser_cfg.py:93
Darwin::Tools::Flow
User-friendly handling of input and output n-tuples.
Definition: Flow.h:69
Step::def
static const char * def
Definition: Step.h:36
Darwin::Tools::Friend
@ Friend
activate -F to only fill the new branches
Definition: Options.h:28
Ntupliser_cfg.args
args
Definition: Ntupliser_cfg.py:11
Darwin::Tools::Flow::tOut
std::unique_ptr< TTree > tOut
output tree
Definition: Flow.h:77
Darwin::Tools::Flow::fOut
std::shared_ptr< TFile > fOut
output ROOT file
Definition: Flow.h:76
Darwin::Tools::GetOutputFile
std::shared_ptr< TFile > GetOutputFile(const std::filesystem::path &, const std::source_location=std::source_location::current())
Shortcut to create a reproducible output file (see ROOT Doxygen for details)
Definition: FileUtils.cc:99
Darwin::Exceptions
Handling of exceptions.
Definition: darwin.h:36
Darwin::Tools::verbose
@ verbose
bit for debug mode (-v is always available)
Definition: Options.h:30
orange
static const char * orange
Definition: colours.h:6
DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.input
input
Definition: DYToLL_M-50_13TeV_pythia8_cff_GEN_SIM_RECOBEFMIX_DIGI_L1_DIGI2RAW_L1Reco_RECO.py:35
Darwin::Tools::Flow::inputs
std::vector< std::filesystem::path > inputs
ROOT files or directories.
Definition: Flow.h:73
Darwin::Tools::Flow::GetOutputTree
TTree * GetOutputTree(std::shared_ptr< TFile >={}, const std::source_location=std::source_location::current())
Create an output TTree object.
Definition: Flow.cc:91
DAS::RecDijet
Di< RecJet, RecJet > RecDijet
Definition: Di.h:80
Darwin::Tools::Flow::GetInputTree
ChainSlice * GetInputTree(std::vector< std::filesystem::path >, const Slice={1, 0}, const std::string &="events")
Load chain from a list of files.
Definition: Flow.cc:46
Darwin::Tools::GetROOTfiles
std::vector< std::filesystem::path > GetROOTfiles(std::vector< std::filesystem::path > inputs)
ROOT files or directories.
Definition: FileUtils.cc:37
Darwin::Tools::Flow::steering
int steering
steering from Options, mostly useful for friends
Definition: Flow.h:71
Darwin::Tools::Flow::tIn
std::unique_ptr< ChainSlice > tIn
input chain
Definition: Flow.h:75
Darwin::Tools::Flow::GetInputHist
std::unique_ptr< THX > GetInputHist(const std::string &name)
Load a single ROOT histogram from a list of files.
Definition: Flow.h:204
Darwin::Tools::SlicedFriendElement::AddTo
static SlicedFriendElement * AddTo(TTree *tree, ChainSlice *chain, const char *alias)
Adds a ChainSlice as a friend to a TTree.
Definition: FriendUtils.cc:80
Darwin::Tools::Flow::SetOutputFile
void SetOutputFile(std::shared_ptr< TFile > fOut)
Set the output file where the output TTree should be saved.
Definition: Flow.h:234
Darwin::Exceptions::BadInput
Generic exception for ill-defined input (before the event loop).
Definition: exceptions.h:83
Darwin::Tools::facultative
@ facultative
mounting branch is facultative
Definition: Flow.h:31