fmu-manipulation-toolbox 1.9rc6__tar.gz → 1.9rc8__tar.gz
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-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/PKG-INFO +1 -1
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/README.md +49 -20
- fmu_manipulation_toolbox-1.9rc8/fmu_manipulation_toolbox/__version__.py +1 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/cli/fmucontainer.py +8 -6
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/cli/fmusplit.py +8 -5
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/cli/fmutool.py +15 -4
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/container.py +19 -16
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/operations.py +10 -6
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/remoting.py +4 -2
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/darwin64/container.dylib +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/linux32/client_sm.so +0 -0
- fmu_manipulation_toolbox-1.9rc8/fmu_manipulation_toolbox/resources/linux32/server_sm +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/linux64/client_sm.so +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/linux64/container.so +0 -0
- fmu_manipulation_toolbox-1.9rc8/fmu_manipulation_toolbox/resources/linux64/server_sm +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/win32/client_sm.dll +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/win32/server_sm.exe +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/win64/client_sm.dll +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/win64/container.dll +0 -0
- fmu_manipulation_toolbox-1.9rc8/fmu_manipulation_toolbox/resources/win64/server_sm.exe +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/split.py +8 -3
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox.egg-info/PKG-INFO +1 -1
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/tests/test_suite.py +75 -5
- fmu_manipulation_toolbox-1.9rc6/fmu_manipulation_toolbox/__version__.py +0 -1
- fmu_manipulation_toolbox-1.9rc6/fmu_manipulation_toolbox/resources/linux32/server_sm +0 -0
- fmu_manipulation_toolbox-1.9rc6/fmu_manipulation_toolbox/resources/linux64/server_sm +0 -0
- fmu_manipulation_toolbox-1.9rc6/fmu_manipulation_toolbox/resources/win64/server_sm.exe +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/LICENSE.txt +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/__init__.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/__main__.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/assembly.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/checker.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/cli/__init__.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/cli/utils.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/gui.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/gui_style.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/help.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/checkbox-checked-disabled.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/checkbox-checked-hover.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/checkbox-checked.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/checkbox-unchecked-disabled.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/checkbox-unchecked-hover.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/checkbox-unchecked.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/container.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/drop_fmu.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2Annotation.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2AttributeGroups.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2ModelDescription.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2ScalarVariable.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2Type.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2Unit.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2VariableDependency.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Annotation.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3AttributeGroups.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3BuildDescription.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3InterfaceType.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3LayeredStandardManifest.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3ModelDescription.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Terminal.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3TerminalsAndIcons.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Type.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Unit.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Variable.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3VariableDependency.xsd +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmu.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/fmu_manipulation_toolbox.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/help.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/icon-round.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/icon.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/icon_fmu.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/license.txt +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/mask.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/resources/model.png +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/version.py +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox.egg-info/SOURCES.txt +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox.egg-info/dependency_links.txt +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox.egg-info/entry_points.txt +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox.egg-info/requires.txt +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox.egg-info/top_level.txt +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/setup.cfg +0 -0
- {fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fmu_manipulation_toolbox
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.9rc8
|
|
4
4
|
Summary: FMU Manipulation Toolbox is a python application for modifying Functional Mock-up Units (FMUs) without recompilation or bundling them into FMU Containers
|
|
5
5
|
Home-page: https://github.com/grouperenault/fmu_manipulation_toolbox/
|
|
6
6
|
Author: Nicolas.LAURENT@Renault.com
|
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-

|
|
2
2
|
|
|
3
|
-
FMU Manipulation Toolbox is a python package which help to analyse
|
|
4
|
-
without recompilation. It is highly customizable
|
|
3
|
+
FMU Manipulation Toolbox is a python package which help to analyse, modify or combine
|
|
4
|
+
[Functional Mock-up Units (FMUs)](http://fmi-standard.org/) without recompilation. It is highly customizable as it comes with
|
|
5
|
+
a Python API.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
FMU Manipulation Toolbox can be used in different ways :
|
|
8
|
+
- Using a Graphical User Interface: suitable for end user
|
|
9
|
+
- Using a Command Line Interface: useful in
|
|
10
|
+
- Using a python API: the most efficient for automation (CI/CD, transformation scripts, ...)
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
Major features:
|
|
13
|
+
- Analyse FMU content: list ports and their attributes, check compliance of `ModelDescription.xml` with XSD, ...
|
|
14
|
+
- Alter FMU by modifying its `modelDescription.xml` file. NOTE: manipulating this file can be a dangerous
|
|
15
|
+
thing! Communicating with the FMU-developer and adapting the way the FMU is generated is preferable when
|
|
16
|
+
possible.
|
|
17
|
+
- Add binary interface. Typical use case is porting a 32bits FMUs to 64bits (or vice et versa).
|
|
18
|
+
- Nest FMUs in a [FMU Container](doc/container.md)
|
|
19
|
+
|
|
20
|
+
FMI versions 2.0 and 3.0 are supported.
|
|
10
21
|
|
|
11
22
|
## Installation
|
|
12
23
|
|
|
@@ -17,29 +28,39 @@ Two options available to install FMU Manipulation Toolbox:
|
|
|
17
28
|
- Compile and install from [github repository](https://github.com/grouperenault/fmu_manipulation_toolbox). You will need
|
|
18
29
|
- Python required packages. See [`requirements.txt`](requirements.txt).
|
|
19
30
|
- C compiler (C99 or later)
|
|
20
|
-
- CMake (>= 3.
|
|
31
|
+
- CMake (>= 3.20)
|
|
32
|
+
|
|
21
33
|
|
|
22
34
|
### Supported platforms
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
|
|
36
|
+
FMU Manipulation Toolbox is packaged for:
|
|
37
|
+
- Windows 10/11 (primary platform)
|
|
25
38
|
- Linux (Ubuntu 22.04)
|
|
39
|
+
- Darwin
|
|
26
40
|
|
|
27
|
-
Compilation is reported to work on:
|
|
28
|
-
- MacOS (Apple Silicon and Intel)
|
|
29
41
|
|
|
30
42
|
## Graphical User Interface
|
|
31
43
|
|
|
32
|
-
FMU Manipulation Toolbox is released with a GUI. You can launch it with the following command `fmutool`
|
|
33
|
-
(without any option)
|
|
44
|
+
FMU Manipulation Toolbox is released with a GUI. You can launch it with the following command `fmutool-gui`
|
|
34
45
|
|
|
35
46
|

|
|
36
47
|
|
|
48
|
+
Button colors descriptions:
|
|
49
|
+
- red: remove information from the `modelDescription.xml`
|
|
50
|
+
- orange: alter `modelDescription.xml`
|
|
51
|
+
- green: add component into the FMU or check it
|
|
52
|
+
- violet: extract and save
|
|
53
|
+
- blue: filter actions scope or exit
|
|
54
|
+
|
|
55
|
+
**Original FMU is never modified**. Use `Save` button to get modified copy of the original FMU.
|
|
56
|
+
|
|
37
57
|
|
|
38
58
|
## Command Line Interface
|
|
39
59
|
|
|
40
60
|
FMU Manipulation Toolbox comes with 2 commands:
|
|
41
61
|
- `fmutool`: a versatile analysis and manipulation tool for FMU.
|
|
42
|
-
- `fmucontainer`: group
|
|
62
|
+
- `fmucontainer`: group FMUs inside FMU Containers. (see [container/README.md](container/README.md))
|
|
63
|
+
- `fmusplit: to extract FMUs from a FMU Container.
|
|
43
64
|
|
|
44
65
|
|
|
45
66
|
### Analysis and Manipulation tool:
|
|
@@ -163,14 +184,13 @@ You can write your own FMU Manipulation scripts. Once you downloaded fmutool mod
|
|
|
163
184
|
adding the `import` statement lets you access the API :
|
|
164
185
|
|
|
165
186
|
```python
|
|
166
|
-
from fmu_manipulation_toolbox.operations import
|
|
167
|
-
|
|
168
|
-
OperationRenameFromCSV
|
|
187
|
+
from fmu_manipulation_toolbox.operations import ...
|
|
169
188
|
```
|
|
170
189
|
|
|
190
|
+
|
|
171
191
|
### remove toplevel bus (if any)
|
|
172
192
|
|
|
173
|
-
|
|
193
|
+
Given a FMU with the following I/O structure
|
|
174
194
|
```
|
|
175
195
|
├── Parameters
|
|
176
196
|
│ ├── Foo
|
|
@@ -194,6 +214,8 @@ The following transformation will lead into:
|
|
|
194
214
|
|
|
195
215
|
The following code will do this transformation:
|
|
196
216
|
```python
|
|
217
|
+
from fmu_manipulation_toolbox.operations import FMU, OperationStripTopLevel
|
|
218
|
+
|
|
197
219
|
fmu = FMU(r"bouncing_ball.fmu")
|
|
198
220
|
operation = OperationStripTopLevel()
|
|
199
221
|
fmu.apply_operation(operation)
|
|
@@ -205,8 +227,10 @@ fmu.repack(r"bouncing_ball-modified.fmu")
|
|
|
205
227
|
The following code will dump all FMU's Scalars names into a CSV:
|
|
206
228
|
|
|
207
229
|
```python
|
|
230
|
+
from fmu_manipulation_toolbox.operations import FMU, OperationSaveNamesToCSV
|
|
231
|
+
|
|
208
232
|
fmu = FMU(r"bouncing_ball.fmu")
|
|
209
|
-
operation =
|
|
233
|
+
operation = OperationSaveNamesToCSV()
|
|
210
234
|
fmu.apply_operation(operation)
|
|
211
235
|
operation.write_csv(r"bouncing_ball.csv")
|
|
212
236
|
```
|
|
@@ -224,15 +248,20 @@ g;g;4;parameter;fixed
|
|
|
224
248
|
e;e;5;parameter;tunable
|
|
225
249
|
```
|
|
226
250
|
|
|
251
|
+
|
|
227
252
|
### Read CSV and rename FMU ports
|
|
228
253
|
|
|
229
|
-
CSV file should contain
|
|
254
|
+
CSV file should contain 2 columns:
|
|
230
255
|
1. the current name
|
|
231
256
|
2. the new name
|
|
232
257
|
|
|
233
258
|
```python
|
|
259
|
+
from fmu_manipulation_toolbox.operations import FMU, OperationRenameFromCSV
|
|
260
|
+
|
|
234
261
|
fmu = FMU(r"bouncing_ball.fmu")
|
|
235
262
|
operation = OperationRenameFromCSV(r"bouncing_ball-modified.csv")
|
|
236
263
|
fmu.apply_operation(operation)
|
|
237
264
|
fmu.repack(r"bouncing_ball-renamed.fmu")
|
|
238
265
|
```
|
|
266
|
+
|
|
267
|
+
More operations exist in [`Operation.py`](fmu_manipulation_toolbox/operations.py)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'V1.9-rc8'
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import logging
|
|
3
|
+
import sys
|
|
3
4
|
|
|
5
|
+
from typing import *
|
|
4
6
|
from pathlib import Path
|
|
5
7
|
|
|
6
8
|
from .utils import setup_logger, make_wide
|
|
@@ -9,7 +11,7 @@ from ..container import FMUContainerError
|
|
|
9
11
|
from ..version import __version__ as version
|
|
10
12
|
|
|
11
13
|
|
|
12
|
-
def fmucontainer():
|
|
14
|
+
def fmucontainer(command_options: Sequence[str]):
|
|
13
15
|
logger = setup_logger()
|
|
14
16
|
|
|
15
17
|
logger.info(f"FMUContainer version {version}")
|
|
@@ -63,7 +65,7 @@ def fmucontainer():
|
|
|
63
65
|
parser.add_argument("-dump-json", action="store_true", dest="dump", default=False,
|
|
64
66
|
help="Dump a JSON file for each container.")
|
|
65
67
|
|
|
66
|
-
config = parser.parse_args()
|
|
68
|
+
config = parser.parse_args(command_options)
|
|
67
69
|
|
|
68
70
|
if config.debug:
|
|
69
71
|
logger.setLevel(logging.DEBUG)
|
|
@@ -88,16 +90,16 @@ def fmucontainer():
|
|
|
88
90
|
auto_parameter=config.auto_parameter)
|
|
89
91
|
except FileNotFoundError as e:
|
|
90
92
|
logger.fatal(f"Cannot read file: {e}")
|
|
91
|
-
|
|
93
|
+
sys.exit(-1)
|
|
92
94
|
except (FMUContainerError, AssemblyError) as e:
|
|
93
95
|
logger.fatal(f"{filename}: {e}")
|
|
94
|
-
|
|
96
|
+
sys.exit(-2)
|
|
95
97
|
|
|
96
98
|
try:
|
|
97
99
|
assembly.make_fmu(dump_json=config.dump, fmi_version=int(config.fmi_version))
|
|
98
100
|
except FMUContainerError as e:
|
|
99
101
|
logger.fatal(f"{filename}: {e}")
|
|
100
|
-
|
|
102
|
+
sys.exit(-3)
|
|
101
103
|
|
|
102
104
|
if __name__ == "__main__":
|
|
103
|
-
fmucontainer()
|
|
105
|
+
fmucontainer(sys.argv[1:])
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import logging
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
from typing import *
|
|
3
6
|
|
|
4
7
|
from .utils import setup_logger, make_wide
|
|
5
8
|
from ..split import FMUSplitter, FMUSplitterError
|
|
6
9
|
from ..version import __version__ as version
|
|
7
10
|
|
|
8
11
|
|
|
9
|
-
def fmusplit():
|
|
12
|
+
def fmusplit(command_options: Sequence[str]):
|
|
10
13
|
logger = setup_logger()
|
|
11
14
|
|
|
12
15
|
logger.info(f"FMUSplit version {version}")
|
|
@@ -24,7 +27,7 @@ def fmusplit():
|
|
|
24
27
|
metavar="filename.fmu", required=True,
|
|
25
28
|
help="Description of the FMU container to split.")
|
|
26
29
|
|
|
27
|
-
config = parser.parse_args()
|
|
30
|
+
config = parser.parse_args(command_options)
|
|
28
31
|
|
|
29
32
|
if config.debug:
|
|
30
33
|
logger.setLevel(logging.DEBUG)
|
|
@@ -35,11 +38,11 @@ def fmusplit():
|
|
|
35
38
|
splitter.split_fmu()
|
|
36
39
|
except FMUSplitterError as e:
|
|
37
40
|
logger.fatal(f"{fmu_filename}: {e}")
|
|
38
|
-
|
|
41
|
+
sys.exit(-1)
|
|
39
42
|
except FileNotFoundError as e:
|
|
40
43
|
logger.fatal(f"Cannot read file: {e}")
|
|
41
|
-
|
|
44
|
+
sys.exit(-2)
|
|
42
45
|
|
|
43
46
|
|
|
44
47
|
if __name__ == "__main__":
|
|
45
|
-
fmusplit()
|
|
48
|
+
fmusplit(sys.argv[1:])
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import sys
|
|
3
3
|
|
|
4
|
+
from typing import *
|
|
5
|
+
|
|
4
6
|
from .utils import setup_logger, make_wide
|
|
5
7
|
from ..operations import (OperationSummary, OperationError, OperationRemoveRegexp,
|
|
6
8
|
OperationRemoveSources, OperationTrimUntil, OperationKeepOnlyRegexp, OperationMergeTopLevel,
|
|
@@ -12,7 +14,7 @@ from ..version import __version__ as version
|
|
|
12
14
|
from ..help import Help
|
|
13
15
|
|
|
14
16
|
|
|
15
|
-
def fmutool():
|
|
17
|
+
def fmutool(command_options: Sequence[str]):
|
|
16
18
|
logger = setup_logger()
|
|
17
19
|
|
|
18
20
|
logger.info(f"FMU Manipulation Toolbox version {version}")
|
|
@@ -68,7 +70,7 @@ def fmutool():
|
|
|
68
70
|
add_option('-summary', action='append_const', dest='operations_list', const=OperationSummary())
|
|
69
71
|
add_option('-check', action='append_const', dest='operations_list', const=[checker() for checker in checker_list])
|
|
70
72
|
|
|
71
|
-
cli_options = parser.parse_args()
|
|
73
|
+
cli_options = parser.parse_args(command_options)
|
|
72
74
|
# handle the "no operation" use case
|
|
73
75
|
if not cli_options.operations_list:
|
|
74
76
|
cli_options.operations_list = []
|
|
@@ -89,7 +91,16 @@ def fmutool():
|
|
|
89
91
|
for causality in cli_options.apply_on:
|
|
90
92
|
logger.info(f" - causality = {causality}")
|
|
91
93
|
|
|
92
|
-
|
|
94
|
+
# Checker operations are added as a list into operations_list
|
|
95
|
+
def operation_iterator():
|
|
96
|
+
for op in cli_options.operations_list:
|
|
97
|
+
if isinstance(op, list):
|
|
98
|
+
for sub_op in op:
|
|
99
|
+
yield sub_op
|
|
100
|
+
else:
|
|
101
|
+
yield op
|
|
102
|
+
|
|
103
|
+
for operation in operation_iterator():
|
|
93
104
|
logger.info(f" => {operation}")
|
|
94
105
|
try:
|
|
95
106
|
fmu.apply_operation(operation, cli_options.apply_on)
|
|
@@ -112,4 +123,4 @@ def fmutool():
|
|
|
112
123
|
logger.info(f"INFO Modified FMU is not saved. If necessary use '-output' option.")
|
|
113
124
|
|
|
114
125
|
if __name__ == "__main__":
|
|
115
|
-
fmutool()
|
|
126
|
+
fmutool(sys.argv[1:])
|
|
@@ -796,23 +796,26 @@ class FMUContainer:
|
|
|
796
796
|
def make_fmu_xml_epilog_2(self, xml_file, index_offset):
|
|
797
797
|
xml_file.write(" </ModelVariables>\n"
|
|
798
798
|
"\n"
|
|
799
|
-
" <ModelStructure>\n"
|
|
800
|
-
" <Outputs>\n")
|
|
799
|
+
" <ModelStructure>\n")
|
|
801
800
|
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
801
|
+
|
|
802
|
+
if self.outputs:
|
|
803
|
+
xml_file.write(" <Outputs>\n")
|
|
804
|
+
index = index_offset
|
|
805
|
+
for output in self.outputs.values():
|
|
806
|
+
if output.port.type_name in EmbeddedFMUPort.CONTAINER_TO_FMI[2]:
|
|
807
|
+
print(f' <Unknown index="{index}"/>', file=xml_file)
|
|
808
|
+
index += 1
|
|
809
|
+
xml_file.write(" </Outputs>\n"
|
|
810
|
+
" <InitialUnknowns>\n")
|
|
811
|
+
index = index_offset
|
|
812
|
+
for output in self.outputs.values():
|
|
813
|
+
if output.port.type_name in EmbeddedFMUPort.CONTAINER_TO_FMI[2]:
|
|
814
|
+
print(f' <Unknown index="{index}"/>', file=xml_file)
|
|
815
|
+
index += 1
|
|
816
|
+
xml_file.write(" </InitialUnknowns>\n")
|
|
817
|
+
|
|
818
|
+
xml_file.write(" </ModelStructure>\n"
|
|
816
819
|
"\n"
|
|
817
820
|
"</fmiModelDescription>")
|
|
818
821
|
|
|
@@ -416,8 +416,8 @@ class OperationSummary(OperationAbstract):
|
|
|
416
416
|
hash_md5.update(chunk)
|
|
417
417
|
digest = hash_md5.hexdigest()
|
|
418
418
|
logger.info(f"| MD5Sum = {digest}")
|
|
419
|
-
|
|
420
|
-
logger.info(f"
|
|
419
|
+
logger.info(f"|")
|
|
420
|
+
logger.info(f"| FMI properties: ")
|
|
421
421
|
for (k, v) in attrs.items():
|
|
422
422
|
logger.info(f"| - {k} = {v}")
|
|
423
423
|
logger.info(f"|")
|
|
@@ -457,21 +457,25 @@ class OperationSummary(OperationAbstract):
|
|
|
457
457
|
|
|
458
458
|
resource_dir = os.path.join(self.fmu.tmp_directory, "resources")
|
|
459
459
|
if os.path.isdir(resource_dir):
|
|
460
|
-
logger.info("
|
|
460
|
+
logger.info("|")
|
|
461
|
+
logger.info("| Embedded resources:")
|
|
461
462
|
for resource in os.listdir(resource_dir):
|
|
462
463
|
logger.info(f"| - {resource}")
|
|
463
464
|
|
|
464
465
|
extra_dir = os.path.join(self.fmu.tmp_directory, "extra")
|
|
465
466
|
if os.path.isdir(extra_dir):
|
|
466
|
-
logger.info("
|
|
467
|
+
logger.info("|")
|
|
468
|
+
logger.info("| Additional (meta-)data:")
|
|
467
469
|
for extra in os.listdir(extra_dir):
|
|
468
470
|
logger.info(f"| - {extra}")
|
|
469
471
|
|
|
470
|
-
logger.info("
|
|
472
|
+
logger.info("|")
|
|
473
|
+
logger.info("| Number of ports")
|
|
471
474
|
for causality, nb_ports in self.nb_port_per_causality.items():
|
|
472
475
|
logger.info(f"| {causality} : {nb_ports}")
|
|
473
476
|
|
|
474
|
-
logger.info("
|
|
477
|
+
logger.info("|")
|
|
478
|
+
logger.info("| [End of report]")
|
|
475
479
|
|
|
476
480
|
|
|
477
481
|
class OperationRemoveSources(OperationAbstract):
|
|
@@ -60,9 +60,11 @@ class OperationAddRemotingWinAbstract(OperationAbstract):
|
|
|
60
60
|
fmu_bin[self.bitness_to] / "license.txt")
|
|
61
61
|
|
|
62
62
|
def port_attrs(self, fmu_port) -> int:
|
|
63
|
+
vr = int(fmu_port["valueReference"])
|
|
64
|
+
causality = fmu_port.get("causality", "local")
|
|
63
65
|
try:
|
|
64
|
-
self.vr[fmu_port.fmi_type].append(
|
|
65
|
-
if
|
|
66
|
+
self.vr[fmu_port.fmi_type].append(vr)
|
|
67
|
+
if causality in ("input", "parameter"):
|
|
66
68
|
self.nb_input += 1
|
|
67
69
|
else:
|
|
68
70
|
self.nb_output += 1
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -6,6 +6,8 @@ import xml.parsers.expat
|
|
|
6
6
|
from typing import *
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
|
+
from .container import EmbeddedFMUPort
|
|
10
|
+
|
|
9
11
|
logger = logging.getLogger("fmu_manipulation_toolbox")
|
|
10
12
|
|
|
11
13
|
|
|
@@ -66,7 +68,7 @@ class FMUSplitter:
|
|
|
66
68
|
def split_fmu(self):
|
|
67
69
|
logger.info(f"Splitting...")
|
|
68
70
|
config = self._split_fmu(fmu_filename=str(self.fmu_filename), relative_path="")
|
|
69
|
-
config_filename = self.directory / self.fmu_filename.with_suffix(".json")
|
|
71
|
+
config_filename = self.directory / self.fmu_filename.with_suffix(".json").name
|
|
70
72
|
with open(config_filename, "w") as file:
|
|
71
73
|
json.dump(config, file, indent=2)
|
|
72
74
|
logger.info(f"Container definition saved to '{config_filename}'")
|
|
@@ -77,7 +79,7 @@ class FMUSplitter:
|
|
|
77
79
|
if txt_filename in self.filenames_list:
|
|
78
80
|
description = FMUSplitterDescription(self.zip)
|
|
79
81
|
config = description.parse_txt_file(txt_filename)
|
|
80
|
-
config["name"] = fmu_filename
|
|
82
|
+
config["name"] = Path(fmu_filename).name
|
|
81
83
|
for i, fmu_filename in enumerate(config["candidate_fmu"]):
|
|
82
84
|
directory = f"{relative_path}resources/{i:02x}/"
|
|
83
85
|
if directory not in self.dir_set:
|
|
@@ -134,6 +136,7 @@ class FMUSplitterDescription:
|
|
|
134
136
|
self.current_vr = None
|
|
135
137
|
self.current_name = None
|
|
136
138
|
self.current_causality = None
|
|
139
|
+
self.supported_fmi_types: Tuple[str] = ()
|
|
137
140
|
|
|
138
141
|
@staticmethod
|
|
139
142
|
def get_line(file):
|
|
@@ -182,10 +185,12 @@ class FMUSplitterDescription:
|
|
|
182
185
|
def parse_txt_file_header(self, file, txt_filename):
|
|
183
186
|
flags = self.get_line(file).split(" ")
|
|
184
187
|
if len(flags) == 1:
|
|
188
|
+
self.supported_fmi_types = ("Real", "Integer", "Boolean", "String")
|
|
185
189
|
self.config["mt"] = flags[0] == "1"
|
|
186
190
|
self.config["profiling"] = self.get_line(file) == "1"
|
|
187
191
|
self.config["sequential"] = False
|
|
188
192
|
elif len(flags) == 3:
|
|
193
|
+
self.supported_fmi_types = EmbeddedFMUPort.ALL_TYPES
|
|
189
194
|
self.config["mt"] = flags[0] == "1"
|
|
190
195
|
self.config["profiling"] = flags[1] == "1"
|
|
191
196
|
self.config["sequential"] = flags[2] == "1"
|
|
@@ -242,7 +247,7 @@ class FMUSplitterDescription:
|
|
|
242
247
|
logger.debug(f"Adding container port {causality}: {definition}")
|
|
243
248
|
|
|
244
249
|
def parse_txt_file_ports(self, file):
|
|
245
|
-
for fmi_type in
|
|
250
|
+
for fmi_type in self.supported_fmi_types:
|
|
246
251
|
nb_port_variables = self.get_line(file).split(" ")[0]
|
|
247
252
|
for i in range(int(nb_port_variables)):
|
|
248
253
|
tokens = self.get_line(file).split(" ")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fmu_manipulation_toolbox
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.9rc8
|
|
4
4
|
Summary: FMU Manipulation Toolbox is a python application for modifying Functional Mock-up Units (FMUs) without recompilation or bundling them into FMU Containers
|
|
5
5
|
Home-page: https://github.com/grouperenault/fmu_manipulation_toolbox/
|
|
6
6
|
Author: Nicolas.LAURENT@Renault.com
|
|
@@ -1,24 +1,42 @@
|
|
|
1
1
|
import unittest
|
|
2
2
|
import sys
|
|
3
3
|
from pathlib import Path
|
|
4
|
+
from fmpy.simulation import simulate_fmu
|
|
5
|
+
import numpy as np
|
|
4
6
|
|
|
5
7
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
6
8
|
from fmu_manipulation_toolbox.operations import *
|
|
7
9
|
from fmu_manipulation_toolbox.remoting import *
|
|
8
10
|
from fmu_manipulation_toolbox.container import *
|
|
9
11
|
from fmu_manipulation_toolbox.assembly import *
|
|
10
|
-
|
|
12
|
+
from fmu_manipulation_toolbox.cli.fmutool import fmutool
|
|
13
|
+
from fmu_manipulation_toolbox.cli.fmusplit import fmusplit
|
|
14
|
+
from fmu_manipulation_toolbox.cli.fmucontainer import fmucontainer
|
|
11
15
|
|
|
12
16
|
class FMUManipulationToolboxTestSuite(unittest.TestCase):
|
|
13
17
|
def __init__(self, *args, **kwargs):
|
|
14
18
|
super().__init__(*args, **kwargs)
|
|
15
19
|
self.fmu_filename = "operations/bouncing_ball.fmu"
|
|
16
20
|
|
|
21
|
+
def assert_simulation(self, filename: Union[Path, str], step_size: Optional[float] = None):
|
|
22
|
+
if isinstance(filename, str):
|
|
23
|
+
filename = Path(filename)
|
|
24
|
+
result_filename = filename.with_name("results-" + filename.with_suffix(".csv").name)
|
|
25
|
+
ref_filename = result_filename.with_stem("REF-" + result_filename.stem)
|
|
26
|
+
|
|
27
|
+
result = simulate_fmu(filename, step_size=step_size, stop_time=10, relative_tolerance=1e-9,
|
|
28
|
+
output_interval=step_size, validate=True)
|
|
29
|
+
|
|
30
|
+
np.savetxt(result_filename, result, delimiter=',', fmt="%.5e")
|
|
31
|
+
|
|
32
|
+
self.assert_identical_files(result_filename, ref_filename)
|
|
33
|
+
|
|
17
34
|
def assert_identical_files(self, filename1, filename2):
|
|
18
35
|
with open(filename1, mode="rt", newline=None) as a, open(filename2, mode="rt", newline=None) as b:
|
|
19
36
|
self.assertTrue(all(lineA == lineB for lineA, lineB in zip(a, b)))
|
|
20
37
|
|
|
21
|
-
|
|
38
|
+
@staticmethod
|
|
39
|
+
def assert_identical_files_but_guid(filename1, filename2):
|
|
22
40
|
with open(filename1, mode="rt", newline=None) as a, open(filename2, mode="rt", newline=None) as b:
|
|
23
41
|
for lineA, lineB in zip(a, b):
|
|
24
42
|
if not "guid" in lineA and not lineA == lineB:
|
|
@@ -51,10 +69,12 @@ class FMUManipulationToolboxTestSuite(unittest.TestCase):
|
|
|
51
69
|
|
|
52
70
|
@unittest.skipUnless(sys.platform.startswith("win"), "Supported only on Windows")
|
|
53
71
|
def test_add_remoting_win32(self):
|
|
54
|
-
fmu = FMU(
|
|
55
|
-
operation =
|
|
72
|
+
fmu = FMU("remoting/bouncing_ball-win32.fmu")
|
|
73
|
+
operation = OperationAddRemotingWin64()
|
|
56
74
|
fmu.apply_operation(operation)
|
|
57
|
-
fmu.repack("
|
|
75
|
+
fmu.repack("remoting/bouncing_ball-win64.fmu")
|
|
76
|
+
self.assert_simulation("remoting/bouncing_ball-win32.fmu")
|
|
77
|
+
self.assert_simulation("remoting/bouncing_ball-win64.fmu")
|
|
58
78
|
|
|
59
79
|
def test_remove_regexp(self):
|
|
60
80
|
self.assert_operation_match_ref("operations/bouncing_ball-removed.fmu",
|
|
@@ -72,6 +92,8 @@ class FMUManipulationToolboxTestSuite(unittest.TestCase):
|
|
|
72
92
|
"containers/bouncing_ball/bouncing/resources/container.txt")
|
|
73
93
|
self.assert_identical_files("containers/bouncing_ball/REF-bouncing.json",
|
|
74
94
|
"containers/bouncing_ball/bouncing.json")
|
|
95
|
+
if os.name == 'nt':
|
|
96
|
+
self.assert_simulation("containers/bouncing_ball/bouncing.fmu")
|
|
75
97
|
|
|
76
98
|
def test_container_bouncing_ball_seq(self):
|
|
77
99
|
assembly = Assembly("bouncing-seq.csv", fmu_directory=Path("containers/bouncing_ball"), mt=True, debug=True,
|
|
@@ -82,6 +104,8 @@ class FMUManipulationToolboxTestSuite(unittest.TestCase):
|
|
|
82
104
|
"containers/bouncing_ball/bouncing-seq/resources/container.txt")
|
|
83
105
|
self.assert_identical_files("containers/bouncing_ball/REF-bouncing-seq.json",
|
|
84
106
|
"containers/bouncing_ball/bouncing-seq.json")
|
|
107
|
+
if os.name == 'nt':
|
|
108
|
+
self.assert_simulation("containers/bouncing_ball/bouncing-seq.fmu")
|
|
85
109
|
|
|
86
110
|
def test_container_bouncing_ball_profiling(self):
|
|
87
111
|
assembly = Assembly("bouncing-profiling.csv", fmu_directory=Path("containers/bouncing_ball"), profiling=True,
|
|
@@ -94,6 +118,8 @@ class FMUManipulationToolboxTestSuite(unittest.TestCase):
|
|
|
94
118
|
"containers/bouncing_ball/bouncing-profiling.json")
|
|
95
119
|
self.assert_identical_files_but_guid("containers/bouncing_ball/REF-modelDescription-profiling.xml",
|
|
96
120
|
"containers/bouncing_ball/bouncing-profiling/modelDescription.xml")
|
|
121
|
+
if os.name == 'nt':
|
|
122
|
+
self.assert_simulation("containers/bouncing_ball/bouncing-profiling.fmu")
|
|
97
123
|
|
|
98
124
|
def test_container_bouncing_ball_profiling_3(self):
|
|
99
125
|
assembly = Assembly("bouncing-3.csv", fmu_directory=Path("containers/bouncing_ball"), profiling=True,
|
|
@@ -103,18 +129,24 @@ class FMUManipulationToolboxTestSuite(unittest.TestCase):
|
|
|
103
129
|
"containers/bouncing_ball/bouncing-3/resources/container.txt")
|
|
104
130
|
self.assert_identical_files_but_guid("containers/bouncing_ball/REF-modelDescription-3.xml",
|
|
105
131
|
"containers/bouncing_ball/bouncing-3/modelDescription.xml")
|
|
132
|
+
if os.name == 'nt':
|
|
133
|
+
self.assert_simulation("containers/bouncing_ball/bouncing-3.fmu")
|
|
106
134
|
|
|
107
135
|
def test_container_ssp(self):
|
|
108
136
|
assembly = Assembly("bouncing.ssp", fmu_directory=Path("containers/ssp"))
|
|
109
137
|
assembly.make_fmu(dump_json=True)
|
|
110
138
|
self.assert_identical_files("containers/ssp/REF-bouncing-dump.json",
|
|
111
139
|
"containers/ssp/bouncing-dump.json")
|
|
140
|
+
if os.name == 'nt':
|
|
141
|
+
self.assert_simulation("containers/ssp/bouncing.fmu")
|
|
112
142
|
|
|
113
143
|
def test_container_json_flat(self):
|
|
114
144
|
assembly = Assembly("flat.json", fmu_directory=Path("containers/arch"))
|
|
115
145
|
assembly.make_fmu(dump_json=True)
|
|
116
146
|
self.assert_identical_files("containers/arch/REF-flat-dump.json",
|
|
117
147
|
"containers/arch/flat-dump.json")
|
|
148
|
+
if os.name == 'nt':
|
|
149
|
+
self.assert_simulation("containers/arch/flat.fmu")
|
|
118
150
|
|
|
119
151
|
def test_container_subdir_flat(self):
|
|
120
152
|
container = FMUContainer("sub.fmu", fmu_directory=Path("containers/arch"))
|
|
@@ -123,18 +155,24 @@ class FMUManipulationToolboxTestSuite(unittest.TestCase):
|
|
|
123
155
|
container.get_fmu("sine.fmu")
|
|
124
156
|
container.add_implicit_rule()
|
|
125
157
|
container.make_fmu("sub.fmu", step_size=0.5)
|
|
158
|
+
if os.name == 'nt':
|
|
159
|
+
self.assert_simulation("containers/arch/sub.fmu")
|
|
126
160
|
|
|
127
161
|
def test_container_json_hierarchical(self):
|
|
128
162
|
assembly = Assembly("hierarchical.json", fmu_directory=Path("containers/arch"))
|
|
129
163
|
assembly.make_fmu(dump_json=True)
|
|
130
164
|
self.assert_identical_files("containers/arch/REF-hierarchical-dump.json",
|
|
131
165
|
"containers/arch/hierarchical-dump.json")
|
|
166
|
+
if os.name == 'nt':
|
|
167
|
+
self.assert_simulation("containers/arch/hierarchical.fmu")
|
|
132
168
|
|
|
133
169
|
def test_container_json_reversed(self):
|
|
134
170
|
assembly = Assembly("reversed.json", fmu_directory=Path("containers/arch"))
|
|
135
171
|
assembly.make_fmu(dump_json=True)
|
|
136
172
|
self.assert_identical_files("containers/arch/REF-reversed-dump.json",
|
|
137
173
|
"containers/arch/reversed-dump.json")
|
|
174
|
+
if os.name == 'nt':
|
|
175
|
+
self.assert_simulation("containers/arch/reversed.fmu")
|
|
138
176
|
|
|
139
177
|
def test_container_start(self):
|
|
140
178
|
assembly = Assembly("slx.json", fmu_directory=Path("containers/start"), debug=True)
|
|
@@ -143,12 +181,22 @@ class FMUManipulationToolboxTestSuite(unittest.TestCase):
|
|
|
143
181
|
"containers/start/container-slx/resources/container.txt")
|
|
144
182
|
self.assert_identical_files_but_guid("containers/start/REF-modelDescription.xml",
|
|
145
183
|
"containers/start/container-slx/modelDescription.xml")
|
|
184
|
+
if os.name == 'nt':
|
|
185
|
+
self.assert_simulation("containers/start/slx.fmu")
|
|
186
|
+
|
|
187
|
+
def test_container_vanderpol(self):
|
|
188
|
+
self.assert_simulation("containers/VanDerPol/VanDerPol.fmu", 0.1)
|
|
189
|
+
assembly = Assembly("VanDerPol.json", fmu_directory=Path("containers/VanDerPol"))
|
|
190
|
+
assembly.make_fmu()
|
|
191
|
+
self.assert_simulation("containers/VanDerPol/VanDerPol-Container.fmu", 0.1)
|
|
146
192
|
|
|
147
193
|
def test_fmi3_pt2(self):
|
|
148
194
|
assembly = Assembly("passthrough.json", fmu_directory=Path("fmi3/passthrough"), debug=True)
|
|
149
195
|
assembly.make_fmu(fmi_version=2)
|
|
150
196
|
self.assert_identical_files("fmi3/passthrough/REF-container.txt",
|
|
151
197
|
"fmi3/passthrough/container-passthrough/resources/container.txt")
|
|
198
|
+
if os.name == 'nt':
|
|
199
|
+
self.assert_simulation("fmi3/passthrough/container-passthrough.fmu")
|
|
152
200
|
|
|
153
201
|
def test_container_move(self):
|
|
154
202
|
#bb = Assembly("bouncing.csv", fmu_directory=Path("containers/bouncing_ball"))
|
|
@@ -168,6 +216,28 @@ class FMUManipulationToolboxTestSuite(unittest.TestCase):
|
|
|
168
216
|
for link in links_fmu0a:
|
|
169
217
|
print(f"{link}")
|
|
170
218
|
|
|
219
|
+
def test_fmutool(self):
|
|
220
|
+
fmutool(['-input', 'operations/bouncing_ball.fmu', '-summary', '-check', '-dump-csv',
|
|
221
|
+
'operations/cli-bouncing_ball.csv'])
|
|
222
|
+
self.assert_identical_files("operations/cli-bouncing_ball.csv", "operations/REF-bouncing_ball.csv")
|
|
223
|
+
|
|
224
|
+
def test_fmucontainer_csv(self):
|
|
225
|
+
fmucontainer(['-container', 'cli-bouncing.csv', '-fmu-directory', 'containers/bouncing_ball', '-mt', '-debug'])
|
|
226
|
+
self.assert_identical_files("containers/bouncing_ball/REF-container.txt",
|
|
227
|
+
"containers/bouncing_ball/cli-bouncing/resources/container.txt")
|
|
228
|
+
|
|
229
|
+
def test_fmucontainer_json(self):
|
|
230
|
+
fmucontainer(['-fmu-directory', 'containers/arch', '-container', 'cli-flat.json', '-dump'])
|
|
231
|
+
self.assert_identical_files("containers/arch/REF-cli-flat-dump.json",
|
|
232
|
+
"containers/arch/cli-flat-dump.json")
|
|
233
|
+
|
|
234
|
+
def test_fmusplit(self):
|
|
235
|
+
fmusplit(["-fmu", "containers/ssp/bouncing.fmu"])
|
|
236
|
+
self.assertTrue(Path("containers/ssp/bouncing.dir/bb_position.fmu").exists())
|
|
237
|
+
self.assertTrue(Path("containers/ssp/bouncing.dir/bb_velocity.fmu").exists())
|
|
238
|
+
self.assert_identical_files("containers/ssp/REF-split-bouncing.json",
|
|
239
|
+
"containers/ssp/bouncing.dir/bouncing.json")
|
|
240
|
+
|
|
171
241
|
|
|
172
242
|
if __name__ == '__main__':
|
|
173
243
|
unittest.main()
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
'V1.9-rc6'
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/gui.py
RENAMED
|
File without changes
|
|
File without changes
|
{fmu_manipulation_toolbox-1.9rc6 → fmu_manipulation_toolbox-1.9rc8}/fmu_manipulation_toolbox/help.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|