rootloader 0.4.2__tar.gz → 0.6.0__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.
Files changed (26) hide show
  1. {rootloader-0.4.2 → rootloader-0.6.0}/PKG-INFO +2 -2
  2. {rootloader-0.4.2 → rootloader-0.6.0}/docs/rootloader/attrdict.md +2 -2
  3. {rootloader-0.4.2 → rootloader-0.6.0}/docs/rootloader/tdirectory.md +16 -10
  4. {rootloader-0.4.2 → rootloader-0.6.0}/docs/rootloader/tfile.md +14 -4
  5. {rootloader-0.4.2 → rootloader-0.6.0}/docs/rootloader/th1.md +6 -6
  6. {rootloader-0.4.2 → rootloader-0.6.0}/docs/rootloader/th2.md +6 -6
  7. {rootloader-0.4.2 → rootloader-0.6.0}/docs/rootloader/tleaf.md +16 -16
  8. {rootloader-0.4.2 → rootloader-0.6.0}/docs/rootloader/ttree.md +19 -17
  9. rootloader-0.6.0/gen_documentation.bash +25 -0
  10. {rootloader-0.4.2 → rootloader-0.6.0}/rootloader/tdirectory.py +18 -9
  11. {rootloader-0.4.2 → rootloader-0.6.0}/rootloader/tfile.py +8 -2
  12. {rootloader-0.4.2 → rootloader-0.6.0}/rootloader/th1.py +10 -2
  13. {rootloader-0.4.2 → rootloader-0.6.0}/rootloader/th2.py +31 -12
  14. {rootloader-0.4.2 → rootloader-0.6.0}/rootloader/ttree.py +20 -5
  15. rootloader-0.6.0/rootloader/version.py +1 -0
  16. rootloader-0.4.2/rootloader/version.py +0 -1
  17. {rootloader-0.4.2 → rootloader-0.6.0}/.gitignore +0 -0
  18. {rootloader-0.4.2 → rootloader-0.6.0}/LICENSE +0 -0
  19. {rootloader-0.4.2 → rootloader-0.6.0}/README.md +0 -0
  20. {rootloader-0.4.2 → rootloader-0.6.0}/docs/README.md +0 -0
  21. {rootloader-0.4.2 → rootloader-0.6.0}/docs/rootloader/index.md +0 -0
  22. {rootloader-0.4.2 → rootloader-0.6.0}/docs/rootloader/version.md +0 -0
  23. {rootloader-0.4.2 → rootloader-0.6.0}/pyproject.toml +0 -0
  24. {rootloader-0.4.2 → rootloader-0.6.0}/rootloader/__init__.py +0 -0
  25. {rootloader-0.4.2 → rootloader-0.6.0}/rootloader/attrdict.py +0 -0
  26. {rootloader-0.4.2 → rootloader-0.6.0}/rootloader/tleaf.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: rootloader
3
- Version: 0.4.2
3
+ Version: 0.6.0
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
@@ -6,7 +6,7 @@
6
6
 
7
7
  - [attrdict](#attrdict)
8
8
  - [attrdict](#attrdict-1)
9
- - [attrdict().copy](#attrdict()copy)
9
+ - [attrdict.copy](#attrdictcopy)
10
10
 
11
11
  ## attrdict
12
12
 
@@ -20,7 +20,7 @@ Provides common functions for dictionaries of data containers
20
20
  class attrdict(dict): ...
21
21
  ```
22
22
 
23
- ### attrdict().copy
23
+ ### attrdict.copy
24
24
 
25
25
  [Show source in attrdict.py:38](../../rootloader/attrdict.py#L38)
26
26
 
@@ -6,9 +6,9 @@
6
6
 
7
7
  - [tdirectory](#tdirectory)
8
8
  - [tdirectory](#tdirectory-1)
9
- - [tdirectory().copy](#tdirectory()copy)
10
- - [tdirectory().from_dataframe](#tdirectory()from_dataframe)
11
- - [tdirectory().to_dataframe](#tdirectory()to_dataframe)
9
+ - [tdirectory.copy](#tdirectorycopy)
10
+ - [tdirectory.from_dataframe](#tdirectoryfrom_dataframe)
11
+ - [tdirectory.to_dataframe](#tdirectoryto_dataframe)
12
12
 
13
13
  ## tdirectory
14
14
 
@@ -25,17 +25,23 @@ key_filter (function handle): a function with the following signature:
25
25
  bool fn(str) -- takes as input a string and returns a bool
26
26
  indicating whether the object with the corresponding key should
27
27
  be read
28
+ - `tree_filter` *dict* - {treename: (filter_string, [columns])}
29
+ - `treename` *str* - name of the tree to apply elements to
30
+ - `filter_string` *str|None* - if not none then pass this to [`RDataFrame.Filter`](https://root.cern/doc/master/classROOT_1_1RDF_1_1RInterface.html#ad6a94ba7e70fc8f6425a40a4057d40a0)
31
+ - `[columns]` *list|None* - list of column names to include in fetch, if None, get all
28
32
 
29
33
  #### Signature
30
34
 
31
35
  ```python
32
36
  class tdirectory(attrdict):
33
- def __init__(self, directory, empty_ok=True, quiet=True, key_filter=None): ...
37
+ def __init__(
38
+ self, directory, empty_ok=True, quiet=True, key_filter=None, tree_filter=None
39
+ ): ...
34
40
  ```
35
41
 
36
- ### tdirectory().copy
42
+ ### tdirectory.copy
37
43
 
38
- [Show source in tdirectory.py:108](../../rootloader/tdirectory.py#L108)
44
+ [Show source in tdirectory.py:121](../../rootloader/tdirectory.py#L121)
39
45
 
40
46
  Make a copy of this object
41
47
 
@@ -45,9 +51,9 @@ Make a copy of this object
45
51
  def copy(self): ...
46
52
  ```
47
53
 
48
- ### tdirectory().from_dataframe
54
+ ### tdirectory.from_dataframe
49
55
 
50
- [Show source in tdirectory.py:117](../../rootloader/tdirectory.py#L117)
56
+ [Show source in tdirectory.py:130](../../rootloader/tdirectory.py#L130)
51
57
 
52
58
  Convert all elements contained in self to original objects
53
59
 
@@ -57,9 +63,9 @@ Convert all elements contained in self to original objects
57
63
  def from_dataframe(self): ...
58
64
  ```
59
65
 
60
- ### tdirectory().to_dataframe
66
+ ### tdirectory.to_dataframe
61
67
 
62
- [Show source in tdirectory.py:128](../../rootloader/tdirectory.py#L128)
68
+ [Show source in tdirectory.py:141](../../rootloader/tdirectory.py#L141)
63
69
 
64
70
  Convert all objects possible (th1, th2, and ttree) into pandas dataframes
65
71
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  - [tfile](#tfile)
8
8
  - [tfile](#tfile-1)
9
- - [tfile().copy](#tfile()copy)
9
+ - [tfile.copy](#tfilecopy)
10
10
 
11
11
  ## tfile
12
12
 
@@ -24,19 +24,29 @@ key_filter (function handle): a function with the following signature:
24
24
  bool fn(str) -- takes as input a string and returns a bool
25
25
  indicating whether the object with the corresponding key should
26
26
  be read
27
+ - `tree_filter` *dict* - {treename: (filter_string, [columns])}
28
+ - `treename` *str* - name of the tree to apply elements to
29
+ - `filter_string` *str|None* - if not none then pass this to [`RDataFrame.Filter`](https://root.cern/doc/master/classROOT_1_1RDF_1_1RInterface.html#ad6a94ba7e70fc8f6425a40a4057d40a0)
30
+ - `[columns]` *list|None* - list of column names to include in fetch, if None, get all
27
31
 
28
32
  #### Signature
29
33
 
30
34
  ```python
31
35
  class tfile(tdirectory):
32
36
  def __init__(
33
- self, filename, as_dataframe=False, empty_ok=True, quiet=True, key_filter=None
37
+ self,
38
+ filename,
39
+ as_dataframe=False,
40
+ empty_ok=True,
41
+ quiet=True,
42
+ key_filter=None,
43
+ tree_filter=None,
34
44
  ): ...
35
45
  ```
36
46
 
37
- ### tfile().copy
47
+ ### tfile.copy
38
48
 
39
- [Show source in tfile.py:48](../../rootloader/tfile.py#L48)
49
+ [Show source in tfile.py:54](../../rootloader/tfile.py#L54)
40
50
 
41
51
  Make a copy of this object
42
52
 
@@ -6,9 +6,9 @@
6
6
 
7
7
  - [th1](#th1)
8
8
  - [th1](#th1-1)
9
- - [th1().copy](#th1()copy)
10
- - [th1().plot](#th1()plot)
11
- - [th1().to_dataframe](#th1()to_dataframe)
9
+ - [th1.copy](#th1copy)
10
+ - [th1.plot](#th1plot)
11
+ - [th1.to_dataframe](#th1to_dataframe)
12
12
 
13
13
  ## th1
14
14
 
@@ -42,7 +42,7 @@ class th1(object):
42
42
  def __init__(self, hist=None): ...
43
43
  ```
44
44
 
45
- ### th1().copy
45
+ ### th1.copy
46
46
 
47
47
  [Show source in th1.py:84](../../rootloader/th1.py#L84)
48
48
 
@@ -54,7 +54,7 @@ Produce a copy of this object
54
54
  def copy(self): ...
55
55
  ```
56
56
 
57
- ### th1().plot
57
+ ### th1.plot
58
58
 
59
59
  [Show source in th1.py:94](../../rootloader/th1.py#L94)
60
60
 
@@ -72,7 +72,7 @@ Draw the histogram
72
72
  def plot(self, ax=None, data_only=False, **kwargs): ...
73
73
  ```
74
74
 
75
- ### th1().to_dataframe
75
+ ### th1.to_dataframe
76
76
 
77
77
  [Show source in th1.py:122](../../rootloader/th1.py#L122)
78
78
 
@@ -6,9 +6,9 @@
6
6
 
7
7
  - [th2](#th2)
8
8
  - [th2](#th2-1)
9
- - [th2().copy](#th2()copy)
10
- - [th2().plot](#th2()plot)
11
- - [th2().to_dataframe](#th2()to_dataframe)
9
+ - [th2.copy](#th2copy)
10
+ - [th2.plot](#th2plot)
11
+ - [th2.to_dataframe](#th2to_dataframe)
12
12
 
13
13
  ## th2
14
14
 
@@ -42,7 +42,7 @@ class th2(object):
42
42
  def __init__(self, hist=None): ...
43
43
  ```
44
44
 
45
- ### th2().copy
45
+ ### th2.copy
46
46
 
47
47
  [Show source in th2.py:95](../../rootloader/th2.py#L95)
48
48
 
@@ -54,7 +54,7 @@ Produce a copy of this object
54
54
  def copy(self): ...
55
55
  ```
56
56
 
57
- ### th2().plot
57
+ ### th2.plot
58
58
 
59
59
  [Show source in th2.py:105](../../rootloader/th2.py#L105)
60
60
 
@@ -73,7 +73,7 @@ Draw the histogram
73
73
  def plot(self, ax=None, flat=True, **kwargs): ...
74
74
  ```
75
75
 
76
- ### th2().to_dataframe
76
+ ### th2.to_dataframe
77
77
 
78
78
  [Show source in th2.py:143](../../rootloader/th2.py#L143)
79
79
 
@@ -6,14 +6,14 @@
6
6
 
7
7
  - [tleaf](#tleaf)
8
8
  - [tleaf](#tleaf-1)
9
- - [tleaf().branch](#tleaf()branch)
10
- - [tleaf().copy](#tleaf()copy)
11
- - [tleaf().fullname](#tleaf()fullname)
12
- - [tleaf().get_entry](#tleaf()get_entry)
13
- - [tleaf().leaftype](#tleaf()leaftype)
14
- - [tleaf().len](#tleaf()len)
15
- - [tleaf().name](#tleaf()name)
16
- - [tleaf().value](#tleaf()value)
9
+ - [tleaf.branch](#tleafbranch)
10
+ - [tleaf.copy](#tleafcopy)
11
+ - [tleaf.fullname](#tleaffullname)
12
+ - [tleaf.get_entry](#tleafget_entry)
13
+ - [tleaf.leaftype](#tleafleaftype)
14
+ - [tleaf.len](#tleaflen)
15
+ - [tleaf.name](#tleafname)
16
+ - [tleaf.value](#tleafvalue)
17
17
 
18
18
  ## tleaf
19
19
 
@@ -32,7 +32,7 @@ class tleaf(object):
32
32
  def __init__(self, leaf): ...
33
33
  ```
34
34
 
35
- ### tleaf().branch
35
+ ### tleaf.branch
36
36
 
37
37
  [Show source in tleaf.py:25](../../rootloader/tleaf.py#L25)
38
38
 
@@ -43,7 +43,7 @@ class tleaf(object):
43
43
  def branch(self): ...
44
44
  ```
45
45
 
46
- ### tleaf().copy
46
+ ### tleaf.copy
47
47
 
48
48
  [Show source in tleaf.py:17](../../rootloader/tleaf.py#L17)
49
49
 
@@ -55,7 +55,7 @@ Make a copy of this object
55
55
  def copy(self): ...
56
56
  ```
57
57
 
58
- ### tleaf().fullname
58
+ ### tleaf.fullname
59
59
 
60
60
  [Show source in tleaf.py:27](../../rootloader/tleaf.py#L27)
61
61
 
@@ -66,7 +66,7 @@ def copy(self): ...
66
66
  def fullname(self): ...
67
67
  ```
68
68
 
69
- ### tleaf().get_entry
69
+ ### tleaf.get_entry
70
70
 
71
71
  [Show source in tleaf.py:21](../../rootloader/tleaf.py#L21)
72
72
 
@@ -76,7 +76,7 @@ def fullname(self): ...
76
76
  def get_entry(self, i): ...
77
77
  ```
78
78
 
79
- ### tleaf().leaftype
79
+ ### tleaf.leaftype
80
80
 
81
81
  [Show source in tleaf.py:31](../../rootloader/tleaf.py#L31)
82
82
 
@@ -87,7 +87,7 @@ def get_entry(self, i): ...
87
87
  def leaftype(self): ...
88
88
  ```
89
89
 
90
- ### tleaf().len
90
+ ### tleaf.len
91
91
 
92
92
  [Show source in tleaf.py:33](../../rootloader/tleaf.py#L33)
93
93
 
@@ -98,7 +98,7 @@ def leaftype(self): ...
98
98
  def len(self): ...
99
99
  ```
100
100
 
101
- ### tleaf().name
101
+ ### tleaf.name
102
102
 
103
103
  [Show source in tleaf.py:29](../../rootloader/tleaf.py#L29)
104
104
 
@@ -109,7 +109,7 @@ def len(self): ...
109
109
  def name(self): ...
110
110
  ```
111
111
 
112
- ### tleaf().value
112
+ ### tleaf.value
113
113
 
114
114
  [Show source in tleaf.py:35](../../rootloader/tleaf.py#L35)
115
115
 
@@ -6,11 +6,11 @@
6
6
 
7
7
  - [ttree](#ttree)
8
8
  - [ttree](#ttree-1)
9
- - [ttree().copy](#ttree()copy)
10
- - [ttree().entries](#ttree()entries)
11
- - [ttree().get_subtree](#ttree()get_subtree)
12
- - [ttree().plot](#ttree()plot)
13
- - [ttree().to_dataframe](#ttree()to_dataframe)
9
+ - [ttree.copy](#ttreecopy)
10
+ - [ttree.entries](#ttreeentries)
11
+ - [ttree.get_subtree](#ttreeget_subtree)
12
+ - [ttree.plot](#ttreeplot)
13
+ - [ttree.to_dataframe](#ttreeto_dataframe)
14
14
 
15
15
  ## ttree
16
16
 
@@ -21,17 +21,19 @@ Extract ROOT.TTree fully into memory
21
21
  #### Arguments
22
22
 
23
23
  - `tree` *ROOT.TTree|pd.DataFrame* - tree to load
24
+ - `filter_string` *str|None* - if not none then pass this to [`RDataFrame.Filter`](https://root.cern/doc/master/classROOT_1_1RDF_1_1RInterface.html#ad6a94ba7e70fc8f6425a40a4057d40a0)
25
+ - `columns` *list|None* - list of column names to include in fetch, if None, get all
24
26
 
25
27
  #### Signature
26
28
 
27
29
  ```python
28
30
  class ttree(attrdict):
29
- def __init__(self, tree=None): ...
31
+ def __init__(self, tree=None, filter_str=None, columns=None): ...
30
32
  ```
31
33
 
32
- ### ttree().copy
34
+ ### ttree.copy
33
35
 
34
- [Show source in ttree.py:144](../../rootloader/ttree.py#L144)
36
+ [Show source in ttree.py:162](../../rootloader/ttree.py#L162)
35
37
 
36
38
  Produce a copy of this object
37
39
 
@@ -41,9 +43,9 @@ Produce a copy of this object
41
43
  def copy(self): ...
42
44
  ```
43
45
 
44
- ### ttree().entries
46
+ ### ttree.entries
45
47
 
46
- [Show source in ttree.py:155](../../rootloader/ttree.py#L155)
48
+ [Show source in ttree.py:173](../../rootloader/ttree.py#L173)
47
49
 
48
50
  #### Signature
49
51
 
@@ -52,15 +54,15 @@ def copy(self): ...
52
54
  def entries(self): ...
53
55
  ```
54
56
 
55
- ### ttree().get_subtree
57
+ ### ttree.get_subtree
56
58
 
57
- [Show source in ttree.py:158](../../rootloader/ttree.py#L158)
59
+ [Show source in ttree.py:176](../../rootloader/ttree.py#L176)
58
60
 
59
61
  Return a copy of self but only for a subset of entries
60
62
 
61
63
  #### Arguments
62
64
 
63
- - [ttree().entries](#ttreeentries) *list|np.array* - list of entries to get from tree
65
+ - [ttree.entries](#ttreeentries) *list|np.array* - list of entries to get from tree
64
66
 
65
67
  #### Returns
66
68
 
@@ -72,9 +74,9 @@ Return a copy of self but only for a subset of entries
72
74
  def get_subtree(self, entries): ...
73
75
  ```
74
76
 
75
- ### ttree().plot
77
+ ### ttree.plot
76
78
 
77
- [Show source in ttree.py:180](../../rootloader/ttree.py#L180)
79
+ [Show source in ttree.py:198](../../rootloader/ttree.py#L198)
78
80
 
79
81
  Convert to dataframe and plot. Arguments passed to [pandas.DataFrame.plot](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.html)
80
82
 
@@ -88,9 +90,9 @@ same as pandas.DataFrame.plot
88
90
  def plot(self, *args, **kwargs): ...
89
91
  ```
90
92
 
91
- ### ttree().to_dataframe
93
+ ### ttree.to_dataframe
92
94
 
93
- [Show source in ttree.py:188](../../rootloader/ttree.py#L188)
95
+ [Show source in ttree.py:206](../../rootloader/ttree.py#L206)
94
96
 
95
97
  Convert tree to pandas dataframe
96
98
 
@@ -0,0 +1,25 @@
1
+ #!/bin/bash
2
+ # generate documentation with working links
3
+ # Derek Fujimoto
4
+ # Nov 2024
5
+
6
+ # note: requires handsdown (https://github.com/vemel/handsdown)
7
+
8
+ # generate the documentation
9
+ # cd rootloader
10
+ handsdown -o docs --theme readthedocs
11
+
12
+ # fix the broken links
13
+ cd docs/rootloader
14
+ for file in *;
15
+ do
16
+ if [ -f "$file" ]; then
17
+
18
+ # replace bad empty parentheses
19
+ sed -i 's/()././' $file
20
+
21
+ # repace broken table of contents links
22
+ name=$(basename $file .md)
23
+ sed -i "s/#${name}()/#${name}/" $file
24
+ fi
25
+ done
@@ -15,19 +15,28 @@ class tdirectory(attrdict):
15
15
  """Contains root file data
16
16
 
17
17
  Args:
18
- directory (ROOT.TDirectoryFile|ROOT.TFile): object to parse
19
- empty_ok (bool): if true, save empty objects
20
- quiet (bool): if true, don't print skipped statement if object empty
21
- key_filter (function handle): a function with the following signature:
22
- bool fn(str) -- takes as input a string and returns a bool
23
- indicating whether the object with the corresponding key should
24
- be read
18
+ directory (ROOT.TDirectoryFile|ROOT.TFile): object to parse
19
+ empty_ok (bool): if true, save empty objects
20
+ quiet (bool): if true, don't print skipped statement if object empty
21
+ key_filter (function handle): a function with the following signature:
22
+ bool fn(str) -- takes as input a string and returns a bool
23
+ indicating whether the object with the corresponding key should
24
+ be read
25
+ tree_filter (dict): {treename: (filter_string, [columns])}
26
+ treename (str): name of the tree to apply elements to
27
+ filter_string (str|None): if not none then pass this to [`RDataFrame.Filter`](https://root.cern/doc/master/classROOT_1_1RDF_1_1RInterface.html#ad6a94ba7e70fc8f6425a40a4057d40a0)
28
+ [columns] (list|None): list of column names to include in fetch, if None, get all
25
29
  """
26
30
 
27
- def __init__(self, directory, empty_ok=True, quiet=True, key_filter=None):
31
+ def __init__(self, directory, empty_ok=True, quiet=True, key_filter=None,
32
+ tree_filter=None):
28
33
 
34
+ # copy
29
35
  if directory is None: return
36
+
37
+ # defaults
30
38
  if key_filter is None: key_filter = lambda x: True
39
+ tree_filter = {} if tree_filter is None else tree_filter
31
40
 
32
41
  # get keys and read only those with highest cycle number
33
42
  keys = {}
@@ -55,7 +64,7 @@ class tdirectory(attrdict):
55
64
  # TTree
56
65
  if 'TTree' == classname:
57
66
  if empty_ok or obj.GetEntries() > 0:
58
- self[name] = ttree(obj)
67
+ self[name] = ttree(obj, *tree_filter.get(name, (None, None)))
59
68
  elif not quiet:
60
69
  tqdm.write(f'Skipped "{name}" due to lack of entries')
61
70
 
@@ -18,10 +18,14 @@ class tfile(tdirectory):
18
18
  bool fn(str) -- takes as input a string and returns a bool
19
19
  indicating whether the object with the corresponding key should
20
20
  be read
21
+ tree_filter (dict): {treename: (filter_string, [columns])}
22
+ treename (str): name of the tree to apply elements to
23
+ filter_string (str|None): if not none then pass this to [`RDataFrame.Filter`](https://root.cern/doc/master/classROOT_1_1RDF_1_1RInterface.html#ad6a94ba7e70fc8f6425a40a4057d40a0)
24
+ [columns] (list|None): list of column names to include in fetch, if None, get all
21
25
  """
22
26
 
23
27
  def __init__(self, filename, as_dataframe=False, empty_ok=True, quiet=True,
24
- key_filter=None):
28
+ key_filter=None, tree_filter=None):
25
29
 
26
30
  if filename is None: return
27
31
 
@@ -36,7 +40,9 @@ class tfile(tdirectory):
36
40
  super().__init__(fid,
37
41
  empty_ok=empty_ok,
38
42
  quiet=quiet,
39
- key_filter=key_filter)
43
+ key_filter=key_filter,
44
+ tree_filter=tree_filter,
45
+ )
40
46
 
41
47
  # close the file
42
48
  fid.Close()
@@ -114,8 +114,13 @@ class th1(object):
114
114
 
115
115
  # plot elements
116
116
  if not data_only:
117
- ax.set_xlabel(self.xlabel)
118
- ax.set_ylabel(self.ylabel)
117
+
118
+ if len(self.xlabel) > 15: ax.set_xlabel(self.xlabel, fontsize='x-small')
119
+ else: ax.set_xlabel(self.xlabel)
120
+
121
+ if len(self.ylabel) > 15: ax.set_ylabel(self.ylabel, fontsize='x-small')
122
+ else: ax.set_ylabel(self.ylabel)
123
+
119
124
  ax.set_title(self.title, fontsize='x-small')
120
125
  plt.tight_layout()
121
126
 
@@ -138,4 +143,7 @@ class th1(object):
138
143
  for key in keys:
139
144
  df.attrs[key] = getattr(self, key)
140
145
 
146
+ # special draw function
147
+ df.draw = lambda ax=None, data_only=False, **kwargs: th1(df).plot(ax, data_only, **kwargs)
148
+
141
149
  return df
@@ -67,6 +67,9 @@ class th2(object):
67
67
  self.z = self.z.reshape(self.nbinsx, self.nbinsy)
68
68
  self.dz = self.dz.reshape(self.nbinsx, self.nbinsy)
69
69
 
70
+ self.z = self.z.transpose()
71
+ self.dz = self.dz.transpose()
72
+
70
73
  def __len__(self):
71
74
  return self.nbins
72
75
 
@@ -89,8 +92,8 @@ class th2(object):
89
92
  level = df.index.names.index(self.ylabel)
90
93
  self.y = df.index.get_level_values(level).unique().values
91
94
 
92
- self.z = df[self.zlabel].values.reshape(self.nbinsy, self.nbinsx)
93
- self.dz = df[self.zlabel + " error"].values.reshape(self.nbinsy, self.nbinsx)
95
+ self.z = df[self.zlabel].values.reshape(self.nbinsx, self.nbinsy)
96
+ self.dz = df[self.zlabel + " error"].values.reshape(self.nbinsx, self.nbinsy)
94
97
 
95
98
  def copy(self):
96
99
  """Produce a copy of this object"""
@@ -117,7 +120,8 @@ class th2(object):
117
120
  # draw flat
118
121
  if flat:
119
122
  if ax is None:
120
- ax = plt.gcf().add_subplot()
123
+ plt.figure()
124
+ ax = plt.gca()
121
125
 
122
126
  # defaults
123
127
  if 'cmap' not in kwargs.keys(): kwargs['cmap'] = 'RdBu'
@@ -125,20 +129,32 @@ class th2(object):
125
129
  c = ax.pcolormesh(xx, yy, self.z, **kwargs)
126
130
  ax.axis([self.x.min(), self.x.max(), self.y.min(), self.y.max()])
127
131
  plt.gcf().colorbar(c, ax=ax)
128
- ax.set_xlabel(self.xlabel)
129
- ax.set_ylabel(self.ylabel)
130
- ax.set_title(self.title)
132
+
133
+ if len(self.xlabel) > 15: ax.set_xlabel(self.xlabel, fontsize='x-small')
134
+ else: ax.set_xlabel(self.xlabel)
135
+
136
+ if len(self.ylabel) > 15: ax.set_ylabel(self.ylabel, fontsize='x-small')
137
+ else: ax.set_ylabel(self.ylabel)
138
+
139
+ ax.set_title(self.title, fontsize='x-small')
131
140
 
132
141
  # draw 3d
133
142
  else:
134
143
 
135
144
  if ax is None:
136
- ax = plt.gcf().add_subplot(projection='3d')
145
+ plt.figure()
146
+ ax = plt.gca().add_subplot(projection='3d')
137
147
 
138
148
  ax.plot_surface(xx, yy, self.z, **kwargs)
139
- ax.set_xlabel(self.xlabel)
140
- ax.set_ylabel(self.ylabel)
141
- ax.set_zlabel(self.zlabel)
149
+
150
+ if len(self.xlabel) > 15: ax.set_xlabel(self.xlabel, fontsize='x-small')
151
+ else: ax.set_xlabel(self.xlabel)
152
+
153
+ if len(self.ylabel) > 15: ax.set_ylabel(self.ylabel, fontsize='x-small')
154
+ else: ax.set_ylabel(self.ylabel)
155
+
156
+ if len(self.zlabel) > 15: ax.set_zlabel(self.zlabel, fontsize='x-small')
157
+ else: ax.set_zlabel(self.zlabel)
142
158
 
143
159
  def to_dataframe(self):
144
160
  """Convert tree to pandas dataframe
@@ -149,8 +165,8 @@ class th2(object):
149
165
  xx, yy = np.meshgrid(self.x, self.y)
150
166
  idx = pd.MultiIndex.from_arrays((xx.flatten(), yy.flatten()),
151
167
  names=(self.xlabel, self.ylabel))
152
- df = pd.DataFrame({self.zlabel: self.z.flatten(),
153
- f'{self.zlabel} error': self.dz.flatten()},
168
+ df = pd.DataFrame({self.zlabel: self.z.transpose().flatten(),
169
+ f'{self.zlabel} error': self.dz.transpose().flatten()},
154
170
  index=idx)
155
171
 
156
172
  # reconvert instructions
@@ -160,4 +176,7 @@ class th2(object):
160
176
  for key in keys:
161
177
  df.attrs[key] = getattr(self, key)
162
178
 
179
+ # special draw function
180
+ df.draw = lambda ax=None, flat=True, **kwargs: th2(df).plot(ax, flat, **kwargs)
181
+
163
182
  return df
@@ -14,13 +14,19 @@ class ttree(attrdict):
14
14
 
15
15
  Args:
16
16
  tree (ROOT.TTree|pd.DataFrame): tree to load
17
+ filter_string (str|None): if not none then pass this to [`RDataFrame.Filter`](https://root.cern/doc/master/classROOT_1_1RDF_1_1RInterface.html#ad6a94ba7e70fc8f6425a40a4057d40a0)
18
+ columns (list|None): list of column names to include in fetch, if None, get all
17
19
  """
18
20
 
19
- def __init__(self, tree=None):
21
+ def __init__(self, tree=None, filter_str=None, columns=None):
20
22
 
21
23
  if tree is None:
22
24
  return
23
25
 
26
+ # check input
27
+ if isinstance(columns, str):
28
+ columns = [columns]
29
+
24
30
  # extract from dataframe
25
31
  if type(tree) is pd.DataFrame:
26
32
  self._from_dataframe(tree)
@@ -40,12 +46,15 @@ class ttree(attrdict):
40
46
 
41
47
  # extraction of data: fast
42
48
  try:
43
- data = self._extract_event_fast(tree)
49
+ if filter_str is None:
50
+ data = self._extract_event_fast(tree, columns)
51
+ else:
52
+ data = self._extract_event_fast_filtered(tree, filter_str, columns)
44
53
 
45
54
  # if there is a problem, revert to slower, but more robust version
46
55
  except Exception:
47
56
 
48
- tqdm.write("Reverting to robust ttree reader")
57
+ tqdm.write(f"{tree.GetName()}: Reverting to robust ttree reader")
49
58
  entries = tree.GetEntries()
50
59
  if entries == 0: return
51
60
 
@@ -96,9 +105,15 @@ class ttree(attrdict):
96
105
  else:
97
106
  return self.__class__.__name__ + "()"
98
107
 
99
- def _extract_event_fast(self, tree):
108
+ def _extract_event_fast(self, tree, columns):
109
+ # fast version of getting events using RDataFrame
110
+ data = ROOT.RDataFrame(tree).AsNumpy(columns=columns)
111
+ for key, value in data.items():
112
+ setattr(self, key, pd.Series(value))
113
+
114
+ def _extract_event_fast_filtered(self, tree, filter_str, columns):
100
115
  # fast version of getting events using RDataFrame
101
- data = ROOT.RDataFrame(tree).AsNumpy()
116
+ data = ROOT.RDataFrame(tree).Filter(filter_str).AsNumpy(columns=columns)
102
117
  for key, value in data.items():
103
118
  setattr(self, key, pd.Series(value))
104
119
 
@@ -0,0 +1 @@
1
+ __version__ = '0.6.0'
@@ -1 +0,0 @@
1
- __version__ = '0.4.2'
File without changes
File without changes
File without changes
File without changes
File without changes