Skip to content
This repository was archived by the owner on Jan 7, 2023. It is now read-only.

Commit c332a0f

Browse files
committed
Merge pull request #202 from ndawe/master
[MRG] Rewrite tree2array
2 parents 76930a7 + 3b29e09 commit c332a0f

33 files changed

+16848
-15280
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ python:
44
- "2.7"
55
- "3.4"
66
env:
7-
- ROOT=v5-34-18
7+
- ROOT=5.34.18
88
- ROOT=master COVERAGE=1
99
install: source ci/install.sh
1010
script: bash ci/test.sh

README.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ At the core of root_numpy are powerful and flexible functions for converting
4646
or `structured arrays <http://docs.scipy.org/doc/numpy/user/basics.rec.html>`_
4747
as well as converting NumPy arrays back into ROOT TTrees. root_numpy can
4848
convert branches of strings and basic types such as bool, int, float, double,
49-
etc. as well as variable and fixed-length 1D arrays and 1D or 2D vectors of
50-
basic types and strings. root_numpy can also create columns in the output array
51-
that are expressions involving the TTree branches (i.e. ``'vect.Pt() / 1000'``)
52-
similar to ``TTree::Draw()``.
49+
etc. as well as variable-length and fixed-length multidimensional arrays and 1D
50+
or 2D vectors of basic types and strings. root_numpy can also create columns in
51+
the output array that are expressions involving the TTree branches (i.e.
52+
``'vect.Pt() / 1000'``) similar to ``TTree::Draw()``.
5353

5454
For example, get a NumPy structured or record array from a TTree
5555
(copy and paste the following examples into your Python prompt):

ci/install.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ sudo apt-get -qq install python-nose python-pip
1717
pip install coverage coveralls
1818

1919
# Install the ROOT binary
20-
build=root${ROOT}_python${TRAVIS_PYTHON_VERSION}_gcc4.8_x86_64
20+
ROOT_BUILD=ROOT-${ROOT}_Python-${TRAVIS_PYTHON_VERSION}_GCC-4.8_x86_64
2121
if [ ! -z ${NOTMVA+x} ]; then
2222
# Use a build without TMVA
23-
build+=_notmva
23+
ROOT_BUILD+=_notmva
2424
fi
25-
time wget --no-check-certificate https://copy.com/rtIyUdxgjt7h/ci/root_builds/${build}.tar.gz
26-
time tar zxf ${build}.tar.gz
27-
mv ${build} root
25+
time wget --no-check-certificate https://copy.com/rtIyUdxgjt7h/ci/root_builds/${ROOT_BUILD}.tar.gz
26+
time tar zxf ${ROOT_BUILD}.tar.gz
27+
mv ${ROOT_BUILD} root
2828
source root/bin/thisroot.sh

root_numpy/_tree.py

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,10 @@ def root2array(filenames,
114114
treename : str, optional (default=None)
115115
Name of the tree to convert (optional if each file contains exactly one
116116
tree).
117-
branches : list of str, optional (default=None)
118-
List of branch names to include as columns of the array. If None or
119-
empty then include all branches than can be converted in the first
120-
tree. If branches contains duplicate branches, only the first one is
121-
used.
117+
branches : list of strings or single string, optional (default=None)
118+
List of branch names to include as columns of the array or a single
119+
branch name to convert into a one-dimensional array. If None then
120+
include all branches that can be converted.
122121
selection : str, optional (default=None)
123122
Only include entries fulfilling this condition.
124123
start, stop, step: int, optional (default=None)
@@ -189,16 +188,27 @@ def root2array(filenames,
189188
elif not trees:
190189
raise IOError(
191190
"no trees present in {0}".format(filenames[0]))
192-
else:
193-
treename = trees[0]
191+
treename = trees[0]
192+
193+
if isinstance(branches, string_types):
194+
# single branch selected
195+
branches = [branches]
196+
flatten = True
197+
else:
198+
flatten = False
194199

195-
return _librootnumpy.root2array_fromFname(
200+
arr = _librootnumpy.root2array_fromFname(
196201
filenames, treename, branches,
197202
selection,
198203
start, stop, step,
199204
include_weight,
200205
weight_name)
201206

207+
if flatten:
208+
# select single column
209+
return arr[branches[0]]
210+
return arr
211+
202212

203213
def root2rec(filenames,
204214
treename=None,
@@ -245,11 +255,10 @@ def tree2array(tree,
245255
----------
246256
tree : ROOT TTree instance
247257
The ROOT TTree to convert into an array.
248-
branches : list of str, optional (default=None)
249-
List of branch names to include as columns of the array. If None or
250-
empty then include all branches than can be converted in the first
251-
tree. If branches contains duplicate branches, only the first one is
252-
used.
258+
branches : list of strings or single string, optional (default=None)
259+
List of branch names to include as columns of the array or a single
260+
branch name to convert into a one-dimensional array. If None then
261+
include all branches that can be converted.
253262
selection : str, optional (default=None)
254263
Only include entries fulfilling this condition.
255264
start, stop, step: int, optional (default=None)
@@ -271,13 +280,24 @@ def tree2array(tree,
271280
import ROOT
272281
if not isinstance(tree, ROOT.TTree):
273282
raise TypeError("tree must be a ROOT.TTree")
274-
# will need AsCapsule for Python 3
275283
cobj = ROOT.AsCObject(tree)
284+
285+
if isinstance(branches, string_types):
286+
# single branch selected
287+
branches = [branches]
288+
flatten = True
289+
else:
290+
flatten = False
291+
276292
arr = _librootnumpy.root2array_fromCObj(
277293
cobj, branches, selection,
278294
start, stop, step,
279295
include_weight,
280296
weight_name)
297+
298+
if flatten:
299+
# select single column
300+
return arr[branches[0]]
281301
return arr
282302

283303

root_numpy/info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
|_| \___/ \___/ \__|___|_| |_|\__,_|_| |_| |_| .__/ \__, | {0}
77
|_____| |_| |___/
88
"""
9-
__version__ = '4.1.2.dev0'
9+
__version__ = '4.2.0.dev0'
1010
__doc__ = __doc__.format(__version__) # pylint:disable=redefined-builtin

root_numpy/src/Column.h

Lines changed: 30 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,32 @@
66
#include <string>
77

88

9-
enum ColumnType
10-
{
11-
SINGLE = 1,
12-
FIXED = 2,
13-
VARY = 3
14-
};
15-
16-
179
class Column
1810
{
1911
public:
2012
virtual ~Column() {}
2113
virtual int GetLen() = 0;
14+
virtual int GetCountLen() = 0;
2215
virtual int GetSize() = 0;
2316
virtual void* GetValuePointer() = 0;
2417
virtual const char* GetTypeName() = 0;
2518

26-
bool skipped;
27-
// single fixed vary?
28-
ColumnType coltype;
29-
// column name
30-
std::string colname;
31-
// useful in case of fixed element
32-
int countval;
33-
// name of the roottype
34-
std::string rttype;
19+
// Column name
20+
std::string name;
21+
// Name of the ROOT type
22+
std::string type;
3523
};
3624

3725

3826
class FormulaColumn: public Column
3927
{
4028
public:
4129

42-
FormulaColumn(std::string _colname, TTreeFormula* _formula)
30+
FormulaColumn(std::string _name, TTreeFormula* _formula)
4331
{
44-
colname = _colname;
45-
coltype = SINGLE;
32+
name = _name;
4633
formula = _formula;
47-
rttype = "Double_t";
34+
type = "Double_t";
4835
value = new double[1];
4936
}
5037

@@ -58,6 +45,11 @@ class FormulaColumn: public Column
5845
return 1;
5946
}
6047

48+
int GetCountLen()
49+
{
50+
return 1;
51+
}
52+
6153
int GetSize()
6254
{
6355
return sizeof(double) * GetLen();
@@ -81,73 +73,24 @@ class FormulaColumn: public Column
8173
};
8274

8375

84-
// This describes the structure of the tree
85-
// Converter should take this and make the appropriate data structure
8676
class BranchColumn: public Column
8777
{
8878
public:
8979

90-
static int find_coltype(TLeaf* leaf,
91-
ColumnType& coltype,
92-
int& countval)
93-
{
94-
// Check whether it's array if so of which type
95-
TLeaf* len_leaf = leaf->GetLeafCounter(countval);
96-
if (countval == 1)
97-
{
98-
if (len_leaf == 0)
99-
{ // single element
100-
coltype = SINGLE;
101-
}
102-
else
103-
{ // variable length
104-
coltype = VARY;
105-
}
106-
}
107-
else if (countval > 0)
108-
{
109-
// fixed multiple array
110-
coltype = FIXED;
111-
}
112-
else
113-
{
114-
// negative
115-
std::string msg("Unable to understand the structure of leaf ");
116-
msg += leaf->GetName();
117-
PyErr_SetString(PyExc_IOError, msg.c_str());
118-
return 0;
119-
}
120-
return 1;
121-
}
122-
123-
static BranchColumn* build(TLeaf* leaf, const std::string& colname)
80+
BranchColumn(std::string& _name, TLeaf* _leaf)
12481
{
125-
BranchColumn* ret = new BranchColumn();
126-
ret->leaf = leaf;
127-
ret->colname = colname;
128-
ret->skipped = false;
129-
if (!find_coltype(leaf, ret->coltype, ret->countval))
130-
{
131-
delete ret;
132-
return NULL;
133-
}
134-
ret->rttype = leaf->GetTypeName();
135-
return ret;
82+
name = _name;
83+
leaf = _leaf;
84+
type = leaf->GetTypeName();
13685
}
13786

13887
void SetLeaf(TLeaf* newleaf, bool check=false)
13988
{
14089
leaf = newleaf;
14190
if (check)
14291
{
143-
assert(leaf->GetTypeName() == rttype);
144-
int cv;
145-
ColumnType ct;
146-
if (find_coltype(leaf, ct, cv) == 0)
147-
abort();
148-
if (ct != coltype)
149-
abort();
150-
//if(ct==FIXED){assert(cv==countval);}
92+
assert(leaf->GetTypeName() == type);
93+
// TODO: compare shape
15194
}
15295
}
15396

@@ -157,6 +100,17 @@ class BranchColumn: public Column
157100
return leaf->GetLen();
158101
}
159102

103+
int GetCountLen()
104+
{
105+
// get count leaf value
106+
TLeaf* count_leaf = leaf->GetLeafCount();
107+
if (count_leaf != NULL)
108+
{
109+
return int(count_leaf->GetValue());
110+
}
111+
return 1;
112+
}
113+
160114
int GetSize()
161115
{
162116
// get size of this block in bytes

root_numpy/src/ROOT.pxi

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,19 @@ cdef extern from "TBranch.h":
4646

4747
cdef extern from "TLeaf.h":
4848
cdef cppclass TLeaf:
49+
const_char* GetName()
50+
const_char* GetTitle()
4951
const_char* GetTypeName()
52+
TLeaf* GetLeafCount()
5053
TLeaf* GetLeafCounter(int&)
51-
const_char* GetName()
52-
54+
TBranch* GetBranch()
55+
5356
cdef extern from "TTree.h":
5457
cdef cppclass TTree:
5558
TTree()
5659
TTree(const_char*, const_char*)
57-
void GetEntry(int i)
58-
int GetEntries()
60+
int GetEntry(long_long entry)
61+
long_long GetEntries()
5962
void SetBranchAddress(const_char* bname, void* addr)
6063
void SetBranchStatus(const_char* bname, bool status)
6164
void Print()
@@ -66,15 +69,16 @@ cdef extern from "TTree.h":
6669
int Fill()
6770
int Scan()
6871
void Delete(void*)
69-
long SetEntries(long)
72+
long_long SetEntries(long_long)
73+
double GetWeight()
7074
int Write()
7175
int Write(const_char* name, int option)
7276

7377
cdef extern from "TChain.h":
7478
cdef cppclass TChain(TTree):
7579
TChain()
7680
TChain(const_char*)
77-
int Add(const_char*, long)
81+
int Add(const_char*, long_long)
7882
void Print()
7983

8084
cdef extern from "TFormula.h":

0 commit comments

Comments
 (0)