psr-factory 5.0.0b69__py3-none-manylinux_2_28_x86_64.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.
Potentially problematic release.
This version of psr-factory might be problematic. Click here for more details.
- psr/apps/__init__.py +7 -0
- psr/apps/apps.py +225 -0
- psr/apps/version.py +5 -0
- psr/execqueue/client.py +126 -0
- psr/execqueue/config.py +52 -0
- psr/execqueue/db.py +286 -0
- psr/execqueue/server.py +689 -0
- psr/execqueue/watcher.py +146 -0
- psr/factory/__init__.py +7 -0
- psr/factory/api.py +2745 -0
- psr/factory/factory.pmd +7322 -0
- psr/factory/factory.pmk +19461 -0
- psr/factory/factorylib.py +410 -0
- psr/factory/libfactory.so +0 -0
- psr/factory/py.typed +0 -0
- psr/factory/samples/__init__.py +2 -0
- psr/factory/samples/sddp_case01.py +166 -0
- psr/factory/samples/sddp_case21.py +242 -0
- psr/outputs/__init__.py +5 -0
- psr/outputs/outputs.py +179 -0
- psr/outputs/resample.py +289 -0
- psr/psrfcommon/__init__.py +6 -0
- psr/psrfcommon/psrfcommon.py +57 -0
- psr/psrfcommon/tempfile.py +118 -0
- psr/runner/__init__.py +7 -0
- psr/runner/runner.py +743 -0
- psr/runner/version.py +5 -0
- psr_factory-5.0.0b69.dist-info/METADATA +47 -0
- psr_factory-5.0.0b69.dist-info/RECORD +32 -0
- psr_factory-5.0.0b69.dist-info/WHEEL +5 -0
- psr_factory-5.0.0b69.dist-info/licenses/LICENSE.txt +21 -0
- psr_factory-5.0.0b69.dist-info/top_level.txt +1 -0
psr/factory/api.py
ADDED
|
@@ -0,0 +1,2745 @@
|
|
|
1
|
+
# PSR Factory. Copyright (C) PSR, Inc - All Rights Reserved
|
|
2
|
+
# Unauthorized copying of this file, via any medium is strictly prohibited
|
|
3
|
+
# Proprietary and confidential
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import locale
|
|
8
|
+
from typing import Dict, List, Optional, Tuple, Union, Any
|
|
9
|
+
from types import ModuleType
|
|
10
|
+
import copy
|
|
11
|
+
import ctypes
|
|
12
|
+
import datetime as dt
|
|
13
|
+
import enum
|
|
14
|
+
import numbers
|
|
15
|
+
import os
|
|
16
|
+
import sys
|
|
17
|
+
import threading
|
|
18
|
+
import pathlib
|
|
19
|
+
import warnings
|
|
20
|
+
|
|
21
|
+
from typing import TypeAlias
|
|
22
|
+
|
|
23
|
+
from . import factorylib
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Check whether pandas' dataframe is available.
|
|
27
|
+
_HAS_PANDAS: Optional[bool] = None
|
|
28
|
+
|
|
29
|
+
# Check whether polars' dataframe is available.
|
|
30
|
+
_HAS_POLARS: Optional[bool] = None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
pandas: Optional[ModuleType] = None
|
|
34
|
+
polars: Optional[ModuleType] = None
|
|
35
|
+
numpy: Optional[ModuleType] = None
|
|
36
|
+
|
|
37
|
+
# Values returned by the library.
|
|
38
|
+
ValueLike: TypeAlias = Union[
|
|
39
|
+
bool,
|
|
40
|
+
int,
|
|
41
|
+
float,
|
|
42
|
+
dt.datetime,
|
|
43
|
+
str,
|
|
44
|
+
"DataObject",
|
|
45
|
+
List[Any],
|
|
46
|
+
Dict[str, Any],
|
|
47
|
+
None,
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
PathLike: TypeAlias = Union[str, pathlib.Path]
|
|
51
|
+
|
|
52
|
+
DateLike: TypeAlias = Union[str, dt.datetime]
|
|
53
|
+
|
|
54
|
+
DataFrameLike: TypeAlias = Union["pandas.DataFrame", "polars.DataFrame", "DataFrame"]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
_default_dataframe_type: str = "pandas"
|
|
58
|
+
|
|
59
|
+
_TYPES_WITHOUT_CONTEXT = ("Context", "ConvertOutputOptions", "DataFrameLoadOptions", "DataFrameSaveOptions", "DataFrameMetadata", "StudyLoadOptions", "StudySaveOptions")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _has_pandas() -> bool:
|
|
63
|
+
"""Check if pandas is available."""
|
|
64
|
+
global _HAS_PANDAS
|
|
65
|
+
global pandas
|
|
66
|
+
global numpy
|
|
67
|
+
if _HAS_PANDAS is None:
|
|
68
|
+
try:
|
|
69
|
+
import pandas
|
|
70
|
+
import pandas.api.interchange
|
|
71
|
+
import pandas.api.types
|
|
72
|
+
if numpy is not None:
|
|
73
|
+
import numpy
|
|
74
|
+
import numpy.ctypeslib
|
|
75
|
+
_HAS_PANDAS = True
|
|
76
|
+
except ImportError:
|
|
77
|
+
_HAS_PANDAS = False
|
|
78
|
+
return _HAS_PANDAS
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _has_polars() -> bool:
|
|
82
|
+
"""Check if polars is available."""
|
|
83
|
+
global _HAS_POLARS
|
|
84
|
+
global polars
|
|
85
|
+
global numpy
|
|
86
|
+
if _HAS_POLARS is None:
|
|
87
|
+
try:
|
|
88
|
+
import polars
|
|
89
|
+
import polars.datatypes.classes
|
|
90
|
+
if numpy is not None:
|
|
91
|
+
import numpy
|
|
92
|
+
import numpy.ctypeslib
|
|
93
|
+
_HAS_POLARS = True
|
|
94
|
+
except ImportError:
|
|
95
|
+
_HAS_POLARS = False
|
|
96
|
+
return _HAS_POLARS
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def set_default_dataframe_type(df_type: str):
|
|
100
|
+
"""Set the default dataframe type to be used by the library."""
|
|
101
|
+
global _default_dataframe_type
|
|
102
|
+
df_type = df_type.lower()
|
|
103
|
+
if df_type not in ["pandas", "polars", "factory"]:
|
|
104
|
+
raise ValueError("Unsupported dataframe type. Supported types are 'pandas' and 'polars'.")
|
|
105
|
+
if df_type == "pandas" and not _has_pandas():
|
|
106
|
+
raise ValueError("Pandas is not installed. Please install it to use this dataframe type.")
|
|
107
|
+
if df_type == "polars" and not _has_polars():
|
|
108
|
+
raise ValueError("Polars is not installed. Please install it to use this dataframe type.")
|
|
109
|
+
_default_dataframe_type = df_type
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def get_default_dataframe_type() -> str:
|
|
113
|
+
"""Get the default dataframe type used by the library."""
|
|
114
|
+
return _default_dataframe_type
|
|
115
|
+
|
|
116
|
+
_basic_data_initialized = False
|
|
117
|
+
_basic_data_initialized_lock = threading.Lock()
|
|
118
|
+
|
|
119
|
+
_study_data_initialized = False
|
|
120
|
+
_study_data_initialized_lock = threading.Lock()
|
|
121
|
+
|
|
122
|
+
_constants_initialized = False
|
|
123
|
+
_constants_initialized_lock = threading.Lock()
|
|
124
|
+
|
|
125
|
+
_loaded = False
|
|
126
|
+
_loaded_lock = threading.Lock()
|
|
127
|
+
|
|
128
|
+
# System encoding for interface with the library.
|
|
129
|
+
_preferred_encoding = locale.getpreferredencoding()
|
|
130
|
+
|
|
131
|
+
# Internal date epoch
|
|
132
|
+
_date_transform: Optional[int] = None
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _check_basic_data_initialized():
|
|
136
|
+
"""Checks if the module was initialized."""
|
|
137
|
+
global _basic_data_initialized
|
|
138
|
+
if not _basic_data_initialized:
|
|
139
|
+
_initialize_basic_data()
|
|
140
|
+
return _basic_data_initialized
|
|
141
|
+
|
|
142
|
+
def _check_study_data_initialized():
|
|
143
|
+
"""Checks if the module was initialized."""
|
|
144
|
+
global _study_data_initialized
|
|
145
|
+
if not _study_data_initialized:
|
|
146
|
+
_initialize_study_data()
|
|
147
|
+
return _study_data_initialized
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _check_loaded() -> bool:
|
|
151
|
+
"""Checks if the library was loaded."""
|
|
152
|
+
global _loaded
|
|
153
|
+
if not _loaded:
|
|
154
|
+
_load_library()
|
|
155
|
+
return _loaded
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def _c_str(value: str) -> bytes:
|
|
159
|
+
"""Convert a Python object/string into a bytes/c-array."""
|
|
160
|
+
return bytes(value, encoding=_preferred_encoding)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _from_c_str(value: bytes) -> str:
|
|
164
|
+
"""Convert ASCII bytes back into utf-8 strings."""
|
|
165
|
+
return value.decode(encoding=_preferred_encoding)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _bytes(value: str) -> int:
|
|
169
|
+
"""Return the bytes' count of the equivalent C buffer to
|
|
170
|
+
hold this string."""
|
|
171
|
+
return len(value) + 1
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class FactoryException(Exception):
|
|
175
|
+
pass
|
|
176
|
+
|
|
177
|
+
class FactoryLicenseError(Exception):
|
|
178
|
+
pass
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class LogLevel(enum.Enum):
|
|
182
|
+
NOTSET = 0
|
|
183
|
+
DEBUG = 10
|
|
184
|
+
INFO = 20
|
|
185
|
+
WARNING = 30
|
|
186
|
+
ERROR = 40
|
|
187
|
+
CRITICAL = 50
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class ValueType(enum.Enum):
|
|
191
|
+
INT32 = 0
|
|
192
|
+
INT64 = 1
|
|
193
|
+
FLOAT32 = 2
|
|
194
|
+
FLOAT64 = 3
|
|
195
|
+
BOOL = 4
|
|
196
|
+
STRING = 5
|
|
197
|
+
DATE = 6
|
|
198
|
+
OBJECT = 7
|
|
199
|
+
LIST = 8
|
|
200
|
+
DICT = 9
|
|
201
|
+
NULL = 10
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _version_long() -> str:
|
|
205
|
+
_check_loaded()
|
|
206
|
+
size = 200
|
|
207
|
+
buffer = ctypes.create_string_buffer(size)
|
|
208
|
+
status = factorylib.lib.psrd_version_long(buffer, size)
|
|
209
|
+
if status == 0:
|
|
210
|
+
return _from_c_str(buffer.value)
|
|
211
|
+
return ""
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def _version_short() -> str:
|
|
215
|
+
_check_loaded()
|
|
216
|
+
size = 200
|
|
217
|
+
buffer = ctypes.create_string_buffer(size)
|
|
218
|
+
status = factorylib.lib.psrd_version_short(buffer, size)
|
|
219
|
+
if status == 0:
|
|
220
|
+
return _from_c_str(buffer.value)
|
|
221
|
+
return ""
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def version() -> str:
|
|
225
|
+
"""Returns module version."""
|
|
226
|
+
return _version_long()
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def short_version() -> str:
|
|
230
|
+
"""Returns short library version."""
|
|
231
|
+
return _version_short()
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def check_license() -> Tuple[bool, str]:
|
|
235
|
+
"""Returns True if license is valid and active."""
|
|
236
|
+
_check_loaded()
|
|
237
|
+
error = Error()
|
|
238
|
+
factorylib.lib.psrd_check_license(error.handler())
|
|
239
|
+
valid = error.code == 0
|
|
240
|
+
invalid = error.code == 15
|
|
241
|
+
if not valid and not invalid:
|
|
242
|
+
raise FactoryException("Error checking license: " + error.what)
|
|
243
|
+
return valid, error.what
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def get_log_level() -> LogLevel:
|
|
247
|
+
"""Get log level."""
|
|
248
|
+
_check_loaded()
|
|
249
|
+
log_level = ctypes.c_int()
|
|
250
|
+
code = factorylib.lib.psrd_get_log_level(ctypes.byref(log_level))
|
|
251
|
+
if code != 0:
|
|
252
|
+
raise FactoryException("Error getting log level")
|
|
253
|
+
return LogLevel(log_level.value)
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def set_log_level(log_level: LogLevel):
|
|
257
|
+
"""Set log level."""
|
|
258
|
+
if not isinstance(log_level, LogLevel):
|
|
259
|
+
raise TypeError("log_level must be an instance of LogLevel")
|
|
260
|
+
_check_loaded()
|
|
261
|
+
as_int = log_level.value
|
|
262
|
+
code = factorylib.lib.psrd_set_log_level(as_int)
|
|
263
|
+
if code != 0:
|
|
264
|
+
raise FactoryException("Error setting log level")
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def get_log_file_path() -> str:
|
|
268
|
+
"""Get log file path."""
|
|
269
|
+
_check_loaded()
|
|
270
|
+
error = Error()
|
|
271
|
+
size = 1000
|
|
272
|
+
buffer = ctypes.create_string_buffer(size)
|
|
273
|
+
code = factorylib.lib.psrd_get_log_file_path(buffer, size, error.handler())
|
|
274
|
+
if code != 0:
|
|
275
|
+
raise FactoryException("Error getting log file path")
|
|
276
|
+
return _from_c_str(buffer.value)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def set_debug_mode(value: Union[bool, int]):
|
|
280
|
+
warnings.warn(DeprecationWarning("set_debug_mode is deprecated, use set_diagnostics_mode instead."))
|
|
281
|
+
set_diagnostics_mode(value)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def set_diagnostics_mode(value: Union[bool, int]):
|
|
285
|
+
"""Set debug mode."""
|
|
286
|
+
_check_loaded()
|
|
287
|
+
if isinstance(value, bool):
|
|
288
|
+
value = 1 if value else 0
|
|
289
|
+
code = factorylib.lib.psrd_set_diagnostics_mode(value)
|
|
290
|
+
if code != 0:
|
|
291
|
+
raise FactoryException("Error setting diagnostics mode")
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
def diagnostics() -> str:
|
|
295
|
+
global _basic_data_initialized
|
|
296
|
+
global _basic_data_initialized_lock
|
|
297
|
+
global _study_data_initialized
|
|
298
|
+
global _study_data_initialized_lock
|
|
299
|
+
with _basic_data_initialized_lock, _study_data_initialized_lock:
|
|
300
|
+
"""Get diagnostics information."""
|
|
301
|
+
py_diagnostics = f"Python version: {sys.version}\n" \
|
|
302
|
+
f"Python encoding: {sys.getdefaultencoding()}\n" \
|
|
303
|
+
f"Python locale: {locale.getlocale()}\n" \
|
|
304
|
+
f"Operating system: {sys.platform}\n" \
|
|
305
|
+
f"Operating system encoding: {locale.getpreferredencoding()}\n" \
|
|
306
|
+
f"Module path: {os.path.abspath(os.path.dirname(__file__))}\n" \
|
|
307
|
+
f"Working directory: {os.getcwd()}\n"
|
|
308
|
+
|
|
309
|
+
_check_loaded()
|
|
310
|
+
error = Error()
|
|
311
|
+
size = 10000
|
|
312
|
+
buffer = ctypes.create_string_buffer(size)
|
|
313
|
+
module_path = os.path.dirname(__file__)
|
|
314
|
+
factorylib.lib.psrd_diagnostics(_c_str(module_path), _bytes(module_path),
|
|
315
|
+
buffer, size, error.handler())
|
|
316
|
+
if error.code != 0:
|
|
317
|
+
raise FactoryException(error.what)
|
|
318
|
+
_basic_data_initialized = True
|
|
319
|
+
_study_data_initialized = True
|
|
320
|
+
return py_diagnostics + _from_c_str(buffer.value)
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def get_constant(key: str) -> ValueLike:
|
|
324
|
+
_check_loaded()
|
|
325
|
+
error = Error()
|
|
326
|
+
value = Value()
|
|
327
|
+
factorylib.lib.psrd_get_constant(_c_str(key),
|
|
328
|
+
_bytes(key),
|
|
329
|
+
value.handler(),
|
|
330
|
+
error.handler())
|
|
331
|
+
if error.code != 0:
|
|
332
|
+
raise FactoryException(error.what)
|
|
333
|
+
return value.get()
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def get_setting(key: str) -> ValueLike:
|
|
337
|
+
_check_loaded()
|
|
338
|
+
error = Error()
|
|
339
|
+
value = Value()
|
|
340
|
+
factorylib.lib.psrd_get_global_setting(_c_str(key),
|
|
341
|
+
_bytes(key),
|
|
342
|
+
value.handler(),
|
|
343
|
+
error.handler())
|
|
344
|
+
if error.code != 0:
|
|
345
|
+
raise FactoryException(error.what)
|
|
346
|
+
return value.get()
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def set_setting(key: str, value: ValueLike):
|
|
350
|
+
_check_loaded()
|
|
351
|
+
error = Error()
|
|
352
|
+
_value = Value()
|
|
353
|
+
_value.set(value)
|
|
354
|
+
factorylib.lib.psrd_set_global_setting(_c_str(key),
|
|
355
|
+
_bytes(key),
|
|
356
|
+
_value.handler(),
|
|
357
|
+
error.handler())
|
|
358
|
+
if error.code != 0:
|
|
359
|
+
raise FactoryException(error.what)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def _get_context(models_or_context: Union[str, list, dict, "Context", None],
|
|
363
|
+
blocks: Optional[int] = None) -> "Value":
|
|
364
|
+
value = Value()
|
|
365
|
+
if isinstance(models_or_context, (Context, dict)):
|
|
366
|
+
context = models_or_context
|
|
367
|
+
elif isinstance(models_or_context, (str, list)) or models_or_context is None:
|
|
368
|
+
context = dict()
|
|
369
|
+
if isinstance(models_or_context, list):
|
|
370
|
+
context["Models"] = models_or_context
|
|
371
|
+
elif isinstance(models_or_context, str):
|
|
372
|
+
context["Models"] = [models_or_context, ]
|
|
373
|
+
else:
|
|
374
|
+
raise TypeError("Unexpected type for model_or_context argument.")
|
|
375
|
+
if blocks is not None and isinstance(blocks, int):
|
|
376
|
+
if isinstance(blocks, Context):
|
|
377
|
+
context.set("Blocks", blocks)
|
|
378
|
+
else:
|
|
379
|
+
context["Blocks"] = blocks
|
|
380
|
+
value.set(context)
|
|
381
|
+
return value
|
|
382
|
+
|
|
383
|
+
def _get_arg_object(arg: Union[dict, "Value", "DataObject", None]) -> "Value":
|
|
384
|
+
if isinstance(arg, dict):
|
|
385
|
+
value = Value()
|
|
386
|
+
value.set(arg)
|
|
387
|
+
return value
|
|
388
|
+
elif isinstance(arg, Value):
|
|
389
|
+
return arg
|
|
390
|
+
elif isinstance(arg, DataObject):
|
|
391
|
+
value = Value()
|
|
392
|
+
value.set(arg)
|
|
393
|
+
return value
|
|
394
|
+
elif arg is None:
|
|
395
|
+
return Value()
|
|
396
|
+
else:
|
|
397
|
+
raise TypeError("Unexpected type for argument.")
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
class _BaseObject:
|
|
402
|
+
def __init__(self):
|
|
403
|
+
self._hdr = None
|
|
404
|
+
|
|
405
|
+
def handler(self):
|
|
406
|
+
return self._hdr
|
|
407
|
+
|
|
408
|
+
def __hash__(self):
|
|
409
|
+
return self._hdr
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
class Error(_BaseObject):
|
|
413
|
+
def __init__(self):
|
|
414
|
+
super().__init__()
|
|
415
|
+
self._hdr = factorylib.lib.psrd_new_error()
|
|
416
|
+
|
|
417
|
+
@property
|
|
418
|
+
def code(self) -> int:
|
|
419
|
+
return factorylib.lib.psrd_error_code(self._hdr)
|
|
420
|
+
|
|
421
|
+
@code.setter
|
|
422
|
+
def code(self, value):
|
|
423
|
+
raise AttributeError("do not set code")
|
|
424
|
+
|
|
425
|
+
@code.deleter
|
|
426
|
+
def code(self):
|
|
427
|
+
raise AttributeError("do not delete code")
|
|
428
|
+
|
|
429
|
+
@property
|
|
430
|
+
def what(self) -> str:
|
|
431
|
+
size = factorylib.lib.psrd_error_message(self._hdr, None, 0)
|
|
432
|
+
if size <= 0:
|
|
433
|
+
size = 800
|
|
434
|
+
buffer = ctypes.create_string_buffer(size)
|
|
435
|
+
status = factorylib.lib.psrd_error_message(self._hdr,
|
|
436
|
+
buffer, size)
|
|
437
|
+
if status == 0:
|
|
438
|
+
return _from_c_str(buffer.value)
|
|
439
|
+
return ""
|
|
440
|
+
|
|
441
|
+
@what.deleter
|
|
442
|
+
def what(self):
|
|
443
|
+
raise AttributeError("do not delete what")
|
|
444
|
+
|
|
445
|
+
@what.setter
|
|
446
|
+
def what(self, value):
|
|
447
|
+
raise AttributeError("do not set what")
|
|
448
|
+
|
|
449
|
+
def __del__(self):
|
|
450
|
+
if self._hdr is not None:
|
|
451
|
+
factorylib.lib.psrd_free_error(self._hdr)
|
|
452
|
+
|
|
453
|
+
def __repr__(self):
|
|
454
|
+
return f"Error object with code \"{self.code}\" and message:\n" \
|
|
455
|
+
f"{self.what}"
|
|
456
|
+
|
|
457
|
+
def __str__(self):
|
|
458
|
+
return self.what
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
class _TableColumn:
|
|
462
|
+
def __init__(self):
|
|
463
|
+
self.name = ""
|
|
464
|
+
# values: a pure Python list or a ctypes array
|
|
465
|
+
self.values: Union[list, ctypes.c_int, ctypes.c_long, ctypes.c_float, ctypes.c_double] = []
|
|
466
|
+
|
|
467
|
+
def __len__(self):
|
|
468
|
+
return len(self.values)
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
class ValueList(_BaseObject):
|
|
472
|
+
def __init__(self, initialized=True):
|
|
473
|
+
super().__init__()
|
|
474
|
+
self._hdr = factorylib.lib.psrd_new_list() if initialized else None
|
|
475
|
+
|
|
476
|
+
def __del__(self):
|
|
477
|
+
if self._hdr is not None:
|
|
478
|
+
factorylib.lib.psrd_free_list(self._hdr)
|
|
479
|
+
|
|
480
|
+
@staticmethod
|
|
481
|
+
def from_list(value: Union[List, Tuple]):
|
|
482
|
+
_err = Error()
|
|
483
|
+
list_obj = ValueList()
|
|
484
|
+
for obj in value:
|
|
485
|
+
val_obj = Value()
|
|
486
|
+
val_obj.set(obj)
|
|
487
|
+
factorylib.lib.psrd_list_append(list_obj.handler(),
|
|
488
|
+
val_obj.handler(),
|
|
489
|
+
_err.handler())
|
|
490
|
+
if _err.code != 0:
|
|
491
|
+
FactoryException(_err.what)
|
|
492
|
+
return list_obj
|
|
493
|
+
|
|
494
|
+
def to_list(self) -> list:
|
|
495
|
+
_err = Error()
|
|
496
|
+
count_value = ctypes.c_long()
|
|
497
|
+
factorylib.lib.psrd_list_count(self._hdr,
|
|
498
|
+
ctypes.byref(count_value),
|
|
499
|
+
_err.handler())
|
|
500
|
+
if _err.code != 0:
|
|
501
|
+
raise FactoryException(_err.what)
|
|
502
|
+
values_count = int(count_value.value)
|
|
503
|
+
|
|
504
|
+
list_of_values = []
|
|
505
|
+
_value = Value()
|
|
506
|
+
for i_value in range(values_count):
|
|
507
|
+
factorylib.lib.psrd_list_get(self._hdr, i_value,
|
|
508
|
+
_value.handler(), _err.handler())
|
|
509
|
+
if _err.code != 0:
|
|
510
|
+
raise FactoryException(_err.what)
|
|
511
|
+
list_of_values.append(_value.get())
|
|
512
|
+
return list_of_values
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
class ValueDict(_BaseObject):
|
|
516
|
+
def __init__(self, initialized=True):
|
|
517
|
+
super().__init__()
|
|
518
|
+
self._hdr = factorylib.lib.psrd_new_dict() if initialized else None
|
|
519
|
+
|
|
520
|
+
def __del__(self):
|
|
521
|
+
if self._hdr is not None:
|
|
522
|
+
factorylib.lib.psrd_free_dict(self._hdr)
|
|
523
|
+
|
|
524
|
+
def __getitem__(self, key: ValueLike) -> ValueLike:
|
|
525
|
+
if not isinstance(key, Value):
|
|
526
|
+
old_key = key
|
|
527
|
+
key = Value()
|
|
528
|
+
key.set(old_key)
|
|
529
|
+
error = Error()
|
|
530
|
+
value = Value()
|
|
531
|
+
factorylib.lib.psrd_dict_get_by_key(self._hdr,
|
|
532
|
+
key.handler(),
|
|
533
|
+
value.handler(),
|
|
534
|
+
error.handler())
|
|
535
|
+
if error.code != 0:
|
|
536
|
+
raise FactoryException(error.what)
|
|
537
|
+
return value.get()
|
|
538
|
+
|
|
539
|
+
def __contains__(self, key: ValueLike) -> bool:
|
|
540
|
+
if not isinstance(key, Value):
|
|
541
|
+
old_key = key
|
|
542
|
+
key = Value()
|
|
543
|
+
key.set(old_key)
|
|
544
|
+
error = Error()
|
|
545
|
+
value = Value()
|
|
546
|
+
factorylib.lib.psrd_dict_get_by_key(self._hdr,
|
|
547
|
+
key.handler(),
|
|
548
|
+
value.handler(),
|
|
549
|
+
error.handler())
|
|
550
|
+
return error.code == 0
|
|
551
|
+
|
|
552
|
+
def __len__(self) -> int:
|
|
553
|
+
error = Error()
|
|
554
|
+
count_value = ctypes.c_long()
|
|
555
|
+
factorylib.lib.psrd_dict_count(self._hdr,
|
|
556
|
+
ctypes.byref(count_value),
|
|
557
|
+
error.handler())
|
|
558
|
+
if error.code != 0:
|
|
559
|
+
raise FactoryException(error.what)
|
|
560
|
+
return int(count_value.value)
|
|
561
|
+
|
|
562
|
+
class KeyIterator:
|
|
563
|
+
def __init__(self, dict_obj: "ValueDict"):
|
|
564
|
+
self.dict_obj = dict_obj
|
|
565
|
+
self.error = Error()
|
|
566
|
+
self.key = Value()
|
|
567
|
+
self.index = 0
|
|
568
|
+
|
|
569
|
+
def __iter__(self):
|
|
570
|
+
return self
|
|
571
|
+
|
|
572
|
+
def __next__(self) -> ValueLike:
|
|
573
|
+
if self.index >= self.dict_obj.__len__():
|
|
574
|
+
raise StopIteration
|
|
575
|
+
factorylib.lib.psrd_dict_get_key_by_index(self.dict_obj._hdr, self.index,
|
|
576
|
+
self.key.handler(),
|
|
577
|
+
self.error.handler())
|
|
578
|
+
if self.error.code != 0:
|
|
579
|
+
raise FactoryException(self.error.what)
|
|
580
|
+
self.index += 1
|
|
581
|
+
return self.key.get()
|
|
582
|
+
|
|
583
|
+
def keys(self) -> KeyIterator:
|
|
584
|
+
return self.KeyIterator(self)
|
|
585
|
+
|
|
586
|
+
class ValueIterator:
|
|
587
|
+
def __init__(self, dict_obj: "ValueDict"):
|
|
588
|
+
self.dict_obj = dict_obj
|
|
589
|
+
self.error = Error()
|
|
590
|
+
self.value = Value()
|
|
591
|
+
self.index = 0
|
|
592
|
+
|
|
593
|
+
def __iter__(self):
|
|
594
|
+
return self
|
|
595
|
+
|
|
596
|
+
def __next__(self) -> ValueLike:
|
|
597
|
+
if self.index >= self.dict_obj.__len__():
|
|
598
|
+
raise StopIteration
|
|
599
|
+
factorylib.lib.psrd_dict_get_value_by_index(self.dict_obj._hdr, self.index,
|
|
600
|
+
self.value.handler(),
|
|
601
|
+
self.error.handler())
|
|
602
|
+
if self.error.code != 0:
|
|
603
|
+
raise FactoryException(self.error.what)
|
|
604
|
+
self.index += 1
|
|
605
|
+
return self.value.get()
|
|
606
|
+
|
|
607
|
+
def values(self) -> ValueIterator:
|
|
608
|
+
return self.ValueIterator(self)
|
|
609
|
+
|
|
610
|
+
class ItemIterator:
|
|
611
|
+
def __init__(self, dict_obj: "ValueDict"):
|
|
612
|
+
self.dict_obj = dict_obj
|
|
613
|
+
self.error = Error()
|
|
614
|
+
self.key = Value()
|
|
615
|
+
self.value = Value()
|
|
616
|
+
self.index = 0
|
|
617
|
+
|
|
618
|
+
def __iter__(self):
|
|
619
|
+
return self
|
|
620
|
+
|
|
621
|
+
def __next__(self) -> Tuple[ValueLike, ValueLike]:
|
|
622
|
+
if self.index >= self.dict_obj.__len__():
|
|
623
|
+
raise StopIteration
|
|
624
|
+
factorylib.lib.psrd_dict_get_by_index(self.dict_obj._hdr, self.index,
|
|
625
|
+
self.key.handler(),
|
|
626
|
+
self.value.handler(),
|
|
627
|
+
self.error.handler())
|
|
628
|
+
if self.error.code != 0:
|
|
629
|
+
raise FactoryException(self.error.what)
|
|
630
|
+
self.index += 1
|
|
631
|
+
return self.key.get(), self.value.get()
|
|
632
|
+
|
|
633
|
+
def items(self) -> ItemIterator:
|
|
634
|
+
return self.ItemIterator(self)
|
|
635
|
+
|
|
636
|
+
def clear(self):
|
|
637
|
+
error = Error()
|
|
638
|
+
factorylib.lib.psrd_dict_clear(self._hdr, error.handler())
|
|
639
|
+
if error.code != 0:
|
|
640
|
+
raise FactoryException(error.what)
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
@staticmethod
|
|
644
|
+
def from_dict(dict_value: dict):
|
|
645
|
+
error = Error()
|
|
646
|
+
dict_obj = ValueDict()
|
|
647
|
+
key_obj = Value()
|
|
648
|
+
val_obj = Value()
|
|
649
|
+
for key, value in dict_value.items():
|
|
650
|
+
key_obj.set(key)
|
|
651
|
+
val_obj.set(value)
|
|
652
|
+
factorylib.lib.psrd_dict_set(dict_obj.handler(),
|
|
653
|
+
key_obj.handler(),
|
|
654
|
+
val_obj.handler(),
|
|
655
|
+
error.handler())
|
|
656
|
+
if error.code != 0:
|
|
657
|
+
FactoryException(error.what)
|
|
658
|
+
return dict_obj
|
|
659
|
+
|
|
660
|
+
def to_dict(self) -> dict:
|
|
661
|
+
"""Converts Factory dictionary to Python's"""
|
|
662
|
+
error = Error()
|
|
663
|
+
count_value: Union[ctypes.c_long, int] = ctypes.c_long()
|
|
664
|
+
factorylib.lib.psrd_dict_count(self._hdr,
|
|
665
|
+
ctypes.byref(count_value),
|
|
666
|
+
error.handler())
|
|
667
|
+
if error.code != 0:
|
|
668
|
+
raise FactoryException(error.what)
|
|
669
|
+
count_value = int(count_value.value)
|
|
670
|
+
|
|
671
|
+
read_dict = dict()
|
|
672
|
+
key = Value()
|
|
673
|
+
value = Value()
|
|
674
|
+
for i_value in range(count_value):
|
|
675
|
+
factorylib.lib.psrd_dict_get_by_index(self._hdr, i_value,
|
|
676
|
+
key.handler(),
|
|
677
|
+
value.handler(),
|
|
678
|
+
error.handler())
|
|
679
|
+
if error.code != 0:
|
|
680
|
+
raise FactoryException(error.what)
|
|
681
|
+
read_dict[key.get()] = value.get()
|
|
682
|
+
return read_dict
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
class Value(_BaseObject):
|
|
686
|
+
def __init__(self):
|
|
687
|
+
super().__init__()
|
|
688
|
+
_check_loaded()
|
|
689
|
+
self._hdr = factorylib.lib.psrd_new_value()
|
|
690
|
+
|
|
691
|
+
def __del__(self):
|
|
692
|
+
if self._hdr is not None:
|
|
693
|
+
factorylib.lib.psrd_free_value(self._hdr)
|
|
694
|
+
|
|
695
|
+
def get(self) -> ValueLike:
|
|
696
|
+
_err = Error()
|
|
697
|
+
uint_value = ctypes.c_long()
|
|
698
|
+
factorylib.lib.psrd_value_get_type(self._hdr,
|
|
699
|
+
ctypes.byref(uint_value),
|
|
700
|
+
_err.handler())
|
|
701
|
+
if _err.code != 0:
|
|
702
|
+
raise FactoryException(_err.what)
|
|
703
|
+
var_type = int(uint_value.value)
|
|
704
|
+
if var_type == ValueType.INT32.value:
|
|
705
|
+
int_value = ctypes.c_int()
|
|
706
|
+
factorylib.lib.psrd_value_get_int32(self._hdr,
|
|
707
|
+
ctypes.byref(int_value),
|
|
708
|
+
_err.handler())
|
|
709
|
+
if _err.code != 0:
|
|
710
|
+
raise FactoryException(_err.what)
|
|
711
|
+
return int(int_value.value)
|
|
712
|
+
elif var_type == ValueType.INT64.value:
|
|
713
|
+
long_value = ctypes.c_longlong()
|
|
714
|
+
factorylib.lib.psrd_value_get_int64(self._hdr,
|
|
715
|
+
ctypes.byref(long_value),
|
|
716
|
+
_err.handler())
|
|
717
|
+
if _err.code != 0:
|
|
718
|
+
raise FactoryException(_err.what)
|
|
719
|
+
return int(long_value.value)
|
|
720
|
+
elif var_type == ValueType.FLOAT32.value:
|
|
721
|
+
float_value = ctypes.c_float()
|
|
722
|
+
factorylib.lib.psrd_value_get_float32(self._hdr,
|
|
723
|
+
ctypes.byref(float_value),
|
|
724
|
+
_err.handler())
|
|
725
|
+
if _err.code != 0:
|
|
726
|
+
raise FactoryException(_err.what)
|
|
727
|
+
return float(float_value.value)
|
|
728
|
+
elif var_type == ValueType.FLOAT64.value:
|
|
729
|
+
float_value = ctypes.c_double()
|
|
730
|
+
factorylib.lib.psrd_value_get_float64(self._hdr,
|
|
731
|
+
ctypes.byref(float_value),
|
|
732
|
+
_err.handler())
|
|
733
|
+
if _err.code != 0:
|
|
734
|
+
raise FactoryException(_err.what)
|
|
735
|
+
return float(float_value.value)
|
|
736
|
+
elif var_type == ValueType.STRING.value:
|
|
737
|
+
size = factorylib.lib.psrd_value_get_string(self._hdr, None, 0,
|
|
738
|
+
_err.handler())
|
|
739
|
+
buffer = ctypes.create_string_buffer(size)
|
|
740
|
+
factorylib.lib.psrd_value_get_string(self._hdr, buffer, size,
|
|
741
|
+
_err.handler())
|
|
742
|
+
if _err.code != 0:
|
|
743
|
+
raise FactoryException(_err.what)
|
|
744
|
+
return _from_c_str(buffer.value)
|
|
745
|
+
elif var_type == ValueType.DATE.value:
|
|
746
|
+
date_value = ctypes.c_longlong()
|
|
747
|
+
factorylib.lib.psrd_value_get_date(self._hdr,
|
|
748
|
+
ctypes.byref(date_value),
|
|
749
|
+
_err.handler())
|
|
750
|
+
if _err.code != 0:
|
|
751
|
+
raise FactoryException(_err.what)
|
|
752
|
+
if _date_transform is None:
|
|
753
|
+
raise FactoryException("Factory is not initialized correctly.")
|
|
754
|
+
return dt.datetime.fromtimestamp(date_value.value - _date_transform, dt.timezone.utc)
|
|
755
|
+
|
|
756
|
+
elif var_type == ValueType.BOOL.value:
|
|
757
|
+
# read bool as int first
|
|
758
|
+
bool_value = ctypes.c_bool()
|
|
759
|
+
factorylib.lib.psrd_value_get_bool(self._hdr,
|
|
760
|
+
ctypes.byref(bool_value),
|
|
761
|
+
_err.handler())
|
|
762
|
+
if _err.code != 0:
|
|
763
|
+
raise FactoryException(_err.what)
|
|
764
|
+
return bool(bool_value.value)
|
|
765
|
+
elif var_type == ValueType.NULL.value:
|
|
766
|
+
# Null type
|
|
767
|
+
return None
|
|
768
|
+
elif var_type == ValueType.OBJECT.value:
|
|
769
|
+
obj = DataObject()
|
|
770
|
+
ref = factorylib.lib.psrd_value_get_object(self._hdr,
|
|
771
|
+
_err.handler())
|
|
772
|
+
if _err.code != 0 or ref is None:
|
|
773
|
+
raise FactoryException(_err.what)
|
|
774
|
+
obj._hdr = ref
|
|
775
|
+
return obj
|
|
776
|
+
elif var_type == ValueType.LIST.value:
|
|
777
|
+
dict_obj = ValueList()
|
|
778
|
+
ref = factorylib.lib.psrd_value_get_list(self._hdr,
|
|
779
|
+
_err.handler())
|
|
780
|
+
if _err.code != 0 or ref is None:
|
|
781
|
+
raise FactoryException(_err.what)
|
|
782
|
+
dict_obj._hdr = ref
|
|
783
|
+
return dict_obj.to_list()
|
|
784
|
+
elif var_type == ValueType.DICT.value:
|
|
785
|
+
dict_obj = ValueDict()
|
|
786
|
+
ref = factorylib.lib.psrd_value_get_dict(self._hdr,
|
|
787
|
+
_err.handler())
|
|
788
|
+
if _err.code != 0 or ref is None:
|
|
789
|
+
raise FactoryException(_err.what)
|
|
790
|
+
dict_obj._hdr = ref
|
|
791
|
+
return dict_obj.to_dict()
|
|
792
|
+
else:
|
|
793
|
+
raise NotImplementedError()
|
|
794
|
+
|
|
795
|
+
def set(self, value: ValueLike):
|
|
796
|
+
_err = Error()
|
|
797
|
+
if isinstance(value, bool):
|
|
798
|
+
factorylib.lib.psrd_value_set_bool(self._hdr, value,
|
|
799
|
+
_err.handler())
|
|
800
|
+
if _err.code != 0:
|
|
801
|
+
raise FactoryException(_err.what)
|
|
802
|
+
elif isinstance(value, dt.datetime):
|
|
803
|
+
if _date_transform is None:
|
|
804
|
+
raise FactoryException("Factory is not initialized correctly.")
|
|
805
|
+
value.replace(tzinfo=dt.timezone.utc)
|
|
806
|
+
date_epoch = int(value.timestamp()) + _date_transform
|
|
807
|
+
factorylib.lib.psrd_value_set_date(self._hdr, date_epoch,
|
|
808
|
+
_err.handler())
|
|
809
|
+
if _err.code != 0:
|
|
810
|
+
raise FactoryException(_err.what)
|
|
811
|
+
# TODO: individual test for int32 and int64
|
|
812
|
+
elif isinstance(value, numbers.Integral):
|
|
813
|
+
factorylib.lib.psrd_value_set_int32(self._hdr, value,
|
|
814
|
+
_err.handler())
|
|
815
|
+
if _err.code != 0:
|
|
816
|
+
raise FactoryException(_err.what)
|
|
817
|
+
|
|
818
|
+
# TODO: individual test for float32 and float64
|
|
819
|
+
elif isinstance(value, numbers.Real):
|
|
820
|
+
factorylib.lib.psrd_value_set_float64(self._hdr, value,
|
|
821
|
+
_err.handler())
|
|
822
|
+
if _err.code != 0:
|
|
823
|
+
raise FactoryException(_err.what)
|
|
824
|
+
|
|
825
|
+
elif isinstance(value, str):
|
|
826
|
+
factorylib.lib.psrd_value_set_string(self._hdr,
|
|
827
|
+
_c_str(value),
|
|
828
|
+
_bytes(value),
|
|
829
|
+
_err.handler())
|
|
830
|
+
if _err.code != 0:
|
|
831
|
+
raise FactoryException(_err.what)
|
|
832
|
+
|
|
833
|
+
elif isinstance(value, DataObject):
|
|
834
|
+
factorylib.lib.psrd_value_set_object(self._hdr,
|
|
835
|
+
value.handler(),
|
|
836
|
+
_err.handler())
|
|
837
|
+
if _err.code != 0:
|
|
838
|
+
raise FactoryException(_err.what)
|
|
839
|
+
|
|
840
|
+
elif isinstance(value, (list, tuple, ValueList)):
|
|
841
|
+
if isinstance(value, (list, tuple)):
|
|
842
|
+
dict_obj = ValueList.from_list(value)
|
|
843
|
+
else:
|
|
844
|
+
dict_obj = value
|
|
845
|
+
factorylib.lib.psrd_value_set_list(self._hdr,
|
|
846
|
+
dict_obj.handler(),
|
|
847
|
+
_err.handler())
|
|
848
|
+
if _err.code != 0:
|
|
849
|
+
raise FactoryException(_err.what)
|
|
850
|
+
|
|
851
|
+
elif isinstance(value, dict):
|
|
852
|
+
dict_obj = ValueDict.from_dict(value)
|
|
853
|
+
factorylib.lib.psrd_value_set_dict(self._hdr,
|
|
854
|
+
dict_obj.handler(),
|
|
855
|
+
_err.handler())
|
|
856
|
+
if _err.code != 0:
|
|
857
|
+
raise FactoryException(_err.what)
|
|
858
|
+
|
|
859
|
+
elif isinstance(value, Study):
|
|
860
|
+
raise FactoryException("Study object cannot be set as value.")
|
|
861
|
+
|
|
862
|
+
elif value is None:
|
|
863
|
+
factorylib.lib.psrd_value_set_null(self._hdr,
|
|
864
|
+
_err.handler())
|
|
865
|
+
if _err.code != 0:
|
|
866
|
+
raise FactoryException(_err.what)
|
|
867
|
+
|
|
868
|
+
else:
|
|
869
|
+
raise FactoryException(f"Unsupported type \"{type(value).__name__}\" for value.")
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
class PropertyDescription(_BaseObject):
|
|
873
|
+
def __init__(self):
|
|
874
|
+
super().__init__()
|
|
875
|
+
self._hdr = None
|
|
876
|
+
|
|
877
|
+
def __del__(self):
|
|
878
|
+
if self._hdr is not None:
|
|
879
|
+
factorylib.lib.psrd_free_property_description(self._hdr)
|
|
880
|
+
|
|
881
|
+
@property
|
|
882
|
+
def name(self) -> str:
|
|
883
|
+
_err = Error()
|
|
884
|
+
size = factorylib.lib.psrd_property_description_get_name(self._hdr, None, 0, _err.handler())
|
|
885
|
+
if _err.code != 0:
|
|
886
|
+
raise FactoryException(_err.what)
|
|
887
|
+
buffer = ctypes.create_string_buffer(size)
|
|
888
|
+
factorylib.lib.psrd_property_description_get_name(self._hdr, buffer, size, _err.handler())
|
|
889
|
+
if _err.code != 0:
|
|
890
|
+
raise FactoryException(_err.what)
|
|
891
|
+
return _from_c_str(buffer.value)
|
|
892
|
+
|
|
893
|
+
@name.setter
|
|
894
|
+
def name(self, value):
|
|
895
|
+
raise AttributeError("do not set name")
|
|
896
|
+
|
|
897
|
+
@name.deleter
|
|
898
|
+
def name(self):
|
|
899
|
+
raise AttributeError("do not delete name")
|
|
900
|
+
|
|
901
|
+
@property
|
|
902
|
+
def alt_name(self) -> str:
|
|
903
|
+
_err = Error()
|
|
904
|
+
size = factorylib.lib.psrd_property_description_get_alternative_name(self._hdr, None, 0, _err.handler())
|
|
905
|
+
if _err.code != 0:
|
|
906
|
+
raise FactoryException(_err.what)
|
|
907
|
+
buffer = ctypes.create_string_buffer(size)
|
|
908
|
+
factorylib.lib.psrd_property_description_get_alternative_name(
|
|
909
|
+
self._hdr, buffer, size, _err.handler())
|
|
910
|
+
if _err.code != 0:
|
|
911
|
+
raise FactoryException(_err.what)
|
|
912
|
+
return _from_c_str(buffer.value)
|
|
913
|
+
|
|
914
|
+
@alt_name.setter
|
|
915
|
+
def alt_name(self, value):
|
|
916
|
+
raise AttributeError("do not set alt_name")
|
|
917
|
+
|
|
918
|
+
@alt_name.deleter
|
|
919
|
+
def alt_name(self):
|
|
920
|
+
raise AttributeError("do not delete alt_name")
|
|
921
|
+
|
|
922
|
+
def is_required(self) -> bool:
|
|
923
|
+
_err = Error()
|
|
924
|
+
value = ctypes.c_bool()
|
|
925
|
+
factorylib.lib.psrd_property_description_is_required(self._hdr,
|
|
926
|
+
ctypes.byref(value),
|
|
927
|
+
_err.handler())
|
|
928
|
+
if _err.code != 0:
|
|
929
|
+
raise FactoryException(_err.what)
|
|
930
|
+
return bool(value.value)
|
|
931
|
+
|
|
932
|
+
def is_reference(self) -> bool:
|
|
933
|
+
_err = Error()
|
|
934
|
+
value = ctypes.c_bool()
|
|
935
|
+
factorylib.lib.psrd_property_description_is_reference(self._hdr,
|
|
936
|
+
ctypes.byref(value),
|
|
937
|
+
_err.handler())
|
|
938
|
+
if _err.code != 0:
|
|
939
|
+
raise FactoryException(_err.what)
|
|
940
|
+
return bool(value.value)
|
|
941
|
+
|
|
942
|
+
def is_dynamic(self) -> bool:
|
|
943
|
+
_err = Error()
|
|
944
|
+
value = ctypes.c_bool()
|
|
945
|
+
factorylib.lib.psrd_property_description_is_dynamic(self._hdr,
|
|
946
|
+
ctypes.byref(value),
|
|
947
|
+
_err.handler())
|
|
948
|
+
if _err.code != 0:
|
|
949
|
+
raise FactoryException(_err.what)
|
|
950
|
+
return bool(value.value)
|
|
951
|
+
|
|
952
|
+
def is_indexed(self) -> bool:
|
|
953
|
+
_err = Error()
|
|
954
|
+
value = ctypes.c_bool()
|
|
955
|
+
factorylib.lib.psrd_property_description_is_indexed(self._hdr,
|
|
956
|
+
ctypes.byref(value),
|
|
957
|
+
_err.handler())
|
|
958
|
+
if _err.code != 0:
|
|
959
|
+
raise FactoryException(_err.what)
|
|
960
|
+
return bool(value.value)
|
|
961
|
+
|
|
962
|
+
def is_grouped(self) -> bool:
|
|
963
|
+
_err = Error()
|
|
964
|
+
value = ctypes.c_bool()
|
|
965
|
+
factorylib.lib.psrd_property_description_is_grouped(self._hdr,
|
|
966
|
+
ctypes.byref(value),
|
|
967
|
+
_err.handler())
|
|
968
|
+
if _err.code != 0:
|
|
969
|
+
raise FactoryException(_err.what)
|
|
970
|
+
return bool(value.value)
|
|
971
|
+
|
|
972
|
+
def grouped_with(self) -> List[str]:
|
|
973
|
+
_err = Error()
|
|
974
|
+
_list_obj = ValueList()
|
|
975
|
+
ref = factorylib.lib.psrd_property_description_grouped_with(self._hdr,
|
|
976
|
+
_err.handler())
|
|
977
|
+
if _err.code != 0 or ref is None:
|
|
978
|
+
raise FactoryException(_err.what)
|
|
979
|
+
_list_obj._hdr = ref
|
|
980
|
+
return _list_obj.to_list()
|
|
981
|
+
|
|
982
|
+
def dimensions(self) -> Dict[str, int]:
|
|
983
|
+
_err = Error()
|
|
984
|
+
dimensions = {}
|
|
985
|
+
value = ctypes.c_long()
|
|
986
|
+
factorylib.lib.psrd_property_description_dimensions_count(self._hdr,
|
|
987
|
+
ctypes.byref(value),
|
|
988
|
+
_err.handler())
|
|
989
|
+
if _err.code != 0:
|
|
990
|
+
raise FactoryException(_err.what)
|
|
991
|
+
dimensions_count = int(value.value)
|
|
992
|
+
|
|
993
|
+
for i_dim in range(dimensions_count):
|
|
994
|
+
size = factorylib.lib.psrd_property_description_get_dimension_name(self._hdr, i_dim, None, 0, _err.handler())
|
|
995
|
+
if _err.code != 0:
|
|
996
|
+
raise FactoryException(_err.what)
|
|
997
|
+
buffer = ctypes.create_string_buffer(size)
|
|
998
|
+
factorylib.lib.psrd_property_description_get_dimension_name(self._hdr,
|
|
999
|
+
i_dim, buffer,
|
|
1000
|
+
size,
|
|
1001
|
+
_err.handler())
|
|
1002
|
+
if _err.code != 0:
|
|
1003
|
+
raise FactoryException(_err.what)
|
|
1004
|
+
name = _from_c_str(buffer.value)
|
|
1005
|
+
factorylib.lib.psrd_property_description_get_dimension_size(self._hdr,
|
|
1006
|
+
i_dim,
|
|
1007
|
+
ctypes.byref(value),
|
|
1008
|
+
_err.handler())
|
|
1009
|
+
if _err.code != 0:
|
|
1010
|
+
raise FactoryException(_err.what)
|
|
1011
|
+
size = int(value.value)
|
|
1012
|
+
|
|
1013
|
+
dimensions[name] = size
|
|
1014
|
+
return dimensions
|
|
1015
|
+
|
|
1016
|
+
def type(self) -> ValueType:
|
|
1017
|
+
_err = Error()
|
|
1018
|
+
value = ctypes.c_long()
|
|
1019
|
+
factorylib.lib.psrd_property_description_get_type(self._hdr,
|
|
1020
|
+
ctypes.byref(value),
|
|
1021
|
+
_err.handler())
|
|
1022
|
+
if _err.code != 0:
|
|
1023
|
+
raise FactoryException(_err.what)
|
|
1024
|
+
return ValueType(value.value)
|
|
1025
|
+
|
|
1026
|
+
def __repr__(self):
|
|
1027
|
+
return self.__str__()
|
|
1028
|
+
|
|
1029
|
+
def __str__(self):
|
|
1030
|
+
dimensions = self.dimensions()
|
|
1031
|
+
if len(dimensions) == 0:
|
|
1032
|
+
return f"Property {self.name}"
|
|
1033
|
+
else:
|
|
1034
|
+
return f"Property {self.name} with dimensions {self.dimensions()}"
|
|
1035
|
+
|
|
1036
|
+
|
|
1037
|
+
class DataObject(_BaseObject):
|
|
1038
|
+
def __init__(self):
|
|
1039
|
+
super().__init__()
|
|
1040
|
+
self._hdr = None
|
|
1041
|
+
|
|
1042
|
+
def __del__(self):
|
|
1043
|
+
if self._hdr is not None:
|
|
1044
|
+
factorylib.lib.psrd_free_object(self._hdr)
|
|
1045
|
+
|
|
1046
|
+
def __eq__(self, other):
|
|
1047
|
+
if not isinstance(other, DataObject):
|
|
1048
|
+
return False
|
|
1049
|
+
_err = Error()
|
|
1050
|
+
value = ctypes.c_bool()
|
|
1051
|
+
if self._hdr == other.handler():
|
|
1052
|
+
return True
|
|
1053
|
+
factorylib.lib.psrd_object_is_equals_to(self._hdr,
|
|
1054
|
+
other.handler(),
|
|
1055
|
+
ctypes.byref(value),
|
|
1056
|
+
_err.handler())
|
|
1057
|
+
if _err.code != 0:
|
|
1058
|
+
raise FactoryException(_err.what)
|
|
1059
|
+
return bool(value.value)
|
|
1060
|
+
|
|
1061
|
+
def __hash__(self):
|
|
1062
|
+
_err = Error()
|
|
1063
|
+
handler = factorylib.lib.psrd_object_get_handler(self._hdr, _err.handler())
|
|
1064
|
+
if _err.code != 0:
|
|
1065
|
+
raise FactoryException(_err.what)
|
|
1066
|
+
return handler
|
|
1067
|
+
|
|
1068
|
+
def __copy__(self):
|
|
1069
|
+
dest = DataObject()
|
|
1070
|
+
_err = Error()
|
|
1071
|
+
ref = factorylib.lib.psrd_object_clone(self.handler(),
|
|
1072
|
+
_err.handler())
|
|
1073
|
+
if _err.code != 0 or ref is None:
|
|
1074
|
+
raise FactoryException(_err.what)
|
|
1075
|
+
dest._hdr = ref
|
|
1076
|
+
return dest
|
|
1077
|
+
|
|
1078
|
+
def __deepcopy__(self, memo_dict=None):
|
|
1079
|
+
raise NotImplementedError()
|
|
1080
|
+
|
|
1081
|
+
def __repr__(self):
|
|
1082
|
+
identifiers = []
|
|
1083
|
+
if self.has_code():
|
|
1084
|
+
identifiers.append(f"code={self.code}")
|
|
1085
|
+
if self.has_id():
|
|
1086
|
+
identifiers.append(f"id={self.id.strip()}")
|
|
1087
|
+
if self.has_name():
|
|
1088
|
+
identifiers.append(f"name={self.name.strip()}")
|
|
1089
|
+
return f"psr.factory.DataObject({self.type}, {', '.join(identifiers)})"
|
|
1090
|
+
|
|
1091
|
+
def help(self) -> str:
|
|
1092
|
+
return help(self.type)
|
|
1093
|
+
|
|
1094
|
+
def clone(self) -> "DataObject":
|
|
1095
|
+
return copy.copy(self)
|
|
1096
|
+
|
|
1097
|
+
@property
|
|
1098
|
+
def context(self) -> "Context":
|
|
1099
|
+
_check_basic_data_initialized()
|
|
1100
|
+
_check_study_data_initialized()
|
|
1101
|
+
obj = Context()
|
|
1102
|
+
_err = Error()
|
|
1103
|
+
ref = factorylib.lib.psrd_object_context(self._hdr,
|
|
1104
|
+
_err.handler())
|
|
1105
|
+
if _err.code != 0 or ref is None:
|
|
1106
|
+
raise FactoryException(_err.what)
|
|
1107
|
+
obj._hdr = ref
|
|
1108
|
+
return obj
|
|
1109
|
+
|
|
1110
|
+
def descriptions(self) -> Dict[str, PropertyDescription]:
|
|
1111
|
+
_err = Error()
|
|
1112
|
+
value = ctypes.c_long()
|
|
1113
|
+
factorylib.lib.psrd_object_property_description_count(self._hdr,
|
|
1114
|
+
ctypes.byref(value),
|
|
1115
|
+
_err.handler())
|
|
1116
|
+
if _err.code != 0:
|
|
1117
|
+
raise FactoryException(_err.what)
|
|
1118
|
+
var_count = int(value.value)
|
|
1119
|
+
properties = {}
|
|
1120
|
+
for i_var in range(var_count):
|
|
1121
|
+
var = PropertyDescription()
|
|
1122
|
+
ref = factorylib.lib.psrd_object_get_property_description(self._hdr,
|
|
1123
|
+
i_var,
|
|
1124
|
+
_err.handler())
|
|
1125
|
+
if _err.code != 0 or ref is None:
|
|
1126
|
+
raise FactoryException(_err.what)
|
|
1127
|
+
var._hdr = ref
|
|
1128
|
+
properties[var.name] = var
|
|
1129
|
+
return properties
|
|
1130
|
+
|
|
1131
|
+
def description(self, name: str) -> Optional[PropertyDescription]:
|
|
1132
|
+
_err = Error()
|
|
1133
|
+
var = PropertyDescription()
|
|
1134
|
+
ref = factorylib.lib.psrd_object_get_property_description_by_name(self._hdr,
|
|
1135
|
+
_c_str(name),
|
|
1136
|
+
_bytes(name),
|
|
1137
|
+
_err.handler())
|
|
1138
|
+
if _err.code != 0:
|
|
1139
|
+
raise FactoryException(_err.what)
|
|
1140
|
+
if ref is not None:
|
|
1141
|
+
var._hdr = ref
|
|
1142
|
+
return var
|
|
1143
|
+
return None
|
|
1144
|
+
|
|
1145
|
+
def has_property(self, expression: str) -> bool:
|
|
1146
|
+
_err = Error()
|
|
1147
|
+
bool_value = ctypes.c_bool()
|
|
1148
|
+
factorylib.lib.psrd_object_has_property(self._hdr, _c_str(expression), _bytes(expression),
|
|
1149
|
+
ctypes.byref(bool_value), _err.handler())
|
|
1150
|
+
if _err.code != 0:
|
|
1151
|
+
raise FactoryException(_err.what)
|
|
1152
|
+
return bool(bool_value.value)
|
|
1153
|
+
|
|
1154
|
+
def get(self, expression: str) -> ValueLike:
|
|
1155
|
+
value = Value()
|
|
1156
|
+
_err = Error()
|
|
1157
|
+
factorylib.lib.psrd_object_get_value(self._hdr,
|
|
1158
|
+
_c_str(expression),
|
|
1159
|
+
value.handler(),
|
|
1160
|
+
_err.handler())
|
|
1161
|
+
if _err.code != 0:
|
|
1162
|
+
raise FactoryException(_err.what)
|
|
1163
|
+
return value.get()
|
|
1164
|
+
|
|
1165
|
+
def get_at(self, expression: str, range_expr: DateLike) -> ValueLike:
|
|
1166
|
+
if not isinstance(range_expr, (str, dt.datetime)):
|
|
1167
|
+
raise FactoryException("range_expr must be a string or datetime object.")
|
|
1168
|
+
_value = Value()
|
|
1169
|
+
_err = Error()
|
|
1170
|
+
_range = Value()
|
|
1171
|
+
_range.set(range_expr)
|
|
1172
|
+
factorylib.lib.psrd_object_get_value_at(self._hdr,
|
|
1173
|
+
_c_str(expression),
|
|
1174
|
+
_range.handler(),
|
|
1175
|
+
_value.handler(),
|
|
1176
|
+
_err.handler())
|
|
1177
|
+
if _err.code != 0:
|
|
1178
|
+
raise FactoryException(_err.what)
|
|
1179
|
+
return _value.get()
|
|
1180
|
+
|
|
1181
|
+
def as_dict(self) -> Dict[str, ValueLike]:
|
|
1182
|
+
value_dict = ValueDict()
|
|
1183
|
+
error = Error()
|
|
1184
|
+
handler = factorylib.lib.psrd_object_get_as_dict(self._hdr,
|
|
1185
|
+
error.handler())
|
|
1186
|
+
if error.code != 0 or handler is None:
|
|
1187
|
+
raise FactoryException(error.what)
|
|
1188
|
+
value_dict._hdr = handler
|
|
1189
|
+
return value_dict.to_dict()
|
|
1190
|
+
|
|
1191
|
+
def from_dict(self, input_dict: Dict[str, any]):
|
|
1192
|
+
value_dict = ValueDict.from_dict(input_dict)
|
|
1193
|
+
error = Error()
|
|
1194
|
+
factorylib.lib.psrd_object_set_from_dict(self._hdr, value_dict.handler(),
|
|
1195
|
+
error.handler())
|
|
1196
|
+
if error.code != 0:
|
|
1197
|
+
raise FactoryException(error.what)
|
|
1198
|
+
|
|
1199
|
+
def get_df(self, expression: str) -> DataFrameLike:
|
|
1200
|
+
_err = Error()
|
|
1201
|
+
_df = DataFrame()
|
|
1202
|
+
factorylib.lib.psrd_object_get_table(self._hdr, _df.handler(),
|
|
1203
|
+
_c_str(expression),
|
|
1204
|
+
_bytes(expression),
|
|
1205
|
+
_err.handler())
|
|
1206
|
+
if _err.code != 0:
|
|
1207
|
+
raise FactoryException(_err.what)
|
|
1208
|
+
df_builder = _DataFrameBuilder()
|
|
1209
|
+
df_builder.build_dataframe(_df)
|
|
1210
|
+
return df_builder.build_desired_dataframe_type()
|
|
1211
|
+
|
|
1212
|
+
def set(self, expression: str, value):
|
|
1213
|
+
_err = Error()
|
|
1214
|
+
_val = Value()
|
|
1215
|
+
_val.set(value)
|
|
1216
|
+
factorylib.lib.psrd_object_set_value(self._hdr, _c_str(expression),
|
|
1217
|
+
_bytes(expression),
|
|
1218
|
+
_val.handler(),
|
|
1219
|
+
_err.handler())
|
|
1220
|
+
if _err.code != 0:
|
|
1221
|
+
raise FactoryException(_err.what)
|
|
1222
|
+
|
|
1223
|
+
def set_at(self, expression: str, range_expr: DateLike, value):
|
|
1224
|
+
if not isinstance(range_expr, (str, dt.datetime)):
|
|
1225
|
+
raise FactoryException("range_expr must be a string or datetime object.")
|
|
1226
|
+
_err = Error()
|
|
1227
|
+
_value = Value()
|
|
1228
|
+
_value.set(value)
|
|
1229
|
+
_range = Value()
|
|
1230
|
+
_range.set(range_expr)
|
|
1231
|
+
factorylib.lib.psrd_object_set_value_at(self._hdr,
|
|
1232
|
+
_c_str(expression),
|
|
1233
|
+
_bytes(expression),
|
|
1234
|
+
_range.handler(),
|
|
1235
|
+
_value.handler(),
|
|
1236
|
+
_err.handler())
|
|
1237
|
+
if _err.code != 0:
|
|
1238
|
+
raise FactoryException(_err.what)
|
|
1239
|
+
|
|
1240
|
+
def set_df(self, dataframe_like: DataFrameLike):
|
|
1241
|
+
df_builder = _DataFrameBuilder()
|
|
1242
|
+
if _has_pandas() and isinstance(dataframe_like, pandas.DataFrame):
|
|
1243
|
+
_df = df_builder.build_from_pandas(dataframe_like)
|
|
1244
|
+
elif _has_polars() and isinstance(dataframe_like, polars.DataFrame):
|
|
1245
|
+
_df = df_builder.build_from_polars(dataframe_like)
|
|
1246
|
+
else:
|
|
1247
|
+
raise FactoryException("No supported DataFrame library is available.")
|
|
1248
|
+
_err = Error()
|
|
1249
|
+
factorylib.lib.psrd_object_set_table(self._hdr, _df.handler(), _err.handler())
|
|
1250
|
+
if _err.code != 0:
|
|
1251
|
+
raise FactoryException(_err.what)
|
|
1252
|
+
|
|
1253
|
+
def clear_values(self, expression: str):
|
|
1254
|
+
_err = Error()
|
|
1255
|
+
factorylib.lib.psrd_object_clear_values(self._hdr,
|
|
1256
|
+
_c_str(expression),
|
|
1257
|
+
_bytes(expression),
|
|
1258
|
+
_err.handler())
|
|
1259
|
+
if _err.code != 0:
|
|
1260
|
+
raise FactoryException(_err.what)
|
|
1261
|
+
|
|
1262
|
+
def parent(self) -> Optional["Study"]:
|
|
1263
|
+
study_ptr = Study()
|
|
1264
|
+
_err = Error()
|
|
1265
|
+
ref = factorylib.lib.psrd_object_get_parent(self._hdr,
|
|
1266
|
+
_err.handler())
|
|
1267
|
+
if _err.code != 0:
|
|
1268
|
+
raise FactoryException(_err.what)
|
|
1269
|
+
if ref is None:
|
|
1270
|
+
return None
|
|
1271
|
+
study_ptr._hdr = ref
|
|
1272
|
+
return study_ptr
|
|
1273
|
+
|
|
1274
|
+
def referenced_by(self) -> List["DataObject"]:
|
|
1275
|
+
object_list = ValueList(False)
|
|
1276
|
+
_err = Error()
|
|
1277
|
+
ref = factorylib.lib.psrd_object_referenced_by(self._hdr,
|
|
1278
|
+
_err.handler())
|
|
1279
|
+
if _err.code != 0 or ref is None:
|
|
1280
|
+
raise FactoryException(_err.what)
|
|
1281
|
+
object_list._hdr = ref
|
|
1282
|
+
return object_list.to_list()
|
|
1283
|
+
|
|
1284
|
+
def has_code(self) -> bool:
|
|
1285
|
+
_err = Error()
|
|
1286
|
+
bool_value = ctypes.c_bool()
|
|
1287
|
+
factorylib.lib.psrd_object_has_code(self._hdr, ctypes.byref(bool_value), _err.handler())
|
|
1288
|
+
if _err.code != 0:
|
|
1289
|
+
raise FactoryException(_err.what)
|
|
1290
|
+
return bool(bool_value.value)
|
|
1291
|
+
|
|
1292
|
+
@property
|
|
1293
|
+
def code(self) -> int:
|
|
1294
|
+
_err = Error()
|
|
1295
|
+
value = ctypes.c_int()
|
|
1296
|
+
factorylib.lib.psrd_object_get_code(self._hdr,
|
|
1297
|
+
ctypes.byref(value),
|
|
1298
|
+
_err.handler())
|
|
1299
|
+
if _err.code != 0:
|
|
1300
|
+
raise FactoryException(_err.what)
|
|
1301
|
+
return value.value
|
|
1302
|
+
|
|
1303
|
+
@code.setter
|
|
1304
|
+
def code(self, value: int):
|
|
1305
|
+
_err = Error()
|
|
1306
|
+
factorylib.lib.psrd_object_set_code(self._hdr, value,
|
|
1307
|
+
_err.handler())
|
|
1308
|
+
if _err.code != 0:
|
|
1309
|
+
raise FactoryException(_err.what)
|
|
1310
|
+
|
|
1311
|
+
@code.deleter
|
|
1312
|
+
def code(self):
|
|
1313
|
+
raise AttributeError("do not delete code")
|
|
1314
|
+
|
|
1315
|
+
@property
|
|
1316
|
+
def type(self) -> str:
|
|
1317
|
+
err = Error()
|
|
1318
|
+
size = factorylib.lib.psrd_object_get_type(self._hdr, None,
|
|
1319
|
+
0, err.handler())
|
|
1320
|
+
if err.code != 0:
|
|
1321
|
+
raise FactoryException(err.what)
|
|
1322
|
+
buffer = ctypes.create_string_buffer(size)
|
|
1323
|
+
factorylib.lib.psrd_object_get_type(self._hdr, buffer,
|
|
1324
|
+
size, err.handler())
|
|
1325
|
+
if err.code != 0:
|
|
1326
|
+
raise FactoryException(err.what)
|
|
1327
|
+
return _from_c_str(buffer.value)
|
|
1328
|
+
|
|
1329
|
+
@type.setter
|
|
1330
|
+
def type(self, value: str):
|
|
1331
|
+
raise AttributeError("do not set type")
|
|
1332
|
+
|
|
1333
|
+
@type.deleter
|
|
1334
|
+
def type(self):
|
|
1335
|
+
raise AttributeError("do not delete type")
|
|
1336
|
+
|
|
1337
|
+
@property
|
|
1338
|
+
def key(self) -> str:
|
|
1339
|
+
err = Error()
|
|
1340
|
+
size = factorylib.lib.psrd_object_get_key(self._hdr, None,
|
|
1341
|
+
0, err.handler())
|
|
1342
|
+
if err.code != 0:
|
|
1343
|
+
raise FactoryException(err.what)
|
|
1344
|
+
buffer = ctypes.create_string_buffer(size)
|
|
1345
|
+
factorylib.lib.psrd_object_get_key(self._hdr, buffer,
|
|
1346
|
+
size, err.handler())
|
|
1347
|
+
if err.code == 0:
|
|
1348
|
+
return _from_c_str(buffer.value)
|
|
1349
|
+
raise FactoryException(err.what)
|
|
1350
|
+
|
|
1351
|
+
@key.setter
|
|
1352
|
+
def key(self, value: str):
|
|
1353
|
+
err = Error()
|
|
1354
|
+
factorylib.lib.psrd_object_set_key(self._hdr,
|
|
1355
|
+
_c_str(value),
|
|
1356
|
+
_bytes(value),
|
|
1357
|
+
err.handler())
|
|
1358
|
+
if err.code != 0:
|
|
1359
|
+
raise FactoryException(err.what)
|
|
1360
|
+
|
|
1361
|
+
@key.deleter
|
|
1362
|
+
def key(self):
|
|
1363
|
+
raise AttributeError("do not delete key")
|
|
1364
|
+
|
|
1365
|
+
def has_name(self) -> bool:
|
|
1366
|
+
_err = Error()
|
|
1367
|
+
bool_value = ctypes.c_bool()
|
|
1368
|
+
factorylib.lib.psrd_object_has_name(self._hdr, ctypes.byref(bool_value), _err.handler())
|
|
1369
|
+
if _err.code != 0:
|
|
1370
|
+
raise FactoryException(_err.what)
|
|
1371
|
+
return bool(bool_value.value)
|
|
1372
|
+
|
|
1373
|
+
@property
|
|
1374
|
+
def name(self) -> str:
|
|
1375
|
+
err = Error()
|
|
1376
|
+
size = factorylib.lib.psrd_object_get_name(self._hdr, None,
|
|
1377
|
+
0, err.handler())
|
|
1378
|
+
if err.code != 0:
|
|
1379
|
+
raise FactoryException(err.what)
|
|
1380
|
+
buffer = ctypes.create_string_buffer(size)
|
|
1381
|
+
factorylib.lib.psrd_object_get_name(self._hdr, buffer,
|
|
1382
|
+
size, err.handler())
|
|
1383
|
+
if err.code == 0:
|
|
1384
|
+
return _from_c_str(buffer.value)
|
|
1385
|
+
raise FactoryException(err.what)
|
|
1386
|
+
|
|
1387
|
+
@name.setter
|
|
1388
|
+
def name(self, value: str):
|
|
1389
|
+
err = Error()
|
|
1390
|
+
factorylib.lib.psrd_object_set_name(self._hdr,
|
|
1391
|
+
_c_str(value),
|
|
1392
|
+
_bytes(value),
|
|
1393
|
+
err.handler())
|
|
1394
|
+
if err.code != 0:
|
|
1395
|
+
raise FactoryException(err.what)
|
|
1396
|
+
|
|
1397
|
+
@name.deleter
|
|
1398
|
+
def name(self):
|
|
1399
|
+
raise AttributeError("do not delete name")
|
|
1400
|
+
|
|
1401
|
+
def has_id(self) -> bool:
|
|
1402
|
+
_err = Error()
|
|
1403
|
+
bool_value = ctypes.c_bool()
|
|
1404
|
+
factorylib.lib.psrd_object_has_id(self._hdr, ctypes.byref(bool_value), _err.handler())
|
|
1405
|
+
if _err.code != 0:
|
|
1406
|
+
raise FactoryException(_err.what)
|
|
1407
|
+
return bool(bool_value.value)
|
|
1408
|
+
|
|
1409
|
+
@property
|
|
1410
|
+
def id(self) -> str:
|
|
1411
|
+
err = Error()
|
|
1412
|
+
size = factorylib.lib.psrd_object_get_id(self._hdr, None,
|
|
1413
|
+
0, err.handler())
|
|
1414
|
+
if err.code != 0:
|
|
1415
|
+
raise FactoryException(err.what)
|
|
1416
|
+
buffer = ctypes.create_string_buffer(size)
|
|
1417
|
+
factorylib.lib.psrd_object_get_id(self._hdr, buffer,
|
|
1418
|
+
size, err.handler())
|
|
1419
|
+
if err.code == 0:
|
|
1420
|
+
return _from_c_str(buffer.value)
|
|
1421
|
+
raise FactoryException(err.what)
|
|
1422
|
+
|
|
1423
|
+
@id.setter
|
|
1424
|
+
def id(self, value: str):
|
|
1425
|
+
_err = Error()
|
|
1426
|
+
factorylib.lib.psrd_object_set_id(self._hdr,
|
|
1427
|
+
_c_str(value),
|
|
1428
|
+
_bytes(value),
|
|
1429
|
+
_err.handler())
|
|
1430
|
+
if _err.code != 0:
|
|
1431
|
+
raise FactoryException(_err.what)
|
|
1432
|
+
|
|
1433
|
+
@id.deleter
|
|
1434
|
+
def id(self):
|
|
1435
|
+
raise AttributeError("do not delete id")
|
|
1436
|
+
|
|
1437
|
+
|
|
1438
|
+
class Context(DataObject):
|
|
1439
|
+
@staticmethod
|
|
1440
|
+
def default_context() -> "Context":
|
|
1441
|
+
_check_basic_data_initialized()
|
|
1442
|
+
context = Context()
|
|
1443
|
+
err = Error()
|
|
1444
|
+
ref = factorylib.lib.psrd_get_default_context(err.handler())
|
|
1445
|
+
if err.code != 0 or ref is None:
|
|
1446
|
+
raise FactoryException(err.what)
|
|
1447
|
+
context._hdr = ref
|
|
1448
|
+
return context
|
|
1449
|
+
|
|
1450
|
+
@staticmethod
|
|
1451
|
+
def create() -> "Context":
|
|
1452
|
+
context_obj = create("Context", None)
|
|
1453
|
+
context = Context()
|
|
1454
|
+
context._hdr = context_obj._hdr
|
|
1455
|
+
context_obj._hdr = None
|
|
1456
|
+
return context
|
|
1457
|
+
|
|
1458
|
+
def __repr__(self):
|
|
1459
|
+
properties = self.as_dict()
|
|
1460
|
+
props_str = ', '.join(f"{key}={repr(value)}" for key, value in properties.items())
|
|
1461
|
+
return f"psr.factory.Context({props_str})"
|
|
1462
|
+
|
|
1463
|
+
|
|
1464
|
+
class Study(_BaseObject):
|
|
1465
|
+
def __init__(self):
|
|
1466
|
+
super().__init__()
|
|
1467
|
+
|
|
1468
|
+
def __del__(self):
|
|
1469
|
+
if self._hdr is not None:
|
|
1470
|
+
factorylib.lib.psrd_free_study(self._hdr)
|
|
1471
|
+
|
|
1472
|
+
def __hash__(self):
|
|
1473
|
+
return factorylib.lib.psrd_study_get_handler(self._hdr)
|
|
1474
|
+
|
|
1475
|
+
def __eq__(self, other: "Study"):
|
|
1476
|
+
_err = Error()
|
|
1477
|
+
value = ctypes.c_bool()
|
|
1478
|
+
if self._hdr == other.handler():
|
|
1479
|
+
return True
|
|
1480
|
+
factorylib.lib.psrd_study_is_equals_to(self._hdr,
|
|
1481
|
+
other.handler(),
|
|
1482
|
+
ctypes.byref(value),
|
|
1483
|
+
_err.handler())
|
|
1484
|
+
if _err.code != 0:
|
|
1485
|
+
raise FactoryException(_err.what)
|
|
1486
|
+
return bool(value.value)
|
|
1487
|
+
|
|
1488
|
+
def __copy__(self):
|
|
1489
|
+
raise NotImplementedError()
|
|
1490
|
+
|
|
1491
|
+
def __deepcopy__(self, memo_dict=None):
|
|
1492
|
+
dest = Study()
|
|
1493
|
+
_err = Error()
|
|
1494
|
+
ref = factorylib.lib.psrd_study_clone(self.handler(),
|
|
1495
|
+
_err.handler())
|
|
1496
|
+
if _err.code != 0 or ref is None:
|
|
1497
|
+
raise FactoryException(_err.what)
|
|
1498
|
+
dest._hdr = ref
|
|
1499
|
+
return dest
|
|
1500
|
+
|
|
1501
|
+
def create(self, object_type: str) -> DataObject:
|
|
1502
|
+
_check_basic_data_initialized()
|
|
1503
|
+
_check_study_data_initialized()
|
|
1504
|
+
return create(object_type, self.context)
|
|
1505
|
+
|
|
1506
|
+
|
|
1507
|
+
@staticmethod
|
|
1508
|
+
def help():
|
|
1509
|
+
return help("Study")
|
|
1510
|
+
|
|
1511
|
+
def clone(self) -> "Study":
|
|
1512
|
+
return copy.deepcopy(self)
|
|
1513
|
+
|
|
1514
|
+
@staticmethod
|
|
1515
|
+
def create_object(model_or_context: Union[str, Context, dict, None],
|
|
1516
|
+
blocks: Optional[int] = None):
|
|
1517
|
+
_check_basic_data_initialized()
|
|
1518
|
+
_check_study_data_initialized()
|
|
1519
|
+
err = Error()
|
|
1520
|
+
context = _get_context(model_or_context, blocks)
|
|
1521
|
+
study = Study()
|
|
1522
|
+
study._hdr = factorylib.lib.psrd_study_create(context.handler(),
|
|
1523
|
+
err.handler())
|
|
1524
|
+
if err.code != 0:
|
|
1525
|
+
raise FactoryException(err.what)
|
|
1526
|
+
return study
|
|
1527
|
+
|
|
1528
|
+
@staticmethod
|
|
1529
|
+
def load(study_path: PathLike, model_or_context: Union[str, Context, None],
|
|
1530
|
+
settings_only: bool = False,
|
|
1531
|
+
options: Optional[Union[dict, "Value", "DataObject"]] = None):
|
|
1532
|
+
if not isinstance(options, (DataObject, type(None))):
|
|
1533
|
+
raise TypeError("options must be a DataObject or None.")
|
|
1534
|
+
_check_basic_data_initialized()
|
|
1535
|
+
_check_study_data_initialized()
|
|
1536
|
+
study_path = str(study_path)
|
|
1537
|
+
context = _get_context(model_or_context, None)
|
|
1538
|
+
error = Error()
|
|
1539
|
+
options_value = _get_arg_object(options)
|
|
1540
|
+
study = Study()
|
|
1541
|
+
if not settings_only:
|
|
1542
|
+
load_fn = factorylib.lib.psrd_study_load
|
|
1543
|
+
else:
|
|
1544
|
+
load_fn = factorylib.lib.psrd_study_load_settings
|
|
1545
|
+
study._hdr = load_fn(_c_str(study_path), _bytes(study_path),
|
|
1546
|
+
options_value.handler(), context.handler(),
|
|
1547
|
+
error.handler())
|
|
1548
|
+
if error.code != 0:
|
|
1549
|
+
raise FactoryException(error.what)
|
|
1550
|
+
return study
|
|
1551
|
+
|
|
1552
|
+
def save(self, output_path: PathLike,
|
|
1553
|
+
options: Optional[Union[dict, Value, DataObject]] = None):
|
|
1554
|
+
output_path = str(output_path)
|
|
1555
|
+
error = Error()
|
|
1556
|
+
options_value = _get_arg_object(options)
|
|
1557
|
+
factorylib.lib.psrd_study_save(self._hdr,
|
|
1558
|
+
_c_str(output_path), _bytes(output_path),
|
|
1559
|
+
options_value.handler(),
|
|
1560
|
+
error.handler())
|
|
1561
|
+
if error.code != 0:
|
|
1562
|
+
raise FactoryException(error.what)
|
|
1563
|
+
|
|
1564
|
+
def save_settings(self, output_path: PathLike,
|
|
1565
|
+
options: Optional[Union[dict, Value, DataObject]] = None):
|
|
1566
|
+
output_path = str(output_path)
|
|
1567
|
+
error = Error()
|
|
1568
|
+
options_value = _get_arg_object(options)
|
|
1569
|
+
factorylib.lib.psrd_study_save_settings(self._hdr, _c_str(output_path),
|
|
1570
|
+
_bytes(output_path),
|
|
1571
|
+
options_value.handler(),
|
|
1572
|
+
error.handler())
|
|
1573
|
+
if error.code != 0:
|
|
1574
|
+
raise FactoryException(error.what)
|
|
1575
|
+
|
|
1576
|
+
@property
|
|
1577
|
+
def context(self) -> "Context":
|
|
1578
|
+
_check_basic_data_initialized()
|
|
1579
|
+
_check_study_data_initialized()
|
|
1580
|
+
obj = Context()
|
|
1581
|
+
error = Error()
|
|
1582
|
+
ref = factorylib.lib.psrd_study_context(self._hdr,
|
|
1583
|
+
error.handler())
|
|
1584
|
+
if error.code != 0 or ref is None:
|
|
1585
|
+
raise FactoryException(error.what)
|
|
1586
|
+
obj._hdr = ref
|
|
1587
|
+
return obj
|
|
1588
|
+
|
|
1589
|
+
def get(self, expression: str) -> ValueLike:
|
|
1590
|
+
value = Value()
|
|
1591
|
+
error = Error()
|
|
1592
|
+
factorylib.lib.psrd_study_get_value(self._hdr,
|
|
1593
|
+
_c_str(expression),
|
|
1594
|
+
value.handler(),
|
|
1595
|
+
error.handler())
|
|
1596
|
+
if error.code != 0:
|
|
1597
|
+
raise FactoryException(error.what)
|
|
1598
|
+
return value.get()
|
|
1599
|
+
|
|
1600
|
+
def get_at(self, expression: str, range_expr: DateLike) -> ValueLike:
|
|
1601
|
+
if not isinstance(range_expr, (str, dt.datetime)):
|
|
1602
|
+
raise FactoryException("range_expr must be a string or datetime object.")
|
|
1603
|
+
value = Value()
|
|
1604
|
+
error = Error()
|
|
1605
|
+
range_value = Value()
|
|
1606
|
+
range_value.set(range_expr)
|
|
1607
|
+
factorylib.lib.psrd_study_get_value_at(self._hdr,
|
|
1608
|
+
_c_str(expression),
|
|
1609
|
+
range_value.handler(),
|
|
1610
|
+
value.handler(),
|
|
1611
|
+
error.handler())
|
|
1612
|
+
if error.code != 0:
|
|
1613
|
+
raise FactoryException(error.what)
|
|
1614
|
+
return value.get()
|
|
1615
|
+
|
|
1616
|
+
def as_dict(self) -> Dict[str, ValueLike]:
|
|
1617
|
+
value_dict = ValueDict()
|
|
1618
|
+
error = Error()
|
|
1619
|
+
handler = factorylib.lib.psrd_study_get_as_dict(self._hdr,
|
|
1620
|
+
error.handler())
|
|
1621
|
+
if error.code != 0 or handler is None:
|
|
1622
|
+
raise FactoryException(error.what)
|
|
1623
|
+
value_dict._hdr = handler
|
|
1624
|
+
return value_dict.to_dict()
|
|
1625
|
+
|
|
1626
|
+
def from_dict(self, input_dict: Dict[str, any]):
|
|
1627
|
+
value_dict = ValueDict.from_dict(input_dict)
|
|
1628
|
+
error = Error()
|
|
1629
|
+
factorylib.lib.psrd_study_set_from_dict(self._hdr, value_dict.handler(),
|
|
1630
|
+
error.handler())
|
|
1631
|
+
if error.code != 0:
|
|
1632
|
+
raise FactoryException(error.what)
|
|
1633
|
+
|
|
1634
|
+
def add(self, obj: DataObject):
|
|
1635
|
+
if not isinstance(obj, DataObject):
|
|
1636
|
+
raise TypeError("obj must be a DataObject.")
|
|
1637
|
+
error = Error()
|
|
1638
|
+
factorylib.lib.psrd_study_add(self._hdr,
|
|
1639
|
+
obj.handler(),
|
|
1640
|
+
error.handler())
|
|
1641
|
+
if error.code != 0:
|
|
1642
|
+
raise FactoryException(error.what)
|
|
1643
|
+
|
|
1644
|
+
def remove(self, obj: DataObject):
|
|
1645
|
+
if not isinstance(obj, DataObject):
|
|
1646
|
+
raise TypeError("obj must be a DataObject.")
|
|
1647
|
+
error = Error()
|
|
1648
|
+
factorylib.lib.psrd_study_remove(self._hdr,
|
|
1649
|
+
obj.handler(),
|
|
1650
|
+
error.handler())
|
|
1651
|
+
if error.code != 0:
|
|
1652
|
+
raise FactoryException(error.what)
|
|
1653
|
+
|
|
1654
|
+
def get_all_objects(self) -> List[DataObject]:
|
|
1655
|
+
object_list = ValueList(False)
|
|
1656
|
+
error = Error()
|
|
1657
|
+
ref = factorylib.lib.psrd_study_get_all_objects(self._hdr,
|
|
1658
|
+
error.handler())
|
|
1659
|
+
if error.code != 0 or ref is None:
|
|
1660
|
+
raise FactoryException(error.what)
|
|
1661
|
+
object_list._hdr = ref
|
|
1662
|
+
return object_list.to_list()
|
|
1663
|
+
|
|
1664
|
+
def get_by_key(self) -> Optional[DataObject]:
|
|
1665
|
+
object_value = Value()
|
|
1666
|
+
error = Error()
|
|
1667
|
+
factorylib.lib.psrd_study_get_object_by_key(self._hdr,
|
|
1668
|
+
object_value.handler(),
|
|
1669
|
+
error.handler())
|
|
1670
|
+
if error.code != 0:
|
|
1671
|
+
raise FactoryException(error.what)
|
|
1672
|
+
obj = object_value.get()
|
|
1673
|
+
if isinstance(obj, DataObject):
|
|
1674
|
+
return obj
|
|
1675
|
+
return None
|
|
1676
|
+
|
|
1677
|
+
def get_key_object_map(self) -> Dict[str, DataObject]:
|
|
1678
|
+
object_dict = ValueDict()
|
|
1679
|
+
error = Error()
|
|
1680
|
+
ref = factorylib.lib.psrd_study_get_key_object_map(self._hdr,
|
|
1681
|
+
error.handler())
|
|
1682
|
+
if error.code != 0 or ref is None:
|
|
1683
|
+
raise FactoryException(error.what)
|
|
1684
|
+
object_dict._hdr = ref
|
|
1685
|
+
result = {}
|
|
1686
|
+
for key, value in object_dict.to_dict().items():
|
|
1687
|
+
if isinstance(value, DataObject):
|
|
1688
|
+
result[key] = value
|
|
1689
|
+
return result
|
|
1690
|
+
|
|
1691
|
+
def find(self, expression: str) -> List[DataObject]:
|
|
1692
|
+
object_list = ValueList(False)
|
|
1693
|
+
error = Error()
|
|
1694
|
+
handler = factorylib.lib.psrd_study_find(self._hdr,
|
|
1695
|
+
_c_str(expression),
|
|
1696
|
+
error.handler())
|
|
1697
|
+
if error.code != 0 or handler is None:
|
|
1698
|
+
raise FactoryException(error.what)
|
|
1699
|
+
object_list._hdr = handler
|
|
1700
|
+
return object_list.to_list()
|
|
1701
|
+
|
|
1702
|
+
def find_by_name(self, type_name: str, name_or_pattern: str) -> List[DataObject]:
|
|
1703
|
+
if name_or_pattern is None or name_or_pattern == "":
|
|
1704
|
+
raise DeprecationWarning("Starting from Factory 4.0.28 "
|
|
1705
|
+
"the second argument 'name_or_pattern' must be provided.\n"
|
|
1706
|
+
"Use find_by_name(type_name, name_or_pattern)")
|
|
1707
|
+
object_list = ValueList(False)
|
|
1708
|
+
error = Error()
|
|
1709
|
+
expression = f"{type_name}.{name_or_pattern}"
|
|
1710
|
+
handler = factorylib.lib.psrd_study_find(self._hdr,
|
|
1711
|
+
_c_str(expression),
|
|
1712
|
+
error.handler())
|
|
1713
|
+
if error.code != 0 or handler is None:
|
|
1714
|
+
raise FactoryException(error.what)
|
|
1715
|
+
object_list._hdr = handler
|
|
1716
|
+
return object_list.to_list()
|
|
1717
|
+
|
|
1718
|
+
def find_by_code(self, type_name: str, code: int) -> List[DataObject]:
|
|
1719
|
+
if code is None:
|
|
1720
|
+
raise DeprecationWarning("Starting from Factory 4.0.9 "
|
|
1721
|
+
"the second argument 'code' must be provided.\n"
|
|
1722
|
+
"Use find_by_code(type_name, code)")
|
|
1723
|
+
|
|
1724
|
+
object_list = ValueList(False)
|
|
1725
|
+
error = Error()
|
|
1726
|
+
handler = factorylib.lib.psrd_study_find_by_code(self._hdr,
|
|
1727
|
+
_c_str(type_name),
|
|
1728
|
+
code,
|
|
1729
|
+
error.handler())
|
|
1730
|
+
if error.code != 0 or handler is None:
|
|
1731
|
+
raise FactoryException(error.what)
|
|
1732
|
+
object_list._hdr = handler
|
|
1733
|
+
return object_list.to_list()
|
|
1734
|
+
|
|
1735
|
+
def find_by_id(self, type_name: str, id_or_pattern: str) -> List[DataObject]:
|
|
1736
|
+
if id_or_pattern is None or id_or_pattern == "":
|
|
1737
|
+
raise DeprecationWarning("Starting from Factory 5.0.0 "
|
|
1738
|
+
"the second argument 'id' must be provided.\n"
|
|
1739
|
+
"Use find_by_id(type_name, id)")
|
|
1740
|
+
expression = f"{type_name}.{id_or_pattern}"
|
|
1741
|
+
object_list = ValueList(False)
|
|
1742
|
+
error = Error()
|
|
1743
|
+
ref = factorylib.lib.psrd_study_find_by_id(self._hdr,
|
|
1744
|
+
_c_str(expression),
|
|
1745
|
+
error.handler())
|
|
1746
|
+
if error.code != 0 or ref is None:
|
|
1747
|
+
raise FactoryException(error.what)
|
|
1748
|
+
object_list._hdr = ref
|
|
1749
|
+
return object_list.to_list()
|
|
1750
|
+
|
|
1751
|
+
def set(self, expression: str, value: ValueLike):
|
|
1752
|
+
error = Error()
|
|
1753
|
+
value_object = Value()
|
|
1754
|
+
value_object.set(value)
|
|
1755
|
+
factorylib.lib.psrd_study_set_value(self._hdr,
|
|
1756
|
+
_c_str(expression),
|
|
1757
|
+
_bytes(expression),
|
|
1758
|
+
value_object.handler(),
|
|
1759
|
+
error.handler())
|
|
1760
|
+
if error.code != 0:
|
|
1761
|
+
raise FactoryException(error.what)
|
|
1762
|
+
|
|
1763
|
+
def set_at(self, expression: str, range_expr: DateLike, value: ValueLike):
|
|
1764
|
+
if not isinstance(range_expr, (str, dt.datetime)):
|
|
1765
|
+
raise FactoryException("range_expr must be a string or datetime object.")
|
|
1766
|
+
error = Error()
|
|
1767
|
+
value_object = Value()
|
|
1768
|
+
value_object.set(value)
|
|
1769
|
+
range_value = Value()
|
|
1770
|
+
range_value.set(range_expr)
|
|
1771
|
+
factorylib.lib.psrd_study_set_value_at(self._hdr,
|
|
1772
|
+
_c_str(expression),
|
|
1773
|
+
_bytes(expression),
|
|
1774
|
+
range_value.handler(),
|
|
1775
|
+
value_object.handler(),
|
|
1776
|
+
error.handler())
|
|
1777
|
+
if error.code != 0:
|
|
1778
|
+
raise FactoryException(error.what)
|
|
1779
|
+
|
|
1780
|
+
def get_df(self, expression: str) -> DataFrameLike:
|
|
1781
|
+
error = Error()
|
|
1782
|
+
df = DataFrame()
|
|
1783
|
+
factorylib.lib.psrd_study_get_table(self._hdr, df.handler(),
|
|
1784
|
+
_c_str(expression),
|
|
1785
|
+
_bytes(expression),
|
|
1786
|
+
error.handler())
|
|
1787
|
+
if error.code != 0:
|
|
1788
|
+
raise FactoryException(error.what)
|
|
1789
|
+
df_builder = _DataFrameBuilder()
|
|
1790
|
+
df_builder.build_dataframe(df)
|
|
1791
|
+
return df_builder.build_desired_dataframe_type()
|
|
1792
|
+
|
|
1793
|
+
def get_objects_values(self, object_type: str, columns: List[str]) -> DataFrameLike:
|
|
1794
|
+
error = Error()
|
|
1795
|
+
df = DataFrame()
|
|
1796
|
+
columns_list = Value()
|
|
1797
|
+
columns_list.set(columns)
|
|
1798
|
+
factorylib.lib.psrd_study_get_objects_values(self._hdr, df.handler(),
|
|
1799
|
+
_c_str(object_type),
|
|
1800
|
+
columns_list.handler(),
|
|
1801
|
+
error.handler())
|
|
1802
|
+
if error.code != 0:
|
|
1803
|
+
raise FactoryException(error.what)
|
|
1804
|
+
df_builder = _DataFrameBuilder()
|
|
1805
|
+
df_builder.build_dataframe(df)
|
|
1806
|
+
return df_builder.build_desired_dataframe_type()
|
|
1807
|
+
|
|
1808
|
+
def get_objects_values_at(self, object_type: str, columns: List[str], range_value: DateLike) -> DataFrameLike:
|
|
1809
|
+
error = Error()
|
|
1810
|
+
df = DataFrame()
|
|
1811
|
+
range_object = Value()
|
|
1812
|
+
range_object.set(range_value)
|
|
1813
|
+
columns_list = Value()
|
|
1814
|
+
columns_list.set(columns)
|
|
1815
|
+
factorylib.lib.psrd_study_get_objects_values_at(self._hdr, df.handler(),
|
|
1816
|
+
_c_str(object_type),
|
|
1817
|
+
columns_list.handler(),
|
|
1818
|
+
range_object.handler(),
|
|
1819
|
+
error.handler())
|
|
1820
|
+
if error.code != 0:
|
|
1821
|
+
raise FactoryException(error.what)
|
|
1822
|
+
df_builder = _DataFrameBuilder()
|
|
1823
|
+
df_builder.build_dataframe(df)
|
|
1824
|
+
return df_builder.build_desired_dataframe_type()
|
|
1825
|
+
|
|
1826
|
+
def descriptions(self) -> Dict[str, PropertyDescription]:
|
|
1827
|
+
error = Error()
|
|
1828
|
+
value = ctypes.c_long()
|
|
1829
|
+
factorylib.lib.psrd_study_property_description_count(self._hdr,
|
|
1830
|
+
ctypes.byref(value),
|
|
1831
|
+
error.handler())
|
|
1832
|
+
if error.code != 0:
|
|
1833
|
+
raise FactoryException(error.what)
|
|
1834
|
+
var_count = int(value.value)
|
|
1835
|
+
properties = {}
|
|
1836
|
+
for i_var in range(var_count):
|
|
1837
|
+
var = PropertyDescription()
|
|
1838
|
+
ref = factorylib.lib.psrd_study_get_property_description(self._hdr,
|
|
1839
|
+
i_var,
|
|
1840
|
+
error.handler())
|
|
1841
|
+
if error.code != 0 or ref is None:
|
|
1842
|
+
raise FactoryException(error.what)
|
|
1843
|
+
var._hdr = ref
|
|
1844
|
+
properties[var.name] = var
|
|
1845
|
+
return properties
|
|
1846
|
+
|
|
1847
|
+
def description(self, name: str) -> Optional[PropertyDescription]:
|
|
1848
|
+
_err = Error()
|
|
1849
|
+
var = PropertyDescription()
|
|
1850
|
+
ref = factorylib.lib.psrd_study_get_property_description_by_name(self._hdr,
|
|
1851
|
+
_c_str(name),
|
|
1852
|
+
_bytes(name),
|
|
1853
|
+
_err.handler())
|
|
1854
|
+
if _err.code != 0:
|
|
1855
|
+
raise FactoryException(_err.what)
|
|
1856
|
+
if ref is not None:
|
|
1857
|
+
var._hdr = ref
|
|
1858
|
+
return var
|
|
1859
|
+
return None
|
|
1860
|
+
|
|
1861
|
+
def has_property(self, expression: str) -> bool:
|
|
1862
|
+
_err = Error()
|
|
1863
|
+
bool_value = ctypes.c_bool()
|
|
1864
|
+
factorylib.lib.psrd_study_has_property(self._hdr, _c_str(expression), _bytes(expression),
|
|
1865
|
+
ctypes.byref(bool_value), _err.handler())
|
|
1866
|
+
if _err.code != 0:
|
|
1867
|
+
raise FactoryException(_err.what)
|
|
1868
|
+
return bool(bool_value.value)
|
|
1869
|
+
|
|
1870
|
+
def set_df(self, dataframe_like):
|
|
1871
|
+
if not _has_pandas():
|
|
1872
|
+
raise ModuleNotFoundError("pandas required.")
|
|
1873
|
+
dataframe_like = pandas.api.interchange.from_dataframe(dataframe_like)
|
|
1874
|
+
df_builder = _DataFrameBuilder()
|
|
1875
|
+
df = df_builder.build_from_pandas(dataframe_like)
|
|
1876
|
+
error = Error()
|
|
1877
|
+
factorylib.lib.psrd_study_set_table(self._hdr, df.handler(),
|
|
1878
|
+
error.handler())
|
|
1879
|
+
if error.code != 0:
|
|
1880
|
+
raise FactoryException(error.what)
|
|
1881
|
+
|
|
1882
|
+
def clear_values(self, expression: str):
|
|
1883
|
+
error = Error()
|
|
1884
|
+
factorylib.lib.psrd_study_clear_values(self._hdr,
|
|
1885
|
+
_c_str(expression),
|
|
1886
|
+
_bytes(expression),
|
|
1887
|
+
error.handler())
|
|
1888
|
+
if error.code != 0:
|
|
1889
|
+
raise FactoryException(error.what)
|
|
1890
|
+
|
|
1891
|
+
|
|
1892
|
+
def _is_int64(value):
|
|
1893
|
+
return isinstance(value, int) or isinstance(value, numpy.int64) or (isinstance(value, numpy.ndarray) and value.dtype == numpy.int64)
|
|
1894
|
+
|
|
1895
|
+
def _is_float32(value):
|
|
1896
|
+
return isinstance(value, (numpy.float32,)) or (isinstance(value, numpy.ndarray) and value.dtype == numpy.float32)
|
|
1897
|
+
|
|
1898
|
+
def _is_float64(value):
|
|
1899
|
+
return isinstance(value, (numpy.float64, float)) or (isinstance(value, numpy.ndarray) and value.dtype == numpy.float64)
|
|
1900
|
+
|
|
1901
|
+
|
|
1902
|
+
def _pandas_dtype_to_column_type(dtype: str) -> int:
|
|
1903
|
+
if dtype == "object":
|
|
1904
|
+
return 0
|
|
1905
|
+
elif dtype == "int32":
|
|
1906
|
+
return 1
|
|
1907
|
+
elif dtype == "int64":
|
|
1908
|
+
return 2
|
|
1909
|
+
elif dtype == "float32":
|
|
1910
|
+
return 3
|
|
1911
|
+
elif dtype == "float64":
|
|
1912
|
+
return 4
|
|
1913
|
+
elif dtype == "string":
|
|
1914
|
+
return 5
|
|
1915
|
+
elif dtype == "datetime64[ns]":
|
|
1916
|
+
return 6
|
|
1917
|
+
else:
|
|
1918
|
+
raise FactoryException(f"Unsupported pandas dtype \"{dtype}\".")
|
|
1919
|
+
|
|
1920
|
+
|
|
1921
|
+
def _polars_dtype_to_column_type(dtype: "polars.datatypes.classes.DataTypeClass") -> int:
|
|
1922
|
+
if dtype == polars.Int32:
|
|
1923
|
+
return 1
|
|
1924
|
+
if dtype == polars.Int64:
|
|
1925
|
+
return 2
|
|
1926
|
+
if dtype == polars.Float64:
|
|
1927
|
+
return 3
|
|
1928
|
+
if dtype == polars.Float64:
|
|
1929
|
+
return 4
|
|
1930
|
+
if dtype == polars.String:
|
|
1931
|
+
return 5
|
|
1932
|
+
if dtype == polars.Boolean:
|
|
1933
|
+
return 1 # TODO: create a boolean column type
|
|
1934
|
+
else:
|
|
1935
|
+
raise FactoryException(f"Unsupported polars dtype \"{dtype}\".")
|
|
1936
|
+
|
|
1937
|
+
|
|
1938
|
+
class _DataFrameBuilder:
|
|
1939
|
+
def __init__(self):
|
|
1940
|
+
self.indices: List[Optional[_TableColumn]] = []
|
|
1941
|
+
self.columns: List[Optional[_TableColumn]] = []
|
|
1942
|
+
self.column_names: List[str] = []
|
|
1943
|
+
self.index_names: List[str] = []
|
|
1944
|
+
self.column_types: List[int] = []
|
|
1945
|
+
self.index_types: List[int] = []
|
|
1946
|
+
self._not_built = True
|
|
1947
|
+
self._value: Optional[Value] = None
|
|
1948
|
+
self._error: Optional[Error] = None
|
|
1949
|
+
|
|
1950
|
+
def build_dataframe(self, df: "DataFrame"):
|
|
1951
|
+
self._error = Error()
|
|
1952
|
+
name_buffer_length = 200
|
|
1953
|
+
columns_count = ctypes.c_long()
|
|
1954
|
+
factorylib.lib.psrd_table_columns_count(df.handler(),
|
|
1955
|
+
ctypes.byref(columns_count),
|
|
1956
|
+
self._error.handler())
|
|
1957
|
+
if self._error.code != 0:
|
|
1958
|
+
raise FactoryException(self._error.what)
|
|
1959
|
+
columns_count = columns_count.value
|
|
1960
|
+
|
|
1961
|
+
rows_count = ctypes.c_long()
|
|
1962
|
+
factorylib.lib.psrd_table_rows_count(df.handler(),
|
|
1963
|
+
ctypes.byref(rows_count),
|
|
1964
|
+
self._error.handler())
|
|
1965
|
+
if self._error.code != 0:
|
|
1966
|
+
raise FactoryException(self._error.what)
|
|
1967
|
+
rows_count = rows_count.value
|
|
1968
|
+
|
|
1969
|
+
indices_count = ctypes.c_long()
|
|
1970
|
+
factorylib.lib.psrd_table_index_count(df.handler(),
|
|
1971
|
+
ctypes.byref(indices_count),
|
|
1972
|
+
self._error.handler())
|
|
1973
|
+
if self._error.code != 0:
|
|
1974
|
+
raise FactoryException(self._error.what)
|
|
1975
|
+
indices_count = indices_count.value
|
|
1976
|
+
|
|
1977
|
+
value = Value()
|
|
1978
|
+
buffer = ctypes.create_string_buffer(name_buffer_length)
|
|
1979
|
+
|
|
1980
|
+
self.indices = [_TableColumn() for _ in range(indices_count)]
|
|
1981
|
+
for index in range(indices_count):
|
|
1982
|
+
factorylib.lib.psrd_table_index_get_name(df.handler(), index,
|
|
1983
|
+
buffer, name_buffer_length,
|
|
1984
|
+
self._error.handler())
|
|
1985
|
+
if self._error.code != 0:
|
|
1986
|
+
raise FactoryException(self._error.what)
|
|
1987
|
+
self.indices[index].name = _from_c_str(buffer.value)
|
|
1988
|
+
|
|
1989
|
+
self.indices[index].values = [None] * rows_count
|
|
1990
|
+
for i_row in range(0, rows_count):
|
|
1991
|
+
factorylib.lib.psrd_table_index_get_value(df.handler(), index,
|
|
1992
|
+
i_row, value.handler(),
|
|
1993
|
+
self._error.handler())
|
|
1994
|
+
if self._error.code != 0:
|
|
1995
|
+
raise FactoryException(self._error.what)
|
|
1996
|
+
self.indices[index].values[i_row] = value.get()
|
|
1997
|
+
|
|
1998
|
+
self.columns = [_TableColumn() for _ in range(columns_count)]
|
|
1999
|
+
for column in range(columns_count):
|
|
2000
|
+
factorylib.lib.psrd_table_column_get_name(df.handler(), column,
|
|
2001
|
+
buffer, name_buffer_length,
|
|
2002
|
+
self._error.handler())
|
|
2003
|
+
if self._error.code != 0:
|
|
2004
|
+
raise FactoryException(self._error.what)
|
|
2005
|
+
self.columns[column].name = _from_c_str(buffer.value)
|
|
2006
|
+
|
|
2007
|
+
self.columns[column].values = [None] * rows_count
|
|
2008
|
+
for row in range(rows_count):
|
|
2009
|
+
factorylib.lib.psrd_table_column_get_value(df.handler(),
|
|
2010
|
+
column, row,
|
|
2011
|
+
value.handler(),
|
|
2012
|
+
self._error.handler())
|
|
2013
|
+
if self._error.code != 0:
|
|
2014
|
+
raise FactoryException(self._error.what)
|
|
2015
|
+
self.columns[column].values[row] = value.get()
|
|
2016
|
+
self._not_built = False
|
|
2017
|
+
|
|
2018
|
+
def build_dataframe_of_integral_types(self, df: "DataFrame"):
|
|
2019
|
+
self._error = Error()
|
|
2020
|
+
name_buffer_length = 200
|
|
2021
|
+
columns_count = ctypes.c_long()
|
|
2022
|
+
factorylib.lib.psrd_table_columns_count(df.handler(),
|
|
2023
|
+
ctypes.byref(columns_count),
|
|
2024
|
+
self._error.handler())
|
|
2025
|
+
if self._error.code != 0:
|
|
2026
|
+
raise FactoryException(self._error.what)
|
|
2027
|
+
columns_count = columns_count.value
|
|
2028
|
+
|
|
2029
|
+
rows_count = ctypes.c_long()
|
|
2030
|
+
factorylib.lib.psrd_table_rows_count(df.handler(),
|
|
2031
|
+
ctypes.byref(rows_count),
|
|
2032
|
+
self._error.handler())
|
|
2033
|
+
if self._error.code != 0:
|
|
2034
|
+
raise FactoryException(self._error.what)
|
|
2035
|
+
rows_count = rows_count.value
|
|
2036
|
+
|
|
2037
|
+
indices_count = ctypes.c_long()
|
|
2038
|
+
factorylib.lib.psrd_table_index_count(df.handler(),
|
|
2039
|
+
ctypes.byref(indices_count),
|
|
2040
|
+
self._error.handler())
|
|
2041
|
+
if self._error.code != 0:
|
|
2042
|
+
raise FactoryException(self._error.what)
|
|
2043
|
+
indices_count = indices_count.value
|
|
2044
|
+
|
|
2045
|
+
buffer = ctypes.create_string_buffer(name_buffer_length)
|
|
2046
|
+
|
|
2047
|
+
self.indices = [_TableColumn() for _ in range(indices_count)]
|
|
2048
|
+
for index in range(indices_count):
|
|
2049
|
+
factorylib.lib.psrd_table_index_get_name(df.handler(), index,
|
|
2050
|
+
buffer, name_buffer_length,
|
|
2051
|
+
self._error.handler())
|
|
2052
|
+
if self._error.code != 0:
|
|
2053
|
+
raise FactoryException(self._error.what)
|
|
2054
|
+
index_name = _from_c_str(buffer.value)
|
|
2055
|
+
self.indices[index].name = index_name
|
|
2056
|
+
self.indices[index].values = [None] * rows_count
|
|
2057
|
+
if index_name in ("date", "datetime"):
|
|
2058
|
+
array_values = (ctypes.c_longlong * rows_count)()
|
|
2059
|
+
factorylib.lib.psrd_table_index_get_date_values(df.handler(),
|
|
2060
|
+
index,
|
|
2061
|
+
array_values,
|
|
2062
|
+
self._error.handler())
|
|
2063
|
+
if self._error.code != 0:
|
|
2064
|
+
raise FactoryException(self._error.what)
|
|
2065
|
+
# convert array values to python datetime
|
|
2066
|
+
if _date_transform is None:
|
|
2067
|
+
raise FactoryException("Factory is not initialized correctly.")
|
|
2068
|
+
self.indices[index].values = [dt.datetime.fromtimestamp(value - _date_transform, dt.UTC) for value in array_values]
|
|
2069
|
+
else:
|
|
2070
|
+
array_values = (ctypes.c_int * rows_count)()
|
|
2071
|
+
factorylib.lib.psrd_table_index_get_int32_values(df.handler(),
|
|
2072
|
+
index,
|
|
2073
|
+
array_values,
|
|
2074
|
+
self._error.handler())
|
|
2075
|
+
if self._error.code != 0:
|
|
2076
|
+
raise FactoryException(self._error.what)
|
|
2077
|
+
self.indices[index].values = array_values
|
|
2078
|
+
|
|
2079
|
+
self.columns = [_TableColumn() for _ in range(columns_count)]
|
|
2080
|
+
for column in range(columns_count):
|
|
2081
|
+
factorylib.lib.psrd_table_column_get_name(df.handler(), column,
|
|
2082
|
+
buffer, name_buffer_length,
|
|
2083
|
+
self._error.handler())
|
|
2084
|
+
if self._error.code != 0:
|
|
2085
|
+
raise FactoryException(self._error.what)
|
|
2086
|
+
self.columns[column].name = _from_c_str(buffer.value)
|
|
2087
|
+
|
|
2088
|
+
array_values = (ctypes.c_double * rows_count)()
|
|
2089
|
+
factorylib.lib.psrd_table_column_get_float64_values(df.handler(),
|
|
2090
|
+
column,
|
|
2091
|
+
array_values,
|
|
2092
|
+
self._error.handler())
|
|
2093
|
+
if self._error.code != 0:
|
|
2094
|
+
raise FactoryException(self._error.what)
|
|
2095
|
+
self.columns[column].values = array_values
|
|
2096
|
+
self._not_built = False
|
|
2097
|
+
|
|
2098
|
+
def build_desired_dataframe_type(self, **kwargs) -> DataFrameLike:
|
|
2099
|
+
if _default_dataframe_type == "pandas":
|
|
2100
|
+
return self.build_pandas_dataframe(**kwargs)
|
|
2101
|
+
elif _default_dataframe_type == "polars":
|
|
2102
|
+
return self.build_polars_dataframe(**kwargs)
|
|
2103
|
+
elif _default_dataframe_type == "factory":
|
|
2104
|
+
raise NotImplementedError("Returning a psr.factory.DataFrame not implemented yet.")
|
|
2105
|
+
else:
|
|
2106
|
+
raise FactoryException(f"Unsupported default dataframe type \"{_default_dataframe_type}\".")
|
|
2107
|
+
|
|
2108
|
+
def build_pandas_dataframe(self, **kwargs) -> "pandas.DataFrame":
|
|
2109
|
+
use_object_dtype = kwargs.get("use_object_dtype", True)
|
|
2110
|
+
if not _has_pandas():
|
|
2111
|
+
raise ModuleNotFoundError("pandas required.")
|
|
2112
|
+
def convert_column_values(values):
|
|
2113
|
+
if isinstance(values, list):
|
|
2114
|
+
return values
|
|
2115
|
+
# Looks like ctype array, smells like ctype array
|
|
2116
|
+
if hasattr(values, "_length_") and hasattr(values, "_type_"):
|
|
2117
|
+
return numpy.ctypeslib.as_array(values)
|
|
2118
|
+
return values
|
|
2119
|
+
|
|
2120
|
+
data = {column.name: convert_column_values(column.values)
|
|
2121
|
+
for column in self.columns}
|
|
2122
|
+
if len(self.indices) > 1:
|
|
2123
|
+
# TODO: store index as rows of tuples
|
|
2124
|
+
index = pandas.MultiIndex.from_tuples(
|
|
2125
|
+
[tuple(self.indices[i].values[row] for i in range(len(self.indices))) for row in range(len(self.indices[0].values))],
|
|
2126
|
+
names=[index.name for index in self.indices])
|
|
2127
|
+
elif len(self.indices) == 1:
|
|
2128
|
+
index_value_type = type(self.indices[0].values[0]) if len(self.indices[0].values) > 0 else object
|
|
2129
|
+
if index_value_type == dt.datetime:
|
|
2130
|
+
index = pandas.DatetimeIndex(self.indices[0].values, name=self.indices[0].name)
|
|
2131
|
+
else:
|
|
2132
|
+
if index_value_type == DataObject:
|
|
2133
|
+
index_value_type = object
|
|
2134
|
+
index = pandas.Index(tuple(self.indices[0].values), dtype=index_value_type, name=self.indices[0].name)
|
|
2135
|
+
else:
|
|
2136
|
+
index = None
|
|
2137
|
+
if use_object_dtype:
|
|
2138
|
+
return pandas.DataFrame(data=data, index=index, dtype=object)
|
|
2139
|
+
else:
|
|
2140
|
+
return pandas.DataFrame(data=data, index=index)
|
|
2141
|
+
|
|
2142
|
+
def build_from_pandas(self, table_data: "pandas.DataFrame") -> "DataFrame":
|
|
2143
|
+
# check if the table has indices and if its multi-index or common index
|
|
2144
|
+
if isinstance(table_data.index, pandas.MultiIndex):
|
|
2145
|
+
table_data_indices = table_data.index.levels
|
|
2146
|
+
elif isinstance(table_data.index, pandas.Index) and not table_data.index.empty:
|
|
2147
|
+
table_data_indices = [table_data.index]
|
|
2148
|
+
else:
|
|
2149
|
+
table_data_indices = []
|
|
2150
|
+
|
|
2151
|
+
self.column_names = table_data.columns
|
|
2152
|
+
if len(self.column_names) != len(set(self.column_names)):
|
|
2153
|
+
raise FactoryException("DataFrame contains repeated column names.")
|
|
2154
|
+
self.index_names = [index.name for index in table_data_indices]
|
|
2155
|
+
self.column_types = [_pandas_dtype_to_column_type(dtype) for dtype in table_data.dtypes]
|
|
2156
|
+
self.index_types = [_pandas_dtype_to_column_type(index.dtype) for index in table_data_indices]
|
|
2157
|
+
replaced_name = False
|
|
2158
|
+
for i, name in enumerate(self.index_names):
|
|
2159
|
+
if name is None:
|
|
2160
|
+
self.index_names[i] = 'date'
|
|
2161
|
+
replaced_name = True
|
|
2162
|
+
rows = len(table_data.index)
|
|
2163
|
+
df = self._pre_build_generic(rows, self.index_types, self.column_types)
|
|
2164
|
+
|
|
2165
|
+
test_conversion_types = {
|
|
2166
|
+
pandas.api.types.is_integer_dtype: numpy.int32,
|
|
2167
|
+
_is_int64: numpy.int64,
|
|
2168
|
+
_is_float32: numpy.float32,
|
|
2169
|
+
_is_float64: numpy.float64,
|
|
2170
|
+
pandas.api.types.is_datetime64_any_dtype: numpy.datetime64,
|
|
2171
|
+
}
|
|
2172
|
+
convert_to_ctype = {
|
|
2173
|
+
numpy.int32: ctypes.c_int32,
|
|
2174
|
+
numpy.int64: ctypes.c_int64,
|
|
2175
|
+
numpy.float32: ctypes.c_float,
|
|
2176
|
+
numpy.float64: ctypes.c_double,
|
|
2177
|
+
numpy.datetime64: ctypes.c_longlong,
|
|
2178
|
+
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
# Check column value types - if they support, call efficient set methods
|
|
2182
|
+
column_convert_to = {}
|
|
2183
|
+
column_fast_set = {}
|
|
2184
|
+
for i_column, column_name in enumerate(table_data.columns):
|
|
2185
|
+
column_values = table_data[column_name]
|
|
2186
|
+
column_fast_set[column_name] = False
|
|
2187
|
+
for test_func, convert_to_type in test_conversion_types.items():
|
|
2188
|
+
if test_func(column_values):
|
|
2189
|
+
column_convert_to[column_name] = convert_to_type
|
|
2190
|
+
column_fast_set[column_name] = True
|
|
2191
|
+
break
|
|
2192
|
+
|
|
2193
|
+
if replaced_name:
|
|
2194
|
+
for i_index, name in enumerate(self.index_names):
|
|
2195
|
+
if name == "date":
|
|
2196
|
+
self.index_names[i_index] = None
|
|
2197
|
+
# check index value types
|
|
2198
|
+
index_convert_to = {}
|
|
2199
|
+
index_fast_set = {}
|
|
2200
|
+
for i_index, index_name in enumerate(self.index_names):
|
|
2201
|
+
index_fast_set[index_name] = False
|
|
2202
|
+
index_values = table_data.index.get_level_values(index_name)
|
|
2203
|
+
for test_func, convert_to_type in test_conversion_types.items():
|
|
2204
|
+
if test_func(index_values):
|
|
2205
|
+
index_convert_to[index_name] = convert_to_type
|
|
2206
|
+
index_fast_set[index_name] = True
|
|
2207
|
+
break
|
|
2208
|
+
|
|
2209
|
+
# replace None as index name with "date", the default index type.
|
|
2210
|
+
for i_index, index_name in enumerate(self.index_names):
|
|
2211
|
+
if index_name is None:
|
|
2212
|
+
self.index_names[i_index] = "date"
|
|
2213
|
+
|
|
2214
|
+
for i_index, index_name in enumerate(self.index_names):
|
|
2215
|
+
if index_name in index_convert_to.keys():
|
|
2216
|
+
convert_to_type = index_convert_to[index_name]
|
|
2217
|
+
else:
|
|
2218
|
+
convert_to_type = None
|
|
2219
|
+
if isinstance(table_data.index, pandas.MultiIndex):
|
|
2220
|
+
index_values = table_data.index.get_level_values(index_name).to_numpy(dtype=convert_to_type)
|
|
2221
|
+
else:
|
|
2222
|
+
index_values = table_data.index.to_numpy(dtype=convert_to_type)
|
|
2223
|
+
if index_name in index_fast_set.keys() and index_fast_set[index_name]:
|
|
2224
|
+
if convert_to_type == numpy.datetime64:
|
|
2225
|
+
# convert index_values to utc timezone and then to timestamp
|
|
2226
|
+
# TODO: check if original dataframe values is unaltered
|
|
2227
|
+
index_values = index_values.astype('datetime64[s]').astype(dt.datetime)
|
|
2228
|
+
# for each value, convert to timestamp
|
|
2229
|
+
if _date_transform is None:
|
|
2230
|
+
raise FactoryException("Factory is not initialized correctly.")
|
|
2231
|
+
for ix, x in enumerate(index_values):
|
|
2232
|
+
index_values[ix] = int(x.replace(tzinfo=dt.timezone.utc).timestamp() + _date_transform)
|
|
2233
|
+
# convert to int64
|
|
2234
|
+
index_values = index_values.astype(numpy.int64)
|
|
2235
|
+
ptr = index_values.ctypes.data_as(ctypes.POINTER(convert_to_ctype[convert_to_type]))
|
|
2236
|
+
factorylib.lib.psrd_table_index_set_date_values(df.handler(),
|
|
2237
|
+
i_index,
|
|
2238
|
+
ptr,
|
|
2239
|
+
self._error.handler())
|
|
2240
|
+
if self._error.code != 0:
|
|
2241
|
+
raise FactoryException(self._error.what)
|
|
2242
|
+
elif convert_to_type == numpy.int32:
|
|
2243
|
+
ptr = index_values.ctypes.data_as(ctypes.POINTER(convert_to_ctype[convert_to_type]))
|
|
2244
|
+
factorylib.lib.psrd_table_index_set_int32_values(df.handler(),
|
|
2245
|
+
i_index,
|
|
2246
|
+
ptr,
|
|
2247
|
+
self._error.handler())
|
|
2248
|
+
if self._error.code != 0:
|
|
2249
|
+
raise FactoryException(self._error.what)
|
|
2250
|
+
elif convert_to_type == numpy.int64:
|
|
2251
|
+
ptr = index_values.ctypes.data_as(ctypes.POINTER(convert_to_ctype[convert_to_type]))
|
|
2252
|
+
factorylib.lib.psrd_table_index_set_int64_values(df.handler(),
|
|
2253
|
+
i_index,
|
|
2254
|
+
ptr,
|
|
2255
|
+
self._error.handler())
|
|
2256
|
+
if self._error.code != 0:
|
|
2257
|
+
raise FactoryException(self._error.what)
|
|
2258
|
+
elif convert_to_type == numpy.float32:
|
|
2259
|
+
ptr = index_values.ctypes.data_as(ctypes.POINTER(convert_to_ctype[convert_to_type]))
|
|
2260
|
+
factorylib.lib.psrd_table_index_set_float32_values(df.handler(),
|
|
2261
|
+
i_index,
|
|
2262
|
+
ptr,
|
|
2263
|
+
self._error.handler())
|
|
2264
|
+
if self._error.code != 0:
|
|
2265
|
+
raise FactoryException(self._error.what)
|
|
2266
|
+
elif convert_to_type == numpy.float64:
|
|
2267
|
+
ptr = index_values.ctypes.data_as(ctypes.POINTER(convert_to_ctype[convert_to_type]))
|
|
2268
|
+
factorylib.lib.psrd_table_index_set_float64_values(df.handler(),
|
|
2269
|
+
i_index,
|
|
2270
|
+
ptr,
|
|
2271
|
+
self._error.handler())
|
|
2272
|
+
if self._error.code != 0:
|
|
2273
|
+
raise FactoryException(self._error.what)
|
|
2274
|
+
else:
|
|
2275
|
+
raise FactoryException("Unsupported index type: " + str(convert_to_type))
|
|
2276
|
+
else:
|
|
2277
|
+
for i_row, column_value in enumerate(index_values):
|
|
2278
|
+
self._value.set(column_value)
|
|
2279
|
+
factorylib.lib.psrd_table_index_set_value(df.handler(),
|
|
2280
|
+
i_index,
|
|
2281
|
+
i_row,
|
|
2282
|
+
self._value.handler(),
|
|
2283
|
+
self._error.handler())
|
|
2284
|
+
if self._error.code != 0:
|
|
2285
|
+
raise FactoryException(self._error.what)
|
|
2286
|
+
|
|
2287
|
+
for i_column, column_name in enumerate(self.column_names):
|
|
2288
|
+
if column_name in column_convert_to.keys():
|
|
2289
|
+
convert_to_type = column_convert_to[column_name]
|
|
2290
|
+
else:
|
|
2291
|
+
convert_to_type = None
|
|
2292
|
+
column_values = table_data[column_name].to_numpy(dtype=convert_to_type)
|
|
2293
|
+
if column_name in column_fast_set.keys() and column_fast_set[column_name]:
|
|
2294
|
+
if convert_to_type == numpy.float32:
|
|
2295
|
+
ptr = column_values.ctypes.data_as(ctypes.POINTER(convert_to_ctype[convert_to_type]))
|
|
2296
|
+
factorylib.lib.psrd_table_column_set_float32_values(df.handler(),
|
|
2297
|
+
i_column,
|
|
2298
|
+
ptr,
|
|
2299
|
+
self._error.handler())
|
|
2300
|
+
if self._error.code != 0:
|
|
2301
|
+
raise FactoryException(self._error.code)
|
|
2302
|
+
if convert_to_type == numpy.float64:
|
|
2303
|
+
ptr = column_values.ctypes.data_as(ctypes.POINTER(convert_to_ctype[convert_to_type]))
|
|
2304
|
+
factorylib.lib.psrd_table_column_set_float64_values(df.handler(),
|
|
2305
|
+
i_column,
|
|
2306
|
+
ptr,
|
|
2307
|
+
self._error.handler())
|
|
2308
|
+
if self._error.code != 0:
|
|
2309
|
+
raise FactoryException(self._error.what)
|
|
2310
|
+
elif convert_to_type == numpy.int32:
|
|
2311
|
+
ptr = column_values.ctypes.data_as(ctypes.POINTER(convert_to_ctype[convert_to_type]))
|
|
2312
|
+
factorylib.lib.psrd_table_column_set_int32_values(df.handler(),
|
|
2313
|
+
i_column,
|
|
2314
|
+
ptr,
|
|
2315
|
+
self._error.handler())
|
|
2316
|
+
if self._error.code != 0:
|
|
2317
|
+
raise FactoryException(self._error.what)
|
|
2318
|
+
elif convert_to_type == numpy.int64:
|
|
2319
|
+
ptr = column_values.ctypes.data_as(ctypes.POINTER(convert_to_ctype[convert_to_type]))
|
|
2320
|
+
factorylib.lib.psrd_table_column_set_int64_values(df.handler(),
|
|
2321
|
+
i_column,
|
|
2322
|
+
ptr,
|
|
2323
|
+
self._error.handler())
|
|
2324
|
+
if self._error.code != 0:
|
|
2325
|
+
raise FactoryException(self._error.what)
|
|
2326
|
+
else:
|
|
2327
|
+
column_values = table_data[column_name]
|
|
2328
|
+
for i_row, column_value in enumerate(column_values):
|
|
2329
|
+
self._value.set(column_value)
|
|
2330
|
+
factorylib.lib.psrd_table_column_set_value(df.handler(),
|
|
2331
|
+
i_column,
|
|
2332
|
+
i_row,
|
|
2333
|
+
self._value.handler(),
|
|
2334
|
+
self._error.handler())
|
|
2335
|
+
if self._error.code != 0:
|
|
2336
|
+
raise FactoryException(self._error.what)
|
|
2337
|
+
return df
|
|
2338
|
+
|
|
2339
|
+
def build_polars_dataframe(self, **kwargs) -> "polars.DataFrame":
|
|
2340
|
+
use_object_dtype = kwargs.get("use_object_dtype", False)
|
|
2341
|
+
if not _has_polars():
|
|
2342
|
+
raise ModuleNotFoundError("polars required.")
|
|
2343
|
+
def convert_column_values(column_name:str, values):
|
|
2344
|
+
if isinstance(values, list):
|
|
2345
|
+
return values
|
|
2346
|
+
# Looks like ctype array, smells like ctype array
|
|
2347
|
+
if hasattr(values, "_length_") and hasattr(values, "_type_"):
|
|
2348
|
+
return polars.Series(column_name, numpy.ctypeslib.as_array(values))
|
|
2349
|
+
return values
|
|
2350
|
+
|
|
2351
|
+
data = {column.name: convert_column_values(column.name, column.values)
|
|
2352
|
+
for column in self.indices + self.columns}
|
|
2353
|
+
if use_object_dtype:
|
|
2354
|
+
return polars.DataFrame({k: polars.Series(k, v, dtype=polars.Object) for k, v in data.items()})
|
|
2355
|
+
else:
|
|
2356
|
+
return polars.DataFrame(data=data)
|
|
2357
|
+
|
|
2358
|
+
def build_from_polars(self, table_data: "polars.DataFrame") -> "DataFrame":
|
|
2359
|
+
# check if the table has indices and if its multi-index or common index
|
|
2360
|
+
index_names = ("year", "week", "month", "hour", "scenario", "block", "stage", "date")
|
|
2361
|
+
column_index = 0
|
|
2362
|
+
data_columns = table_data.columns[:]
|
|
2363
|
+
if len(self.column_names) != len(set(self.column_names)):
|
|
2364
|
+
raise FactoryException("DataFrame contains repeated column names.")
|
|
2365
|
+
index_columns = []
|
|
2366
|
+
while column_index < len(data_columns):
|
|
2367
|
+
if data_columns[column_index] in index_names:
|
|
2368
|
+
index_columns.append(data_columns.pop(column_index))
|
|
2369
|
+
continue
|
|
2370
|
+
column_index += 1
|
|
2371
|
+
self.column_types = [_polars_dtype_to_column_type(table_data[column_name].dtype) for column_name in data_columns]
|
|
2372
|
+
self.index_types = [_polars_dtype_to_column_type(table_data[index_name].dtype) for index_name in index_columns]
|
|
2373
|
+
|
|
2374
|
+
self.column_names = data_columns
|
|
2375
|
+
self.index_names = index_columns
|
|
2376
|
+
rows = table_data.height
|
|
2377
|
+
df = self._pre_build_generic(rows, self.index_types, self.column_types)
|
|
2378
|
+
|
|
2379
|
+
for i_row, all_row_values in enumerate(table_data.iter_rows()):
|
|
2380
|
+
index = all_row_values[:len(index_columns)]
|
|
2381
|
+
row_values = all_row_values[len(index_columns):]
|
|
2382
|
+
self._set_row_values(df, i_row, index, row_values)
|
|
2383
|
+
return df
|
|
2384
|
+
|
|
2385
|
+
def _pre_build_generic(self, rows: int, index_types: List[int], column_types: List[int]) -> "DataFrame":
|
|
2386
|
+
df = DataFrame()
|
|
2387
|
+
self._error = Error()
|
|
2388
|
+
self._value = Value()
|
|
2389
|
+
|
|
2390
|
+
factorylib.lib.psrd_table_resize(df.handler(), rows,
|
|
2391
|
+
self._error.handler())
|
|
2392
|
+
if self._error.code != 0:
|
|
2393
|
+
raise FactoryException(self._error.what)
|
|
2394
|
+
|
|
2395
|
+
for i_index, index_type in enumerate(index_types):
|
|
2396
|
+
factorylib.lib.psrd_table_configure_index(df.handler(),
|
|
2397
|
+
i_index,
|
|
2398
|
+
index_type,
|
|
2399
|
+
self._error.handler())
|
|
2400
|
+
if self._error.code != 0:
|
|
2401
|
+
raise FactoryException(self._error.what)
|
|
2402
|
+
for i_column, column_type in enumerate(column_types):
|
|
2403
|
+
factorylib.lib.psrd_table_configure_column(df.handler(),
|
|
2404
|
+
i_column,
|
|
2405
|
+
column_type,
|
|
2406
|
+
self._error.handler())
|
|
2407
|
+
if self._error.code != 0:
|
|
2408
|
+
raise FactoryException(self._error.what)
|
|
2409
|
+
|
|
2410
|
+
# Set column names
|
|
2411
|
+
for i_column, column_name in enumerate(self.column_names):
|
|
2412
|
+
factorylib.lib.psrd_table_column_set_name(df.handler(),
|
|
2413
|
+
i_column,
|
|
2414
|
+
_c_str(column_name),
|
|
2415
|
+
_bytes(column_name),
|
|
2416
|
+
self._error.handler())
|
|
2417
|
+
if self._error.code != 0:
|
|
2418
|
+
raise FactoryException(self._error.what)
|
|
2419
|
+
|
|
2420
|
+
# Set index names
|
|
2421
|
+
for i_index, index_name in enumerate(self.index_names):
|
|
2422
|
+
factorylib.lib.psrd_table_index_set_name(df.handler(),
|
|
2423
|
+
i_index,
|
|
2424
|
+
_c_str(index_name),
|
|
2425
|
+
_bytes(index_name),
|
|
2426
|
+
self._error.handler())
|
|
2427
|
+
if self._error.code != 0:
|
|
2428
|
+
raise FactoryException(self._error.what)
|
|
2429
|
+
return df
|
|
2430
|
+
|
|
2431
|
+
def _set_row_values(self, df: "DataFrame", i_row: int, index_values: List[Union[int, float, str]], column_values: List[Union[int, float, str]]):
|
|
2432
|
+
self._value = Value()
|
|
2433
|
+
for i_index, index_value in enumerate(index_values):
|
|
2434
|
+
self._value.set(index_value)
|
|
2435
|
+
factorylib.lib.psrd_table_index_set_value(df.handler(),
|
|
2436
|
+
i_index,
|
|
2437
|
+
i_row,
|
|
2438
|
+
self._value.handler(),
|
|
2439
|
+
self._error.handler())
|
|
2440
|
+
if self._error.code != 0:
|
|
2441
|
+
raise FactoryException(self._error.what)
|
|
2442
|
+
|
|
2443
|
+
for i_column, column_value in enumerate(column_values):
|
|
2444
|
+
self._value.set(column_value)
|
|
2445
|
+
factorylib.lib.psrd_table_column_set_value(df.handler(),
|
|
2446
|
+
i_column,
|
|
2447
|
+
i_row,
|
|
2448
|
+
self._value.handler(),
|
|
2449
|
+
self._error.handler())
|
|
2450
|
+
if self._error.code != 0:
|
|
2451
|
+
raise FactoryException(self._error.what)
|
|
2452
|
+
|
|
2453
|
+
|
|
2454
|
+
class DataFrame(_BaseObject):
|
|
2455
|
+
def __init__(self):
|
|
2456
|
+
super().__init__()
|
|
2457
|
+
self._hdr = factorylib.lib.psrd_new_table()
|
|
2458
|
+
self._not_built = True
|
|
2459
|
+
|
|
2460
|
+
def __del__(self):
|
|
2461
|
+
if self._hdr is not None:
|
|
2462
|
+
factorylib.lib.psrd_free_table(self._hdr)
|
|
2463
|
+
|
|
2464
|
+
@staticmethod
|
|
2465
|
+
def load_from_file(input_file: PathLike, options: Optional[Union[dict, Value, DataObject]] = None) -> "DataFrame":
|
|
2466
|
+
input_file = str(input_file)
|
|
2467
|
+
_check_basic_data_initialized()
|
|
2468
|
+
error = Error()
|
|
2469
|
+
df = DataFrame()
|
|
2470
|
+
options_value = _get_arg_object(options)
|
|
2471
|
+
factorylib.lib.psrd_table_load(df.handler(),
|
|
2472
|
+
_c_str(input_file),
|
|
2473
|
+
_bytes(input_file),
|
|
2474
|
+
options_value.handler(),
|
|
2475
|
+
error.handler())
|
|
2476
|
+
if error.code != 0:
|
|
2477
|
+
raise FactoryException(error.what)
|
|
2478
|
+
return df
|
|
2479
|
+
|
|
2480
|
+
@staticmethod
|
|
2481
|
+
def from_dataframe(df: DataFrameLike) -> "DataFrame":
|
|
2482
|
+
_check_basic_data_initialized()
|
|
2483
|
+
df_builder = _DataFrameBuilder()
|
|
2484
|
+
if isinstance(df, DataFrame):
|
|
2485
|
+
# FIXME: implement this
|
|
2486
|
+
raise NotImplementedError("Creating a DataFrame from another psr.factory.DataFrame is not implemented.")
|
|
2487
|
+
if _has_pandas() and isinstance(df, pandas.DataFrame):
|
|
2488
|
+
dataframe_like = pandas.api.interchange.from_dataframe(df)
|
|
2489
|
+
return df_builder.build_from_pandas(dataframe_like)
|
|
2490
|
+
if _has_polars() and isinstance(df, polars.DataFrame):
|
|
2491
|
+
dataframe_like = polars.from_dataframe(df)
|
|
2492
|
+
# FIXME: needs auto tests.
|
|
2493
|
+
return df_builder.build_from_polars(dataframe_like)
|
|
2494
|
+
raise ImportError("Pandas or polars is not available. Please install pandas to use this feature.")
|
|
2495
|
+
|
|
2496
|
+
def save(self, output_file: PathLike, options: Optional[Union[dict, Value, DataObject]] = None):
|
|
2497
|
+
output_file = str(output_file)
|
|
2498
|
+
error = Error()
|
|
2499
|
+
options_value = _get_arg_object(options)
|
|
2500
|
+
factorylib.lib.psrd_table_save(self._hdr, _c_str(output_file),
|
|
2501
|
+
_bytes(output_file),
|
|
2502
|
+
options_value.handler(),
|
|
2503
|
+
error.handler())
|
|
2504
|
+
if error.code != 0:
|
|
2505
|
+
raise FactoryException(error.what)
|
|
2506
|
+
|
|
2507
|
+
def to_pandas(self) -> "pandas.DataFrame":
|
|
2508
|
+
df_builder = _DataFrameBuilder()
|
|
2509
|
+
df_builder.build_dataframe_of_integral_types(self)
|
|
2510
|
+
return df_builder.build_pandas_dataframe(use_object_dtype=False)
|
|
2511
|
+
|
|
2512
|
+
def to_polars(self) -> "polars.DataFrame":
|
|
2513
|
+
df_builder = _DataFrameBuilder()
|
|
2514
|
+
df_builder.build_dataframe_of_integral_types(self)
|
|
2515
|
+
return df_builder.build_polars_dataframe(use_object_dtype=False)
|
|
2516
|
+
|
|
2517
|
+
|
|
2518
|
+
def get(self, expression: str) -> ValueLike:
|
|
2519
|
+
value = Value()
|
|
2520
|
+
error = Error()
|
|
2521
|
+
factorylib.lib.psrd_table_get_property(self._hdr,
|
|
2522
|
+
_c_str(expression),
|
|
2523
|
+
value.handler(),
|
|
2524
|
+
error.handler())
|
|
2525
|
+
if error.code != 0:
|
|
2526
|
+
raise FactoryException(error.what)
|
|
2527
|
+
return value.get()
|
|
2528
|
+
|
|
2529
|
+
def set(self, expression: str, value: ValueLike):
|
|
2530
|
+
error = Error()
|
|
2531
|
+
value_object = Value()
|
|
2532
|
+
value_object.set(value)
|
|
2533
|
+
factorylib.lib.psrd_table_set_property(self._hdr, _c_str(expression),
|
|
2534
|
+
_bytes(expression),
|
|
2535
|
+
value_object.handler(),
|
|
2536
|
+
error.handler())
|
|
2537
|
+
if error.code != 0:
|
|
2538
|
+
raise FactoryException(error.what)
|
|
2539
|
+
|
|
2540
|
+
def as_dict(self) -> Dict[str, ValueLike]:
|
|
2541
|
+
value_dict = ValueDict()
|
|
2542
|
+
error = Error()
|
|
2543
|
+
handler = factorylib.lib.psrd_table_get_as_dict(self._hdr,
|
|
2544
|
+
error.handler())
|
|
2545
|
+
if error.code != 0 or handler is None:
|
|
2546
|
+
raise FactoryException(error.what)
|
|
2547
|
+
value_dict._hdr = handler
|
|
2548
|
+
return value_dict.to_dict()
|
|
2549
|
+
|
|
2550
|
+
def from_dict(self, input_dict: Dict[str, any]):
|
|
2551
|
+
value_dict = ValueDict.from_dict(input_dict)
|
|
2552
|
+
error = Error()
|
|
2553
|
+
factorylib.lib.psrd_table_set_from_dict(self._hdr, value_dict.handler(),
|
|
2554
|
+
error.handler())
|
|
2555
|
+
if error.code != 0:
|
|
2556
|
+
raise FactoryException(error.what)
|
|
2557
|
+
|
|
2558
|
+
|
|
2559
|
+
def load_dataframe(input_file: PathLike, **kwargs) -> DataFrame:
|
|
2560
|
+
options = kwargs.get("options", None)
|
|
2561
|
+
return DataFrame.load_from_file(input_file, options)
|
|
2562
|
+
|
|
2563
|
+
|
|
2564
|
+
def create_dataframe(data: Union[DataFrameLike, dict]) -> DataFrame:
|
|
2565
|
+
if isinstance(data, dict):
|
|
2566
|
+
df = DataFrame()
|
|
2567
|
+
df.from_dict(data)
|
|
2568
|
+
return df
|
|
2569
|
+
return DataFrame.from_dataframe(data)
|
|
2570
|
+
|
|
2571
|
+
|
|
2572
|
+
def _load_library():
|
|
2573
|
+
global _loaded
|
|
2574
|
+
global _loaded_lock
|
|
2575
|
+
with _loaded_lock:
|
|
2576
|
+
factorylib.initialize()
|
|
2577
|
+
_loaded = True
|
|
2578
|
+
return _loaded
|
|
2579
|
+
|
|
2580
|
+
|
|
2581
|
+
def _initialize_basic_data():
|
|
2582
|
+
global _basic_data_initialized
|
|
2583
|
+
global _basic_data_initialized_lock
|
|
2584
|
+
with _basic_data_initialized_lock:
|
|
2585
|
+
_check_loaded()
|
|
2586
|
+
error = Error()
|
|
2587
|
+
|
|
2588
|
+
# Set binding info
|
|
2589
|
+
map_prop_values = {
|
|
2590
|
+
"NULL_TYPE": "None",
|
|
2591
|
+
"LIST_TYPE": "list",
|
|
2592
|
+
"INDEX_STARTS_AT_ZERO": True,
|
|
2593
|
+
"NAME": "Python",
|
|
2594
|
+
"VERSION": f"{sys.version}",
|
|
2595
|
+
"EXE": f"{sys.executable}",
|
|
2596
|
+
"LIB": f"{factorylib.get_lib_path()}",
|
|
2597
|
+
"BASE_PREFIX": f"{sys.base_prefix}",
|
|
2598
|
+
"REAL_PREFIX": f"{sys.prefix}",
|
|
2599
|
+
}
|
|
2600
|
+
for prop, prop_value in map_prop_values.items():
|
|
2601
|
+
value_object = Value()
|
|
2602
|
+
value_object.set(prop_value)
|
|
2603
|
+
factorylib.lib.psrd_set_binding_property(_c_str(prop),
|
|
2604
|
+
_bytes(prop),
|
|
2605
|
+
value_object.handler(),
|
|
2606
|
+
error.handler())
|
|
2607
|
+
if error.code != 0:
|
|
2608
|
+
raise FactoryException(error.what)
|
|
2609
|
+
|
|
2610
|
+
factorylib.lib.psrd_initialize_basic_data(error.handler())
|
|
2611
|
+
if error.code != 0:
|
|
2612
|
+
raise FactoryException(error.what)
|
|
2613
|
+
_basic_data_initialized = True
|
|
2614
|
+
|
|
2615
|
+
_initialize_constants()
|
|
2616
|
+
|
|
2617
|
+
|
|
2618
|
+
def _initialize_study_data():
|
|
2619
|
+
global _study_data_initialized
|
|
2620
|
+
global _study_data_initialized_lock
|
|
2621
|
+
with _study_data_initialized_lock:
|
|
2622
|
+
_check_loaded()
|
|
2623
|
+
error = Error()
|
|
2624
|
+
|
|
2625
|
+
# Where to look for pmd and pmk files
|
|
2626
|
+
module_path = os.path.dirname(__file__)
|
|
2627
|
+
factorylib.lib.psrd_initialize_study_data(_c_str(module_path), _bytes(module_path), error.handler())
|
|
2628
|
+
if error.code != 0:
|
|
2629
|
+
raise FactoryException(error.what)
|
|
2630
|
+
_study_data_initialized = True
|
|
2631
|
+
|
|
2632
|
+
|
|
2633
|
+
def _initialize_constants():
|
|
2634
|
+
global _constants_initialized
|
|
2635
|
+
global _constants_initialized_lock
|
|
2636
|
+
with _constants_initialized_lock:
|
|
2637
|
+
global _date_transform
|
|
2638
|
+
_check_basic_data_initialized()
|
|
2639
|
+
_date_transform = int(get_constant("DATE_TRANSFORM"))
|
|
2640
|
+
_constants_initialized = True
|
|
2641
|
+
|
|
2642
|
+
def _unload():
|
|
2643
|
+
error = Error()
|
|
2644
|
+
factorylib.lib.psrd_unload(error.handler())
|
|
2645
|
+
if error.code != 0:
|
|
2646
|
+
raise FactoryException(error.what)
|
|
2647
|
+
|
|
2648
|
+
|
|
2649
|
+
def help(context: str = "") -> str:
|
|
2650
|
+
error = Error()
|
|
2651
|
+
size = factorylib.lib.psrd_help(_c_str(context), _bytes(context),
|
|
2652
|
+
None, 0, error.handler())
|
|
2653
|
+
if error.code != 0:
|
|
2654
|
+
raise FactoryException(error.what)
|
|
2655
|
+
buffer = ctypes.create_string_buffer(size)
|
|
2656
|
+
factorylib.lib.psrd_help(_c_str(context), _bytes(context),
|
|
2657
|
+
buffer, size, error.handler())
|
|
2658
|
+
if error.code != 0:
|
|
2659
|
+
raise FactoryException(error.what)
|
|
2660
|
+
return _from_c_str(buffer.value)
|
|
2661
|
+
|
|
2662
|
+
|
|
2663
|
+
def create_study(*args, **kwargs) -> Study:
|
|
2664
|
+
blocks = kwargs.get("blocks", None)
|
|
2665
|
+
models = kwargs.get("models", None)
|
|
2666
|
+
context = kwargs.get("context", None) if len(args) == 0 else args[0]
|
|
2667
|
+
if "profile" in kwargs:
|
|
2668
|
+
raise DeprecationWarning("The 'profile' argument is deprecated. Use 'models' instead.")
|
|
2669
|
+
model_or_context = models if models is not None and len(models) > 0 else context
|
|
2670
|
+
return Study.create_object(model_or_context, blocks)
|
|
2671
|
+
|
|
2672
|
+
|
|
2673
|
+
def load_study(study_path: PathLike,
|
|
2674
|
+
model_or_context: Union[str, Context, None] = None,
|
|
2675
|
+
options: Optional[DataObject] = None) -> Study:
|
|
2676
|
+
settings_only = False
|
|
2677
|
+
return Study.load(study_path, model_or_context, settings_only, options)
|
|
2678
|
+
|
|
2679
|
+
|
|
2680
|
+
def load_study_settings(study_path: PathLike,
|
|
2681
|
+
model_or_context: Union[str, Context, None] = None,
|
|
2682
|
+
options: Optional[DataObject] = None) -> Study:
|
|
2683
|
+
settings_only = True
|
|
2684
|
+
return Study.load(study_path, model_or_context, settings_only, options)
|
|
2685
|
+
|
|
2686
|
+
|
|
2687
|
+
def create(type_name: str, model_or_context: Union[str, Context, None] = None) -> DataObject:
|
|
2688
|
+
_check_basic_data_initialized()
|
|
2689
|
+
if type_name not in _TYPES_WITHOUT_CONTEXT:
|
|
2690
|
+
_check_study_data_initialized()
|
|
2691
|
+
error = Error()
|
|
2692
|
+
data_object = DataObject()
|
|
2693
|
+
context = _get_context(model_or_context, None)
|
|
2694
|
+
context_handler = context.handler() if context is not None else None
|
|
2695
|
+
handler = factorylib.lib.psrd_create(_c_str(type_name),
|
|
2696
|
+
context_handler,
|
|
2697
|
+
error.handler())
|
|
2698
|
+
else:
|
|
2699
|
+
error = Error()
|
|
2700
|
+
data_object = DataObject()
|
|
2701
|
+
context_handler = None
|
|
2702
|
+
handler = factorylib.lib.psrd_create(_c_str(type_name),
|
|
2703
|
+
context_handler,
|
|
2704
|
+
error.handler())
|
|
2705
|
+
if error.code != 0 or handler is None:
|
|
2706
|
+
raise FactoryException(error.what)
|
|
2707
|
+
data_object._hdr = handler
|
|
2708
|
+
return data_object
|
|
2709
|
+
|
|
2710
|
+
|
|
2711
|
+
|
|
2712
|
+
def convert_output(input_path: PathLike, output_path: PathLike, **kwargs):
|
|
2713
|
+
_check_basic_data_initialized()
|
|
2714
|
+
options: Optional[Union[dict, Value, DataObject]] = kwargs.get("options", None)
|
|
2715
|
+
input_path = str(input_path)
|
|
2716
|
+
output_path = str(output_path)
|
|
2717
|
+
error = Error()
|
|
2718
|
+
options_value = _get_arg_object(options)
|
|
2719
|
+
factorylib.lib.psrd_convert_output(_c_str(input_path),
|
|
2720
|
+
_bytes(input_path),
|
|
2721
|
+
_c_str(output_path),
|
|
2722
|
+
_bytes(output_path),
|
|
2723
|
+
options_value.handler(),
|
|
2724
|
+
error.handler())
|
|
2725
|
+
if error.code != 0:
|
|
2726
|
+
raise FactoryException(error.what)
|
|
2727
|
+
|
|
2728
|
+
|
|
2729
|
+
def get_default_context() -> "Context":
|
|
2730
|
+
_check_basic_data_initialized()
|
|
2731
|
+
return Context.default_context()
|
|
2732
|
+
|
|
2733
|
+
|
|
2734
|
+
def get_new_context() -> "Context":
|
|
2735
|
+
_check_basic_data_initialized()
|
|
2736
|
+
return Context.create()
|
|
2737
|
+
|
|
2738
|
+
|
|
2739
|
+
def get_default_encoding() -> str:
|
|
2740
|
+
return _preferred_encoding
|
|
2741
|
+
|
|
2742
|
+
|
|
2743
|
+
def set_default_encoding(encoding: str):
|
|
2744
|
+
global _preferred_encoding
|
|
2745
|
+
_preferred_encoding = encoding
|