rootloader 1.3.1__tar.gz → 1.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rootloader-1.4.1/.claude/settings.local.json +14 -0
- rootloader-1.4.1/.coverage +0 -0
- rootloader-1.4.1/CLAUDE.md +31 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/PKG-INFO +4 -1
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/rootloader/tdirectory.md +3 -3
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/rootloader/th2.md +1 -1
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/rootloader/ttree.md +30 -24
- {rootloader-1.3.1 → rootloader-1.4.1}/pyproject.toml +3 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/rootloader/tdirectory.py +6 -1
- {rootloader-1.3.1 → rootloader-1.4.1}/rootloader/th2.py +3 -2
- {rootloader-1.3.1 → rootloader-1.4.1}/rootloader/tleaf.py +1 -1
- {rootloader-1.3.1 → rootloader-1.4.1}/rootloader/ttree.py +11 -9
- rootloader-1.4.1/rootloader/version.py +1 -0
- rootloader-1.4.1/tests/README.md +315 -0
- rootloader-1.4.1/tests/conftest.py +319 -0
- rootloader-1.4.1/tests/test_attrdict.py +159 -0
- rootloader-1.4.1/tests/test_package.py +47 -0
- rootloader-1.4.1/tests/test_tdirectory.py +368 -0
- rootloader-1.4.1/tests/test_tfile.py +278 -0
- rootloader-1.4.1/tests/test_th1.py +341 -0
- rootloader-1.4.1/tests/test_th2.py +301 -0
- rootloader-1.4.1/tests/test_tleaf.py +128 -0
- rootloader-1.4.1/tests/test_ttree.py +743 -0
- rootloader-1.3.1/rootloader/version.py +0 -1
- {rootloader-1.3.1 → rootloader-1.4.1}/.gitignore +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/LICENSE +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/README.md +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/README.md +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/rootloader/attrdict.md +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/rootloader/index.md +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/rootloader/tfile.md +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/rootloader/th1.md +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/rootloader/tleaf.md +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/docs/rootloader/version.md +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/gen_documentation.bash +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/rootloader/__init__.py +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/rootloader/attrdict.py +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/rootloader/tfile.py +0 -0
- {rootloader-1.3.1 → rootloader-1.4.1}/rootloader/th1.py +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(python -m py_compile rootloader/th2.py rootloader/tleaf.py rootloader/ttree.py rootloader/tdirectory.py)",
|
|
5
|
+
"Bash(python3 -m py_compile rootloader/th2.py rootloader/tleaf.py rootloader/ttree.py rootloader/tdirectory.py)",
|
|
6
|
+
"Bash(python -m pytest tests/ -x --tb=short -q)",
|
|
7
|
+
"Bash(python3 -m pytest tests/ --tb=short -q)",
|
|
8
|
+
"Bash(python3 -m pytest tests/ --tb=no -q)",
|
|
9
|
+
"Bash(python3 -m pytest tests/test_ttree.py::test_stats_scalar_single_column_float tests/test_ttree.py::test_loc_slice_reduces_size --tb=long -q)",
|
|
10
|
+
"Bash(python3 -m pytest tests/ -v --tb=short -q)",
|
|
11
|
+
"Bash(python3 -m pytest tests/ -v --tb=short)"
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
`rootloader` is a Python library that wraps PyROOT to load ROOT files into memory as Python-native objects (numpy arrays, pandas DataFrames). It targets physicists at TRIUMF who work with ROOT data but prefer Python workflows.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
The class hierarchy mirrors ROOT's object model:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
attrdict (dict subclass — attribute-style key access)
|
|
13
|
+
└── tdirectory — wraps ROOT.TDirectoryFile or ROOT.TFile; iterates keys and dispatches to typed wrappers
|
|
14
|
+
└── tfile — entry point; opens a ROOT.TFile and delegates to tdirectory
|
|
15
|
+
|
|
16
|
+
ttree — wraps ROOT.TTree via RDataFrame; supports lazy column selection, filters, and conversion to pandas/numpy
|
|
17
|
+
th1 — wraps ROOT.TH1; stores x/y/dy arrays and provides .plot() and .to_dataframe()
|
|
18
|
+
th2 — wraps ROOT.TH2; stores x/y/z/dz arrays and provides .plot() and .to_dataframe()
|
|
19
|
+
tleaf — thin wrapper around ROOT.TLeaf for direct leaf-level access
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Key design decisions:**
|
|
23
|
+
|
|
24
|
+
- `attrdict` makes all dict keys accessible as attributes (`fid.tree1` == `fid['tree1']`). This is the base for `tdirectory`.
|
|
25
|
+
- `tdirectory.__init__` resolves ROOT key cycles (keeps highest cycle number) and dispatches each object to `ttree`, `th1`, `th2`, or a nested `tdirectory`.
|
|
26
|
+
- `ttree` is lazy: it holds a `ROOT.RDataFrame` and only materializes data when `.to_dataframe()`, `.to_dict()`, `.to_array()`, or a stats method (`.min()`, `.max()`, etc.) is called. Column selection via `__getitem__` returns a view (not a copy).
|
|
27
|
+
- Stats methods (`min`, `max`, `mean`, `sum`, `std`) use JIT-compiled C++ templates (`cpp_template` in `ttree.py`) to avoid memory creep from repeated ROOT JIT compilations. Each unique `(function, dtype)` pair is compiled once and cached on the ROOT module.
|
|
28
|
+
- `th1.to_dataframe()` and `th2.to_dataframe()` store reconstruction metadata in `df.attrs` so the original typed object can be restored via `tdirectory.from_dataframe()`.
|
|
29
|
+
- `ROOT.EnableImplicitMT()` is called at import time in `ttree.py` to enable multithreading for RDataFrame operations.
|
|
30
|
+
- `ROOT.gROOT.SetBatch(1)` is set at import in `__init__.py` to suppress graphical output.
|
|
31
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rootloader
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.1
|
|
4
4
|
Summary: Read simple root files into memory
|
|
5
5
|
Project-URL: Homepage, https://github.com/ucn-triumf/rootloader
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/ucn-triumf/rootloader/issues
|
|
@@ -687,6 +687,9 @@ Requires-Dist: matplotlib
|
|
|
687
687
|
Requires-Dist: numpy
|
|
688
688
|
Requires-Dist: pandas
|
|
689
689
|
Requires-Dist: tqdm
|
|
690
|
+
Provides-Extra: test
|
|
691
|
+
Requires-Dist: pytest; extra == 'test'
|
|
692
|
+
Requires-Dist: pytest-cov; extra == 'test'
|
|
690
693
|
Description-Content-Type: text/markdown
|
|
691
694
|
|
|
692
695
|
# ROOTLOADER
|
|
@@ -41,7 +41,7 @@ class tdirectory(attrdict):
|
|
|
41
41
|
|
|
42
42
|
### tdirectory.copy
|
|
43
43
|
|
|
44
|
-
[Show source in tdirectory.py:
|
|
44
|
+
[Show source in tdirectory.py:127](../../rootloader/tdirectory.py#L127)
|
|
45
45
|
|
|
46
46
|
Make a copy of this object
|
|
47
47
|
|
|
@@ -53,7 +53,7 @@ def copy(self): ...
|
|
|
53
53
|
|
|
54
54
|
### tdirectory.from_dataframe
|
|
55
55
|
|
|
56
|
-
[Show source in tdirectory.py:
|
|
56
|
+
[Show source in tdirectory.py:136](../../rootloader/tdirectory.py#L136)
|
|
57
57
|
|
|
58
58
|
Convert all elements contained in self to original objects
|
|
59
59
|
|
|
@@ -65,7 +65,7 @@ def from_dataframe(self): ...
|
|
|
65
65
|
|
|
66
66
|
### tdirectory.to_dataframe
|
|
67
67
|
|
|
68
|
-
[Show source in tdirectory.py:
|
|
68
|
+
[Show source in tdirectory.py:147](../../rootloader/tdirectory.py#L147)
|
|
69
69
|
|
|
70
70
|
Convert all objects possible (th1, th2, and ttree) into pandas dataframes
|
|
71
71
|
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
> Auto-generated documentation for [rootloader.ttree](../../rootloader/ttree.py) module.
|
|
6
6
|
|
|
7
|
+
#### Attributes
|
|
8
|
+
|
|
9
|
+
- `cpp_template` - template to pre-compile stats functions to avoid memory creep during JIT compilations
|
|
10
|
+
used in ttree._get_stat: '\n{TYPE2} RDF_{FNNAME}_{TYPE2}({DTYPE} df, string col){\n return df.{FNNAME}<{TYPE2}>(col).GetValue.\n}\n'
|
|
11
|
+
|
|
12
|
+
|
|
7
13
|
- [ttree](#ttree)
|
|
8
14
|
- [ttree](#ttree-1)
|
|
9
15
|
- [ttree.__getitem__](#ttree__getitem__)
|
|
@@ -31,7 +37,7 @@
|
|
|
31
37
|
|
|
32
38
|
## ttree
|
|
33
39
|
|
|
34
|
-
[Show source in ttree.py:
|
|
40
|
+
[Show source in ttree.py:22](../../rootloader/ttree.py#L22)
|
|
35
41
|
|
|
36
42
|
Extract ROOT.TTree with lazy operation. Looks like a dataframe in most ways
|
|
37
43
|
|
|
@@ -45,12 +51,12 @@ Extract ROOT.TTree with lazy operation. Looks like a dataframe in most ways
|
|
|
45
51
|
|
|
46
52
|
```python
|
|
47
53
|
class ttree(object):
|
|
48
|
-
def __init__(self, tree): ...
|
|
54
|
+
def __init__(self, tree, filter_string=None, columns=None): ...
|
|
49
55
|
```
|
|
50
56
|
|
|
51
57
|
### ttree.__getitem__
|
|
52
58
|
|
|
53
|
-
[Show source in ttree.py:
|
|
59
|
+
[Show source in ttree.py:90](../../rootloader/ttree.py#L90)
|
|
54
60
|
|
|
55
61
|
Fetch a new dataframe with fewer 'columns', as a memory view
|
|
56
62
|
|
|
@@ -62,7 +68,7 @@ def __getitem__(self, key): ...
|
|
|
62
68
|
|
|
63
69
|
### ttree.columns
|
|
64
70
|
|
|
65
|
-
[Show source in ttree.py:
|
|
71
|
+
[Show source in ttree.py:345](../../rootloader/ttree.py#L345)
|
|
66
72
|
|
|
67
73
|
Return list of column (branch) names
|
|
68
74
|
|
|
@@ -75,7 +81,7 @@ def columns(self): ...
|
|
|
75
81
|
|
|
76
82
|
### ttree.filters
|
|
77
83
|
|
|
78
|
-
[Show source in ttree.py:
|
|
84
|
+
[Show source in ttree.py:349](../../rootloader/ttree.py#L349)
|
|
79
85
|
|
|
80
86
|
Return list of RDataFrame filters
|
|
81
87
|
|
|
@@ -88,7 +94,7 @@ def filters(self): ...
|
|
|
88
94
|
|
|
89
95
|
### ttree.hist1d
|
|
90
96
|
|
|
91
|
-
[Show source in ttree.py:
|
|
97
|
+
[Show source in ttree.py:139](../../rootloader/ttree.py#L139)
|
|
92
98
|
|
|
93
99
|
Return histogram of column
|
|
94
100
|
|
|
@@ -113,7 +119,7 @@ def hist1d(self, column=None, nbins=None, step=None, edges=None): ...
|
|
|
113
119
|
|
|
114
120
|
### ttree.hist2d
|
|
115
121
|
|
|
116
|
-
[Show source in ttree.py:
|
|
122
|
+
[Show source in ttree.py:192](../../rootloader/ttree.py#L192)
|
|
117
123
|
|
|
118
124
|
Return histogram of two columns
|
|
119
125
|
|
|
@@ -137,7 +143,7 @@ def hist2d(
|
|
|
137
143
|
|
|
138
144
|
### ttree.index
|
|
139
145
|
|
|
140
|
-
[Show source in ttree.py:
|
|
146
|
+
[Show source in ttree.py:353](../../rootloader/ttree.py#L353)
|
|
141
147
|
|
|
142
148
|
Return ttree of just the index data
|
|
143
149
|
|
|
@@ -150,7 +156,7 @@ def index(self): ...
|
|
|
150
156
|
|
|
151
157
|
### ttree.index_name
|
|
152
158
|
|
|
153
|
-
[Show source in ttree.py:
|
|
159
|
+
[Show source in ttree.py:357](../../rootloader/ttree.py#L357)
|
|
154
160
|
|
|
155
161
|
Return string of the name of the index branch
|
|
156
162
|
|
|
@@ -163,7 +169,7 @@ def index_name(self): ...
|
|
|
163
169
|
|
|
164
170
|
### ttree.loc
|
|
165
171
|
|
|
166
|
-
[Show source in ttree.py:
|
|
172
|
+
[Show source in ttree.py:361](../../rootloader/ttree.py#L361)
|
|
167
173
|
|
|
168
174
|
Return a ttree that can be indexed like a pandas dataframe
|
|
169
175
|
|
|
@@ -176,7 +182,7 @@ def loc(self): ...
|
|
|
176
182
|
|
|
177
183
|
### ttree.max
|
|
178
184
|
|
|
179
|
-
[Show source in ttree.py:
|
|
185
|
+
[Show source in ttree.py:402](../../rootloader/ttree.py#L402)
|
|
180
186
|
|
|
181
187
|
Return the max value of the tree, for each branch
|
|
182
188
|
|
|
@@ -188,7 +194,7 @@ def max(self): ...
|
|
|
188
194
|
|
|
189
195
|
### ttree.mean
|
|
190
196
|
|
|
191
|
-
[Show source in ttree.py:
|
|
197
|
+
[Show source in ttree.py:405](../../rootloader/ttree.py#L405)
|
|
192
198
|
|
|
193
199
|
Return the mean value of the tree, for each branch
|
|
194
200
|
|
|
@@ -200,7 +206,7 @@ def mean(self): ...
|
|
|
200
206
|
|
|
201
207
|
### ttree.min
|
|
202
208
|
|
|
203
|
-
[Show source in ttree.py:
|
|
209
|
+
[Show source in ttree.py:399](../../rootloader/ttree.py#L399)
|
|
204
210
|
|
|
205
211
|
Return the min value of the tree, for each branch
|
|
206
212
|
|
|
@@ -212,7 +218,7 @@ def min(self): ...
|
|
|
212
218
|
|
|
213
219
|
### ttree.reset
|
|
214
220
|
|
|
215
|
-
[Show source in ttree.py:
|
|
221
|
+
[Show source in ttree.py:264](../../rootloader/ttree.py#L264)
|
|
216
222
|
|
|
217
223
|
Make a new tree
|
|
218
224
|
|
|
@@ -224,7 +230,7 @@ def reset(self): ...
|
|
|
224
230
|
|
|
225
231
|
### ttree.reset_columns
|
|
226
232
|
|
|
227
|
-
[Show source in ttree.py:
|
|
233
|
+
[Show source in ttree.py:268](../../rootloader/ttree.py#L268)
|
|
228
234
|
|
|
229
235
|
Include all columns again
|
|
230
236
|
|
|
@@ -236,7 +242,7 @@ def reset_columns(self): ...
|
|
|
236
242
|
|
|
237
243
|
### ttree.set_filter
|
|
238
244
|
|
|
239
|
-
[Show source in ttree.py:
|
|
245
|
+
[Show source in ttree.py:278](../../rootloader/ttree.py#L278)
|
|
240
246
|
|
|
241
247
|
Set a filter on the dataframe to select a subset of the data
|
|
242
248
|
|
|
@@ -248,7 +254,7 @@ def set_filter(self, expression, inplace=False): ...
|
|
|
248
254
|
|
|
249
255
|
### ttree.set_index
|
|
250
256
|
|
|
251
|
-
[Show source in ttree.py:
|
|
257
|
+
[Show source in ttree.py:272](../../rootloader/ttree.py#L272)
|
|
252
258
|
|
|
253
259
|
Set the index column name
|
|
254
260
|
|
|
@@ -260,7 +266,7 @@ def set_index(self, column): ...
|
|
|
260
266
|
|
|
261
267
|
### ttree.size
|
|
262
268
|
|
|
263
|
-
[Show source in ttree.py:
|
|
269
|
+
[Show source in ttree.py:365](../../rootloader/ttree.py#L365)
|
|
264
270
|
|
|
265
271
|
Return the number of rows in the ttree
|
|
266
272
|
|
|
@@ -273,7 +279,7 @@ def size(self): ...
|
|
|
273
279
|
|
|
274
280
|
### ttree.std
|
|
275
281
|
|
|
276
|
-
[Show source in ttree.py:
|
|
282
|
+
[Show source in ttree.py:411](../../rootloader/ttree.py#L411)
|
|
277
283
|
|
|
278
284
|
Return the standard deviationif the of values the tree, for each branch
|
|
279
285
|
|
|
@@ -285,7 +291,7 @@ def std(self): ...
|
|
|
285
291
|
|
|
286
292
|
### ttree.sum
|
|
287
293
|
|
|
288
|
-
[Show source in ttree.py:
|
|
294
|
+
[Show source in ttree.py:408](../../rootloader/ttree.py#L408)
|
|
289
295
|
|
|
290
296
|
Return the sum of the values of the tree, for each branch
|
|
291
297
|
|
|
@@ -297,7 +303,7 @@ def sum(self): ...
|
|
|
297
303
|
|
|
298
304
|
### ttree.to_array
|
|
299
305
|
|
|
300
|
-
[Show source in ttree.py:
|
|
306
|
+
[Show source in ttree.py:289](../../rootloader/ttree.py#L289)
|
|
301
307
|
|
|
302
308
|
Return ttree data as 1D or 2D numpy array (depending on number of columns)
|
|
303
309
|
|
|
@@ -309,7 +315,7 @@ def to_array(self): ...
|
|
|
309
315
|
|
|
310
316
|
### ttree.to_dataframe
|
|
311
317
|
|
|
312
|
-
[Show source in ttree.py:
|
|
318
|
+
[Show source in ttree.py:300](../../rootloader/ttree.py#L300)
|
|
313
319
|
|
|
314
320
|
Return ttree data as pandas dataframe
|
|
315
321
|
|
|
@@ -321,7 +327,7 @@ def to_dataframe(self): ...
|
|
|
321
327
|
|
|
322
328
|
### ttree.to_dict
|
|
323
329
|
|
|
324
|
-
[Show source in ttree.py:
|
|
330
|
+
[Show source in ttree.py:334](../../rootloader/ttree.py#L334)
|
|
325
331
|
|
|
326
332
|
Return ttree data as dict of numpy arrays
|
|
327
333
|
|
|
@@ -333,7 +339,7 @@ def to_dict(self): ...
|
|
|
333
339
|
|
|
334
340
|
### ttree.values
|
|
335
341
|
|
|
336
|
-
[Show source in ttree.py:
|
|
342
|
+
[Show source in ttree.py:369](../../rootloader/ttree.py#L369)
|
|
337
343
|
|
|
338
344
|
Convert ttree 1D or 2D numpy array (depending on number of columns)
|
|
339
345
|
|
|
@@ -22,6 +22,9 @@ dynamic = ["version"]
|
|
|
22
22
|
"Homepage" = "https://github.com/ucn-triumf/rootloader"
|
|
23
23
|
"Bug Tracker" = "https://github.com/ucn-triumf/rootloader/issues"
|
|
24
24
|
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
test = ["pytest", "pytest-cov"]
|
|
27
|
+
|
|
25
28
|
# set version
|
|
26
29
|
[tool.hatch.version]
|
|
27
30
|
path = "rootloader/version.py"
|
|
@@ -65,7 +65,12 @@ class tdirectory(attrdict):
|
|
|
65
65
|
# TTree
|
|
66
66
|
if 'TTree' == classname:
|
|
67
67
|
if empty_ok or obj.GetEntries() > 0:
|
|
68
|
-
|
|
68
|
+
if name in tree_filter:
|
|
69
|
+
filter_string, columns = tree_filter[name]
|
|
70
|
+
self[name] = ttree(obj, filter_string=filter_string,
|
|
71
|
+
columns=columns)
|
|
72
|
+
else:
|
|
73
|
+
self[name] = ttree(obj)
|
|
69
74
|
elif not quiet:
|
|
70
75
|
tqdm.write(f'Skipped "{name}" due to lack of entries')
|
|
71
76
|
|
|
@@ -71,7 +71,7 @@ class th2(object):
|
|
|
71
71
|
self.dz = self.dz.transpose()
|
|
72
72
|
|
|
73
73
|
def __len__(self):
|
|
74
|
-
return self.
|
|
74
|
+
return self.nbinsx * self.nbinsy
|
|
75
75
|
|
|
76
76
|
def __repr__(self):
|
|
77
77
|
return f'{self.base_class}: "{self.name}", {self.entries} entries, sum = {self.sum}'
|
|
@@ -143,7 +143,8 @@ class th2(object):
|
|
|
143
143
|
|
|
144
144
|
if ax is None:
|
|
145
145
|
plt.figure()
|
|
146
|
-
|
|
146
|
+
# add_subplot is a Figure method, not an Axes method
|
|
147
|
+
ax = plt.gcf().add_subplot(111, projection='3d')
|
|
147
148
|
|
|
148
149
|
ax.plot_surface(xx, yy, self.z, **kwargs)
|
|
149
150
|
|
|
@@ -28,7 +28,7 @@ class ttree(object):
|
|
|
28
28
|
columns (list|None): list of column names to include in fetch, if None, get all
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
-
def __init__(self, tree):
|
|
31
|
+
def __init__(self, tree, filter_string=None, columns=None):
|
|
32
32
|
|
|
33
33
|
# copy
|
|
34
34
|
if isinstance(tree, ttree):
|
|
@@ -71,6 +71,12 @@ class ttree(object):
|
|
|
71
71
|
for filt in self._filters:
|
|
72
72
|
self._rdf = self._rdf.Filter(filt, filt)
|
|
73
73
|
|
|
74
|
+
# apply filter and column selection passed to the constructor
|
|
75
|
+
if filter_string is not None:
|
|
76
|
+
self.set_filter(filter_string, inplace=True)
|
|
77
|
+
if columns is not None:
|
|
78
|
+
self._columns = tuple(columns)
|
|
79
|
+
|
|
74
80
|
def __dir__(self):
|
|
75
81
|
superdir = [d for d in super().__dir__() if d[0] != '_']
|
|
76
82
|
return sorted(self._columns) + superdir
|
|
@@ -313,6 +319,8 @@ class ttree(object):
|
|
|
313
319
|
|
|
314
320
|
# set index
|
|
315
321
|
if self._index is not None:
|
|
322
|
+
if self._index not in df.columns:
|
|
323
|
+
df[self._index] = self._rdf.AsNumpy(columns=[self._index])[self._index]
|
|
316
324
|
df.set_index(self._index, inplace=True)
|
|
317
325
|
|
|
318
326
|
# convert to series?
|
|
@@ -327,13 +335,7 @@ class ttree(object):
|
|
|
327
335
|
|
|
328
336
|
def to_dict(self):
|
|
329
337
|
"""Return ttree data as dict of numpy arrays"""
|
|
330
|
-
|
|
331
|
-
if self._index not in self._columns and self._index is not None:
|
|
332
|
-
columns = [*self._columns, self._index]
|
|
333
|
-
else:
|
|
334
|
-
columns = self._columns
|
|
335
|
-
|
|
336
|
-
return self._rdf.AsNumpy(columns=columns)
|
|
338
|
+
return self._rdf.AsNumpy(columns=self._columns)
|
|
337
339
|
|
|
338
340
|
# PROPERTIES ===========================
|
|
339
341
|
@property
|
|
@@ -427,6 +429,6 @@ class _ttree_indexed(object):
|
|
|
427
429
|
raise NotImplementedError('Slicing steps not implemented')
|
|
428
430
|
|
|
429
431
|
elif isinstance(key, (int, float)):
|
|
430
|
-
tr.set_filter(f'{
|
|
432
|
+
tr.set_filter(f'{tr._index} == {key}', inplace=True)
|
|
431
433
|
|
|
432
434
|
return tr
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '1.4.1'
|