fmu-manipulation-toolbox 1.9.1.3__py3-none-any.whl → 1.9.2b2__py3-none-any.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.
- fmu_manipulation_toolbox/__main__.py +2 -2
- fmu_manipulation_toolbox/__version__.py +1 -1
- fmu_manipulation_toolbox/assembly.py +12 -8
- fmu_manipulation_toolbox/checker.py +4 -2
- fmu_manipulation_toolbox/cli/fmucontainer.py +27 -19
- fmu_manipulation_toolbox/cli/fmusplit.py +5 -2
- fmu_manipulation_toolbox/cli/fmutool.py +8 -3
- fmu_manipulation_toolbox/cli/utils.py +11 -1
- fmu_manipulation_toolbox/container.py +292 -82
- fmu_manipulation_toolbox/ls.py +35 -0
- fmu_manipulation_toolbox/operations.py +3 -2
- fmu_manipulation_toolbox/resources/darwin64/container.dylib +0 -0
- fmu_manipulation_toolbox/resources/linux32/client_sm.so +0 -0
- fmu_manipulation_toolbox/resources/linux64/client_sm.so +0 -0
- fmu_manipulation_toolbox/resources/linux64/container.so +0 -0
- fmu_manipulation_toolbox/resources/win32/client_sm.dll +0 -0
- fmu_manipulation_toolbox/resources/win32/server_sm.exe +0 -0
- fmu_manipulation_toolbox/resources/win64/client_sm.dll +0 -0
- fmu_manipulation_toolbox/resources/win64/container.dll +0 -0
- fmu_manipulation_toolbox/resources/win64/server_sm.exe +0 -0
- fmu_manipulation_toolbox/split.py +59 -3
- fmu_manipulation_toolbox/terminals.py +137 -0
- fmu_manipulation_toolbox/version.py +1 -1
- fmu_manipulation_toolbox-1.9.2b2.dist-info/METADATA +42 -0
- {fmu_manipulation_toolbox-1.9.1.3.dist-info → fmu_manipulation_toolbox-1.9.2b2.dist-info}/RECORD +29 -29
- {fmu_manipulation_toolbox-1.9.1.3.dist-info → fmu_manipulation_toolbox-1.9.2b2.dist-info}/entry_points.txt +1 -1
- {fmu_manipulation_toolbox-1.9.1.3.dist-info → fmu_manipulation_toolbox-1.9.2b2.dist-info}/licenses/LICENSE.txt +1 -1
- fmu_manipulation_toolbox/gui.py +0 -749
- fmu_manipulation_toolbox/gui_style.py +0 -252
- fmu_manipulation_toolbox-1.9.1.3.dist-info/METADATA +0 -30
- {fmu_manipulation_toolbox-1.9.1.3.dist-info → fmu_manipulation_toolbox-1.9.2b2.dist-info}/WHEEL +0 -0
- {fmu_manipulation_toolbox-1.9.1.3.dist-info → fmu_manipulation_toolbox-1.9.2b2.dist-info}/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@ import sys
|
|
|
3
3
|
|
|
4
4
|
def gui():
|
|
5
5
|
try:
|
|
6
|
-
from .gui import main
|
|
6
|
+
from .gui.gui import main
|
|
7
7
|
main()
|
|
8
8
|
except ModuleNotFoundError as e:
|
|
9
9
|
print(f"FATAL ERROR: {e}. No GUI Available.")
|
|
@@ -11,7 +11,7 @@ def gui():
|
|
|
11
11
|
|
|
12
12
|
def cli():
|
|
13
13
|
from .cli.fmutool import fmutool
|
|
14
|
-
fmutool(
|
|
14
|
+
fmutool()
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def main():
|
|
@@ -1 +1 @@
|
|
|
1
|
-
'V1.9.
|
|
1
|
+
'V1.9.2b2'
|
|
@@ -7,7 +7,7 @@ import uuid
|
|
|
7
7
|
import xml.parsers.expat
|
|
8
8
|
import zipfile
|
|
9
9
|
|
|
10
|
-
from .container import FMUContainer
|
|
10
|
+
from .container import FMUContainer
|
|
11
11
|
|
|
12
12
|
logger = logging.getLogger("fmu_manipulation_toolbox")
|
|
13
13
|
|
|
@@ -103,7 +103,8 @@ class AssemblyNode:
|
|
|
103
103
|
def add_start_value(self, fmu_filename: str, port_name: str, value: str):
|
|
104
104
|
self.start_values[Port(fmu_filename, port_name)] = value
|
|
105
105
|
|
|
106
|
-
def make_fmu(self, fmu_directory: Path, debug=False, description_pathname=None, fmi_version=2
|
|
106
|
+
def make_fmu(self, fmu_directory: Path, debug=False, description_pathname=None, fmi_version=2, datalog=False,
|
|
107
|
+
filename=None):
|
|
107
108
|
for node in self.children.values():
|
|
108
109
|
node.make_fmu(fmu_directory, debug=debug, fmi_version=fmi_version)
|
|
109
110
|
|
|
@@ -142,8 +143,11 @@ class AssemblyNode:
|
|
|
142
143
|
for link_rule in wired.rule_link:
|
|
143
144
|
self.add_link(link_rule[0], link_rule[1], link_rule[2], link_rule[3])
|
|
144
145
|
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
if filename is None:
|
|
147
|
+
filename = self.name
|
|
148
|
+
|
|
149
|
+
container.make_fmu(filename, self.step_size, mt=self.mt, profiling=self.profiling, sequential=self.sequential,
|
|
150
|
+
debug=debug, ts_multiplier=self.ts_multiplier, datalog=datalog)
|
|
147
151
|
|
|
148
152
|
for node in self.children.values():
|
|
149
153
|
logger.info(f"Deleting transient FMU Container '{node.name}'")
|
|
@@ -241,7 +245,7 @@ class Assembly:
|
|
|
241
245
|
self.transient_dirnames: Set[Path] = set()
|
|
242
246
|
|
|
243
247
|
if not fmu_directory.is_dir():
|
|
244
|
-
raise AssemblyError(f"FMU directory is not valid: '{fmu_directory}'")
|
|
248
|
+
raise AssemblyError(f"FMU directory is not valid: '{fmu_directory.resolve()}'")
|
|
245
249
|
|
|
246
250
|
self.input_pathname = fmu_directory / self.filename
|
|
247
251
|
self.description_pathname = self.input_pathname # For inclusion in FMU
|
|
@@ -284,7 +288,7 @@ class Assembly:
|
|
|
284
288
|
elif filename.endswith(".json"):
|
|
285
289
|
return self.write_json(filename)
|
|
286
290
|
else:
|
|
287
|
-
|
|
291
|
+
raise AssemblyError(f"Unable to write to '{filename}': format unsupported.")
|
|
288
292
|
|
|
289
293
|
def read_csv(self):
|
|
290
294
|
name = str(self.filename.with_suffix(".fmu"))
|
|
@@ -525,9 +529,9 @@ class Assembly:
|
|
|
525
529
|
self.root = sdd.parse(self.description_pathname)
|
|
526
530
|
self.root.name = str(self.filename.with_suffix(".fmu"))
|
|
527
531
|
|
|
528
|
-
def make_fmu(self, dump_json=False, fmi_version=2):
|
|
532
|
+
def make_fmu(self, dump_json=False, fmi_version=2, datalog=False, filename=None):
|
|
529
533
|
self.root.make_fmu(self.fmu_directory, debug=self.debug, description_pathname=self.description_pathname,
|
|
530
|
-
fmi_version=fmi_version)
|
|
534
|
+
fmi_version=fmi_version, datalog=datalog, filename=filename)
|
|
531
535
|
if dump_json:
|
|
532
536
|
dump_file = Path(self.input_pathname.stem + "-dump").with_suffix(".json")
|
|
533
537
|
logger.info(f"Dump Json '{dump_file}'")
|
|
@@ -27,11 +27,11 @@ class OperationGenericCheck(OperationAbstract):
|
|
|
27
27
|
return
|
|
28
28
|
|
|
29
29
|
fmi_name = f"fmi{attrs['fmiVersion'][0]}"
|
|
30
|
-
|
|
31
30
|
xsd_filename = os.path.join(os.path.dirname(__file__), "resources", "fmi-" + attrs['fmiVersion'],
|
|
32
31
|
f"{fmi_name}ModelDescription.xsd")
|
|
32
|
+
xsd = xmlschema.XMLSchema(xsd_filename)
|
|
33
33
|
try:
|
|
34
|
-
|
|
34
|
+
xsd.validate(self.fmu.descriptor_filename)
|
|
35
35
|
except XMLSchemaValidationError as error:
|
|
36
36
|
logger.error(error.reason, error.msg)
|
|
37
37
|
else:
|
|
@@ -43,8 +43,10 @@ class OperationGenericCheck(OperationAbstract):
|
|
|
43
43
|
else:
|
|
44
44
|
logger.error(f"This FMU does not validate with FMI standard.")
|
|
45
45
|
|
|
46
|
+
|
|
46
47
|
_checkers_list: List[type[OperationAbstract]] = [OperationGenericCheck]
|
|
47
48
|
|
|
49
|
+
|
|
48
50
|
def get_checkers() -> List[type[OperationAbstract]]:
|
|
49
51
|
if sys.version_info < (3, 10):
|
|
50
52
|
from importlib_metadata import entry_points
|
|
@@ -4,7 +4,7 @@ import sys
|
|
|
4
4
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
|
-
from .utils import setup_logger, make_wide
|
|
7
|
+
from .utils import setup_logger, close_logger, make_wide
|
|
8
8
|
from ..assembly import Assembly, AssemblyError
|
|
9
9
|
from ..container import FMUContainerError
|
|
10
10
|
from ..version import __version__ as version
|
|
@@ -22,36 +22,42 @@ def fmucontainer():
|
|
|
22
22
|
|
|
23
23
|
parser.add_argument('-h', '-help', action="help")
|
|
24
24
|
|
|
25
|
-
parser.add_argument("-fmu-directory", action="store", dest="fmu_directory", required=False, default=".",
|
|
26
|
-
help="Directory containing initial FMU’s and used to generate containers. "
|
|
27
|
-
"If not defined, current directory is used.")
|
|
28
|
-
|
|
29
|
-
parser.add_argument("-fmi", action="store", dest="fmi_version", required=False, default="2",
|
|
30
|
-
help="Define version of FMI to be used for container interface."
|
|
31
|
-
"Only '2' or '3' is supported.")
|
|
32
|
-
|
|
33
25
|
parser.add_argument("-container", action="append", dest="container_descriptions_list", default=[],
|
|
34
26
|
metavar="filename.{csv|json|ssp},[:step_size]", required=True,
|
|
35
27
|
help="Description of the container to create.")
|
|
36
28
|
|
|
29
|
+
parser.add_argument("-datalog", action="store_true", dest="datalog", default=False,
|
|
30
|
+
help="Log into log file input, output and local variables of the container")
|
|
31
|
+
|
|
37
32
|
parser.add_argument("-debug", action="store_true", dest="debug",
|
|
38
33
|
help="Add lot of useful log during the process.")
|
|
39
34
|
|
|
35
|
+
parser.add_argument("-dump-json", action="store_true", dest="dump", default=False,
|
|
36
|
+
help="Dump a JSON file for each container.")
|
|
37
|
+
|
|
38
|
+
parser.add_argument("-fmi", action="store", dest="fmi_version", required=False, default="2",
|
|
39
|
+
help="Define version of FMI to be used for container interface."
|
|
40
|
+
"Only '2' or '3' is supported.")
|
|
41
|
+
|
|
42
|
+
parser.add_argument("-fmu-directory", action="store", dest="fmu_directory", required=False, default=".",
|
|
43
|
+
help="Directory containing initial FMU’s and used to generate containers. "
|
|
44
|
+
"If not defined, current directory is used.")
|
|
45
|
+
|
|
40
46
|
parser.add_argument("-no-auto-input", action="store_false", dest="auto_input", default=True,
|
|
41
47
|
help="Create ONLY explicit input.")
|
|
42
48
|
|
|
49
|
+
parser.add_argument("-no-auto-link", action="store_false", dest="auto_link", default=True,
|
|
50
|
+
help="Create ONLY explicit links.")
|
|
51
|
+
|
|
52
|
+
parser.add_argument("-auto-local", action="store_true", dest="auto_local", default=False,
|
|
53
|
+
help="Expose local variables of the embedded fmu's.")
|
|
54
|
+
|
|
43
55
|
parser.add_argument("-no-auto-output", action="store_false", dest="auto_output", default=True,
|
|
44
56
|
help="Create ONLY explicit output.")
|
|
45
57
|
|
|
46
58
|
parser.add_argument("-auto-parameter", action="store_true", dest="auto_parameter", default=False,
|
|
47
59
|
help="Expose parameters of the embedded fmu's.")
|
|
48
60
|
|
|
49
|
-
parser.add_argument("-auto-local", action="store_true", dest="auto_local", default=False,
|
|
50
|
-
help="Expose local variables of the embedded fmu's.")
|
|
51
|
-
|
|
52
|
-
parser.add_argument("-no-auto-link", action="store_false", dest="auto_link", default=True,
|
|
53
|
-
help="Create ONLY explicit links.")
|
|
54
|
-
|
|
55
61
|
parser.add_argument("-mt", action="store_true", dest="mt", default=False,
|
|
56
62
|
help="Enable Multi-Threaded mode for the generated container.")
|
|
57
63
|
|
|
@@ -61,9 +67,6 @@ def fmucontainer():
|
|
|
61
67
|
parser.add_argument("-sequential", action="store_true", dest="sequential", default=False,
|
|
62
68
|
help="Use sequential mode to schedule embedded fmu's.")
|
|
63
69
|
|
|
64
|
-
parser.add_argument("-dump-json", action="store_true", dest="dump", default=False,
|
|
65
|
-
help="Dump a JSON file for each container.")
|
|
66
|
-
|
|
67
70
|
parser.add_argument("-vr", action="store_true", dest="ts_multiplier", default=False,
|
|
68
71
|
help="Add TS_MULTIPLIER input port to control step_size")
|
|
69
72
|
|
|
@@ -92,16 +95,21 @@ def fmucontainer():
|
|
|
92
95
|
auto_parameter=config.auto_parameter, ts_multiplier=config.ts_multiplier)
|
|
93
96
|
except FileNotFoundError as e:
|
|
94
97
|
logger.fatal(f"Cannot read file: {e}")
|
|
98
|
+
close_logger(logger)
|
|
95
99
|
sys.exit(-1)
|
|
96
100
|
except (FMUContainerError, AssemblyError) as e:
|
|
97
101
|
logger.fatal(f"{filename}: {e}")
|
|
102
|
+
close_logger(logger)
|
|
98
103
|
sys.exit(-2)
|
|
99
104
|
|
|
100
105
|
try:
|
|
101
|
-
assembly.make_fmu(dump_json=config.dump, fmi_version=int(config.fmi_version))
|
|
106
|
+
assembly.make_fmu(dump_json=config.dump, fmi_version=int(config.fmi_version), datalog=config.datalog)
|
|
102
107
|
except FMUContainerError as e:
|
|
103
108
|
logger.fatal(f"{filename}: {e}")
|
|
109
|
+
close_logger(logger)
|
|
104
110
|
sys.exit(-3)
|
|
105
111
|
|
|
112
|
+
close_logger(logger)
|
|
113
|
+
|
|
106
114
|
if __name__ == "__main__":
|
|
107
115
|
fmucontainer()
|
|
@@ -2,8 +2,7 @@ import argparse
|
|
|
2
2
|
import logging
|
|
3
3
|
import sys
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
from .utils import setup_logger, make_wide
|
|
5
|
+
from .utils import setup_logger, close_logger, make_wide
|
|
7
6
|
from ..split import FMUSplitter, FMUSplitterError
|
|
8
7
|
from ..version import __version__ as version
|
|
9
8
|
|
|
@@ -37,11 +36,15 @@ def fmusplit():
|
|
|
37
36
|
splitter.split_fmu()
|
|
38
37
|
except FMUSplitterError as e:
|
|
39
38
|
logger.fatal(f"{fmu_filename}: {e}")
|
|
39
|
+
close_logger(logger)
|
|
40
40
|
sys.exit(-1)
|
|
41
41
|
except FileNotFoundError as e:
|
|
42
42
|
logger.fatal(f"Cannot read file: {e}")
|
|
43
|
+
close_logger(logger)
|
|
43
44
|
sys.exit(-2)
|
|
44
45
|
|
|
46
|
+
close_logger(logger)
|
|
47
|
+
|
|
45
48
|
|
|
46
49
|
if __name__ == "__main__":
|
|
47
50
|
fmusplit()
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import sys
|
|
3
3
|
|
|
4
|
-
from
|
|
5
|
-
|
|
6
|
-
from .utils import setup_logger, make_wide
|
|
4
|
+
from .utils import setup_logger, close_logger, make_wide
|
|
7
5
|
from ..operations import (OperationSummary, OperationError, OperationRemoveRegexp,
|
|
8
6
|
OperationRemoveSources, OperationTrimUntil, OperationKeepOnlyRegexp, OperationMergeTopLevel,
|
|
9
7
|
OperationStripTopLevel, OperationRenameFromCSV, OperationSaveNamesToCSV, FMU, FMUError)
|
|
@@ -78,6 +76,7 @@ def fmutool():
|
|
|
78
76
|
|
|
79
77
|
if cli_options.fmu_input == cli_options.fmu_output:
|
|
80
78
|
logger.fatal(f"'-input' and '-output' should point to different files.")
|
|
79
|
+
close_logger(logger)
|
|
81
80
|
sys.exit(-3)
|
|
82
81
|
|
|
83
82
|
logger.info(f"READING Input='{cli_options.fmu_input}'")
|
|
@@ -85,6 +84,7 @@ def fmutool():
|
|
|
85
84
|
fmu = FMU(cli_options.fmu_input)
|
|
86
85
|
except FMUError as reason:
|
|
87
86
|
logger.fatal(f"{reason}")
|
|
87
|
+
close_logger(logger)
|
|
88
88
|
sys.exit(-4)
|
|
89
89
|
|
|
90
90
|
if cli_options.apply_on:
|
|
@@ -107,6 +107,7 @@ def fmutool():
|
|
|
107
107
|
fmu.apply_operation(operation, cli_options.apply_on)
|
|
108
108
|
except OperationError as reason:
|
|
109
109
|
logger.fatal(f"{reason}")
|
|
110
|
+
close_logger(logger)
|
|
110
111
|
sys.exit(-6)
|
|
111
112
|
|
|
112
113
|
if cli_options.extract_description:
|
|
@@ -119,9 +120,13 @@ def fmutool():
|
|
|
119
120
|
fmu.repack(cli_options.fmu_output)
|
|
120
121
|
except FMUError as reason:
|
|
121
122
|
logger.fatal(f"FATAL ERROR: {reason}")
|
|
123
|
+
close_logger(logger)
|
|
122
124
|
sys.exit(-5)
|
|
123
125
|
else:
|
|
124
126
|
logger.info(f"INFO Modified FMU is not saved. If necessary use '-output' option.")
|
|
125
127
|
|
|
128
|
+
close_logger(logger)
|
|
129
|
+
|
|
130
|
+
|
|
126
131
|
if __name__ == "__main__":
|
|
127
132
|
fmutool()
|
|
@@ -2,7 +2,8 @@ import logging
|
|
|
2
2
|
import sys
|
|
3
3
|
from colorama import Fore, Style, init
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
def setup_logger() -> logging.Logger:
|
|
6
7
|
class CustomFormatter(logging.Formatter):
|
|
7
8
|
def format(self, record):
|
|
8
9
|
log_format = "%(levelname)-8s | %(message)s"
|
|
@@ -24,6 +25,15 @@ def setup_logger():
|
|
|
24
25
|
|
|
25
26
|
return logger
|
|
26
27
|
|
|
28
|
+
|
|
29
|
+
def close_logger(logger: logging.Logger):
|
|
30
|
+
for handler in logger.handlers:
|
|
31
|
+
logger.removeHandler(handler)
|
|
32
|
+
handler.close()
|
|
33
|
+
logger.setLevel(logging.NOTSET)
|
|
34
|
+
logger.propagate = True
|
|
35
|
+
|
|
36
|
+
|
|
27
37
|
def make_wide(formatter, w=120, h=36):
|
|
28
38
|
"""Return a wider HelpFormatter, if possible."""
|
|
29
39
|
try:
|