Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DTreeInterfaceObjects.h
Go to the documentation of this file.
1 #ifndef DTreeInterfaceObjects_h
2 #define DTreeInterfaceObjects_h
3 
4 #include <typeindex>
5 #include <typeinfo>
6 #include <map>
7 #include <string>
8 #include <deque>
9 #include <vector>
10 
11 #include "TVector2.h"
12 #include "TVector3.h"
13 #include "TLorentzVector.h"
14 
15 using namespace std;
16 
17 class DTreeInterface;
18 
19 /***************************************************************** DTreeTypeChecker *******************************************************************/
20 
22 {
23  public:
24  template <typename DType> static void Is_Supported(void)
25  {
26  static_assert(std::is_same<Char_t, DType>::value || std::is_same<UChar_t, DType>::value ||
27  std::is_same<Short_t, DType>::value || std::is_same<UShort_t, DType>::value || std::is_same<Int_t, DType>::value ||
28  std::is_same<UInt_t, DType>::value || std::is_same<Float_t, DType>::value || std::is_same<Double_t, DType>::value ||
29  std::is_same<Long64_t, DType>::value || std::is_same<ULong64_t, DType>::value || std::is_same<Bool_t, DType>::value ||
30  std::is_same<TVector2, DType>::value || std::is_same<TVector3, DType>::value || std::is_same<TLorentzVector, DType>::value,
31  "DTreeTypeChecker ERROR: TYPE IS NOT SUPPORTED.");
32  }
33 
34  template <typename DType> static void Is_Fundamental(void)
35  {
36  static_assert(std::is_same<Char_t, DType>::value || std::is_same<UChar_t, DType>::value ||
37  std::is_same<Short_t, DType>::value || std::is_same<UShort_t, DType>::value || std::is_same<Int_t, DType>::value ||
38  std::is_same<UInt_t, DType>::value || std::is_same<Float_t, DType>::value || std::is_same<Double_t, DType>::value ||
39  std::is_same<Long64_t, DType>::value || std::is_same<ULong64_t, DType>::value || std::is_same<Bool_t, DType>::value,
40  "DTreeTypeChecker ERROR: TYPE IS NOT A SUPPORTED FUNDAMENTAL TYPE.");
41  }
42 
43  template <typename DType> static void Is_TObject(void)
44  {
45  static_assert(std::is_same<TVector2, DType>::value || std::is_same<TVector3, DType>::value || std::is_same<TLorentzVector, DType>::value,
46  "DTreeTypeChecker ERROR: TYPE IS NOT A SUPPORTED TOBJECT TYPE.");
47  }
48 };
49 
50 /**************************************************************** DTreeBranchRegister *****************************************************************/
51 
53 {
54  friend class DTreeInterface;
55 
56  public:
57  DTreeBranchRegister(void) : dUserInfo(new TList()){}
59  {
60  //If multiple threads, objects in the list may be created by multiple threads on the heap, each with the same name
61  //The TList destructor tries to do something I don't quite understand ...
62  //It looks like it's trying to delete objects on the heap, which it shouldn't try to do by default
63  //Anyway, it looks like things are being double-freed somehow
64  //Instead: Avoid this by removing the list entries
65  while(dUserInfo->GetEntries() > 0)
66  dUserInfo->RemoveLast();
67  //delete dUserInfo; //in fact, deleting this STILL seems to be causing issues. Just don't delete it.
68  }
69 
70  TList* Get_UserInfo(void) const{return dUserInfo;}
71 
72  template <typename DType> void Register_Single(string locBranchName);
73  template <typename DType> void Register_FundamentalArray(string locBranchName, string locArraySizeName, size_t locInitialArraySize = 10);
74  template <typename DType> void Register_ClonesArray(string locBranchName, size_t locInitialArraySize = 10);
75 
76  private:
77  TList* dUserInfo;
78  vector<string> dBranchNames; //keep the order in which they were added
79  map<string, type_index> dBranchTypeMap;
80  map<string, size_t> dInitialArraySizeMap;
81  map<string, string> dArraySizeNameMap; //for fundamental
82 };
83 
84 template <typename DType> inline void DTreeBranchRegister::Register_Single(string locBranchName)
85 {
86  DTreeTypeChecker::Is_Supported<DType>();
87  dBranchNames.push_back(locBranchName);
88  dBranchTypeMap.insert(pair<string, type_index>(locBranchName, type_index(typeid(DType))));
89 }
90 
91 template <typename DType> inline void DTreeBranchRegister::Register_FundamentalArray(string locBranchName, string locArraySizeName, size_t locInitialArraySize)
92 {
93  DTreeTypeChecker::Is_Fundamental<DType>();
94  dBranchNames.push_back(locBranchName);
95  dBranchTypeMap.insert(pair<string, type_index>(locBranchName, type_index(typeid(DType))));
96  dInitialArraySizeMap[locBranchName] = locInitialArraySize;
97  dArraySizeNameMap[locBranchName] = locArraySizeName;
98 }
99 
100 template <typename DType> inline void DTreeBranchRegister::Register_ClonesArray(string locBranchName, size_t locInitialArraySize)
101 {
102  DTreeTypeChecker::Is_TObject<DType>();
103  dBranchNames.push_back(locBranchName);
104  dBranchTypeMap.insert(pair<string, type_index>(locBranchName, type_index(typeid(DType))));
105  dInitialArraySizeMap[locBranchName] = locInitialArraySize;
106 }
107 
108 /******************************************************************* DTreeFillData ********************************************************************/
109 
110 //Want to abstract the fill type so we can hold them in a container without dynamically allocating void*'s
112 {
113  public:
114  virtual ~DFillBaseClass(){};
115  virtual void* Get(size_t locArrayIndex) = 0;
116  virtual void Check_Capacity(void) = 0;
117 };
118 
119 template <typename DType>
121 {
122  public:
123  deque<DType> dFillData; //must use deque because vector<bool> won't compile!!!
124 
126 
127  void* Get(size_t locArrayIndex){return static_cast<void*>(&(dFillData[locArrayIndex]));}
128  void Check_Capacity(void);
129 
130  private:
131  size_t dMaxFillVectorSize = 1000; //if exceeds this, will drop down on next event
132 };
133 
134 template <typename DType> inline void DFillClass<DType>::Check_Capacity(void)
135 {
136  if(dFillData.size() <= dMaxFillVectorSize)
137  return;
138  dFillData.resize(dMaxFillVectorSize);
139 }
140 
141 //Need one per thread:
142  //If this is created within the scope of a single object that is shared amongst all threads (e.g. plugin processor): static thread-local variable
143  //Data stored as void*: Requires new on creation and delete on destruction: Try to re-use object
144  //If this is created within the scope of an object that is unique for each thread: Class member
146 {
147  friend class DTreeInterface;
148 
149  public:
150  ~DTreeFillData(void);
151  template <typename DType> void Fill_Single(string locBranchName, const DType& locData);
152  template <typename DType> void Fill_Array(string locBranchName, const DType& locData, size_t locArrayIndex);
153 
154  private:
155  map<string, pair<type_index, DFillBaseClass*> > dFillData;
156  map<string, int> dArrayLargestIndexFilledMap; //can be less than the size //reset by DTreeInterface after fill
157 };
158 
159 /*********************************************************** DTreeFillData: FILL BRANCHES *************************************************************/
160 
161 template <typename DType> inline void DTreeFillData::Fill_Single(string locBranchName, const DType& locData)
162 {
163  DTreeTypeChecker::Is_Supported<DType>();
164  type_index locTypeIndex(typeid(DType));
165 
166  auto locIterator = dFillData.find(locBranchName);
167  if(locIterator == dFillData.end())
168  {
169  //create new object, register in map
170  auto locFillClass = new DFillClass<DType>();
171  locFillClass->dFillData.push_back(locData);
172  dFillData.emplace(locBranchName, std::make_pair(locTypeIndex, static_cast<DFillBaseClass*>(locFillClass)));
173  }
174  else if(locTypeIndex != locIterator->second.first)
175  cout << "WARNING: CANNOT FILL: IS WRONG TYPE FOR BRANCH " << locBranchName << endl;
176  else
177  {
178  auto locFillClass = static_cast<DFillClass<DType>*>(locIterator->second.second);
179  locFillClass->dFillData[0] = locData;
180  }
181 }
182 
183 template <typename DType> inline void DTreeFillData::Fill_Array(string locBranchName, const DType& locData, size_t locArrayIndex)
184 {
185  DTreeTypeChecker::Is_Supported<DType>();
186  type_index locTypeIndex(typeid(DType));
187 
188  auto locIterator = dFillData.find(locBranchName);
189  if(locIterator == dFillData.end())
190  {
191  //create new object, register in map
192  auto locFillClass = new DFillClass<DType>();
193  dFillData.emplace(locBranchName, std::make_pair(locTypeIndex, static_cast<DFillBaseClass*>(locFillClass)));
194 
195  //fill
196  locFillClass->dFillData.resize(locArrayIndex + 1);
197  locFillClass->dFillData[locArrayIndex] = locData;
198  dArrayLargestIndexFilledMap[locBranchName] = locArrayIndex;
199  }
200  else if(locTypeIndex != locIterator->second.first)
201  cout << "WARNING: CANNOT FILL: IS WRONG TYPE FOR BRANCH " << locBranchName << endl;
202  else
203  {
204  auto locFillClass = static_cast<DFillClass<DType>*>(locIterator->second.second);
205 
206  //resize if needed & fill
207  if(locArrayIndex >= locFillClass->dFillData.size())
208  locFillClass->dFillData.resize(locArrayIndex + 1);
209  locFillClass->dFillData[locArrayIndex] = locData;
210 
211  //register largest index filled
212  auto& locLargestIndexFilled = dArrayLargestIndexFilledMap[locBranchName];
213  if(int(locArrayIndex) > locLargestIndexFilled)
214  locLargestIndexFilled = locArrayIndex;
215  }
216 }
217 /*
218 //Enable this version if type inherits from TObject //void: is return type
219 template <typename DType> typename enable_if<std::is_base_of<TObject, DType>::value, void>::type
220  Create_Branch(string locBranchName, size_t locArraySize, string locArraySizeName);
221 
222 //Enable this version if type does NOT inherit from TObject //void: is return type
223 template <typename DType> typename enable_if<!std::is_base_of<TObject, DType>::value, void>::type
224  Create_Branch(string locBranchName, size_t locArraySize, string locArraySizeName);
225 */
226 /************************************************************* DTreeFillData: DESTRUCTOR **************************************************************/
227 
229 {
230  //delete all memory (void*'s)
231  //loop over branches
232  for(auto& locBranchPair : dFillData)
233  delete locBranchPair.second.second;
234 }
235 
236 #endif //DTreeInterfaceObjects
void * Get(size_t locArrayIndex)
map< string, size_t > dInitialArraySizeMap
void Register_Single(string locBranchName)
void Fill_Array(string locBranchName, const DType &locData, size_t locArrayIndex)
map< string, string > dArraySizeNameMap
map< string, pair< type_index, DFillBaseClass * > > dFillData
vector< string > dBranchNames
void Register_ClonesArray(string locBranchName, size_t locInitialArraySize=10)
deque< DType > dFillData
void Check_Capacity(void)
static void Is_Fundamental(void)
void Register_FundamentalArray(string locBranchName, string locArraySizeName, size_t locInitialArraySize=10)
TList * Get_UserInfo(void) const
static void Is_TObject(void)
static void Is_Supported(void)
map< string, int > dArrayLargestIndexFilledMap
map< string, type_index > dBranchTypeMap
void Fill_Single(string locBranchName, const DType &locData)