AliPhysics  cdeda5a (cdeda5a)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AliEmcalContainerIndexMap.h
Go to the documentation of this file.
1 #if !(defined(__CINT__) || defined(__MAKECINT__))
2 #ifndef ALIEMCALCONTAINERINDEXMAP_H
3 #define ALIEMCALCONTAINERINDEXMAP_H
4 
5 #include <map>
6 #include <typeinfo>
7 
8 #include <TObject.h>
9 #include <TClonesArray.h>
10 #include <TObjArray.h>
11 #include <TClass.h>
12 #include <AliLog.h>
13 
14 #include "AliEmcalContainer.h"
15 
73 template <class U, class V>
75  public:
77 
78  virtual ~AliEmcalContainerIndexMap() { delete fClass; }
79 
80  // Setup index map for AliEmcalContainer or TClonesArray
81  int RegisterArray(U * inputObject);
82 
83  // Copy the mapping from the source "map"; the mapping is between the global index found in "map" for object "cont" and the object "cont" itself
84  template<class U2>
85  void CopyMappingFrom(const AliEmcalContainerIndexMap<U2, V>& map, U* cont);
86 
87  // Copy the mapping from the source "map"; the mapping is between the global index found in "map" for each object in "containers" and the objects in "containers"
88  template<class U2>
89  void CopyMappingFrom(const AliEmcalContainerIndexMap<U2, V>& map, TCollection & containers);
90 
91  // Index operations
92  // Returns the offset of an input object
93  template<class U2>
94  int GetOffset(const U2 * inputObject) const;
95  // Returns the global index of an input object and the local index of the object of interest
96  int GlobalIndexFromLocalIndex(const U * inputObject, const int localIndex) const;
97  // Returns a pair with the local index and the array for a given global index
98  std::pair<int, U *> LocalIndexFromGlobalIndex(const int globalIndex) const;
99  // Get object directly
100  V * GetObjectFromGlobalIndex(const int globalIndex) const;
101 
102  protected:
103  //template<class Z = U>
104  const TClonesArray * GetObject(const AliEmcalContainer * inputObject) const;
105  const TClonesArray * GetObject(const TClonesArray * inputObject) const;
106  bool IsUnderlyingInputObjectTypeCompatible(const U * inputObject) const;
107 
108  std::map <int, U *> fGlobalIndexMap;
109 
110  int fOffset;
111  TClass* fClass;
112 };
113 
114 template<class U, class V>
116  fOffset(100000),
117  fGlobalIndexMap(),
118  fClass(TClass::GetClass(typeid(V)))
119 {
120 
121 }
122 
132 template<class U, class V>
133 //template<class Z = U, typename std::enable_if< std::is_same<Z, AliEmcalContainer>::value,int>::type = 0>
134 inline const TClonesArray * AliEmcalContainerIndexMap<U, V>::GetObject(const AliEmcalContainer * inputObject) const
135 {
136  return inputObject->GetArray();
137 }
138 
147 template<class U, class V>
148 //template<class Z = U, typename std::enable_if< std::is_same<Z, AliEmcalContainer>::value,int>::type = 0>
149 inline const TClonesArray * AliEmcalContainerIndexMap<U, V>::GetObject(const TClonesArray * inputObject) const
150 {
151  return inputObject;
152 }
153 
165 template<class U, class V>
167 {
168  if (!(inputObject->GetClass()->InheritsFrom(fClass))) {
169  AliErrorGeneral("AliEmcalContainerIndexMap", Form("Cannot register array %s. This map can only accept arrays of type %s.", inputObject->GetName(), fClass->GetName()));
170  return false;
171  }
172 
173  return true;
174 }
175 
186 template<class U, class V>
188 {
189  if (IsUnderlyingInputObjectTypeCompatible(inputObject) == false) {
190  return -1;
191  }
192 
193  int index = 0;
194  bool addToMap = true;
195  for (auto val : fGlobalIndexMap)
196  {
197  // Check if the array is already added
198  // We want to compare the address of the TClonesArrays to simplify the comparison
199  if (GetObject(val.second) == GetObject(inputObject)) {
200  addToMap = false;
201  index = val.first;
202  break;
203  }
204 
205  // Find the max index so that we can add at the proper place
206  if (val.first >= index) {
207  index = val.first + fOffset;
208  }
209  }
210 
211  // Add to map
212  if (addToMap) {
213  // We want to compare the address of the TClonesArrays to simplify the comparison
214  fGlobalIndexMap[index] = inputObject;
215  }
216 
217  return index;
218 }
219 
229 template<class U, class V>
230 int AliEmcalContainerIndexMap<U, V>::GlobalIndexFromLocalIndex(const U * inputObject, const int localIndex) const
231 {
232  int globalIndex = GetOffset(inputObject);
233 
234  // Only add the local index if we found a match!
235  if (globalIndex >= 0) {
236  globalIndex += localIndex;
237  }
238  else {
239  AliWarningGeneral("AliEmcalContainerIndexMap", TString::Format("Unable to retrieve global index for input object %s. Was the input object registered?", inputObject->GetName()));
240  }
241 
242  return globalIndex;
243 }
244 
252 template<class U, class V>
253 template<class U2>
254 int AliEmcalContainerIndexMap<U, V>::GetOffset(const U2 * inputObject) const
255 {
256  int globalIndex = -1;
257  for (auto val : fGlobalIndexMap)
258  {
259  // We want to compare the address of the TClonesArrays to simplify the comparison
260  if (GetObject(val.second) == GetObject(inputObject)) {
261  globalIndex = val.first;
262  break;
263  }
264  }
265 
266  return globalIndex;
267 }
268 
276 template<class U, class V>
277 std::pair<int, U *> AliEmcalContainerIndexMap<U, V>::LocalIndexFromGlobalIndex(const int globalIndex) const
278 {
279  // Round to nearest offset
280  int index = (globalIndex + fOffset/2)/fOffset * fOffset;
281 
282  // Used at() to allow the function to be const (operator[] is not const for std::map)
283  U * array = fGlobalIndexMap.at(index);
284 
285  return std::pair<int, U*> (globalIndex - index, array);
286 }
287 
296 template<class U, class V>
298 {
299  auto res = LocalIndexFromGlobalIndex(globalIndex);
300 
301  // We don't need to call GetObject() if we access using operator[]!
302  return static_cast<V *>((*res.second)[res.first]);
303 }
304 
315 template<class U, class V>
316 template<class U2>
318 {
319  TIter next(&containers);
320  TObject* obj = 0;
321  while((obj = next())) {
322  U* cont = dynamic_cast<U*>(obj);
323  if (!cont) continue;
324  if (IsUnderlyingInputObjectTypeCompatible(cont) == false) {
325  continue;
326  }
327 
328  int gindex = map.GetOffset(cont);
329  if (gindex >= 0) fGlobalIndexMap[gindex] = cont;
330  }
331 }
332 
343 template<class U, class V>
344 template<class U2>
346 {
347  if (IsUnderlyingInputObjectTypeCompatible(cont) == false) {
348  return;
349  }
350 
351  int gindex = map.GetOffset(cont);
352  if (gindex >= 0) fGlobalIndexMap[gindex] = cont;
353 }
354 
355 #endif /* AliEmcalContainerIndexMap.h */
356 #endif /* Hiding from CINT */
TObject * GetObject(const TCollection *parent, const TString &name, const TClass *cls=0, Bool_t verbose=true)
std::map< int, U * > fGlobalIndexMap
! Map between index and input object
std::pair< int, U * > LocalIndexFromGlobalIndex(const int globalIndex) const
Container or array to index mapping for AliEmcalContainer derived classes.
const TClonesArray * GetObject(const AliEmcalContainer *inputObject) const
int GetOffset(const U2 *inputObject) const
int GlobalIndexFromLocalIndex(const U *inputObject, const int localIndex) const
V * GetObjectFromGlobalIndex(const int globalIndex) const
TClass * fClass
Used to compare the type of V against the underlying input object type.
void CopyMappingFrom(const AliEmcalContainerIndexMap< U2, V > &map, U *cont)
int fOffset
Offset between each TClonesArray.
bool IsUnderlyingInputObjectTypeCompatible(const U *inputObject) const