Skip to content
Snippets Groups Projects

WIP: Slicing and refactoring offline

Closed Tamas Gal requested to merge 37-user-parameters-seem-to-be-transposed into master
Compare and Show latest version
3 files
+ 123
41
Compare changes
  • Side-by-side
  • Inline
Files
3
+ 73
28
@@ -20,7 +20,19 @@ def _nested_mapper(key):
EXCLUDE_KEYS = set(["AAObject", "t", "fBits", "fUniqueID"])
BRANCH_MAPS = [
EVENTS_MAP = BranchMapper("events", "Evt", {
't_sec': 't.fSec',
't_ns': 't.fNanoSec'
}, [], {
'n_hits': 'hits',
'n_mc_hits': 'mc_hits',
'n_tracks': 'trks',
'n_mc_tracks': 'mc_trks'
}, lambda a: a, True)
SUBBRANCH_MAPS = [
BranchMapper("tracks", "trks", {}, ['trks.usr_data', 'trks.usr'], {},
_nested_mapper, False),
BranchMapper("mc_tracks", "mc_trks", {},
@@ -41,7 +53,6 @@ BRANCH_MAPS = [
}, lambda a: a, True),
]
class cached_property:
"""A simple cache decorator for properties."""
def __init__(self, function):
@@ -78,10 +89,9 @@ class OfflineReader:
self._tree = self._fobj[MAIN_TREE_NAME]
self._data = data
for mapper in BRANCH_MAPS:
# print("setting mapper {}".format(mapper.name))
setattr(self, mapper.name,
Branch(self._tree, mapper=mapper, index=self._index))
@cached_property
def events(self):
return Branch(self._tree, mapper=EVENTS_MAP, index=self._index, subbranchmaps=SUBBRANCH_MAPS)
@classmethod
def from_index(cls, source, index):
@@ -415,10 +425,10 @@ class OfflineReader:
are not found, None is returned as the stages index.
"""
if mc is False:
stages_data = self.tracks.rec_stages
stages_data = self.events.tracks.rec_stages
if mc is True:
stages_data = self.mc_tracks.rec_stages
stages_data = self.events.mc_tracks.rec_stages
for trk_index, rec_stages in enumerate(stages_data):
try:
@@ -554,17 +564,27 @@ class Header:
class Branch:
"""Branch accessor class"""
def __init__(self, tree, mapper, index=None):
def __init__(self, tree, mapper, index=None, subbranches=None, subbranchmaps=None):
self._tree = tree
self._mapper = mapper
self._index = index
self._keymap = None
self._branch = tree[mapper.key]
self._subbranches = []
self._initialise_keys() #
self._initialise_keys()
if subbranches is not None:
self._subbranches = subbranches
if subbranchmaps is not None:
for mapper in subbranchmaps:
subbranch = Branch(self._tree, mapper=mapper, index=self._index)
self._subbranches.append(subbranch)
for subbranch in self._subbranches:
setattr(self, subbranch._mapper.name, subbranch)
def _initialise_keys(self):
"""Create the keymap and instance attributes"""
"""Create the keymap and instance attributes for branch keys"""
keys = set(k.decode('utf-8') for k in self._branch.keys()) - set(
self._mapper.exclude) - EXCLUDE_KEYS
self._keymap = {
@@ -576,9 +596,7 @@ class Branch:
for k in self._mapper.update.values():
del self._keymap[k]
# self._EntryType = namedtuple(mapper.name[:-1], self.keys())
for key in self.keys():
for key in self._keymap.keys():
# print("setting", self._mapper.name, key)
setattr(self, key, self[key])
@@ -592,23 +610,41 @@ class Branch:
def __getitem__(self, item):
"""Slicing magic a la numpy"""
if isinstance(item, slice):
return self.__class__(self._tree, self._mapper, index=item)
return self.__class__(self._tree, self._mapper, index=item, subbranches=self._subbranches)
if isinstance(item, int):
# A bit ugly, but whatever works
if self._mapper.flat:
return BranchElement(
self._mapper.name, {
if self._index is None:
dct = {
key: self._branch[self._keymap[key]].array()
for key in self.keys()
}
else:
dct = {
key:
self._branch[self._keymap[key]].array()[self._index]
for key in self.keys()
})[item]
}
for subbranch in self._subbranches:
dct[subbranch._mapper.name] = subbranch
return BranchElement(self._mapper.name, dct)[item]
else:
return BranchElement(
self._mapper.name, {
if self._index is None:
dct = {
key: self._branch[self._keymap[key]].array()[item]
for key in self.keys()
}
else:
dct = {
key:
self._branch[self._keymap[key]].array()[self._index,
item]
for key in self.keys()
})
}
for subbranch in self._subbranches:
dct[subbranch._mapper.name] = subbranch
return BranchElement(self._mapper.name, dct)
if isinstance(item, tuple):
return self[item[0]][item[1]]
@@ -622,7 +658,7 @@ class Branch:
out = out[self._index]
return out
return self.__class__(self._tree, self._mapper, index=np.array(item))
return self.__class__(self._tree, self._mapper, index=np.array(item), subbranches=self._subbranches)
def __len__(self):
if self._index is None:
@@ -652,21 +688,30 @@ class BranchElement:
index: slice
The slice mask to be applied to the sub-arrays
"""
def __init__(self, name, dct, index=None):
def __init__(self, name, dct, index=None, subbranches=[]):
self._dct = dct
self._name = name
self._index = index
self.ItemConstructor = namedtuple(self._name[:-1], dct.keys())
for key, values in dct.items():
setattr(self, key, values[index])
if index is None:
for key, values in dct.items():
setattr(self, key, values)
else:
for key, values in dct.items():
setattr(self, key, values[index])
def __getitem__(self, item):
if isinstance(item, slice):
return self.__class__(self._name, self._dct, index=item)
if isinstance(item, int):
return self.ItemConstructor(
**{k: v[self._index][item]
for k, v in self._dct.items()})
if self._index is None:
return self.ItemConstructor(
**{k: v[item]
for k, v in self._dct.items()})
else:
return self.ItemConstructor(
**{k: v[self._index][item]
for k, v in self._dct.items()})
def __repr__(self):
return "<{}[{}]>".format(self.__class__.__name__, self._name)
Loading