fmu-manipulation-toolbox 1.8.4.3b0__tar.gz → 1.9__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.
Files changed (91) hide show
  1. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/PKG-INFO +1 -1
  2. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/README.md +57 -23
  3. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/__init__.py +0 -0
  4. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/__main__.py +1 -1
  5. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/__version__.py +1 -0
  6. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/assembly.py +21 -12
  7. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/checker.py +11 -8
  8. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/cli/__init__.py +0 -0
  9. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/cli/fmucontainer.py +105 -0
  10. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/cli/fmusplit.py +48 -0
  11. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/cli/fmutool.py +127 -0
  12. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/cli/utils.py +36 -0
  13. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/container.py +1054 -0
  14. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/gui.py +47 -55
  15. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/gui_style.py +8 -0
  16. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/help.py +3 -0
  17. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/operations.py +577 -0
  18. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/remoting.py +107 -0
  19. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/darwin64/container.dylib +0 -0
  20. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/linux32/client_sm.so +0 -0
  21. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/linux32/server_sm +0 -0
  22. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/linux64/client_sm.so +0 -0
  23. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/linux64/container.so +0 -0
  24. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/linux64/server_sm +0 -0
  25. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/win32/client_sm.dll +0 -0
  26. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/win32/server_sm.exe +0 -0
  27. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/win64/client_sm.dll +0 -0
  28. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/win64/container.dll +0 -0
  29. fmu_manipulation_toolbox-1.9/fmu_manipulation_toolbox/resources/win64/server_sm.exe +0 -0
  30. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/split.py +67 -34
  31. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox.egg-info/PKG-INFO +1 -1
  32. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox.egg-info/SOURCES.txt +7 -0
  33. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/setup.py +2 -1
  34. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/tests/test_suite.py +100 -5
  35. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/__init__.py +0 -1
  36. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/__version__.py +0 -1
  37. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/container.py +0 -767
  38. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/operations.py +0 -505
  39. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/linux32/client_sm.so +0 -0
  40. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/linux32/server_sm +0 -0
  41. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/linux64/client_sm.so +0 -0
  42. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/linux64/container.so +0 -0
  43. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/linux64/server_sm +0 -0
  44. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/win32/client_sm.dll +0 -0
  45. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/win32/server_sm.exe +0 -0
  46. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/win64/client_sm.dll +0 -0
  47. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/win64/container.dll +0 -0
  48. fmu_manipulation_toolbox-1.8.4.3b0/fmu_manipulation_toolbox/resources/win64/server_sm.exe +0 -0
  49. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/LICENSE.txt +0 -0
  50. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/checkbox-checked-disabled.png +0 -0
  51. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/checkbox-checked-hover.png +0 -0
  52. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/checkbox-checked.png +0 -0
  53. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/checkbox-unchecked-disabled.png +0 -0
  54. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/checkbox-unchecked-hover.png +0 -0
  55. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/checkbox-unchecked.png +0 -0
  56. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/container.png +0 -0
  57. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/drop_fmu.png +0 -0
  58. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2Annotation.xsd +0 -0
  59. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2AttributeGroups.xsd +0 -0
  60. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2ModelDescription.xsd +0 -0
  61. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2ScalarVariable.xsd +0 -0
  62. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2Type.xsd +0 -0
  63. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2Unit.xsd +0 -0
  64. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-2.0/fmi2VariableDependency.xsd +0 -0
  65. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Annotation.xsd +0 -0
  66. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3AttributeGroups.xsd +0 -0
  67. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3BuildDescription.xsd +0 -0
  68. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3InterfaceType.xsd +0 -0
  69. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3LayeredStandardManifest.xsd +0 -0
  70. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3ModelDescription.xsd +0 -0
  71. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Terminal.xsd +0 -0
  72. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3TerminalsAndIcons.xsd +0 -0
  73. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Type.xsd +0 -0
  74. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Unit.xsd +0 -0
  75. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3Variable.xsd +0 -0
  76. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmi-3.0/fmi3VariableDependency.xsd +0 -0
  77. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmu.png +0 -0
  78. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/fmu_manipulation_toolbox.png +0 -0
  79. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/help.png +0 -0
  80. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/icon-round.png +0 -0
  81. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/icon.png +0 -0
  82. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/icon_fmu.png +0 -0
  83. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/license.txt +0 -0
  84. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/mask.png +0 -0
  85. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/resources/model.png +0 -0
  86. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox/version.py +0 -0
  87. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox.egg-info/dependency_links.txt +0 -0
  88. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox.egg-info/entry_points.txt +0 -0
  89. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox.egg-info/requires.txt +0 -0
  90. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/fmu_manipulation_toolbox.egg-info/top_level.txt +0 -0
  91. {fmu_manipulation_toolbox-1.8.4.3b0 → fmu_manipulation_toolbox-1.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmu_manipulation_toolbox
3
- Version: 1.8.4.3b0
3
+ Version: 1.9
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
- ![Title](fmu_manipulation_toolbox/resources/fmu_manipulation_toolbox.png)
1
+ ![](fmu_manipulation_toolbox/resources/fmu_manipulation_toolbox.png)
2
2
 
3
- FMU Manipulation Toolbox is a python package which help to analyse and modify a [Functional Mock-up Units (FMUs)](http://fmi-standard.org/)
4
- without recompilation. It is highly customizable. It can even modify the `modelDescription.xml` file.
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
- Manipulating the `modelDescription.xml` can be a dangerous thing! Communicating with the FMU-developer and adapting
7
- the way the FMU is generated, is preferable when possible.
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
- FMU Manipulation Toolbox also allows to group FMU's inside FMU Containers. (see [doc/container.md](doc/container.md))
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.16)
31
+ - CMake (>= 3.20)
32
+
21
33
 
22
34
  ### Supported platforms
23
- FMU Manipulation Toolbox is tested on:
24
- - Windows 10/11
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
  ![GUI](doc/gui.png "GUI")
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 FMU's inside FMU Containers. (see [container/README.md](container/README.md))
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:
@@ -131,24 +152,29 @@ optional arguments:
131
152
  ### FMU Containers
132
153
 
133
154
  ```
134
- usage: fmucontainer [-h] [-fmu-directory FMU_DIRECTORY] -container filename.{csv|json|ssp},[:step_size] [-debug]
135
- [-no-auto-input] [-no-auto-output] [-auto-parameter] [-no-auto-link] [-mt] [-profile] [-dump-json]
155
+ usage: fmucontainer [-h] [-fmu-directory FMU_DIRECTORY] [-fmi FMI_VERSION]
156
+ -container filename.{csv|json|ssp},[:step_size] [-debug] [-no-auto-input] [-no-auto-output]
157
+ [-auto-parameter] [-auto-local] [-no-auto-link] [-mt] [-profile] [-sequential] [-dump-json]
136
158
 
137
159
  Generate FMU from FMU's
138
160
 
139
- optional arguments:
161
+ options:
140
162
  -h, -help
141
163
  -fmu-directory FMU_DIRECTORY Directory containing initial FMU’s and used to generate containers. If not defined,
142
164
  current directory is used. (default: .)
165
+ -fmi FMI_VERSION Define version of FMI to be used for container interface.Only '2' or '3' is
166
+ supported. (default: 2)
143
167
  -container filename.{csv|json|ssp},[:step_size]
144
168
  Description of the container to create. (default: [])
145
169
  -debug Add lot of useful log during the process. (default: False)
146
170
  -no-auto-input Create ONLY explicit input. (default: True)
147
171
  -no-auto-output Create ONLY explicit output. (default: True)
148
172
  -auto-parameter Expose parameters of the embedded fmu's. (default: False)
173
+ -auto-local Expose local variables of the embedded fmu's. (default: False)
149
174
  -no-auto-link Create ONLY explicit links. (default: True)
150
175
  -mt Enable Multi-Threaded mode for the generated container. (default: False)
151
176
  -profile Enable Profiling mode for the generated container. (default: False)
177
+ -sequential Use sequential mode to schedule embedded fmu's. (default: False)
152
178
  -dump-json Dump a JSON file for each container. (default: False)
153
179
  ```
154
180
 
@@ -158,14 +184,13 @@ You can write your own FMU Manipulation scripts. Once you downloaded fmutool mod
158
184
  adding the `import` statement lets you access the API :
159
185
 
160
186
  ```python
161
- from fmu_manipulation_toolbox.operations import FMU, OperationExtractNames, OperationStripTopLevel,
162
-
163
- OperationRenameFromCSV
187
+ from fmu_manipulation_toolbox.operations import ...
164
188
  ```
165
189
 
190
+
166
191
  ### remove toplevel bus (if any)
167
192
 
168
- Give a FMU with the following I/O structure
193
+ Given a FMU with the following I/O structure
169
194
  ```
170
195
  ├── Parameters
171
196
  │ ├── Foo
@@ -189,6 +214,8 @@ The following transformation will lead into:
189
214
 
190
215
  The following code will do this transformation:
191
216
  ```python
217
+ from fmu_manipulation_toolbox.operations import FMU, OperationStripTopLevel
218
+
192
219
  fmu = FMU(r"bouncing_ball.fmu")
193
220
  operation = OperationStripTopLevel()
194
221
  fmu.apply_operation(operation)
@@ -200,8 +227,10 @@ fmu.repack(r"bouncing_ball-modified.fmu")
200
227
  The following code will dump all FMU's Scalars names into a CSV:
201
228
 
202
229
  ```python
230
+ from fmu_manipulation_toolbox.operations import FMU, OperationSaveNamesToCSV
231
+
203
232
  fmu = FMU(r"bouncing_ball.fmu")
204
- operation = OperationExtractNames()
233
+ operation = OperationSaveNamesToCSV()
205
234
  fmu.apply_operation(operation)
206
235
  operation.write_csv(r"bouncing_ball.csv")
207
236
  ```
@@ -219,15 +248,20 @@ g;g;4;parameter;fixed
219
248
  e;e;5;parameter;tunable
220
249
  ```
221
250
 
251
+
222
252
  ### Read CSV and rename FMU ports
223
253
 
224
- CSV file should contain- 2 columns:
254
+ CSV file should contain 2 columns:
225
255
  1. the current name
226
256
  2. the new name
227
257
 
228
258
  ```python
259
+ from fmu_manipulation_toolbox.operations import FMU, OperationRenameFromCSV
260
+
229
261
  fmu = FMU(r"bouncing_ball.fmu")
230
262
  operation = OperationRenameFromCSV(r"bouncing_ball-modified.csv")
231
263
  fmu.apply_operation(operation)
232
264
  fmu.repack(r"bouncing_ball-renamed.fmu")
233
265
  ```
266
+
267
+ More operations exist in [`Operation.py`](fmu_manipulation_toolbox/operations.py)
@@ -10,7 +10,7 @@ def gui():
10
10
 
11
11
 
12
12
  def cli():
13
- from .cli import fmutool
13
+ from .cli.fmutool import fmutool
14
14
  fmutool()
15
15
 
16
16
 
@@ -37,7 +37,7 @@ class Connection:
37
37
 
38
38
 
39
39
  class AssemblyNode:
40
- def __init__(self, name: Optional[str], step_size: float = None, mt=False, profiling=False,
40
+ def __init__(self, name: Optional[str], step_size: float = None, mt=False, profiling=False, sequential=False,
41
41
  auto_link=True, auto_input=True, auto_output=True, auto_parameter=False, auto_local=False):
42
42
  self.name = name
43
43
  if step_size:
@@ -50,6 +50,7 @@ class AssemblyNode:
50
50
  self.step_size = None
51
51
  self.mt = mt
52
52
  self.profiling = profiling
53
+ self.sequential = sequential
53
54
  self.auto_link = auto_link
54
55
  self.auto_input = auto_input
55
56
  self.auto_output = auto_output
@@ -100,12 +101,13 @@ class AssemblyNode:
100
101
  def add_start_value(self, fmu_filename: str, port_name: str, value: str):
101
102
  self.start_values[Port(fmu_filename, port_name)] = value
102
103
 
103
- def make_fmu(self, fmu_directory: Path, debug=False, description_pathname=None):
104
+ def make_fmu(self, fmu_directory: Path, debug=False, description_pathname=None, fmi_version=2):
104
105
  for node in self.children.values():
105
- node.make_fmu(fmu_directory, debug=debug)
106
+ node.make_fmu(fmu_directory, debug=debug, fmi_version=fmi_version)
106
107
 
107
108
  identifier = str(Path(self.name).stem)
108
- container = FMUContainer(identifier, fmu_directory, description_pathname=description_pathname)
109
+ container = FMUContainer(identifier, fmu_directory, description_pathname=description_pathname,
110
+ fmi_version=fmi_version)
109
111
 
110
112
  for fmu_name in self.fmu_names_list:
111
113
  container.get_fmu(fmu_name)
@@ -138,7 +140,8 @@ class AssemblyNode:
138
140
  for link_rule in wired.rule_link:
139
141
  self.add_link(link_rule[0], link_rule[1], link_rule[2], link_rule[3])
140
142
 
141
- container.make_fmu(self.name, self.step_size, mt=self.mt, profiling=self.profiling, debug=debug)
143
+ container.make_fmu(self.name, self.step_size, mt=self.mt, profiling=self.profiling, sequential=self.sequential,
144
+ debug=debug)
142
145
 
143
146
  for node in self.children.values():
144
147
  logger.info(f"Deleting transient FMU Container '{node.name}'")
@@ -216,7 +219,7 @@ class AssemblyError(Exception):
216
219
 
217
220
 
218
221
  class Assembly:
219
- def __init__(self, filename: str, step_size=None, auto_link=True, auto_input=True, debug=False,
222
+ def __init__(self, filename: str, step_size=None, auto_link=True, auto_input=True, debug=False, sequential=False,
220
223
  auto_output=True, mt=False, profiling=False, fmu_directory: Path = Path("."), auto_parameter=False,
221
224
  auto_local=False):
222
225
  self.filename = Path(filename)
@@ -228,6 +231,7 @@ class Assembly:
228
231
  self.default_auto_parameter = auto_parameter
229
232
  self.default_auto_local = auto_local
230
233
  self.default_mt = mt
234
+ self.default_sequential = sequential
231
235
  self.default_profiling = profiling
232
236
  self.fmu_directory = fmu_directory
233
237
  self.transient_filenames: List[Path] = []
@@ -238,7 +242,7 @@ class Assembly:
238
242
 
239
243
  self.input_pathname = fmu_directory / self.filename
240
244
  self.description_pathname = self.input_pathname # For inclusion in FMU
241
- self.root = None
245
+ self.root: Optional[AssemblyNode] = None
242
246
  self.read()
243
247
 
244
248
  def add_transient_file(self, filename: str):
@@ -283,8 +287,9 @@ class Assembly:
283
287
  name = str(self.filename.with_suffix(".fmu"))
284
288
  self.root = AssemblyNode(name, step_size=self.default_step_size, auto_link=self.default_auto_link,
285
289
  mt=self.default_mt, profiling=self.default_profiling,
286
- auto_input=self.default_auto_input, auto_output=self.default_auto_output,
287
- auto_parameter=self.default_auto_parameter, auto_local=self.default_auto_local)
290
+ sequential=self.default_sequential, auto_input=self.default_auto_input,
291
+ auto_output=self.default_auto_output, auto_parameter=self.default_auto_parameter,
292
+ auto_local=self.default_auto_local)
288
293
 
289
294
  with open(self.input_pathname) as file:
290
295
  reader = csv.reader(file, delimiter=';')
@@ -385,6 +390,7 @@ class Assembly:
385
390
  name = data.get("name", None) # 1
386
391
  mt = data.get("mt", self.default_mt) # 2
387
392
  profiling = data.get("profiling", self.default_profiling) # 3
393
+ sequential = data.get("sequential", self.default_sequential) # 3b
388
394
  auto_link = data.get("auto_link", self.default_auto_link) # 4
389
395
  auto_input = data.get("auto_input", self.default_auto_input) # 5
390
396
  auto_output = data.get("auto_output", self.default_auto_output) # 6
@@ -393,11 +399,12 @@ class Assembly:
393
399
  step_size = data.get("step_size", self.default_step_size) # 7
394
400
 
395
401
  node = AssemblyNode(name, step_size=step_size, auto_link=auto_link, mt=mt, profiling=profiling,
402
+ sequential=sequential,
396
403
  auto_input=auto_input, auto_output=auto_output, auto_parameter=auto_parameter,
397
404
  auto_local=auto_local)
398
405
 
399
406
  for key, value in data.items():
400
- if key in ('name', 'step_size', 'auto_link', 'auto_input', 'auto_output', 'mt', 'profiling',
407
+ if key in ('name', 'step_size', 'auto_link', 'auto_input', 'auto_output', 'mt', 'profiling', 'sequential',
401
408
  'auto_parameter', 'auto_local'):
402
409
  continue # Already read
403
410
 
@@ -455,6 +462,7 @@ class Assembly:
455
462
  json_node["name"] = node.name # 1
456
463
  json_node["mt"] = node.mt # 2
457
464
  json_node["profiling"] = node.profiling # 3
465
+ json_node["sequential"] = node.sequential # 3b
458
466
  json_node["auto_link"] = node.auto_link # 4
459
467
  json_node["auto_input"] = node.auto_input # 5
460
468
  json_node["auto_output"] = node.auto_output # 6
@@ -510,8 +518,9 @@ class Assembly:
510
518
  self.root = sdd.parse(self.description_pathname)
511
519
  self.root.name = str(self.filename.with_suffix(".fmu"))
512
520
 
513
- def make_fmu(self, dump_json=False):
514
- self.root.make_fmu(self.fmu_directory, debug=self.debug, description_pathname=self.description_pathname)
521
+ def make_fmu(self, dump_json=False, fmi_version=2):
522
+ self.root.make_fmu(self.fmu_directory, debug=self.debug, description_pathname=self.description_pathname,
523
+ fmi_version=fmi_version)
515
524
  if dump_json:
516
525
  dump_file = Path(self.input_pathname.stem + "-dump").with_suffix(".json")
517
526
  logger.info(f"Dump Json '{dump_file}'")
@@ -1,10 +1,13 @@
1
1
  import importlib.util
2
2
  import inspect
3
+ import logging
3
4
  import os
4
5
  import xmlschema
5
6
  from xmlschema.validators.exceptions import XMLSchemaValidationError
6
7
  from .operations import OperationAbstract
7
8
 
9
+ logger = logging.getLogger("fmu_manipulation_toolbox")
10
+
8
11
 
9
12
  class OperationGenericCheck(OperationAbstract):
10
13
  SUPPORTED_FMI_VERSIONS = ('2.0', '3.0')
@@ -17,7 +20,7 @@ class OperationGenericCheck(OperationAbstract):
17
20
 
18
21
  def fmi_attrs(self, attrs):
19
22
  if attrs['fmiVersion'] not in self.SUPPORTED_FMI_VERSIONS:
20
- print(f"ERROR: Expected FMI {','.join(self.SUPPORTED_FMI_VERSIONS)} versions.")
23
+ logger.error(f"Expected FMI {','.join(self.SUPPORTED_FMI_VERSIONS)} versions.")
21
24
  return
22
25
 
23
26
  fmi_name = f"fmi{attrs['fmiVersion'][0]}"
@@ -27,15 +30,15 @@ class OperationGenericCheck(OperationAbstract):
27
30
  try:
28
31
  xmlschema.validate(self.fmu.descriptor_filename, schema=xsd_filename)
29
32
  except XMLSchemaValidationError as error:
30
- print(error.reason, error.msg)
33
+ logger.error(error.reason, error.msg)
31
34
  else:
32
35
  self.compliant_with_version = attrs['fmiVersion']
33
36
 
34
37
  def closure(self):
35
38
  if self.compliant_with_version:
36
- print(f"INFO: This FMU seems to be compliant with FMI-{self.compliant_with_version}.")
39
+ logger.info(f"This FMU seems to be compliant with FMI-{self.compliant_with_version}.")
37
40
  else:
38
- print(f"ERROR: This FMU does not validate with FMI standard.")
41
+ logger.error(f"This FMU does not validate with FMI standard.")
39
42
 
40
43
 
41
44
  checker_list = [OperationGenericCheck]
@@ -44,20 +47,20 @@ checker_list = [OperationGenericCheck]
44
47
  def add_from_file(checker_filename: str):
45
48
  spec = importlib.util.spec_from_file_location(checker_filename, checker_filename)
46
49
  if not spec:
47
- print(f"ERROR: Cannot load {checker_filename}. Is this a python file?")
50
+ logger.error(f"Cannot load '{checker_filename}'. Is this a python file?")
48
51
  return
49
52
  try:
50
53
  checker_module = importlib.util.module_from_spec(spec)
51
54
  try:
52
55
  spec.loader.exec_module(checker_module)
53
56
  except (ModuleNotFoundError, SyntaxError) as error:
54
- print(f"ERROR: Cannot load {checker_filename}: {error})")
57
+ logger.error(f"Cannot load '{checker_filename}': {error})")
55
58
  return
56
59
 
57
60
  for checker_name, checker_class in inspect.getmembers(checker_module, inspect.isclass):
58
61
  if OperationAbstract in checker_class.__bases__:
59
62
  checker_list.append(checker_class)
60
- print(f"Adding checker: {checker_filename}|{checker_name}")
63
+ logger.info(f"Adding checker: {checker_filename}|{checker_name}")
61
64
 
62
65
  except AttributeError:
63
- print(f"ERROR: {checker_filename} should implement class 'OperationCheck'")
66
+ logger.error(f"'{checker_filename}' should implement class 'OperationCheck'")
@@ -0,0 +1,105 @@
1
+ import argparse
2
+ import logging
3
+ import sys
4
+
5
+ from typing import *
6
+ from pathlib import Path
7
+
8
+ from .utils import setup_logger, make_wide
9
+ from ..assembly import Assembly, AssemblyError
10
+ from ..container import FMUContainerError
11
+ from ..version import __version__ as version
12
+
13
+
14
+ def fmucontainer(command_options: Sequence[str]):
15
+ logger = setup_logger()
16
+
17
+ logger.info(f"FMUContainer version {version}")
18
+ parser = argparse.ArgumentParser(prog="fmucontainer", description="Generate FMU from FMU's",
19
+ formatter_class=make_wide(argparse.ArgumentDefaultsHelpFormatter),
20
+ add_help=False,
21
+ epilog="see: https://github.com/grouperenault/fmu_manipulation_toolbox/blob/main/"
22
+ "container/README.md")
23
+
24
+ parser.add_argument('-h', '-help', action="help")
25
+
26
+ parser.add_argument("-fmu-directory", action="store", dest="fmu_directory", required=False, default=".",
27
+ help="Directory containing initial FMU’s and used to generate containers. "
28
+ "If not defined, current directory is used.")
29
+
30
+ parser.add_argument("-fmi", action="store", dest="fmi_version", required=False, default="2",
31
+ help="Define version of FMI to be used for container interface."
32
+ "Only '2' or '3' is supported.")
33
+
34
+ parser.add_argument("-container", action="append", dest="container_descriptions_list", default=[],
35
+ metavar="filename.{csv|json|ssp},[:step_size]", required=True,
36
+ help="Description of the container to create.")
37
+
38
+ parser.add_argument("-debug", action="store_true", dest="debug",
39
+ help="Add lot of useful log during the process.")
40
+
41
+ parser.add_argument("-no-auto-input", action="store_false", dest="auto_input", default=True,
42
+ help="Create ONLY explicit input.")
43
+
44
+ parser.add_argument("-no-auto-output", action="store_false", dest="auto_output", default=True,
45
+ help="Create ONLY explicit output.")
46
+
47
+ parser.add_argument("-auto-parameter", action="store_true", dest="auto_parameter", default=False,
48
+ help="Expose parameters of the embedded fmu's.")
49
+
50
+ parser.add_argument("-auto-local", action="store_true", dest="auto_local", default=False,
51
+ help="Expose local variables of the embedded fmu's.")
52
+
53
+ parser.add_argument("-no-auto-link", action="store_false", dest="auto_link", default=True,
54
+ help="Create ONLY explicit links.")
55
+
56
+ parser.add_argument("-mt", action="store_true", dest="mt", default=False,
57
+ help="Enable Multi-Threaded mode for the generated container.")
58
+
59
+ parser.add_argument("-profile", action="store_true", dest="profiling", default=False,
60
+ help="Enable Profiling mode for the generated container.")
61
+
62
+ parser.add_argument("-sequential", action="store_true", dest="sequential", default=False,
63
+ help="Use sequential mode to schedule embedded fmu's.")
64
+
65
+ parser.add_argument("-dump-json", action="store_true", dest="dump", default=False,
66
+ help="Dump a JSON file for each container.")
67
+
68
+ config = parser.parse_args(command_options)
69
+
70
+ if config.debug:
71
+ logger.setLevel(logging.DEBUG)
72
+
73
+ fmu_directory = Path(config.fmu_directory)
74
+ logger.info(f"FMU directory: '{fmu_directory}'")
75
+
76
+ for description in config.container_descriptions_list:
77
+ try:
78
+ tokens = description.split(":")
79
+ filename = ":".join(tokens[:-1])
80
+ step_size = float(tokens[-1])
81
+ except ValueError:
82
+ step_size = None
83
+ filename = description
84
+
85
+ try:
86
+ assembly = Assembly(filename, step_size=step_size, auto_link=config.auto_link,
87
+ auto_input=config.auto_input, auto_output=config.auto_output,
88
+ auto_local=config.auto_local, mt=config.mt, sequential=config.sequential,
89
+ profiling=config.profiling, fmu_directory=fmu_directory, debug=config.debug,
90
+ auto_parameter=config.auto_parameter)
91
+ except FileNotFoundError as e:
92
+ logger.fatal(f"Cannot read file: {e}")
93
+ sys.exit(-1)
94
+ except (FMUContainerError, AssemblyError) as e:
95
+ logger.fatal(f"{filename}: {e}")
96
+ sys.exit(-2)
97
+
98
+ try:
99
+ assembly.make_fmu(dump_json=config.dump, fmi_version=int(config.fmi_version))
100
+ except FMUContainerError as e:
101
+ logger.fatal(f"{filename}: {e}")
102
+ sys.exit(-3)
103
+
104
+ if __name__ == "__main__":
105
+ fmucontainer(sys.argv[1:])
@@ -0,0 +1,48 @@
1
+ import argparse
2
+ import logging
3
+ import sys
4
+
5
+ from typing import *
6
+
7
+ from .utils import setup_logger, make_wide
8
+ from ..split import FMUSplitter, FMUSplitterError
9
+ from ..version import __version__ as version
10
+
11
+
12
+ def fmusplit(command_options: Sequence[str]):
13
+ logger = setup_logger()
14
+
15
+ logger.info(f"FMUSplit version {version}")
16
+ parser = argparse.ArgumentParser(prog="fmusplit", description="Split FMU Container into FMU's",
17
+ formatter_class=make_wide(argparse.ArgumentDefaultsHelpFormatter),
18
+ add_help=False,
19
+ epilog="see: https://github.com/grouperenault/fmu_manipulation_toolbox/blob/main/"
20
+ "container/README.md")
21
+ parser.add_argument('-h', '-help', action="help")
22
+
23
+ parser.add_argument("-debug", action="store_true", dest="debug",
24
+ help="Add lot of useful log during the process.")
25
+
26
+ parser.add_argument("-fmu", action="append", dest="fmu_filename_list", default=[],
27
+ metavar="filename.fmu", required=True,
28
+ help="Description of the FMU container to split.")
29
+
30
+ config = parser.parse_args(command_options)
31
+
32
+ if config.debug:
33
+ logger.setLevel(logging.DEBUG)
34
+
35
+ for fmu_filename in config.fmu_filename_list:
36
+ try:
37
+ splitter = FMUSplitter(fmu_filename)
38
+ splitter.split_fmu()
39
+ except FMUSplitterError as e:
40
+ logger.fatal(f"{fmu_filename}: {e}")
41
+ sys.exit(-1)
42
+ except FileNotFoundError as e:
43
+ logger.fatal(f"Cannot read file: {e}")
44
+ sys.exit(-2)
45
+
46
+
47
+ if __name__ == "__main__":
48
+ fmusplit(sys.argv[1:])