h2lib 0.0.3__cp39-cp39-win_amd64.whl → 13.0.705__cp39-cp39-win_amd64.whl

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.
@@ -1,236 +1,326 @@
1
- import numpy as np
2
- from numpy.ctypeslib import ndpointer
3
- import ctypes as ct
4
- import _ctypes
5
-
6
- import os
7
- import ctypes
8
- from _ctypes import POINTER
9
- from ctypes import c_int, c_double, c_char, c_char_p, c_long
10
- try:
11
- from ctypes import windll
12
- except ImportError:
13
- pass
14
- import sys
15
- from pathlib import Path
16
- import atexit
17
- c_int_p = POINTER(ctypes.c_long)
18
- c_double_p = POINTER(ctypes.c_double)
19
-
20
-
21
- class DLLWrapper(object):
22
- def __init__(self, filename, cdecl=True):
23
- self.filename = str(filename)
24
- self.cdecl = cdecl
25
- self.open()
26
- atexit.register(self.close)
27
-
28
- @staticmethod
29
- def find_dll(path, name):
30
- p = Path(path)
31
-
32
- # if sys.platform == "win32":
33
- # prefixes = ['']
34
- # if sys.maxsize > 2**32:
35
- # suffixes = ['.dll', '_64.dll']
36
- # else:
37
- # suffixes = ['.dll']
38
- # elif sys.platform == 'linux':
39
- # prefixes = ['lib','']
40
- # suffixes = ['.so']
41
- # else:
42
- # raise NotImplementedError()
43
-
44
- dll_lst = []
45
- file_patterns = ['*%s*.dll' % name, '*%s*.so' % name]
46
- for fp in file_patterns:
47
- dll_lst.extend(list(p.glob("**/" + fp)))
48
-
49
- def use_first(dll_lst):
50
- f = str(dll_lst[0])
51
- print("Using ", os.path.abspath(f))
52
- return DLLWrapper(f)
53
-
54
- if len(dll_lst) == 1:
55
- return use_first(dll_lst)
56
- elif len(dll_lst) > 1:
57
- # check if excluding dlls in hawc2-binary, i.e. "hawc2-<platform>" results in one dll
58
- dll_lst2 = [d for d in dll_lst if not str(d).startswith('hawc2-')]
59
- if len(dll_lst2) == 1:
60
- return use_first(dll_lst2)
61
- raise FileExistsError("Multiple dlls found:\n" + "\n".join([str(p) for p in dll_lst]))
62
- else:
63
- raise FileNotFoundError("No " + " or ".join(file_patterns) +
64
- " files found in " + os.path.abspath(p.absolute()))
65
-
66
- def open(self):
67
- assert os.path.isfile(self.filename), os.path.abspath(self.filename)
68
- if self.cdecl:
69
- self.lib = ct.CDLL(self.filename, winmode=ctypes.DEFAULT_MODE)
70
- else:
71
- self.lib = windll.LoadLibrary(self.filename)
72
-
73
- def close(self):
74
- if "FreeLibrary" in dir(_ctypes):
75
- _ctypes.FreeLibrary(self.lib._handle)
76
- else:
77
- _ctypes.dlclose(self.lib._handle)
78
- atexit.unregister(self.close)
79
-
80
- # def __enter__(self):
81
- # self.open()
82
- # return self
83
- #
84
- # def __exit__(self, type, value, traceback):
85
- # self.close()
86
- # return False
87
-
88
- def __getattribute__(self, name):
89
- try:
90
- return object.__getattribute__(self, name)
91
- except AttributeError:
92
- if name == 'lib':
93
- raise Exception("DLL not loaded. Run using: 'with dll: ...'")
94
-
95
- try:
96
- f = getattr(self.lib, name)
97
- except AttributeError as e:
98
- raise AttributeError("Attribute '%s' not found in dll ('%s')" % (name, self.filename))
99
-
100
- def wrap(*args, **kwargs):
101
- c_args = []
102
- for arg in args:
103
- if isinstance(arg, int):
104
- c_args.append(c_int_p(c_int(arg)))
105
- elif isinstance(arg, float):
106
- c_args.append(c_double_p(c_double(arg)))
107
- elif isinstance(arg, str):
108
- c_args.append(c_char_p(arg.encode('cp1252')))
109
- # c_args.append(c_int_p(c_int(len(arg))))
110
-
111
- elif isinstance(arg, np.ndarray):
112
- if arg.dtype == int:
113
- c_args.append(arg.ctypes.data_as(c_int_p))
114
- elif arg.dtype == np.float64:
115
- c_args.append(arg.ctypes.data_as(c_double_p))
116
- else:
117
- raise NotImplementedError(arg.dtype)
118
-
119
- else:
120
- # raise NotImplementedError(arg.__class__.__name__)
121
- c_args.append(arg)
122
- if 'restype' in kwargs:
123
- restype = kwargs['restype']
124
- if hasattr(restype, 'dtype'):
125
- restype = np.ctypeslib.as_ctypes_type(restype)
126
- f.restype = restype
127
-
128
- res = f(*c_args)
129
- ret_args = []
130
- for arg in args:
131
- c_arg = c_args.pop(0)
132
- if isinstance(arg, (int, float)):
133
- ret_args.append(c_arg.contents.value)
134
- elif isinstance(arg, (str)):
135
- ret_args.append(c_arg.value.decode('cp1252'))
136
- # c_args.pop(0)
137
- elif isinstance(arg, np.ndarray):
138
- ret_args.append(arg)
139
- else:
140
- raise NotImplementedError(arg.__class__.__name__)
141
- return ret_args, res
142
- return wrap
143
-
144
- def version(self, function_name='get_version'):
145
- try:
146
- f = getattr(self.lib, function_name)
147
- f.argtypes = [c_char_p, c_long]
148
- s = "".ljust(255)
149
- arg = c_char_p(s.encode('utf-8'))
150
- f(arg, len(s))
151
- return arg.value.decode().strip()
152
- except AttributeError:
153
- if function_name == 'get_version':
154
- return self.version('version')
155
-
156
- def getFileProperties(self):
157
- if sys.platform != "win32":
158
- raise OSError("Only supported for Windows")
159
- import win32api
160
- fname = self.filename
161
-
162
- # ==============================================================================
163
- """
164
- Read all properties of the given file return them as a dictionary.
165
- """
166
- propNames = ('Comments', 'InternalName', 'ProductName',
167
- 'CompanyName', 'LegalCopyright', 'ProductVersion',
168
- 'FileDescription', 'LegalTrademarks', 'PrivateBuild',
169
- 'FileVersion', 'OriginalFilename', 'SpecialBuild')
170
-
171
- props = {'FixedFileInfo': None, 'StringFileInfo': None, 'FileVersion': None}
172
-
173
- try:
174
- # backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc
175
- fixedInfo = win32api.GetFileVersionInfo(fname, '\\')
176
- props['FixedFileInfo'] = fixedInfo
177
- props['FileVersion'] = "%d.%d.%d.%d" % (fixedInfo['FileVersionMS'] / 65536,
178
- fixedInfo['FileVersionMS'] % 65536, fixedInfo['FileVersionLS'] / 65536,
179
- fixedInfo['FileVersionLS'] % 65536)
180
-
181
- # \VarFileInfo\Translation returns list of available (language, codepage)
182
- # pairs that can be used to retreive string info. We are using only the first pair.
183
- lang, codepage = win32api.GetFileVersionInfo(fname, '\\VarFileInfo\\Translation')[0]
184
-
185
- # any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle
186
- # two are language/codepage pair returned from above
187
-
188
- strInfo = {}
189
- for propName in propNames:
190
- strInfoPath = u'\\StringFileInfo\\%04X%04X\\%s' % (lang, codepage, propName)
191
- # print str_info
192
- strInfo[propName] = win32api.GetFileVersionInfo(fname, strInfoPath)
193
-
194
- props['StringFileInfo'] = strInfo
195
- except BaseException:
196
- pass
197
-
198
- return props
199
-
200
-
201
- class Type2DllWrapper(DLLWrapper):
202
- def __init__(self, filename, dll_subroutine_init, dll_subroutine_update,
203
- arraysizes_init, arraysizes_update,
204
- init_array):
205
- super().__init__(filename)
206
- self.dll_subroutine_init = dll_subroutine_init
207
- self.dll_subroutine_update = dll_subroutine_update
208
- self.arraysizes_init = arraysizes_init
209
- self.arraysizes_update = arraysizes_update
210
- self.init_array = init_array
211
-
212
- def open(self):
213
- DLLWrapper.open(self)
214
- self.init()
215
-
216
- def call(self, name, array, n1, n2):
217
- f = getattr(self.lib, name)
218
- f.argtypes = [ndpointer(shape=n1, dtype=ct.c_double, flags='FORTRAN'),
219
- ndpointer(shape=n2, dtype=ct.c_double, flags='FORTRAN')]
220
- f.restype = None
221
-
222
- pad_array = np.zeros(n1)
223
- pad_array[:len(array)] = array
224
- arg1 = np.array(pad_array, dtype=ct.c_double, order='F')
225
- arg2 = np.zeros(n2, dtype=ct.c_double, order='F')
226
-
227
- f(arg1, arg2)
228
- return(arg2)
229
-
230
- def init(self):
231
- n1, n2 = self.arraysizes_init
232
- return self.call(self.dll_subroutine_init, self.init_array, n1, n2)
233
-
234
- def update(self, array):
235
- n1, n2 = self.arraysizes_update
236
- return self.call(self.dll_subroutine_update, array, n1, n2)
1
+ import numpy as np
2
+ from numpy.ctypeslib import ndpointer
3
+ import ctypes as ct
4
+ import _ctypes
5
+ import platform
6
+ import os
7
+ import ctypes
8
+ from _ctypes import POINTER
9
+ from ctypes import c_int, c_double, c_char, c_char_p, c_long, c_longlong
10
+ from contextlib import contextmanager
11
+ try:
12
+ from ctypes import windll
13
+ except ImportError:
14
+ pass
15
+ import sys
16
+ from pathlib import Path
17
+ import atexit
18
+ c_int_p = POINTER(ctypes.c_long)
19
+ c_long_p = POINTER(ctypes.c_longlong)
20
+
21
+ c_double_p = POINTER(ctypes.c_double)
22
+ c_float_p = POINTER(ctypes.c_float)
23
+
24
+ in_use = []
25
+
26
+
27
+ class SuppressStream(object):
28
+
29
+ def __init__(self, stream=sys.stderr):
30
+ self.orig_stream_fileno = stream.fileno()
31
+
32
+ def __enter__(self):
33
+ self.orig_stream_dup = os.dup(self.orig_stream_fileno)
34
+ self.devnull = open(os.devnull, 'w')
35
+ os.dup2(self.devnull.fileno(), self.orig_stream_fileno)
36
+
37
+ def __exit__(self, type, value, traceback):
38
+ self.devnull.flush()
39
+ os.close(self.orig_stream_fileno)
40
+ os.dup2(self.orig_stream_dup, self.orig_stream_fileno)
41
+ os.close(self.orig_stream_dup)
42
+ self.devnull.close()
43
+
44
+
45
+ def suppress_output(f):
46
+ def wrap(*args, **kwargs):
47
+ if 'verbose' not in kwargs or not kwargs.pop('verbose'):
48
+ with SuppressStream(sys.stdout), SuppressStream(sys.stderr):
49
+ f(*args, **kwargs)
50
+ else:
51
+ f(*args, **kwargs)
52
+ return wrap
53
+
54
+
55
+ @contextmanager
56
+ def chdir(path):
57
+ oldpwd = os.getcwd()
58
+ os.chdir(path)
59
+ try:
60
+ yield
61
+ finally:
62
+ os.chdir(oldpwd)
63
+
64
+
65
+ def cwd(f):
66
+ def wrap(self, *args, **kwargs):
67
+ with chdir(self.model_path):
68
+ f(self, *args, **kwargs)
69
+ return wrap
70
+
71
+
72
+ def wrap(self, f, *args, **kwargs):
73
+ c_args = []
74
+ args = list(args)
75
+ for i, arg in enumerate(args):
76
+ if isinstance(arg, (list, tuple)):
77
+ if all([isinstance(e, int) for e in arg]):
78
+ # default to int64 which is default on linux but not windows
79
+ args[i] = np.array(arg, dtype=np.int64)
80
+ else:
81
+ args[i] = np.array(arg)
82
+ if isinstance(args[i], np.ndarray):
83
+
84
+ if self.fortran:
85
+ if not args[i].flags.f_contiguous:
86
+ sys.stderr.write(f'argument {i} for {f.__name__} not f_contiguous\n')
87
+ else:
88
+ if not args[i].flags.c_contiguous:
89
+ sys.stderr.write(f'argument {i} for {f.__name__} not c_contiguous\n')
90
+
91
+ args[i] = np.require(args[i], requirements=['C', 'F'][self.fortran])
92
+
93
+ for arg in args:
94
+ if isinstance(arg, int):
95
+ c_args.append(c_long_p(c_longlong(arg)))
96
+ elif isinstance(arg, float):
97
+ c_args.append(c_double_p(c_double(arg)))
98
+ elif isinstance(arg, str):
99
+ c_args.append(c_char_p(arg.encode('cp1252')))
100
+ # c_args.append(c_int_p(c_int(len(arg))))
101
+
102
+ elif isinstance(arg, np.ndarray):
103
+ if arg.dtype in [np.int32]:
104
+ c_args.append(arg.ctypes.data_as(c_int_p))
105
+ elif arg.dtype in [np.int64]:
106
+ c_args.append(arg.ctypes.data_as(c_long_p))
107
+ elif arg.dtype == np.float64:
108
+ c_args.append(arg.ctypes.data_as(c_double_p))
109
+ elif arg.dtype == np.float32:
110
+ c_args.append(arg.ctypes.data_as(c_float_p))
111
+ else:
112
+ raise NotImplementedError(arg.dtype)
113
+
114
+ else:
115
+ # raise NotImplementedError(arg.__class__.__name__)
116
+ c_args.append(arg)
117
+ if 'restype' in kwargs:
118
+ restype = kwargs['restype']
119
+ if hasattr(restype, 'dtype'):
120
+ restype = np.ctypeslib.as_ctypes_type(restype)
121
+ f.restype = restype
122
+ with chdir(self.cwd):
123
+ if self.suppress_output:
124
+ with SuppressStream(sys.stdout), SuppressStream(sys.stderr):
125
+ res = f(*c_args)
126
+ else:
127
+ res = f(*c_args)
128
+ ret_args = []
129
+ for arg in args:
130
+ c_arg = c_args.pop(0)
131
+ if isinstance(arg, (int, float)):
132
+ ret_args.append(c_arg.contents.value)
133
+ elif isinstance(arg, (str)):
134
+ ret_args.append(c_arg.value.decode('cp1252'))
135
+ # c_args.pop(0)
136
+ elif isinstance(arg, np.ndarray):
137
+ ret_args.append(arg)
138
+ else:
139
+ raise NotImplementedError(arg.__class__.__name__)
140
+ return ret_args, res
141
+
142
+
143
+ class DLLWrapper(object):
144
+ def __init__(self, filename, cwd='.', cdecl=True, fortran=True):
145
+ self.filename = str(filename)
146
+ if os.path.abspath(self.filename) in in_use:
147
+ raise Exception(f'{os.path.abspath(self.filename)} already in use in current process.')
148
+ self.cwd = cwd
149
+ self.cdecl = cdecl
150
+ self.fortran = fortran
151
+ self.suppress_output = False
152
+ self.open()
153
+ in_use.append(os.path.abspath(self.filename))
154
+ atexit.register(self.close)
155
+
156
+ @staticmethod
157
+ def find_dll(path, name):
158
+ p = Path(path)
159
+
160
+ # if sys.platform == "win32":
161
+ # prefixes = ['']
162
+ # if sys.maxsize > 2**32:
163
+ # suffixes = ['.dll', '_64.dll']
164
+ # else:
165
+ # suffixes = ['.dll']
166
+ # elif sys.platform == 'linux':
167
+ # prefixes = ['lib','']
168
+ # suffixes = ['.so']
169
+ # else:
170
+ # raise NotImplementedError()
171
+
172
+ dll_lst = []
173
+ file_patterns = ['*%s*.dll' % name, '*%s*.so' % name]
174
+ for fp in file_patterns:
175
+ dll_lst.extend(list(p.glob("**/" + fp)))
176
+
177
+ def use_first(dll_lst):
178
+ f = str(dll_lst[0])
179
+ print("Using ", os.path.abspath(f))
180
+ return DLLWrapper(f)
181
+
182
+ if len(dll_lst) == 1:
183
+ return use_first(dll_lst)
184
+ elif len(dll_lst) > 1:
185
+ # check if excluding dlls in hawc2-binary, i.e. "hawc2-<platform>" results in one dll
186
+ dll_lst2 = [d for d in dll_lst if not str(d).startswith('hawc2-')]
187
+ if len(dll_lst2) == 1:
188
+ return use_first(dll_lst2)
189
+ raise FileExistsError("Multiple dlls found:\n" + "\n".join([str(p) for p in dll_lst]))
190
+ else:
191
+ raise FileNotFoundError("No " + " or ".join(file_patterns) +
192
+ " files found in " + os.path.abspath(p.absolute()))
193
+
194
+ def open(self):
195
+ assert os.path.isfile(self.filename), os.path.abspath(self.filename)
196
+ if self.cdecl:
197
+ try:
198
+ # python < (3, 8) and > 3.10?:
199
+ self.lib = ct.CDLL(self.filename)
200
+ except BaseException:
201
+ self.lib = ct.CDLL(self.filename, winmode=ctypes.DEFAULT_MODE)
202
+ else:
203
+ self.lib = windll.LoadLibrary(self.filename)
204
+
205
+ def close(self):
206
+ if "FreeLibrary" in dir(_ctypes):
207
+ _ctypes.FreeLibrary(self.lib._handle)
208
+ else:
209
+ _ctypes.dlclose(self.lib._handle)
210
+ del self.lib
211
+ atexit.unregister(self.close)
212
+ in_use.remove(os.path.abspath(self.filename))
213
+
214
+ # def __enter__(self):
215
+ # self.open()
216
+ # return self
217
+ #
218
+ # def __exit__(self, type, value, traceback):
219
+ # self.close()
220
+ # return False
221
+
222
+ def __getattr__(self, name):
223
+ if name == 'lib':
224
+ raise Exception("DLL not loaded. Run using: 'with dll: ...'")
225
+ return self.get_lib_function(name)
226
+
227
+ def get_lib_function(self, name):
228
+ try:
229
+ f = getattr(self.lib, name)
230
+ except AttributeError as e:
231
+ raise AttributeError("Attribute '%s' not found in dll ('%s')" % (name, self.filename))
232
+ return lambda *args, **kwargs: wrap(self, f, *args, **kwargs)
233
+
234
+ def version(self, function_name='get_version'):
235
+ try:
236
+ f = getattr(self.lib, function_name)
237
+ f.argtypes = [c_char_p, c_long]
238
+ s = "".ljust(255)
239
+ arg = c_char_p(s.encode('utf-8'))
240
+ f(arg, len(s))
241
+ return arg.value.decode().strip()
242
+ except AttributeError:
243
+ if function_name == 'get_version':
244
+ return self.version('version')
245
+
246
+ def getFileProperties(self):
247
+ if sys.platform != "win32":
248
+ raise OSError("Only supported for Windows")
249
+ import win32api
250
+ fname = self.filename
251
+
252
+ # ==============================================================================
253
+ """
254
+ Read all properties of the given file return them as a dictionary.
255
+ """
256
+ propNames = ('Comments', 'InternalName', 'ProductName',
257
+ 'CompanyName', 'LegalCopyright', 'ProductVersion',
258
+ 'FileDescription', 'LegalTrademarks', 'PrivateBuild',
259
+ 'FileVersion', 'OriginalFilename', 'SpecialBuild')
260
+
261
+ props = {'FixedFileInfo': None, 'StringFileInfo': None, 'FileVersion': None}
262
+
263
+ try:
264
+ # backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc
265
+ fixedInfo = win32api.GetFileVersionInfo(fname, '\\')
266
+ props['FixedFileInfo'] = fixedInfo
267
+ props['FileVersion'] = "%d.%d.%d.%d" % (fixedInfo['FileVersionMS'] / 65536,
268
+ fixedInfo['FileVersionMS'] % 65536, fixedInfo['FileVersionLS'] / 65536,
269
+ fixedInfo['FileVersionLS'] % 65536)
270
+
271
+ # \VarFileInfo\Translation returns list of available (language, codepage)
272
+ # pairs that can be used to retreive string info. We are using only the first pair.
273
+ lang, codepage = win32api.GetFileVersionInfo(fname, '\\VarFileInfo\\Translation')[0]
274
+
275
+ # any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle
276
+ # two are language/codepage pair returned from above
277
+
278
+ strInfo = {}
279
+ for propName in propNames:
280
+ strInfoPath = u'\\StringFileInfo\\%04X%04X\\%s' % (lang, codepage, propName)
281
+ # print str_info
282
+ strInfo[propName] = win32api.GetFileVersionInfo(fname, strInfoPath)
283
+
284
+ props['StringFileInfo'] = strInfo
285
+ except BaseException:
286
+ pass
287
+
288
+ return props
289
+
290
+
291
+ class Type2DllWrapper(DLLWrapper):
292
+ def __init__(self, filename, dll_subroutine_init, dll_subroutine_update,
293
+ arraysizes_init, arraysizes_update,
294
+ init_array):
295
+ super().__init__(filename)
296
+ self.dll_subroutine_init = dll_subroutine_init
297
+ self.dll_subroutine_update = dll_subroutine_update
298
+ self.arraysizes_init = arraysizes_init
299
+ self.arraysizes_update = arraysizes_update
300
+ self.init_array = init_array
301
+
302
+ def open(self):
303
+ DLLWrapper.open(self)
304
+ self.init()
305
+
306
+ def call(self, name, array, n1, n2):
307
+ f = getattr(self.lib, name)
308
+ f.argtypes = [ndpointer(shape=n1, dtype=ct.c_double, flags='FORTRAN'),
309
+ ndpointer(shape=n2, dtype=ct.c_double, flags='FORTRAN')]
310
+ f.restype = None
311
+
312
+ pad_array = np.zeros(n1)
313
+ pad_array[:len(array)] = array
314
+ arg1 = np.array(pad_array, dtype=ct.c_double, order='F')
315
+ arg2 = np.zeros(n2, dtype=ct.c_double, order='F')
316
+
317
+ f(arg1, arg2)
318
+ return arg2
319
+
320
+ def init(self):
321
+ n1, n2 = self.arraysizes_init
322
+ return self.call(self.dll_subroutine_init, self.init_array, n1, n2)
323
+
324
+ def update(self, array):
325
+ n1, n2 = self.arraysizes_update
326
+ return self.call(self.dll_subroutine_update, array, n1, n2)