PandaRoot
PndContainerRegister.h
Go to the documentation of this file.
1 //****************************************************************************
2 //* This file is part of PandaRoot. *
3 //* *
4 //* PandaRoot is distributed under the terms of the *
5 //* GNU General Public License (GPL) version 3, *
6 //* copied verbatim in the file "LICENSE". *
7 //* *
8 //* Copyright (C) 2006 - 2024 FAIR GmbH and copyright holders of PandaRoot *
9 //* The copyright holders are listed in the file "COPYRIGHTHOLDERS". *
10 //* The authors are listed in the file "AUTHORS". *
11 //****************************************************************************
12 
13 #ifndef PNDCONTAINERREGISTER_HH
14 #define PNDCONTAINERREGISTER_HH
15 
16 #include <RtypesCore.h>
17 #include <map>
18 
19 #include "PndMutableContainer.h"
20 #include "TString.h"
21 
22 #include "FairLogger.h"
23 
24 #include "PndConstContainerI.h"
25 #include "PndContainerBaseI.h"
26 #include "PndMutableContainerI.h"
27 
28 class PndContainerRegister : public TObject {
29  public:
31  TString fBranchname{""};
32  TString fClassType{""};
33  Bool_t fIsOutput{kFALSE};
34  Bool_t fIsPersistent{kTRUE};
35  Bool_t RequestsSpecificBranch() const { return fBranchname != ""; }
36  TString GetKey() const { return fBranchname + fClassType; }
37  };
38 
39  void Request(const PndContainerType_t &t_container)
40  {
41  auto pos = fRequests.find(t_container.GetKey());
42  if (pos != fRequests.end()) {
43  if ((*pos).second.fClassType != t_container.fClassType) {
44  LOG(fatal) << "Attempting to request branch " << t_container.fBranchname << " for " << t_container.fClassType << " but branchname already used for "
45  << (*pos).second.fClassType << ". Ignoring this request!";
46  } else {
47  (*pos).second.fIsOutput |= t_container.fIsOutput;
48  (*pos).second.fIsPersistent |= t_container.fIsPersistent;
49  LOG(debug) << "Setting request for an output branch " << t_container.fBranchname << " for " << t_container.fClassType;
50  }
51  } else {
52  fRequests[t_container.GetKey()] = t_container;
53  LOG(debug) << "Setting request for branch " << t_container.fBranchname << " for " << t_container.fClassType;
54  }
55  }
56 
57  Bool_t IsBranchSet(const TString &t_branchname) const
58  {
59  auto pos = fInputs.find(t_branchname);
60  if (pos != fInputs.end()) {
61  return (pos->second) != nullptr;
62  }
63  auto opos = fOutputs.find(t_branchname);
64  if (opos != fOutputs.end()) {
65  return (opos->second) != nullptr;
66  }
67  return false;
68  }
69 
70  template <class T>
71  PndMutableContainerI<T> *GetOutput(const TString &t_branchname)
72  {
73  LOG(debug) << "PndContainerRegister::GetOutput(" << t_branchname << ") for " << T{}.ClassName();
74 
75  if (t_branchname == "" || fDefaultBranches[T{}.ClassName()] == t_branchname) {
76  LOG(debug) << "PndContainerRegister::GetOutput(" << t_branchname << ") from default register";
77  auto *defaultBranch = GetDefaultBranch<T>();
78  if (dynamic_cast<PndMutableContainerI<T> *>(defaultBranch)) {
79  return dynamic_cast<PndMutableContainerI<T> *>(defaultBranch);
80  } else {
81  LOG(error) << "Attempted to cast a InputContainer " << t_branchname << ") for " << T{}.ClassName() << " to PndMutableContainerI! Returning nullptr!";
82  return nullptr;
83  }
84  }
85  return dynamic_cast<PndMutableContainerI<T> *>(fOutputs[t_branchname]);
86  }
87 
88  template <class T>
89  void SetOutput(const TString &t_branchname, PndContainerI<T> *t_ptr)
90  {
91  const TString classname = t_ptr->GetClassName();
92  fOutputs[t_branchname] = t_ptr;
93  fInputs[t_branchname] = t_ptr;
94 
95  if (fDefaultBranches.find(classname) == fDefaultBranches.end()) {
96  SetAsDefaultBranchFor(t_branchname, classname);
97  }
98  }
99 
100  template <class T>
101  PndContainerI<T> *GetInput(const TString &t_branchname)
102  {
103  LOG(debug) << "PndContainerRegister::GetInput(" << t_branchname << ") for " << T{}.ClassName();
104  if (t_branchname == "" || fDefaultBranches[T{}.ClassName()] == t_branchname) {
105  LOG(debug) << "PndContainerRegister::GetInput(" << t_branchname << ") from default register";
106 
107  return (GetDefaultBranch<T>());
108  }
109  return dynamic_cast<PndContainerI<T> *>(fInputs[t_branchname]);
110  }
111 
112  template <class T>
113  void SetInput(const TString &t_branchname, PndContainerI<T> *t_ptr)
114  {
115  const TString classname = t_ptr->GetClassName();
116  fInputs[t_branchname] = t_ptr;
117  if (fDefaultBranches.find(classname) == fDefaultBranches.end()) {
118  SetAsDefaultBranchFor(t_branchname, classname);
119  }
120  }
121 
122  void SetAsDefaultBranchFor(const TString &t_branchname, const TString &t_class)
123  {
124  LOG(info) << "PndContainerRegister::SetAsDefaultBranchFor() Setting " << t_branchname << " as active branch for " << t_class;
125  fDefaultBranches[t_class] = t_branchname;
126  }
127 
128  template <class T>
130  {
131  const TString classname = T{}.ClassName();
132  const TString &defaultBranch = fDefaultBranches[classname];
133  LOG(debug) << "PndContainerRegister::GetDefaultBranch() Returning default branch " << defaultBranch << " for " << classname;
134 
135  auto pos = fInputs.find(defaultBranch);
136  if (pos != fInputs.end()) {
137  return dynamic_cast<PndContainerI<T> *>(pos->second);
138  }
139  return dynamic_cast<PndContainerI<T> *>(fOutputs[defaultBranch]);
140  }
141 
142  const TString &GetCurrentDefaultBranchName(const TString &t_classname) const { return fDefaultBranches.at(t_classname); }
143 
144  template <class T>
145  const TString &GetCurrentDefaultBranchName() const
146  {
147  const TString classname = T{}.ClassName();
148  return GetCurrentDefaultBranchName(classname);
149  }
150 
151  const std::map<TString, PndContainerType_t> &GetRequests() { return fRequests; }
152  const std::map<TString, TString> &GetBranches() { return fContainerOfType; }
153  std::map<TString, PndContainerBaseI *> &Inputs() { return fInputs; }
154  std::map<TString, PndContainerBaseI *> &Outputs() { return fOutputs; }
155 
156  virtual ~PndContainerRegister() = default;
157 
158  private:
159  std::map<TString, PndContainerType_t> fRequests{};
160  std::map<TString, TString> fDefaultBranches{};
161  std::map<TString, TString> fContainerOfType{};
162  std::map<TString, PndContainerBaseI *> fInputs{};
163  std::map<TString, PndContainerBaseI *> fOutputs{};
164 
165  ClassDef(PndContainerRegister, 1);
166 };
167 
168 #endif /*PNDCONTAINERREGISTER_HH*/
PndContainerI< T > * GetDefaultBranch()
const std::map< TString, PndContainerType_t > & GetRequests()
void SetInput(const TString &t_branchname, PndContainerI< T > *t_ptr)
Container to wrap PndTCA/STDMutableContainer (not needed anymore)
void SetOutput(const TString &t_branchname, PndContainerI< T > *t_ptr)
virtual ~PndContainerRegister()=default
void Request(const PndContainerType_t &t_container)
Interface to a datacontainer to be used in PandaROOT.
const TString & GetCurrentDefaultBranchName(const TString &t_classname) const
std::map< TString, PndContainerBaseI * > & Inputs()
TString GetClassName() const
Definition: PndContainerI.h:75
const std::map< TString, TString > & GetBranches()
PndContainerI< T > * GetInput(const TString &t_branchname)
const TString & GetCurrentDefaultBranchName() const
PndMutableContainerI< T > * GetOutput(const TString &t_branchname)
std::map< TString, PndContainerBaseI * > & Outputs()
Bool_t IsBranchSet(const TString &t_branchname) const
void SetAsDefaultBranchFor(const TString &t_branchname, const TString &t_class)