-
Notifications
You must be signed in to change notification settings - Fork 8
/
hipolib.py
175 lines (155 loc) · 7.33 KB
/
hipolib.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
##################################################################
## Python interface for reading HIPO files. ##
## This interface is using fusion class from the hipo4 module ##
## with "C" extern intraface defined in wrapper.cpp class. ##
## the fusion interface allows opening multiple files through ##
## providing unique handles for each opened file. ##
## ##
## Author: G.Gavalian (2022) ##
## Jefferson Lab -------------------------------- ##
##################################################################
import ctypes
class hreader:
def __init__(self,libfilename):
""" hipo reader python class interface to hipo fusion wrapper
(use it wisely)
"""
self.libPath = libfilename
self.lz4lib = ctypes.CDLL(self.libPath+'/liblz4.so');
self.hipo4lib = ctypes.CDLL(self.libPath+'/libhipo4.so')
self.status = ctypes.c_int(0)
self.handle = -1
def open(self,filename):
""" open the file and save the handle returned by fusion wrapper.
each opened file has unique handle, so many files can be opened
in parallel.
"""
self.inputFile = filename
self.handle = self.hipo4lib.fusion_open(ctypes.c_char_p(self.inputFile.encode('ascii')))
print('file open handle = ',self.handle)
def define(self,bankname):
""" define is used to declare a bank that will be read by the fusion wrapper
each time next() is called. The banks are stored in the internal map for
each opened file handle.
"""
self.hipo4lib.fusion_define(self.handle,ctypes.c_char_p(bankname.encode('ascii')))
def describe(self,bankname):
""" define is used to declare a bank that will be read by the fusion wrapper
each time next() is called. The banks are stored in the internal map for
each opened file handle.
"""
self.hipo4lib.fusion_describe(self.handle,ctypes.c_char_p(bankname.encode('ascii')))
def getSize(self,bankname):
""" returns size of the bank that was read for current event.
"""
size = self.hipo4lib.fusion_bankSize(self.handle,ctypes.c_char_p(bankname.encode('ascii')))
return size
def next(self):
""" reads next event in the file, and reads all the banks that were decalred with
hreader.define(bankname) function call.
"""
status = self.hipo4lib.fusion_next(self.handle)
return status==1
def getInt(self,bank,entry,row):
""" returns an integer value for entry and row from requested bank. call getSize()
first to make sure that the row is within the allowable range to avoid hard crashes.
"""
a1 = ctypes.c_char_p(bank.encode('ascii'))
a2 = ctypes.c_char_p(entry.encode('ascii'))
self.hipo4lib.fusion_get_float.restype = ctypes.c_int
value = self.hipo4lib.fusion_get_int(self.handle,a1,a2,row)
return value
def getLong(self,bank,entry,row):
""" returns an integer value for entry and row from requested bank. call getSize()
first to make sure that the row is within the allowable range to avoid hard crashes.
"""
a1 = ctypes.c_char_p(bank.encode('ascii'))
a2 = ctypes.c_char_p(entry.encode('ascii'))
self.hipo4lib.fusion_get_long.restype = ctypes.c_ulonglong
value = self.hipo4lib.fusion_get_long(self.handle,a1,a2,row)
return value
def getFloat(self,bank,entry,row):
""" returns an float value for entry and row from requested bank. call getSize()
"""
a1 = ctypes.c_char_p(bank.encode('ascii'))
a2 = ctypes.c_char_p(entry.encode('ascii'))
self.hipo4lib.fusion_get_float.restype = ctypes.c_float
value = ctypes.c_float(self.hipo4lib.fusion_get_float(self.handle,a1,a2,row)).value
return value
def getDouble(self,bank,entry,row):
""" returns an float value for entry and row from requested bank. call getSize()
"""
a1 = ctypes.c_char_p(bank.encode('ascii'))
a2 = ctypes.c_char_p(entry.encode('ascii'))
self.hipo4lib.fusion_get_float.restype = ctypes.c_double
value = ctypes.c_double(self.hipo4lib.fusion_get_float(self.handle,a1,a2,row)).value
return value
def getType(self,bank,entry):
""" returns type of the entry for the given bank. this is used to determine weather to
use getInt or getFloat function.
"""
a1 = ctypes.c_char_p(bank.encode('ascii'))
a2 = ctypes.c_char_p(entry.encode('ascii'))
type = self.hipo4lib.fusion_entry_type(self.handle,a1,a2)
return type
def getEntry(self,bank,entry):
""" returns a python array containing all rows for given column. the determination of the
is done internaly.
"""
rows = self.getSize(bank)
type = self.getType(bank,entry)
array = []
if(type==1 or type==2 or type==3):
for row in range(rows):
array.append(self.getInt(bank,entry,row))
if(type==4):
for row in range(rows):
array.append(self.getFloat(bank,entry,row))
if(type==5):
for row in range(rows):
array.append(self.getDouble(bank,entry,row))
if(type==8):
for row in range(rows):
array.append(self.getLong(bank,entry,row))
return array
def show(self,bank,entry):
""" simple printout of the given column (entry) from the bank for debugging purposes
"""
rows = self.getSize(bank)
type = self.getType(bank,entry)
print('\t entry = ',entry,' type = ', type)
if(type==4):
for row in range(rows):
value = self.getFloat(bank,entry,row)
print(row,' => ', value)
if(type==1 or type==2 or type==3):
for row in range(rows):
value = self.getInt(bank,entry,row)
print (row, ' => ', value)
def test(self):
""" test method for debugging array creation in C and conversion to python with ctypes
"""
array_type = ctypes.c_float*10
array_pointer = ctypes.cast(self.hipo4lib.fusion_create_array(10),ctypes.POINTER(array_type))
print([i for i in array_pointer().contents])
#******************************************************************
# The main module for internal integrity testting. use this from
# the current directory, since the paths here are hardcoded.
#
# before running this code, compile the examples folder and run
# example code : writeFile to produce the exemple file used
# by this code.
#******************************************************************
if __name__=="__main__":
print('\nHIPO4 python interface.....')
print('>>> executing main testing routine')
filename = '../examples/example_output.hipo'
reader = hreader('../slib')
reader.open(filename)
reader.define('event::particle')
counter = 0
while(reader.next()==True):
size = reader.getSize('event::particle')
print('bank size = ',size)
counter = counter + 1
print('processed event # ', counter)