From bfcdf581c6b5dc0359d6cfeab985bb697d6dd47e Mon Sep 17 00:00:00 2001 From: Jim Pivarski Date: Sun, 19 Jul 2020 20:08:52 -0500 Subject: [PATCH] Model.parent should point to the concrete instance, not the objects referring to base class data. (#53) * Model.parent should point to the concrete instance, not the objects referring to base class data. * Objects in TClonesArrays need an extra level of jaggedness. * Make TRefArray accessible in Awkward. * TRefArrays in TClonesArrays can now be read and converted into Awkward. * Distinguish between branches with the same name in cache_key and object_path. --- ...st_0017-multi-basket-multi-branch-fetch.py | 6 +- tests/test_0018-array-fetching-interface.py | 8 +- .../test_0053-parents-should-not-be-bases.py | 349 ++++++++++++++++++ uproot4/behaviors/TBranch.py | 33 +- uproot4/behaviors/TTree.py | 6 +- uproot4/containers.py | 4 +- uproot4/interpretation/identify.py | 3 + uproot4/interpretation/library.py | 5 +- uproot4/model.py | 15 +- uproot4/models/TBranch.py | 150 +++++--- uproot4/models/THashList.py | 7 +- uproot4/models/TLeaf.py | 86 ++++- uproot4/models/TList.py | 7 +- uproot4/models/TNamed.py | 7 +- uproot4/models/TObjArray.py | 14 +- uproot4/models/TObjString.py | 7 +- uproot4/models/TRef.py | 33 +- uproot4/models/TTree.py | 232 ++++++++---- uproot4/reading.py | 9 +- uproot4/streamers.py | 114 +++++- 20 files changed, 922 insertions(+), 173 deletions(-) create mode 100644 tests/test_0053-parents-should-not-be-bases.py diff --git a/tests/test_0017-multi-basket-multi-branch-fetch.py b/tests/test_0017-multi-basket-multi-branch-fetch.py index 50305a96c..ba795f57c 100644 --- a/tests/test_0017-multi-basket-multi-branch-fetch.py +++ b/tests/test_0017-multi-basket-multi-branch-fetch.py @@ -311,16 +311,16 @@ def test_cache(): skhep_testdata.data_path("uproot-sample-6.20.04-uncompressed.root") ) as f: assert f.cache_key == "db4be408-93ad-11ea-9027-d201a8c0beef:/" - assert f["sample"].cache_key == "db4be408-93ad-11ea-9027-d201a8c0beef:/sample" + assert f["sample"].cache_key == "db4be408-93ad-11ea-9027-d201a8c0beef:/sample;1" assert ( f["sample/i4"].cache_key - == "db4be408-93ad-11ea-9027-d201a8c0beef:/sample:i4" + == "db4be408-93ad-11ea-9027-d201a8c0beef:/sample;1:i4(16)" ) i4 = f["sample/i4"] assert list(f.array_cache) == [] i4.array(uproot4.interpretation.numerical.AsDtype(">i4"), library="np") assert list(f.array_cache) == [ - "db4be408-93ad-11ea-9027-d201a8c0beef:/sample:i4:AsDtype(Bi4(),Li4()):0-30:np" + "db4be408-93ad-11ea-9027-d201a8c0beef:/sample;1:i4(16):AsDtype(Bi4(),Li4()):0-30:np" ] with pytest.raises(OSError): diff --git a/tests/test_0018-array-fetching-interface.py b/tests/test_0018-array-fetching-interface.py index 1ccb1acd0..68602a2eb 100644 --- a/tests/test_0018-array-fetching-interface.py +++ b/tests/test_0018-array-fetching-interface.py @@ -132,8 +132,8 @@ def test_compute(): assert set(sample.file.array_cache) == set( [ - "db4be408-93ad-11ea-9027-d201a8c0beef:/sample:i4:AsDtype(Bi4(),Li4()):0-30:ak", - "db4be408-93ad-11ea-9027-d201a8c0beef:/sample:Ai8:AsJagged(AsDtype(Bi8(),Li8()),0):0-30:ak", + "db4be408-93ad-11ea-9027-d201a8c0beef:/sample;1:i4:AsDtype(Bi4(),Li4()):0-30:ak", + "db4be408-93ad-11ea-9027-d201a8c0beef:/sample;1:Ai8:AsJagged(AsDtype(Bi8(),Li8()),0):0-30:ak", ] ) @@ -189,8 +189,8 @@ def test_arrays(): assert set(sample.file.array_cache) == set( [ - "db4be408-93ad-11ea-9027-d201a8c0beef:/sample:i4:AsDtype(Bi4(),Li4()):0-30:ak", - "db4be408-93ad-11ea-9027-d201a8c0beef:/sample:f4:AsDtype(Bf4(),Lf4()):0-30:ak", + "db4be408-93ad-11ea-9027-d201a8c0beef:/sample;1:i4:AsDtype(Bi4(),Li4()):0-30:ak", + "db4be408-93ad-11ea-9027-d201a8c0beef:/sample;1:f4:AsDtype(Bf4(),Lf4()):0-30:ak", ] ) diff --git a/tests/test_0053-parents-should-not-be-bases.py b/tests/test_0053-parents-should-not-be-bases.py new file mode 100644 index 000000000..f8a159a2a --- /dev/null +++ b/tests/test_0053-parents-should-not-be-bases.py @@ -0,0 +1,349 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE + +from __future__ import absolute_import + +import numpy +import pytest +import skhep_testdata + +import uproot4 + + +def test_TRefArray(): + with uproot4.open(skhep_testdata.data_path("uproot-issue513.root"))["Delphes"] as t: + array = t["GenJet.Particles"].array(entry_stop=1, library="np")[0] + assert len(array) == 7 + assert array[0].refs.tolist() == [ + 2396, + 2320, + 2075, + 2483, + 2479, + 2499, + 2259, + 1865, + 2078, + 2482, + 2503, + 2477, + 2502, + 2480, + 2061, + 2077, + 2393, + 2376, + 2496, + 2504, + 2495, + 2505, + 1318, + 1317, + 2506, + 2076, + 2346, + 2501, + 2107, + 1957, + 2241, + 1823, + 2242, + 1825, + 1863, + 2399, + 1824, + 1866, + 2497, + 1996, + 2345, + 1864, + 2243, + 1821, + 2244, + ] + assert array[1].refs.tolist() == [ + 2370, + 1830, + 2371, + 2024, + 1412, + 2250, + 1530, + 2500, + 2498, + 2388, + 1949, + 1885, + 2055, + 2069, + 2368, + 2054, + 2059, + 2272, + 2053, + 2367, + ] + + +def test_awkward_TRefArray(): + awkward1 = pytest.importorskip("awkward1") + with uproot4.open(skhep_testdata.data_path("uproot-issue513.root"))["Delphes"] as t: + assert t["GenJet.Particles"].array(entry_stop=1)[0].tolist() == [ + { + "fName": "", + "fSize": 45, + "refs": [ + 2396, + 2320, + 2075, + 2483, + 2479, + 2499, + 2259, + 1865, + 2078, + 2482, + 2503, + 2477, + 2502, + 2480, + 2061, + 2077, + 2393, + 2376, + 2496, + 2504, + 2495, + 2505, + 1318, + 1317, + 2506, + 2076, + 2346, + 2501, + 2107, + 1957, + 2241, + 1823, + 2242, + 1825, + 1863, + 2399, + 1824, + 1866, + 2497, + 1996, + 2345, + 1864, + 2243, + 1821, + 2244, + ], + }, + { + "fName": "", + "fSize": 20, + "refs": [ + 2370, + 1830, + 2371, + 2024, + 1412, + 2250, + 1530, + 2500, + 2498, + 2388, + 1949, + 1885, + 2055, + 2069, + 2368, + 2054, + 2059, + 2272, + 2053, + 2367, + ], + }, + { + "fName": "", + "fSize": 21, + "refs": [ + 2284, + 1883, + 2282, + 2108, + 1939, + 2102, + 2356, + 2005, + 2236, + 1364, + 1770, + 1882, + 1840, + 2249, + 2446, + 1985, + 1839, + 2248, + 1365, + 1841, + 1842, + ], + }, + { + "fName": "", + "fSize": 31, + "refs": [ + 1379, + 2123, + 2090, + 1378, + 1593, + 1836, + 1862, + 1859, + 1904, + 1984, + 1322, + 1383, + 2074, + 2257, + 1591, + 1382, + 2357, + 1954, + 2066, + 2256, + 2010, + 2011, + 2490, + 2251, + 2343, + 1993, + 2344, + 1846, + 1992, + 1843, + 1845, + ], + }, + { + "fName": "", + "fSize": 26, + "refs": [ + 1989, + 1911, + 1990, + 1629, + 2277, + 2419, + 2139, + 2292, + 1618, + 2518, + 2519, + 2516, + 2509, + 2135, + 2136, + 2514, + 2517, + 2510, + 2512, + 2420, + 2402, + 1619, + 1617, + 2494, + 1400, + 2511, + ], + }, + { + "fName": "", + "fSize": 32, + "refs": [ + 2082, + 2445, + 1868, + 1893, + 2384, + 2081, + 1512, + 2263, + 2261, + 1870, + 2398, + 2017, + 1849, + 2401, + 1875, + 2387, + 1872, + 2315, + 2260, + 1873, + 2386, + 1522, + 1874, + 2083, + 1775, + 2086, + 2237, + 2087, + 1876, + 2084, + 2264, + 2265, + ], + }, + { + "fName": "", + "fSize": 26, + "refs": [ + 2266, + 1847, + 1894, + 2142, + 2291, + 1599, + 1774, + 1916, + 2200, + 2129, + 2148, + 2146, + 2143, + 2144, + 2145, + 1913, + 2290, + 2421, + 1918, + 1706, + 2137, + 1914, + 2289, + 1915, + 1627, + 1628, + ], + }, + ] + + +def test_same_names(): + with uproot4.open(skhep_testdata.data_path("uproot-issue513.root"))["Delphes"] as t: + one, two = t.values(filter_name="Particle_size") + assert ( + one.cache_key + == "ac4a884e-c931-11ea-a7a5-c78b2480beef:/Delphes;1:Particle_size(3)" + ) + assert ( + two.cache_key + == "ac4a884e-c931-11ea-a7a5-c78b2480beef:/Delphes;1:Particle_size(17)" + ) + assert one.object_path == "/Delphes;1:Particle_size" + assert two.object_path == "/Delphes;1:Particle_size" diff --git a/uproot4/behaviors/TBranch.py b/uproot4/behaviors/TBranch.py index 3f0adb0b4..6b3a7d9ef 100644 --- a/uproot4/behaviors/TBranch.py +++ b/uproot4/behaviors/TBranch.py @@ -1179,6 +1179,7 @@ def postprocess(self, chunk, cursor, context): self._interpretation = None self._typename = None self._streamer = None + self._streamer_isTClonesArray = False self._context = dict(context) self._context["breadcrumbs"] = () self._context["in_TBranch"] = True @@ -1230,19 +1231,31 @@ def context(self): def aliases(self): return self.tree.aliases + @property + def index(self): + for i, branch in enumerate(self.parent.branches): + if branch is self: + return i + else: + raise AssertionError + @property def cache_key(self): if isinstance(self._parent, uproot4.behaviors.TTree.TTree): - return self.parent.cache_key + ":" + self.name + sep = ":" else: - return self.parent.cache_key + "/" + self.name + sep = "/" + return "{0}{1}{2}({3})".format( + self.parent.cache_key, sep, self.name, self.index + ) @property def object_path(self): if isinstance(self._parent, uproot4.behaviors.TTree.TTree): - return self.parent.object_path + ":" + self.name + sep = ":" else: - return self.parent.object_path + "/" + self.name + sep = "/" + return "{0}{1}{2}".format(self.parent.object_path, sep, self.name) @property def entry_offsets(self): @@ -1338,8 +1351,18 @@ def streamer(self): break break + if self.parent.member("fClassName") == "TClonesArray": + self._streamer_isTClonesArray = True + elif fClassName is not None and fClassName != "": - matches = self._file.streamers.get(fClassName) + if fClassName == "TClonesArray": + self._streamer_isTClonesArray = True + matches = self._file.streamers.get( + self.member("fClonesName", none_if_missing=True) + ) + else: + matches = self._file.streamers.get(fClassName) + if matches is not None: self._streamer = matches[max(matches)] diff --git a/uproot4/behaviors/TTree.py b/uproot4/behaviors/TTree.py index 81658925e..eccb5c08c 100644 --- a/uproot4/behaviors/TTree.py +++ b/uproot4/behaviors/TTree.py @@ -49,11 +49,13 @@ def postprocess(self, chunk, cursor, context): @property def cache_key(self): - return self.parent.parent.cache_key + self.name + return "{0}{1};{2}".format( + self.parent.parent.cache_key, self.name, self.parent.fCycle + ) @property def object_path(self): - return self.parent.parent.object_path + self.name + return self.parent.object_path @property def chunk(self): diff --git a/uproot4/containers.py b/uproot4/containers.py index 8304fdea9..74568a7b9 100644 --- a/uproot4/containers.py +++ b/uproot4/containers.py @@ -354,7 +354,9 @@ def awkward_form(self, file, index_format="i64", header=False, tobject_header=Tr return awkward1.forms.ListOffsetForm( index_format, - uproot4._util.awkward_form(self._values, file, header, tobject_header), + uproot4._util.awkward_form( + self._values, file, index_format, header, tobject_header + ), parameters={"uproot": {"as": "array", "header": self._header}}, ) diff --git a/uproot4/interpretation/identify.py b/uproot4/interpretation/identify.py index 2618ab50f..734e519c9 100644 --- a/uproot4/interpretation/identify.py +++ b/uproot4/interpretation/identify.py @@ -1097,6 +1097,9 @@ def interpretation_of(branch, context, simplify=True): while isinstance(model_cls, uproot4.containers.AsPointer): model_cls = model_cls.pointee + if branch._streamer_isTClonesArray: + model_cls = uproot4.containers.AsArray(False, model_cls) + out = uproot4.interpretation.objects.AsObjects(model_cls, branch) if simplify: return out.simplify() diff --git a/uproot4/interpretation/library.py b/uproot4/interpretation/library.py index 4b887d21f..d2f9123e5 100644 --- a/uproot4/interpretation/library.py +++ b/uproot4/interpretation/library.py @@ -170,7 +170,10 @@ def _object_to_awkward_json(form, obj): out = {} for name, subform in form["contents"].items(): if not name.startswith("@"): - out[name] = _object_to_awkward_json(subform, obj.member(name)) + if obj.has_member(name): + out[name] = _object_to_awkward_json(subform, obj.member(name)) + else: + out[name] = _object_to_awkward_json(subform, getattr(obj, name)) return out elif form["class"][:15] == "ListOffsetArray": diff --git a/uproot4/model.py b/uproot4/model.py index e9745f9eb..198684a57 100644 --- a/uproot4/model.py +++ b/uproot4/model.py @@ -88,11 +88,16 @@ def empty(cls): return self @classmethod - def read(cls, chunk, cursor, context, file, parent): + def read(cls, chunk, cursor, context, file, parent, concrete=None): self = cls.__new__(cls) self._cursor = cursor.copy() self._file = file self._parent = parent + if concrete is None: + self._concrete = self + else: + self._concrete = concrete + self._members = {} self._bases = [] self._num_bytes = None @@ -199,6 +204,10 @@ def file(self): def parent(self): return self._parent + @property + def concrete(self): + return self._concrete + @property def encoded_classname(self): return type(self).__name__ @@ -436,7 +445,7 @@ def debug( class DispatchByVersion(object): @classmethod - def read(cls, chunk, cursor, context, file, parent): + def read(cls, chunk, cursor, context, file, parent, concrete=None): import uproot4.deserialization start_cursor = cursor.copy() @@ -466,7 +475,7 @@ def read(cls, chunk, cursor, context, file, parent): ) return cls.postprocess( - versioned_cls.read(chunk, cursor, context, file, parent), + versioned_cls.read(chunk, cursor, context, file, parent, concrete=concrete), chunk, cursor, context, diff --git a/uproot4/models/TBranch.py b/uproot4/models/TBranch.py index e509df59c..44810c1a7 100644 --- a/uproot4/models/TBranch.py +++ b/uproot4/models/TBranch.py @@ -23,12 +23,22 @@ class Model_TBranch_v10( def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttFill", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -45,17 +55,17 @@ def read_members(self, chunk, cursor, context): self._members["fZipBytes"], ) = cursor.fields(chunk, _tbranch10_format1, context) self._members["fBranches"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fLeaves"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._cursor_baskets = cursor.copy() if self._file.options["minimal_ttree_metadata"]: cursor.skip_over(chunk, context) else: self._members["fBaskets"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) tmp = _tbranch10_dtype1 if context.get("speedbump", True): @@ -80,7 +90,7 @@ def read_members(self, chunk, cursor, context): cursor.skip_after(self) else: self._members["fFileName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) @property @@ -127,12 +137,22 @@ class Model_TBranch_v11( def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttFill", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -150,17 +170,17 @@ def read_members(self, chunk, cursor, context): self._members["fZipBytes"], ) = cursor.fields(chunk, _tbranch11_format1, context) self._members["fBranches"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fLeaves"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._cursor_baskets = cursor.copy() if self._file.options["minimal_ttree_metadata"]: cursor.skip_over(chunk, context) else: self._members["fBaskets"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) tmp = _tbranch11_dtype1 if context.get("speedbump", True): @@ -185,7 +205,7 @@ def read_members(self, chunk, cursor, context): cursor.skip_after(self) else: self._members["fFileName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) @property @@ -233,12 +253,22 @@ class Model_TBranch_v12( def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttFill", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -256,17 +286,17 @@ def read_members(self, chunk, cursor, context): self._members["fZipBytes"], ) = cursor.fields(chunk, _tbranch12_format1, context) self._members["fBranches"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fLeaves"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._cursor_baskets = cursor.copy() if self._file.options["minimal_ttree_metadata"]: cursor.skip_over(chunk, context) else: self._members["fBaskets"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) tmp = _tbranch12_dtype1 if context.get("speedbump", True): @@ -291,7 +321,7 @@ def read_members(self, chunk, cursor, context): cursor.skip_after(self) else: self._members["fFileName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) @property @@ -340,12 +370,22 @@ class Model_TBranch_v13( def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttFill", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -356,7 +396,7 @@ def read_members(self, chunk, cursor, context): self._members["fEntryNumber"], ) = cursor.fields(chunk, _tbranch13_format1, context) self._members["fIOFeatures"] = self.class_named("ROOT::TIOFeatures").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) ( self._members["fOffset"], @@ -368,17 +408,17 @@ def read_members(self, chunk, cursor, context): self._members["fZipBytes"], ) = cursor.fields(chunk, _tbranch13_format2, context) self._members["fBranches"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fLeaves"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._cursor_baskets = cursor.copy() if self._file.options["minimal_ttree_metadata"]: cursor.skip_over(chunk, context) else: self._members["fBaskets"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) tmp = _tbranch13_dtype1 if context.get("speedbump", True): @@ -403,7 +443,7 @@ def read_members(self, chunk, cursor, context): cursor.skip_after(self) else: self._members["fFileName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) @property @@ -458,18 +498,23 @@ class Model_TBranchElement_v8( def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TBranch", 10).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._cursor_baskets = self._bases[0]._cursor_baskets self._members["fClassName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fParentName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fClonesName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) ( self._members["fCheckSum"], @@ -480,10 +525,10 @@ def read_members(self, chunk, cursor, context): self._members["fMaximum"], ) = cursor.fields(chunk, _tbranchelement8_format1, context) self._members["fBranchCount"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fBranchCount2"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) base_names_versions = [("TBranch", 10)] @@ -513,18 +558,23 @@ class Model_TBranchElement_v9( def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TBranch", 12).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._cursor_baskets = self._bases[0]._cursor_baskets self._members["fClassName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fParentName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fClonesName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) ( self._members["fCheckSum"], @@ -535,10 +585,10 @@ def read_members(self, chunk, cursor, context): self._members["fMaximum"], ) = cursor.fields(chunk, _tbranchelement9_format1, context) self._members["fBranchCount"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fBranchCount2"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) base_names_versions = [("TBranch", 12)] @@ -568,18 +618,23 @@ class Model_TBranchElement_v10( def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TBranch", 12).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._cursor_baskets = self._bases[0]._cursor_baskets self._members["fClassName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fParentName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fClonesName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) ( self._members["fCheckSum"], @@ -590,10 +645,10 @@ def read_members(self, chunk, cursor, context): self._members["fMaximum"], ) = cursor.fields(chunk, _tbranchelement10_format1, context) self._members["fBranchCount"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fBranchCount2"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) base_names_versions = [("TBranch", 12)] @@ -628,11 +683,16 @@ class Model_TBranchObject_v1( def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TBranch", 13).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fClassName"] = self.class_named("TString").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) base_names_versions = [("TBranch", 13)] diff --git a/uproot4/models/THashList.py b/uproot4/models/THashList.py index e36eacf8e..07500e565 100644 --- a/uproot4/models/THashList.py +++ b/uproot4/models/THashList.py @@ -12,7 +12,12 @@ def read_numbytes_version(self, chunk, cursor, context): def read_members(self, chunk, cursor, context): self._bases.append( uproot4.models.TList.Model_TList.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) diff --git a/uproot4/models/TLeaf.py b/uproot4/models/TLeaf.py index aa8c3e193..3f9e8c84f 100644 --- a/uproot4/models/TLeaf.py +++ b/uproot4/models/TLeaf.py @@ -15,7 +15,12 @@ class Model_TLeaf_v2(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -26,7 +31,7 @@ def read_members(self, chunk, cursor, context): self._members["fIsUnsigned"], ) = cursor.fields(chunk, _tleaf2_format0, context) self._members["fLeafCount"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) base_names_versions = [("TNamed", 1)] @@ -53,7 +58,12 @@ class Model_TLeafB_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"], self._members["fMaximum"] = cursor.fields( @@ -77,7 +87,12 @@ class Model_TLeafC_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"], self._members["fMaximum"] = cursor.fields( @@ -101,7 +116,12 @@ class Model_TLeafD_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"], self._members["fMaximum"] = cursor.fields( @@ -125,7 +145,12 @@ class Model_TLeafF_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"], self._members["fMaximum"] = cursor.fields( @@ -149,7 +174,12 @@ class Model_TLeafI_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"], self._members["fMaximum"] = cursor.fields( @@ -173,7 +203,12 @@ class Model_TLeafL_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"], self._members["fMaximum"] = cursor.fields( @@ -197,7 +232,12 @@ class Model_TLeafO_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"], self._members["fMaximum"] = cursor.fields( @@ -221,7 +261,12 @@ class Model_TLeafS_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"], self._members["fMaximum"] = cursor.fields( @@ -245,7 +290,12 @@ class Model_TLeafElement_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fID"], self._members["fType"] = cursor.fields( @@ -266,7 +316,12 @@ class Model_TLeafD32_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"] = cursor.double32(chunk, context) @@ -285,7 +340,12 @@ class Model_TLeafF16_v1(uproot4.model.VersionedModel): def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TLeaf", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fMinimum"] = cursor.float16(chunk, 12, context) diff --git a/uproot4/models/TList.py b/uproot4/models/TList.py index 188fd5563..4e875929d 100644 --- a/uproot4/models/TList.py +++ b/uproot4/models/TList.py @@ -22,7 +22,12 @@ class Model_TList(uproot4.model.Model, Sequence): def read_members(self, chunk, cursor, context): self._bases.append( uproot4.models.TObject.Model_TObject.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) diff --git a/uproot4/models/TNamed.py b/uproot4/models/TNamed.py index 3643c7b8e..981e73086 100644 --- a/uproot4/models/TNamed.py +++ b/uproot4/models/TNamed.py @@ -13,7 +13,12 @@ class Model_TNamed(uproot4.model.Model): def read_members(self, chunk, cursor, context): self._bases.append( uproot4.models.TObject.Model_TObject.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) diff --git a/uproot4/models/TObjArray.py b/uproot4/models/TObjArray.py index 73dec3edf..772ea090a 100644 --- a/uproot4/models/TObjArray.py +++ b/uproot4/models/TObjArray.py @@ -22,7 +22,12 @@ class Model_TObjArray(uproot4.model.Model, Sequence): def read_members(self, chunk, cursor, context): self._bases.append( uproot4.models.TObject.Model_TObject.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) @@ -66,7 +71,12 @@ class Model_TObjArrayOfTBaskets(Model_TObjArray): def read_members(self, chunk, cursor, context): self._bases.append( uproot4.models.TObject.Model_TObject.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) diff --git a/uproot4/models/TObjString.py b/uproot4/models/TObjString.py index dd624006b..c838907e5 100644 --- a/uproot4/models/TObjString.py +++ b/uproot4/models/TObjString.py @@ -10,7 +10,12 @@ class Model_TObjString(uproot4.model.Model, str): def read_members(self, chunk, cursor, context): self._bases.append( uproot4.models.TObject.Model_TObject.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._data = cursor.string(chunk, context) diff --git a/uproot4/models/TRef.py b/uproot4/models/TRef.py index ebadf7d1f..9e3a8ef0d 100644 --- a/uproot4/models/TRef.py +++ b/uproot4/models/TRef.py @@ -63,7 +63,7 @@ def awkward_form(cls, file, index_format="i64", header=False, tobject_header=Tru contents["@other2"] = uproot4._util.awkward_form( numpy.dtype("u4"), file, index_format, header, tobject_header ) - return awkward1.forms.RecordForm(contents, parameters={"__record__": "TRef"},) + return awkward1.forms.RecordForm(contents, parameters={"__record__": "TRef"}) _trefarray_format1 = struct.Struct(">i") @@ -88,6 +88,10 @@ def name(self): def nbytes(self): return self._data.nbytes + @property + def refs(self): + return self._data + def __getitem__(self, where): return self._data[where] @@ -97,10 +101,35 @@ def __len__(self): def __repr__(self): return "<{0} {1} at 0x{2:012x}>".format( uproot4.model.classname_pretty(self.classname, self.class_version), - str(self._data), + numpy.array2string( + self._data, + max_line_width=numpy.inf, + separator=", ", + formatter={"float": lambda x: "%g" % x}, + threshold=6, + ), id(self), ) + @classmethod + def awkward_form(cls, file, index_format="i64", header=False, tobject_header=True): + import awkward1 + + contents = {} + + contents["fName"] = uproot4.containers.AsString( + False, typename="TString" + ).awkward_form(file, index_format, header, tobject_header) + contents["fSize"] = uproot4._util.awkward_form( + numpy.dtype("i4"), file, index_format, header, tobject_header + ) + contents["refs"] = uproot4._util.awkward_form( + numpy.dtype("i4"), file, index_format, header, tobject_header + ) + return awkward1.forms.RecordForm( + contents, parameters={"__record__": "TRefArray"} + ) + uproot4.classes["TRef"] = Model_TRef uproot4.classes["TRefArray"] = Model_TRefArray diff --git a/uproot4/models/TTree.py b/uproot4/models/TTree.py index 38fafe4be..2f85d042c 100644 --- a/uproot4/models/TTree.py +++ b/uproot4/models/TTree.py @@ -18,22 +18,42 @@ class Model_TTree_v16(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedMode def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttLine", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttFill", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttMarker", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -52,35 +72,35 @@ def read_members(self, chunk, cursor, context): self._members["fEstimate"], ) = cursor.fields(chunk, _ttree16_format1, context) self._members["fBranches"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fLeaves"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fAliases"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) if self._file.options["minimal_ttree_metadata"]: cursor.skip_after(self) else: self._members["fIndexValues"] = self.class_named("TArrayD").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fIndex"] = self.class_named("TArrayI").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fTreeIndex"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fFriends"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fUserInfo"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fBranchRef"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) @property @@ -133,22 +153,42 @@ class Model_TTree_v17(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedMode def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttLine", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttFill", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttMarker", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -168,34 +208,34 @@ def read_members(self, chunk, cursor, context): self._members["fEstimate"], ) = cursor.fields(chunk, _ttree17_format1, context) self._members["fBranches"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fLeaves"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fAliases"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) if self._file.options["minimal_ttree_metadata"]: cursor.skip_after(self) else: self._members["fIndexValues"] = self.class_named("TArrayD").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fIndex"] = self.class_named("TArrayI").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fTreeIndex"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fFriends"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fUserInfo"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fBranchRef"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) @property @@ -249,22 +289,42 @@ class Model_TTree_v18(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedMode def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttLine", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttFill", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttMarker", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -286,34 +346,34 @@ def read_members(self, chunk, cursor, context): self._members["fEstimate"], ) = cursor.fields(chunk, _ttree18_format1, context) self._members["fBranches"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fLeaves"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fAliases"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) if self._file.options["minimal_ttree_metadata"]: cursor.skip_after(self) else: self._members["fIndexValues"] = self.class_named("TArrayD").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fIndex"] = self.class_named("TArrayI").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fTreeIndex"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fFriends"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fUserInfo"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fBranchRef"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) @property @@ -371,22 +431,42 @@ class Model_TTree_v19(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedMode def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttLine", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttFill", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttMarker", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -421,34 +501,34 @@ def read_members(self, chunk, cursor, context): chunk, self.member("fNClusterRange"), tmp, context ) self._members["fBranches"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fLeaves"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fAliases"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) if self._file.options["minimal_ttree_metadata"]: cursor.skip_after(self) else: self._members["fIndexValues"] = self.class_named("TArrayD").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fIndex"] = self.class_named("TArrayI").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fTreeIndex"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fFriends"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fUserInfo"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fBranchRef"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) @property @@ -509,22 +589,42 @@ class Model_TTree_v20(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedMode def read_members(self, chunk, cursor, context): self._bases.append( self.class_named("TNamed", 1).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttLine", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttFill", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases.append( self.class_named("TAttMarker", 2).read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) ( @@ -559,37 +659,37 @@ def read_members(self, chunk, cursor, context): chunk, self.member("fNClusterRange"), tmp, context ) self._members["fIOFeatures"] = self.class_named("ROOT::TIOFeatures").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fBranches"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fLeaves"] = self.class_named("TObjArray").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fAliases"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) if self._file.options["minimal_ttree_metadata"]: cursor.skip_after(self) else: self._members["fIndexValues"] = self.class_named("TArrayD").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fIndex"] = self.class_named("TArrayI").read( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) self._members["fTreeIndex"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fFriends"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fUserInfo"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) self._members["fBranchRef"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self._parent + chunk, cursor, context, self._file, self._concrete ) @property diff --git a/uproot4/reading.py b/uproot4/reading.py index bbb156dfb..d328b9d71 100644 --- a/uproot4/reading.py +++ b/uproot4/reading.py @@ -833,7 +833,9 @@ def cache_key(self): @property def object_path(self): if isinstance(self._parent, ReadOnlyDirectory): - return self._parent.object_path + self.name(False) + return "{0}{1};{2}".format( + self._parent.object_path, self.name(False), self._fCycle + ) else: return "(seek pos {0})/{1}".format(self.data_cursor.index, self.name(False)) @@ -1403,7 +1405,10 @@ def key(self, where): if ";" in where: at = where.rindex(";") item, cycle = where[:at], where[at + 1 :] - cycle = int(cycle) + try: + cycle = int(cycle) + except ValueError: + item, cycle = where, None else: item, cycle = where, None diff --git a/uproot4/streamers.py b/uproot4/streamers.py index 662912a93..d23777862 100644 --- a/uproot4/streamers.py +++ b/uproot4/streamers.py @@ -132,7 +132,12 @@ class Model_TStreamerInfo(uproot4.model.Model): def read_members(self, chunk, cursor, context): self._bases.append( uproot4.models.TNamed.Model_TNamed.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._bases[0]._members["fName"] = _canonical_typename( @@ -144,7 +149,7 @@ def read_members(self, chunk, cursor, context): ) self._members["fElements"] = uproot4.deserialization.read_object_any( - chunk, cursor, context, self._file, self + chunk, cursor, context, self._file, self._concrete ) def postprocess(self, chunk, cursor, context): @@ -331,7 +336,12 @@ def read_members(self, chunk, cursor, context): self._bases.append( uproot4.models.TNamed.Model_TNamed.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) @@ -421,7 +431,12 @@ class Model_TStreamerArtificial(Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) @@ -473,7 +488,12 @@ class Model_TStreamerBase(Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) if self._instance_version >= 2: @@ -519,7 +539,7 @@ def class_code( ): read_members.append( " self._bases.append(c({0}, {1}).read(chunk, cursor, " - "context, self._file, self._parent))".format( + "context, self._file, self._parent, concrete=self._concrete))".format( repr(self.name), self.base_version ) ) @@ -546,7 +566,12 @@ class Model_TStreamerBasicPointer(Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fCountVersion"] = cursor.field( @@ -620,7 +645,12 @@ class Model_TStreamerBasicType(Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) if ( @@ -814,7 +844,12 @@ class Model_TStreamerLoop(Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fCountVersion"] = cursor.field( @@ -855,7 +890,7 @@ def class_code( " cursor.skip(6)", " for tmp in range(self.member({0})):".format(self.count_name), " self._members[{0}] = c({1}).read(chunk, cursor, " - "context, self._file, self)".format( + "context, self._file, self._concrete)".format( repr(self.name), repr(self.typename.rstrip("*")) ), ] @@ -894,7 +929,12 @@ class Model_TStreamerSTL(Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) self._members["fSTLtype"], self._members["fCtype"] = cursor.fields( @@ -948,7 +988,7 @@ def class_code( ) read_members.append( " self._members[{0}] = self._stl_container{1}.read(" - "chunk, cursor, context, self._file, self)" + "chunk, cursor, context, self._file, self._concrete)" "".format(repr(self.name), len(containers)) ) @@ -973,7 +1013,14 @@ def class_code( class Model_TStreamerSTLstring(Model_TStreamerSTL): def read_members(self, chunk, cursor, context): self._bases.append( - Model_TStreamerSTL.read(chunk, cursor, context, self._file, self._parent) + Model_TStreamerSTL.read( + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, + ) ) @@ -1004,7 +1051,7 @@ def class_code( if self.fType == uproot4.const.kObjectp or self.fType == uproot4.const.kAnyp: read_members.append( " self._members[{0}] = c({1}).read(chunk, cursor, context, " - "self._file, self)".format( + "self._file, self._concrete)".format( repr(self.name), repr(self.typename.rstrip("*")) ) ) @@ -1051,7 +1098,12 @@ class Model_TStreamerObjectAnyPointer(pointer_types, Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) @@ -1060,7 +1112,12 @@ class Model_TStreamerObjectPointer(pointer_types, Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) @@ -1091,7 +1148,9 @@ def class_code( ): read_members.append( " self._members[{0}] = c({1}).read(chunk, cursor, context, " - "self._file, self)".format(repr(self.name), repr(self.typename.rstrip("*"))) + "self._file, self._concrete)".format( + repr(self.name), repr(self.typename.rstrip("*")) + ) ) strided_interpretation.append( @@ -1114,7 +1173,12 @@ class Model_TStreamerObject(object_types, Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) @@ -1123,7 +1187,12 @@ class Model_TStreamerObjectAny(object_types, Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) ) @@ -1132,7 +1201,12 @@ class Model_TStreamerString(object_types, Model_TStreamerElement): def read_members(self, chunk, cursor, context): self._bases.append( Model_TStreamerElement.read( - chunk, cursor, context, self._file, self._parent + chunk, + cursor, + context, + self._file, + self._parent, + concrete=self._concrete, ) )