psr-factory 5.0.0b21__py3-none-win_amd64.whl → 5.0.0b69__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- psr/execqueue/client.py +31 -10
- psr/execqueue/config.py +8 -0
- psr/execqueue/db.py +71 -9
- psr/execqueue/server.py +317 -41
- psr/execqueue/watcher.py +1 -1
- psr/factory/__init__.py +7 -7
- psr/factory/api.py +418 -144
- psr/factory/factory.dll +0 -0
- psr/factory/factory.pmd +118 -52
- psr/factory/factory.pmk +3044 -2223
- psr/factory/factorylib.py +36 -2
- psr/factory/samples/sddp_case01.py +3 -2
- psr/factory/samples/sddp_case21.py +3 -3
- psr/{cloud/version.py → outputs/__init__.py} +2 -2
- psr/outputs/outputs.py +179 -0
- psr/outputs/resample.py +289 -0
- psr/psrfcommon/psrfcommon.py +4 -1
- psr/runner/runner.py +90 -22
- {psr_factory-5.0.0b21.dist-info → psr_factory-5.0.0b69.dist-info}/METADATA +5 -15
- psr_factory-5.0.0b69.dist-info/RECORD +33 -0
- psr/cloud/__init__.py +0 -7
- psr/cloud/aws.py +0 -256
- psr/cloud/cloud.py +0 -1444
- psr/cloud/data.py +0 -127
- psr/cloud/desktop.py +0 -82
- psr/cloud/log.py +0 -40
- psr/cloud/status.py +0 -81
- psr/cloud/tempfile.py +0 -117
- psr/cloud/xml.py +0 -57
- psr_factory-5.0.0b21.dist-info/RECORD +0 -40
- {psr_factory-5.0.0b21.dist-info → psr_factory-5.0.0b69.dist-info}/WHEEL +0 -0
- {psr_factory-5.0.0b21.dist-info → psr_factory-5.0.0b69.dist-info}/licenses/LICENSE.txt +0 -0
- {psr_factory-5.0.0b21.dist-info → psr_factory-5.0.0b69.dist-info}/top_level.txt +0 -0
psr/factory/api.py
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
# Unauthorized copying of this file, via any medium is strictly prohibited
|
|
3
3
|
# Proprietary and confidential
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
import locale
|
|
6
|
-
from typing import Dict, List, Optional, Tuple, Union
|
|
8
|
+
from typing import Dict, List, Optional, Tuple, Union, Any
|
|
7
9
|
from types import ModuleType
|
|
8
10
|
import copy
|
|
9
11
|
import ctypes
|
|
@@ -16,6 +18,8 @@ import threading
|
|
|
16
18
|
import pathlib
|
|
17
19
|
import warnings
|
|
18
20
|
|
|
21
|
+
from typing import TypeAlias
|
|
22
|
+
|
|
19
23
|
from . import factorylib
|
|
20
24
|
|
|
21
25
|
|
|
@@ -30,9 +34,30 @@ pandas: Optional[ModuleType] = None
|
|
|
30
34
|
polars: Optional[ModuleType] = None
|
|
31
35
|
numpy: Optional[ModuleType] = None
|
|
32
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
|
+
|
|
33
56
|
|
|
34
57
|
_default_dataframe_type: str = "pandas"
|
|
35
58
|
|
|
59
|
+
_TYPES_WITHOUT_CONTEXT = ("Context", "ConvertOutputOptions", "DataFrameLoadOptions", "DataFrameSaveOptions", "DataFrameMetadata", "StudyLoadOptions", "StudySaveOptions")
|
|
60
|
+
|
|
36
61
|
|
|
37
62
|
def _has_pandas() -> bool:
|
|
38
63
|
"""Check if pandas is available."""
|
|
@@ -88,11 +113,14 @@ def get_default_dataframe_type() -> str:
|
|
|
88
113
|
"""Get the default dataframe type used by the library."""
|
|
89
114
|
return _default_dataframe_type
|
|
90
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()
|
|
91
121
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
_initialized = False
|
|
95
|
-
_initialized_lock = threading.Lock()
|
|
122
|
+
_constants_initialized = False
|
|
123
|
+
_constants_initialized_lock = threading.Lock()
|
|
96
124
|
|
|
97
125
|
_loaded = False
|
|
98
126
|
_loaded_lock = threading.Lock()
|
|
@@ -101,16 +129,22 @@ _loaded_lock = threading.Lock()
|
|
|
101
129
|
_preferred_encoding = locale.getpreferredencoding()
|
|
102
130
|
|
|
103
131
|
# Internal date epoch
|
|
104
|
-
|
|
105
|
-
_date_transform = 12622780800
|
|
132
|
+
_date_transform: Optional[int] = None
|
|
106
133
|
|
|
107
134
|
|
|
108
|
-
def
|
|
135
|
+
def _check_basic_data_initialized():
|
|
109
136
|
"""Checks if the module was initialized."""
|
|
110
|
-
global
|
|
111
|
-
if not
|
|
112
|
-
|
|
113
|
-
return
|
|
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
|
|
114
148
|
|
|
115
149
|
|
|
116
150
|
def _check_loaded() -> bool:
|
|
@@ -192,7 +226,7 @@ def version() -> str:
|
|
|
192
226
|
return _version_long()
|
|
193
227
|
|
|
194
228
|
|
|
195
|
-
def
|
|
229
|
+
def short_version() -> str:
|
|
196
230
|
"""Returns short library version."""
|
|
197
231
|
return _version_short()
|
|
198
232
|
|
|
@@ -258,9 +292,11 @@ def set_diagnostics_mode(value: Union[bool, int]):
|
|
|
258
292
|
|
|
259
293
|
|
|
260
294
|
def diagnostics() -> str:
|
|
261
|
-
global
|
|
262
|
-
global
|
|
263
|
-
|
|
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:
|
|
264
300
|
"""Get diagnostics information."""
|
|
265
301
|
py_diagnostics = f"Python version: {sys.version}\n" \
|
|
266
302
|
f"Python encoding: {sys.getdefaultencoding()}\n" \
|
|
@@ -279,41 +315,48 @@ def diagnostics() -> str:
|
|
|
279
315
|
buffer, size, error.handler())
|
|
280
316
|
if error.code != 0:
|
|
281
317
|
raise FactoryException(error.what)
|
|
282
|
-
|
|
318
|
+
_basic_data_initialized = True
|
|
319
|
+
_study_data_initialized = True
|
|
283
320
|
return py_diagnostics + _from_c_str(buffer.value)
|
|
284
321
|
|
|
285
322
|
|
|
286
|
-
def
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
if error.code != 0:
|
|
298
|
-
raise FactoryException(error.what)
|
|
299
|
-
return value.get()
|
|
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()
|
|
300
334
|
|
|
301
335
|
|
|
302
|
-
def
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
if error.code != 0:
|
|
315
|
-
raise FactoryException(error.what)
|
|
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
|
+
|
|
316
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)
|
|
317
360
|
|
|
318
361
|
|
|
319
362
|
def _get_context(models_or_context: Union[str, list, dict, "Context", None],
|
|
@@ -478,7 +521,7 @@ class ValueDict(_BaseObject):
|
|
|
478
521
|
if self._hdr is not None:
|
|
479
522
|
factorylib.lib.psrd_free_dict(self._hdr)
|
|
480
523
|
|
|
481
|
-
def __getitem__(self, key:
|
|
524
|
+
def __getitem__(self, key: ValueLike) -> ValueLike:
|
|
482
525
|
if not isinstance(key, Value):
|
|
483
526
|
old_key = key
|
|
484
527
|
key = Value()
|
|
@@ -493,7 +536,7 @@ class ValueDict(_BaseObject):
|
|
|
493
536
|
raise FactoryException(error.what)
|
|
494
537
|
return value.get()
|
|
495
538
|
|
|
496
|
-
def __contains__(self, key:
|
|
539
|
+
def __contains__(self, key: ValueLike) -> bool:
|
|
497
540
|
if not isinstance(key, Value):
|
|
498
541
|
old_key = key
|
|
499
542
|
key = Value()
|
|
@@ -526,7 +569,7 @@ class ValueDict(_BaseObject):
|
|
|
526
569
|
def __iter__(self):
|
|
527
570
|
return self
|
|
528
571
|
|
|
529
|
-
def __next__(self) ->
|
|
572
|
+
def __next__(self) -> ValueLike:
|
|
530
573
|
if self.index >= self.dict_obj.__len__():
|
|
531
574
|
raise StopIteration
|
|
532
575
|
factorylib.lib.psrd_dict_get_key_by_index(self.dict_obj._hdr, self.index,
|
|
@@ -550,7 +593,7 @@ class ValueDict(_BaseObject):
|
|
|
550
593
|
def __iter__(self):
|
|
551
594
|
return self
|
|
552
595
|
|
|
553
|
-
def __next__(self) ->
|
|
596
|
+
def __next__(self) -> ValueLike:
|
|
554
597
|
if self.index >= self.dict_obj.__len__():
|
|
555
598
|
raise StopIteration
|
|
556
599
|
factorylib.lib.psrd_dict_get_value_by_index(self.dict_obj._hdr, self.index,
|
|
@@ -575,7 +618,7 @@ class ValueDict(_BaseObject):
|
|
|
575
618
|
def __iter__(self):
|
|
576
619
|
return self
|
|
577
620
|
|
|
578
|
-
def __next__(self) -> Tuple[
|
|
621
|
+
def __next__(self) -> Tuple[ValueLike, ValueLike]:
|
|
579
622
|
if self.index >= self.dict_obj.__len__():
|
|
580
623
|
raise StopIteration
|
|
581
624
|
factorylib.lib.psrd_dict_get_by_index(self.dict_obj._hdr, self.index,
|
|
@@ -649,7 +692,7 @@ class Value(_BaseObject):
|
|
|
649
692
|
if self._hdr is not None:
|
|
650
693
|
factorylib.lib.psrd_free_value(self._hdr)
|
|
651
694
|
|
|
652
|
-
def get(self) ->
|
|
695
|
+
def get(self) -> ValueLike:
|
|
653
696
|
_err = Error()
|
|
654
697
|
uint_value = ctypes.c_long()
|
|
655
698
|
factorylib.lib.psrd_value_get_type(self._hdr,
|
|
@@ -667,13 +710,13 @@ class Value(_BaseObject):
|
|
|
667
710
|
raise FactoryException(_err.what)
|
|
668
711
|
return int(int_value.value)
|
|
669
712
|
elif var_type == ValueType.INT64.value:
|
|
670
|
-
long_value = ctypes.
|
|
713
|
+
long_value = ctypes.c_longlong()
|
|
671
714
|
factorylib.lib.psrd_value_get_int64(self._hdr,
|
|
672
715
|
ctypes.byref(long_value),
|
|
673
716
|
_err.handler())
|
|
674
717
|
if _err.code != 0:
|
|
675
718
|
raise FactoryException(_err.what)
|
|
676
|
-
return int(
|
|
719
|
+
return int(long_value.value)
|
|
677
720
|
elif var_type == ValueType.FLOAT32.value:
|
|
678
721
|
float_value = ctypes.c_float()
|
|
679
722
|
factorylib.lib.psrd_value_get_float32(self._hdr,
|
|
@@ -706,7 +749,8 @@ class Value(_BaseObject):
|
|
|
706
749
|
_err.handler())
|
|
707
750
|
if _err.code != 0:
|
|
708
751
|
raise FactoryException(_err.what)
|
|
709
|
-
|
|
752
|
+
if _date_transform is None:
|
|
753
|
+
raise FactoryException("Factory is not initialized correctly.")
|
|
710
754
|
return dt.datetime.fromtimestamp(date_value.value - _date_transform, dt.timezone.utc)
|
|
711
755
|
|
|
712
756
|
elif var_type == ValueType.BOOL.value:
|
|
@@ -748,7 +792,7 @@ class Value(_BaseObject):
|
|
|
748
792
|
else:
|
|
749
793
|
raise NotImplementedError()
|
|
750
794
|
|
|
751
|
-
def set(self, value:
|
|
795
|
+
def set(self, value: ValueLike):
|
|
752
796
|
_err = Error()
|
|
753
797
|
if isinstance(value, bool):
|
|
754
798
|
factorylib.lib.psrd_value_set_bool(self._hdr, value,
|
|
@@ -756,6 +800,8 @@ class Value(_BaseObject):
|
|
|
756
800
|
if _err.code != 0:
|
|
757
801
|
raise FactoryException(_err.what)
|
|
758
802
|
elif isinstance(value, dt.datetime):
|
|
803
|
+
if _date_transform is None:
|
|
804
|
+
raise FactoryException("Factory is not initialized correctly.")
|
|
759
805
|
value.replace(tzinfo=dt.timezone.utc)
|
|
760
806
|
date_epoch = int(value.timestamp()) + _date_transform
|
|
761
807
|
factorylib.lib.psrd_value_set_date(self._hdr, date_epoch,
|
|
@@ -820,7 +866,7 @@ class Value(_BaseObject):
|
|
|
820
866
|
raise FactoryException(_err.what)
|
|
821
867
|
|
|
822
868
|
else:
|
|
823
|
-
raise FactoryException(f"Unsupported type \"{type(value).
|
|
869
|
+
raise FactoryException(f"Unsupported type \"{type(value).__name__}\" for value.")
|
|
824
870
|
|
|
825
871
|
|
|
826
872
|
class PropertyDescription(_BaseObject):
|
|
@@ -835,11 +881,11 @@ class PropertyDescription(_BaseObject):
|
|
|
835
881
|
@property
|
|
836
882
|
def name(self) -> str:
|
|
837
883
|
_err = Error()
|
|
838
|
-
|
|
839
|
-
|
|
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)
|
|
840
887
|
buffer = ctypes.create_string_buffer(size)
|
|
841
|
-
factorylib.lib.psrd_property_description_get_name(self._hdr, buffer, size,
|
|
842
|
-
_err.handler())
|
|
888
|
+
factorylib.lib.psrd_property_description_get_name(self._hdr, buffer, size, _err.handler())
|
|
843
889
|
if _err.code != 0:
|
|
844
890
|
raise FactoryException(_err.what)
|
|
845
891
|
return _from_c_str(buffer.value)
|
|
@@ -855,8 +901,9 @@ class PropertyDescription(_BaseObject):
|
|
|
855
901
|
@property
|
|
856
902
|
def alt_name(self) -> str:
|
|
857
903
|
_err = Error()
|
|
858
|
-
|
|
859
|
-
|
|
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)
|
|
860
907
|
buffer = ctypes.create_string_buffer(size)
|
|
861
908
|
factorylib.lib.psrd_property_description_get_alternative_name(
|
|
862
909
|
self._hdr, buffer, size, _err.handler())
|
|
@@ -872,6 +919,26 @@ class PropertyDescription(_BaseObject):
|
|
|
872
919
|
def alt_name(self):
|
|
873
920
|
raise AttributeError("do not delete alt_name")
|
|
874
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
|
+
|
|
875
942
|
def is_dynamic(self) -> bool:
|
|
876
943
|
_err = Error()
|
|
877
944
|
value = ctypes.c_bool()
|
|
@@ -924,8 +991,9 @@ class PropertyDescription(_BaseObject):
|
|
|
924
991
|
dimensions_count = int(value.value)
|
|
925
992
|
|
|
926
993
|
for i_dim in range(dimensions_count):
|
|
927
|
-
|
|
928
|
-
|
|
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)
|
|
929
997
|
buffer = ctypes.create_string_buffer(size)
|
|
930
998
|
factorylib.lib.psrd_property_description_get_dimension_name(self._hdr,
|
|
931
999
|
i_dim, buffer,
|
|
@@ -934,7 +1002,6 @@ class PropertyDescription(_BaseObject):
|
|
|
934
1002
|
if _err.code != 0:
|
|
935
1003
|
raise FactoryException(_err.what)
|
|
936
1004
|
name = _from_c_str(buffer.value)
|
|
937
|
-
|
|
938
1005
|
factorylib.lib.psrd_property_description_get_dimension_size(self._hdr,
|
|
939
1006
|
i_dim,
|
|
940
1007
|
ctypes.byref(value),
|
|
@@ -967,7 +1034,6 @@ class PropertyDescription(_BaseObject):
|
|
|
967
1034
|
return f"Property {self.name} with dimensions {self.dimensions()}"
|
|
968
1035
|
|
|
969
1036
|
|
|
970
|
-
|
|
971
1037
|
class DataObject(_BaseObject):
|
|
972
1038
|
def __init__(self):
|
|
973
1039
|
super().__init__()
|
|
@@ -1009,16 +1075,16 @@ class DataObject(_BaseObject):
|
|
|
1009
1075
|
dest._hdr = ref
|
|
1010
1076
|
return dest
|
|
1011
1077
|
|
|
1012
|
-
def __deepcopy__(self,
|
|
1078
|
+
def __deepcopy__(self, memo_dict=None):
|
|
1013
1079
|
raise NotImplementedError()
|
|
1014
1080
|
|
|
1015
1081
|
def __repr__(self):
|
|
1016
1082
|
identifiers = []
|
|
1017
|
-
if self.
|
|
1083
|
+
if self.has_code():
|
|
1018
1084
|
identifiers.append(f"code={self.code}")
|
|
1019
|
-
if self.
|
|
1085
|
+
if self.has_id():
|
|
1020
1086
|
identifiers.append(f"id={self.id.strip()}")
|
|
1021
|
-
if self.
|
|
1087
|
+
if self.has_name():
|
|
1022
1088
|
identifiers.append(f"name={self.name.strip()}")
|
|
1023
1089
|
return f"psr.factory.DataObject({self.type}, {', '.join(identifiers)})"
|
|
1024
1090
|
|
|
@@ -1030,7 +1096,8 @@ class DataObject(_BaseObject):
|
|
|
1030
1096
|
|
|
1031
1097
|
@property
|
|
1032
1098
|
def context(self) -> "Context":
|
|
1033
|
-
|
|
1099
|
+
_check_basic_data_initialized()
|
|
1100
|
+
_check_study_data_initialized()
|
|
1034
1101
|
obj = Context()
|
|
1035
1102
|
_err = Error()
|
|
1036
1103
|
ref = factorylib.lib.psrd_object_context(self._hdr,
|
|
@@ -1040,7 +1107,7 @@ class DataObject(_BaseObject):
|
|
|
1040
1107
|
obj._hdr = ref
|
|
1041
1108
|
return obj
|
|
1042
1109
|
|
|
1043
|
-
def
|
|
1110
|
+
def descriptions(self) -> Dict[str, PropertyDescription]:
|
|
1044
1111
|
_err = Error()
|
|
1045
1112
|
value = ctypes.c_long()
|
|
1046
1113
|
factorylib.lib.psrd_object_property_description_count(self._hdr,
|
|
@@ -1061,7 +1128,30 @@ class DataObject(_BaseObject):
|
|
|
1061
1128
|
properties[var.name] = var
|
|
1062
1129
|
return properties
|
|
1063
1130
|
|
|
1064
|
-
def
|
|
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:
|
|
1065
1155
|
value = Value()
|
|
1066
1156
|
_err = Error()
|
|
1067
1157
|
factorylib.lib.psrd_object_get_value(self._hdr,
|
|
@@ -1072,7 +1162,7 @@ class DataObject(_BaseObject):
|
|
|
1072
1162
|
raise FactoryException(_err.what)
|
|
1073
1163
|
return value.get()
|
|
1074
1164
|
|
|
1075
|
-
def get_at(self, expression: str, range_expr:
|
|
1165
|
+
def get_at(self, expression: str, range_expr: DateLike) -> ValueLike:
|
|
1076
1166
|
if not isinstance(range_expr, (str, dt.datetime)):
|
|
1077
1167
|
raise FactoryException("range_expr must be a string or datetime object.")
|
|
1078
1168
|
_value = Value()
|
|
@@ -1088,7 +1178,7 @@ class DataObject(_BaseObject):
|
|
|
1088
1178
|
raise FactoryException(_err.what)
|
|
1089
1179
|
return _value.get()
|
|
1090
1180
|
|
|
1091
|
-
def as_dict(self) -> Dict[str,
|
|
1181
|
+
def as_dict(self) -> Dict[str, ValueLike]:
|
|
1092
1182
|
value_dict = ValueDict()
|
|
1093
1183
|
error = Error()
|
|
1094
1184
|
handler = factorylib.lib.psrd_object_get_as_dict(self._hdr,
|
|
@@ -1106,7 +1196,7 @@ class DataObject(_BaseObject):
|
|
|
1106
1196
|
if error.code != 0:
|
|
1107
1197
|
raise FactoryException(error.what)
|
|
1108
1198
|
|
|
1109
|
-
def get_df(self, expression: str) ->
|
|
1199
|
+
def get_df(self, expression: str) -> DataFrameLike:
|
|
1110
1200
|
_err = Error()
|
|
1111
1201
|
_df = DataFrame()
|
|
1112
1202
|
factorylib.lib.psrd_object_get_table(self._hdr, _df.handler(),
|
|
@@ -1130,7 +1220,7 @@ class DataObject(_BaseObject):
|
|
|
1130
1220
|
if _err.code != 0:
|
|
1131
1221
|
raise FactoryException(_err.what)
|
|
1132
1222
|
|
|
1133
|
-
def set_at(self, expression: str, range_expr:
|
|
1223
|
+
def set_at(self, expression: str, range_expr: DateLike, value):
|
|
1134
1224
|
if not isinstance(range_expr, (str, dt.datetime)):
|
|
1135
1225
|
raise FactoryException("range_expr must be a string or datetime object.")
|
|
1136
1226
|
_err = Error()
|
|
@@ -1147,19 +1237,19 @@ class DataObject(_BaseObject):
|
|
|
1147
1237
|
if _err.code != 0:
|
|
1148
1238
|
raise FactoryException(_err.what)
|
|
1149
1239
|
|
|
1150
|
-
def set_df(self, dataframe_like):
|
|
1151
|
-
if not _has_pandas():
|
|
1152
|
-
raise ModuleNotFoundError("pandas required.")
|
|
1153
|
-
dataframe_like = pandas.api.interchange.from_dataframe(dataframe_like)
|
|
1240
|
+
def set_df(self, dataframe_like: DataFrameLike):
|
|
1154
1241
|
df_builder = _DataFrameBuilder()
|
|
1155
|
-
|
|
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.")
|
|
1156
1248
|
_err = Error()
|
|
1157
|
-
factorylib.lib.psrd_object_set_table(self._hdr, _df.handler(),
|
|
1158
|
-
_err.handler())
|
|
1249
|
+
factorylib.lib.psrd_object_set_table(self._hdr, _df.handler(), _err.handler())
|
|
1159
1250
|
if _err.code != 0:
|
|
1160
1251
|
raise FactoryException(_err.what)
|
|
1161
1252
|
|
|
1162
|
-
|
|
1163
1253
|
def clear_values(self, expression: str):
|
|
1164
1254
|
_err = Error()
|
|
1165
1255
|
factorylib.lib.psrd_object_clear_values(self._hdr,
|
|
@@ -1191,6 +1281,14 @@ class DataObject(_BaseObject):
|
|
|
1191
1281
|
object_list._hdr = ref
|
|
1192
1282
|
return object_list.to_list()
|
|
1193
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
|
+
|
|
1194
1292
|
@property
|
|
1195
1293
|
def code(self) -> int:
|
|
1196
1294
|
_err = Error()
|
|
@@ -1236,6 +1334,42 @@ class DataObject(_BaseObject):
|
|
|
1236
1334
|
def type(self):
|
|
1237
1335
|
raise AttributeError("do not delete type")
|
|
1238
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
|
+
|
|
1239
1373
|
@property
|
|
1240
1374
|
def name(self) -> str:
|
|
1241
1375
|
err = Error()
|
|
@@ -1264,6 +1398,14 @@ class DataObject(_BaseObject):
|
|
|
1264
1398
|
def name(self):
|
|
1265
1399
|
raise AttributeError("do not delete name")
|
|
1266
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
|
+
|
|
1267
1409
|
@property
|
|
1268
1410
|
def id(self) -> str:
|
|
1269
1411
|
err = Error()
|
|
@@ -1296,7 +1438,7 @@ class DataObject(_BaseObject):
|
|
|
1296
1438
|
class Context(DataObject):
|
|
1297
1439
|
@staticmethod
|
|
1298
1440
|
def default_context() -> "Context":
|
|
1299
|
-
|
|
1441
|
+
_check_basic_data_initialized()
|
|
1300
1442
|
context = Context()
|
|
1301
1443
|
err = Error()
|
|
1302
1444
|
ref = factorylib.lib.psrd_get_default_context(err.handler())
|
|
@@ -1346,7 +1488,7 @@ class Study(_BaseObject):
|
|
|
1346
1488
|
def __copy__(self):
|
|
1347
1489
|
raise NotImplementedError()
|
|
1348
1490
|
|
|
1349
|
-
def __deepcopy__(self,
|
|
1491
|
+
def __deepcopy__(self, memo_dict=None):
|
|
1350
1492
|
dest = Study()
|
|
1351
1493
|
_err = Error()
|
|
1352
1494
|
ref = factorylib.lib.psrd_study_clone(self.handler(),
|
|
@@ -1357,7 +1499,8 @@ class Study(_BaseObject):
|
|
|
1357
1499
|
return dest
|
|
1358
1500
|
|
|
1359
1501
|
def create(self, object_type: str) -> DataObject:
|
|
1360
|
-
|
|
1502
|
+
_check_basic_data_initialized()
|
|
1503
|
+
_check_study_data_initialized()
|
|
1361
1504
|
return create(object_type, self.context)
|
|
1362
1505
|
|
|
1363
1506
|
|
|
@@ -1371,7 +1514,8 @@ class Study(_BaseObject):
|
|
|
1371
1514
|
@staticmethod
|
|
1372
1515
|
def create_object(model_or_context: Union[str, Context, dict, None],
|
|
1373
1516
|
blocks: Optional[int] = None):
|
|
1374
|
-
|
|
1517
|
+
_check_basic_data_initialized()
|
|
1518
|
+
_check_study_data_initialized()
|
|
1375
1519
|
err = Error()
|
|
1376
1520
|
context = _get_context(model_or_context, blocks)
|
|
1377
1521
|
study = Study()
|
|
@@ -1382,12 +1526,13 @@ class Study(_BaseObject):
|
|
|
1382
1526
|
return study
|
|
1383
1527
|
|
|
1384
1528
|
@staticmethod
|
|
1385
|
-
def load(study_path:
|
|
1529
|
+
def load(study_path: PathLike, model_or_context: Union[str, Context, None],
|
|
1386
1530
|
settings_only: bool = False,
|
|
1387
1531
|
options: Optional[Union[dict, "Value", "DataObject"]] = None):
|
|
1388
1532
|
if not isinstance(options, (DataObject, type(None))):
|
|
1389
1533
|
raise TypeError("options must be a DataObject or None.")
|
|
1390
|
-
|
|
1534
|
+
_check_basic_data_initialized()
|
|
1535
|
+
_check_study_data_initialized()
|
|
1391
1536
|
study_path = str(study_path)
|
|
1392
1537
|
context = _get_context(model_or_context, None)
|
|
1393
1538
|
error = Error()
|
|
@@ -1404,7 +1549,7 @@ class Study(_BaseObject):
|
|
|
1404
1549
|
raise FactoryException(error.what)
|
|
1405
1550
|
return study
|
|
1406
1551
|
|
|
1407
|
-
def save(self, output_path:
|
|
1552
|
+
def save(self, output_path: PathLike,
|
|
1408
1553
|
options: Optional[Union[dict, Value, DataObject]] = None):
|
|
1409
1554
|
output_path = str(output_path)
|
|
1410
1555
|
error = Error()
|
|
@@ -1416,7 +1561,7 @@ class Study(_BaseObject):
|
|
|
1416
1561
|
if error.code != 0:
|
|
1417
1562
|
raise FactoryException(error.what)
|
|
1418
1563
|
|
|
1419
|
-
def save_settings(self, output_path:
|
|
1564
|
+
def save_settings(self, output_path: PathLike,
|
|
1420
1565
|
options: Optional[Union[dict, Value, DataObject]] = None):
|
|
1421
1566
|
output_path = str(output_path)
|
|
1422
1567
|
error = Error()
|
|
@@ -1430,7 +1575,8 @@ class Study(_BaseObject):
|
|
|
1430
1575
|
|
|
1431
1576
|
@property
|
|
1432
1577
|
def context(self) -> "Context":
|
|
1433
|
-
|
|
1578
|
+
_check_basic_data_initialized()
|
|
1579
|
+
_check_study_data_initialized()
|
|
1434
1580
|
obj = Context()
|
|
1435
1581
|
error = Error()
|
|
1436
1582
|
ref = factorylib.lib.psrd_study_context(self._hdr,
|
|
@@ -1440,7 +1586,7 @@ class Study(_BaseObject):
|
|
|
1440
1586
|
obj._hdr = ref
|
|
1441
1587
|
return obj
|
|
1442
1588
|
|
|
1443
|
-
def get(self, expression: str) ->
|
|
1589
|
+
def get(self, expression: str) -> ValueLike:
|
|
1444
1590
|
value = Value()
|
|
1445
1591
|
error = Error()
|
|
1446
1592
|
factorylib.lib.psrd_study_get_value(self._hdr,
|
|
@@ -1451,8 +1597,8 @@ class Study(_BaseObject):
|
|
|
1451
1597
|
raise FactoryException(error.what)
|
|
1452
1598
|
return value.get()
|
|
1453
1599
|
|
|
1454
|
-
def get_at(self, expression: str, range_expr:
|
|
1455
|
-
if not isinstance(range_expr, str):
|
|
1600
|
+
def get_at(self, expression: str, range_expr: DateLike) -> ValueLike:
|
|
1601
|
+
if not isinstance(range_expr, (str, dt.datetime)):
|
|
1456
1602
|
raise FactoryException("range_expr must be a string or datetime object.")
|
|
1457
1603
|
value = Value()
|
|
1458
1604
|
error = Error()
|
|
@@ -1467,7 +1613,7 @@ class Study(_BaseObject):
|
|
|
1467
1613
|
raise FactoryException(error.what)
|
|
1468
1614
|
return value.get()
|
|
1469
1615
|
|
|
1470
|
-
def as_dict(self) -> Dict[str,
|
|
1616
|
+
def as_dict(self) -> Dict[str, ValueLike]:
|
|
1471
1617
|
value_dict = ValueDict()
|
|
1472
1618
|
error = Error()
|
|
1473
1619
|
handler = factorylib.lib.psrd_study_get_as_dict(self._hdr,
|
|
@@ -1515,6 +1661,33 @@ class Study(_BaseObject):
|
|
|
1515
1661
|
object_list._hdr = ref
|
|
1516
1662
|
return object_list.to_list()
|
|
1517
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
|
+
|
|
1518
1691
|
def find(self, expression: str) -> List[DataObject]:
|
|
1519
1692
|
object_list = ValueList(False)
|
|
1520
1693
|
error = Error()
|
|
@@ -1575,7 +1748,7 @@ class Study(_BaseObject):
|
|
|
1575
1748
|
object_list._hdr = ref
|
|
1576
1749
|
return object_list.to_list()
|
|
1577
1750
|
|
|
1578
|
-
def set(self, expression: str, value:
|
|
1751
|
+
def set(self, expression: str, value: ValueLike):
|
|
1579
1752
|
error = Error()
|
|
1580
1753
|
value_object = Value()
|
|
1581
1754
|
value_object.set(value)
|
|
@@ -1587,7 +1760,7 @@ class Study(_BaseObject):
|
|
|
1587
1760
|
if error.code != 0:
|
|
1588
1761
|
raise FactoryException(error.what)
|
|
1589
1762
|
|
|
1590
|
-
def set_at(self, expression: str, range_expr:
|
|
1763
|
+
def set_at(self, expression: str, range_expr: DateLike, value: ValueLike):
|
|
1591
1764
|
if not isinstance(range_expr, (str, dt.datetime)):
|
|
1592
1765
|
raise FactoryException("range_expr must be a string or datetime object.")
|
|
1593
1766
|
error = Error()
|
|
@@ -1604,7 +1777,7 @@ class Study(_BaseObject):
|
|
|
1604
1777
|
if error.code != 0:
|
|
1605
1778
|
raise FactoryException(error.what)
|
|
1606
1779
|
|
|
1607
|
-
def get_df(self, expression: str) ->
|
|
1780
|
+
def get_df(self, expression: str) -> DataFrameLike:
|
|
1608
1781
|
error = Error()
|
|
1609
1782
|
df = DataFrame()
|
|
1610
1783
|
factorylib.lib.psrd_study_get_table(self._hdr, df.handler(),
|
|
@@ -1617,7 +1790,7 @@ class Study(_BaseObject):
|
|
|
1617
1790
|
df_builder.build_dataframe(df)
|
|
1618
1791
|
return df_builder.build_desired_dataframe_type()
|
|
1619
1792
|
|
|
1620
|
-
def get_objects_values(self, object_type: str, columns: List[str]) ->
|
|
1793
|
+
def get_objects_values(self, object_type: str, columns: List[str]) -> DataFrameLike:
|
|
1621
1794
|
error = Error()
|
|
1622
1795
|
df = DataFrame()
|
|
1623
1796
|
columns_list = Value()
|
|
@@ -1632,7 +1805,7 @@ class Study(_BaseObject):
|
|
|
1632
1805
|
df_builder.build_dataframe(df)
|
|
1633
1806
|
return df_builder.build_desired_dataframe_type()
|
|
1634
1807
|
|
|
1635
|
-
def get_objects_values_at(self, object_type: str, columns: List[str], range_value:
|
|
1808
|
+
def get_objects_values_at(self, object_type: str, columns: List[str], range_value: DateLike) -> DataFrameLike:
|
|
1636
1809
|
error = Error()
|
|
1637
1810
|
df = DataFrame()
|
|
1638
1811
|
range_object = Value()
|
|
@@ -1650,7 +1823,7 @@ class Study(_BaseObject):
|
|
|
1650
1823
|
df_builder.build_dataframe(df)
|
|
1651
1824
|
return df_builder.build_desired_dataframe_type()
|
|
1652
1825
|
|
|
1653
|
-
def
|
|
1826
|
+
def descriptions(self) -> Dict[str, PropertyDescription]:
|
|
1654
1827
|
error = Error()
|
|
1655
1828
|
value = ctypes.c_long()
|
|
1656
1829
|
factorylib.lib.psrd_study_property_description_count(self._hdr,
|
|
@@ -1671,6 +1844,29 @@ class Study(_BaseObject):
|
|
|
1671
1844
|
properties[var.name] = var
|
|
1672
1845
|
return properties
|
|
1673
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
|
+
|
|
1674
1870
|
def set_df(self, dataframe_like):
|
|
1675
1871
|
if not _has_pandas():
|
|
1676
1872
|
raise ModuleNotFoundError("pandas required.")
|
|
@@ -1733,6 +1929,8 @@ def _polars_dtype_to_column_type(dtype: "polars.datatypes.classes.DataTypeClass"
|
|
|
1733
1929
|
return 4
|
|
1734
1930
|
if dtype == polars.String:
|
|
1735
1931
|
return 5
|
|
1932
|
+
if dtype == polars.Boolean:
|
|
1933
|
+
return 1 # TODO: create a boolean column type
|
|
1736
1934
|
else:
|
|
1737
1935
|
raise FactoryException(f"Unsupported polars dtype \"{dtype}\".")
|
|
1738
1936
|
|
|
@@ -1865,6 +2063,8 @@ class _DataFrameBuilder:
|
|
|
1865
2063
|
if self._error.code != 0:
|
|
1866
2064
|
raise FactoryException(self._error.what)
|
|
1867
2065
|
# convert array values to python datetime
|
|
2066
|
+
if _date_transform is None:
|
|
2067
|
+
raise FactoryException("Factory is not initialized correctly.")
|
|
1868
2068
|
self.indices[index].values = [dt.datetime.fromtimestamp(value - _date_transform, dt.UTC) for value in array_values]
|
|
1869
2069
|
else:
|
|
1870
2070
|
array_values = (ctypes.c_int * rows_count)()
|
|
@@ -1895,7 +2095,7 @@ class _DataFrameBuilder:
|
|
|
1895
2095
|
self.columns[column].values = array_values
|
|
1896
2096
|
self._not_built = False
|
|
1897
2097
|
|
|
1898
|
-
def build_desired_dataframe_type(self, **kwargs) ->
|
|
2098
|
+
def build_desired_dataframe_type(self, **kwargs) -> DataFrameLike:
|
|
1899
2099
|
if _default_dataframe_type == "pandas":
|
|
1900
2100
|
return self.build_pandas_dataframe(**kwargs)
|
|
1901
2101
|
elif _default_dataframe_type == "polars":
|
|
@@ -1949,6 +2149,8 @@ class _DataFrameBuilder:
|
|
|
1949
2149
|
table_data_indices = []
|
|
1950
2150
|
|
|
1951
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.")
|
|
1952
2154
|
self.index_names = [index.name for index in table_data_indices]
|
|
1953
2155
|
self.column_types = [_pandas_dtype_to_column_type(dtype) for dtype in table_data.dtypes]
|
|
1954
2156
|
self.index_types = [_pandas_dtype_to_column_type(index.dtype) for index in table_data_indices]
|
|
@@ -1989,9 +2191,9 @@ class _DataFrameBuilder:
|
|
|
1989
2191
|
break
|
|
1990
2192
|
|
|
1991
2193
|
if replaced_name:
|
|
1992
|
-
for
|
|
2194
|
+
for i_index, name in enumerate(self.index_names):
|
|
1993
2195
|
if name == "date":
|
|
1994
|
-
self.index_names[
|
|
2196
|
+
self.index_names[i_index] = None
|
|
1995
2197
|
# check index value types
|
|
1996
2198
|
index_convert_to = {}
|
|
1997
2199
|
index_fast_set = {}
|
|
@@ -2024,6 +2226,8 @@ class _DataFrameBuilder:
|
|
|
2024
2226
|
# TODO: check if original dataframe values is unaltered
|
|
2025
2227
|
index_values = index_values.astype('datetime64[s]').astype(dt.datetime)
|
|
2026
2228
|
# for each value, convert to timestamp
|
|
2229
|
+
if _date_transform is None:
|
|
2230
|
+
raise FactoryException("Factory is not initialized correctly.")
|
|
2027
2231
|
for ix, x in enumerate(index_values):
|
|
2028
2232
|
index_values[ix] = int(x.replace(tzinfo=dt.timezone.utc).timestamp() + _date_transform)
|
|
2029
2233
|
# convert to int64
|
|
@@ -2133,7 +2337,7 @@ class _DataFrameBuilder:
|
|
|
2133
2337
|
return df
|
|
2134
2338
|
|
|
2135
2339
|
def build_polars_dataframe(self, **kwargs) -> "polars.DataFrame":
|
|
2136
|
-
use_object_dtype = kwargs.get("use_object_dtype",
|
|
2340
|
+
use_object_dtype = kwargs.get("use_object_dtype", False)
|
|
2137
2341
|
if not _has_polars():
|
|
2138
2342
|
raise ModuleNotFoundError("polars required.")
|
|
2139
2343
|
def convert_column_values(column_name:str, values):
|
|
@@ -2147,15 +2351,17 @@ class _DataFrameBuilder:
|
|
|
2147
2351
|
data = {column.name: convert_column_values(column.name, column.values)
|
|
2148
2352
|
for column in self.indices + self.columns}
|
|
2149
2353
|
if use_object_dtype:
|
|
2150
|
-
return polars.DataFrame(
|
|
2354
|
+
return polars.DataFrame({k: polars.Series(k, v, dtype=polars.Object) for k, v in data.items()})
|
|
2151
2355
|
else:
|
|
2152
2356
|
return polars.DataFrame(data=data)
|
|
2153
2357
|
|
|
2154
2358
|
def build_from_polars(self, table_data: "polars.DataFrame") -> "DataFrame":
|
|
2155
2359
|
# check if the table has indices and if its multi-index or common index
|
|
2156
|
-
index_names = ("year", "week", "month", "hour", "scenario", "block", "stage")
|
|
2360
|
+
index_names = ("year", "week", "month", "hour", "scenario", "block", "stage", "date")
|
|
2157
2361
|
column_index = 0
|
|
2158
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.")
|
|
2159
2365
|
index_columns = []
|
|
2160
2366
|
while column_index < len(data_columns):
|
|
2161
2367
|
if data_columns[column_index] in index_names:
|
|
@@ -2256,9 +2462,9 @@ class DataFrame(_BaseObject):
|
|
|
2256
2462
|
factorylib.lib.psrd_free_table(self._hdr)
|
|
2257
2463
|
|
|
2258
2464
|
@staticmethod
|
|
2259
|
-
def load_from_file(input_file:
|
|
2465
|
+
def load_from_file(input_file: PathLike, options: Optional[Union[dict, Value, DataObject]] = None) -> "DataFrame":
|
|
2260
2466
|
input_file = str(input_file)
|
|
2261
|
-
|
|
2467
|
+
_check_basic_data_initialized()
|
|
2262
2468
|
error = Error()
|
|
2263
2469
|
df = DataFrame()
|
|
2264
2470
|
options_value = _get_arg_object(options)
|
|
@@ -2272,8 +2478,8 @@ class DataFrame(_BaseObject):
|
|
|
2272
2478
|
return df
|
|
2273
2479
|
|
|
2274
2480
|
@staticmethod
|
|
2275
|
-
def from_dataframe(df:
|
|
2276
|
-
|
|
2481
|
+
def from_dataframe(df: DataFrameLike) -> "DataFrame":
|
|
2482
|
+
_check_basic_data_initialized()
|
|
2277
2483
|
df_builder = _DataFrameBuilder()
|
|
2278
2484
|
if isinstance(df, DataFrame):
|
|
2279
2485
|
# FIXME: implement this
|
|
@@ -2287,7 +2493,7 @@ class DataFrame(_BaseObject):
|
|
|
2287
2493
|
return df_builder.build_from_polars(dataframe_like)
|
|
2288
2494
|
raise ImportError("Pandas or polars is not available. Please install pandas to use this feature.")
|
|
2289
2495
|
|
|
2290
|
-
def save(self, output_file:
|
|
2496
|
+
def save(self, output_file: PathLike, options: Optional[Union[dict, Value, DataObject]] = None):
|
|
2291
2497
|
output_file = str(output_file)
|
|
2292
2498
|
error = Error()
|
|
2293
2499
|
options_value = _get_arg_object(options)
|
|
@@ -2309,7 +2515,7 @@ class DataFrame(_BaseObject):
|
|
|
2309
2515
|
return df_builder.build_polars_dataframe(use_object_dtype=False)
|
|
2310
2516
|
|
|
2311
2517
|
|
|
2312
|
-
def get(self, expression: str) ->
|
|
2518
|
+
def get(self, expression: str) -> ValueLike:
|
|
2313
2519
|
value = Value()
|
|
2314
2520
|
error = Error()
|
|
2315
2521
|
factorylib.lib.psrd_table_get_property(self._hdr,
|
|
@@ -2320,7 +2526,7 @@ class DataFrame(_BaseObject):
|
|
|
2320
2526
|
raise FactoryException(error.what)
|
|
2321
2527
|
return value.get()
|
|
2322
2528
|
|
|
2323
|
-
def set(self, expression: str, value:
|
|
2529
|
+
def set(self, expression: str, value: ValueLike):
|
|
2324
2530
|
error = Error()
|
|
2325
2531
|
value_object = Value()
|
|
2326
2532
|
value_object.set(value)
|
|
@@ -2331,14 +2537,36 @@ class DataFrame(_BaseObject):
|
|
|
2331
2537
|
if error.code != 0:
|
|
2332
2538
|
raise FactoryException(error.what)
|
|
2333
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)
|
|
2334
2557
|
|
|
2335
|
-
|
|
2558
|
+
|
|
2559
|
+
def load_dataframe(input_file: PathLike, **kwargs) -> DataFrame:
|
|
2336
2560
|
options = kwargs.get("options", None)
|
|
2337
2561
|
return DataFrame.load_from_file(input_file, options)
|
|
2338
2562
|
|
|
2339
2563
|
|
|
2340
|
-
def create_dataframe(data: Union[
|
|
2341
|
-
|
|
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)
|
|
2342
2570
|
|
|
2343
2571
|
|
|
2344
2572
|
def _load_library():
|
|
@@ -2350,11 +2578,10 @@ def _load_library():
|
|
|
2350
2578
|
return _loaded
|
|
2351
2579
|
|
|
2352
2580
|
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
global
|
|
2356
|
-
|
|
2357
|
-
with _initialized_lock:
|
|
2581
|
+
def _initialize_basic_data():
|
|
2582
|
+
global _basic_data_initialized
|
|
2583
|
+
global _basic_data_initialized_lock
|
|
2584
|
+
with _basic_data_initialized_lock:
|
|
2358
2585
|
_check_loaded()
|
|
2359
2586
|
error = Error()
|
|
2360
2587
|
|
|
@@ -2380,15 +2607,37 @@ def _initialize():
|
|
|
2380
2607
|
if error.code != 0:
|
|
2381
2608
|
raise FactoryException(error.what)
|
|
2382
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
|
+
|
|
2383
2625
|
# Where to look for pmd and pmk files
|
|
2384
2626
|
module_path = os.path.dirname(__file__)
|
|
2385
|
-
factorylib.lib.
|
|
2386
|
-
_bytes(module_path),
|
|
2387
|
-
error.handler())
|
|
2627
|
+
factorylib.lib.psrd_initialize_study_data(_c_str(module_path), _bytes(module_path), error.handler())
|
|
2388
2628
|
if error.code != 0:
|
|
2389
2629
|
raise FactoryException(error.what)
|
|
2390
|
-
|
|
2630
|
+
_study_data_initialized = True
|
|
2631
|
+
|
|
2391
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
|
|
2392
2641
|
|
|
2393
2642
|
def _unload():
|
|
2394
2643
|
error = Error()
|
|
@@ -2421,44 +2670,69 @@ def create_study(*args, **kwargs) -> Study:
|
|
|
2421
2670
|
return Study.create_object(model_or_context, blocks)
|
|
2422
2671
|
|
|
2423
2672
|
|
|
2424
|
-
def load_study(study_path:
|
|
2673
|
+
def load_study(study_path: PathLike,
|
|
2425
2674
|
model_or_context: Union[str, Context, None] = None,
|
|
2426
2675
|
options: Optional[DataObject] = None) -> Study:
|
|
2427
2676
|
settings_only = False
|
|
2428
2677
|
return Study.load(study_path, model_or_context, settings_only, options)
|
|
2429
2678
|
|
|
2430
2679
|
|
|
2431
|
-
def load_study_settings(study_path:
|
|
2680
|
+
def load_study_settings(study_path: PathLike,
|
|
2432
2681
|
model_or_context: Union[str, Context, None] = None,
|
|
2433
2682
|
options: Optional[DataObject] = None) -> Study:
|
|
2434
2683
|
settings_only = True
|
|
2435
2684
|
return Study.load(study_path, model_or_context, settings_only, options)
|
|
2436
2685
|
|
|
2437
2686
|
|
|
2438
|
-
def create(
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
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())
|
|
2449
2705
|
if error.code != 0 or handler is None:
|
|
2450
2706
|
raise FactoryException(error.what)
|
|
2451
2707
|
data_object._hdr = handler
|
|
2452
2708
|
return data_object
|
|
2453
2709
|
|
|
2454
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
|
+
|
|
2455
2729
|
def get_default_context() -> "Context":
|
|
2456
|
-
|
|
2730
|
+
_check_basic_data_initialized()
|
|
2457
2731
|
return Context.default_context()
|
|
2458
2732
|
|
|
2459
2733
|
|
|
2460
2734
|
def get_new_context() -> "Context":
|
|
2461
|
-
|
|
2735
|
+
_check_basic_data_initialized()
|
|
2462
2736
|
return Context.create()
|
|
2463
2737
|
|
|
2464
2738
|
|