Skip to content

Commit

Permalink
Add documentation for lena.input (ROOT readers for now). Change conte…
Browse files Browse the repository at this point in the history
…xt for them from "data" to "input".
  • Loading branch information
ynikitenko committed May 8, 2021
1 parent b42e360 commit 746e0fb
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 20 deletions.
16 changes: 16 additions & 0 deletions docs/source/input.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Input
=====
**ROOT readers:**

.. currentmodule:: lena.input
.. autosummary::

ReadROOTFile
ReadROOTTree

ROOT readers
------------
To use these classes, `ROOT <https://root.cern/>`__ must be installed.

.. autoclass:: ReadROOTFile
.. autoclass:: ReadROOTTree
1 change: 1 addition & 0 deletions docs/source/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Reference
context <context>
core <core>
flow <flow>
input <input>
math <math>
output <output>
structures <structures>
Expand Down
23 changes: 13 additions & 10 deletions lena/input/read_root_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,9 @@ def run(self, flow):
For file to be read,
data part of the value must be a string and
*context.data.read_root_file* must not be `False`.
*context.input.read_root_file* must not be `False`.
*context.data.root_file_path* is updated
*context.input.root_file_path* is updated
with the path to the ROOT file.
Warning
Expand All @@ -105,29 +105,32 @@ def run(self, flow):
all its contained objects are destroyed.
Make all processing within one flow:
don't save yielded values to a list,
or make proper copies of them in advance.
or save copies of them.
"""
import ROOT
from ROOT import TFile
from lena.context import get_recursively, update_recursively
from lena.flow import get_data_context
from copy import deepcopy
for val in flow:
data, context = lena.flow.get_data_context(val)
data, context = get_data_context(val)

# skip not ROOT files
if sys.version[0] == 2:
str_type = basestring
else:
str_type = str
if not isinstance(data, str_type) or not \
lena.context.get_recursively(context, "data.read_root_file",
get_recursively(context, "input.read_root_file",
True):
yield val
continue

root_file = ROOT.TFile(data, "read")
root_file = TFile(data, "read")
# context of separate keys shall be updated
# when they are transformed to other types
# in other elements
lena.context.update_recursively(
context, {"data": {"root_file_path": data}}
update_recursively(
context, {"input": {"root_file_path": data}}
)

def get_key_names(fil):
Expand All @@ -140,7 +143,7 @@ def get_key_names(fil):
if self._selector:
if not self._selector(obj):
continue
yield (obj, copy.deepcopy(context))
yield (obj, deepcopy(context))

# will be closed after
# following elements used its data
Expand Down
20 changes: 13 additions & 7 deletions lena/input/read_root_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@


class ReadROOTTree():
"""Read ROOT trees coming from *flow*."""
"""Read ROOT trees from flow."""

def __init__(self, branches=None, get_entry=None):
"""There are two ways in which trees could be read.
"""Trees can be read in two ways.
In the first variant, *branches* is a list of strings
that enables to read the specified tree branches,
Expand All @@ -27,10 +27,10 @@ def __init__(self, branches=None, get_entry=None):
Note
====
If you plan to collect the resulting values
(not use them on the fly), make sure that you use
e.g. *copy.deepcopy* in *get_entry*.
Otherwise all items collected will be the last read value.
To collect the resulting values
(not use them on the fly), make copies of them
in *get_entry* (e.g. use *copy.deepcopy*).
Otherwise all items will be the last value read.
"""
# This loads other classes faster,
# and if ROOT is not installed,
Expand Down Expand Up @@ -94,12 +94,18 @@ def _read_branches(self, tree):
yield entry_tuple(*(getattr(entry, br) for br in branches))

def run(self, flow):
"""Read ROOT trees from *flow* and yield their contents.
*context.input.root_tree_name* is updated with the name
of the current tree.
"""
import ROOT

for val in flow:
# get tree
tree, context = lena.flow.get_data_context(val)
if not isinstance(tree, ROOT.TTree):
# todo: should not other values be forbidden?
yield val
continue

Expand All @@ -113,7 +119,7 @@ def run(self, flow):
# file_name = tree_dir.GetName()
# data_c["root_file_path"] = file_name
data_c["root_tree_name"] = tree.GetName()
lena.context.update_recursively(context, {"data": data_c})
lena.context.update_recursively(context, {"input": data_c})

# get entries
if self._branches:
Expand Down
4 changes: 2 additions & 2 deletions tests/root/test_read_root_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def test_read_root_file(rootfile):
data, context = val
assert data_names[ind] == data.GetName()
assert context == {
'data': {
'root_file_path': rootfile,
"input": {
"root_file_path": rootfile,
}
}
# in this list objects from file will be None!
Expand Down
2 changes: 1 addition & 1 deletion tests/root/test_read_root_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def test_read_root_tree(rootfile):
data, context = val
tree_data.append((data.x, data.y))
assert context == {
'data': {
'input': {
'root_tree_name': 'tree'
}
}
Expand Down

0 comments on commit 746e0fb

Please sign in to comment.