fmu-manipulation-toolbox 1.9rc0__py3-none-any.whl → 1.9rc2__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.
Files changed (23) hide show
  1. fmu_manipulation_toolbox/__init__.py +0 -1
  2. fmu_manipulation_toolbox/__main__.py +1 -1
  3. fmu_manipulation_toolbox/__version__.py +1 -1
  4. fmu_manipulation_toolbox/assembly.py +8 -6
  5. fmu_manipulation_toolbox/checker.py +11 -8
  6. fmu_manipulation_toolbox/container.py +492 -206
  7. fmu_manipulation_toolbox/gui.py +45 -55
  8. fmu_manipulation_toolbox/gui_style.py +8 -0
  9. fmu_manipulation_toolbox/operations.py +184 -120
  10. fmu_manipulation_toolbox/resources/darwin64/container.dylib +0 -0
  11. fmu_manipulation_toolbox/resources/linux64/container.so +0 -0
  12. fmu_manipulation_toolbox/resources/win32/client_sm.dll +0 -0
  13. fmu_manipulation_toolbox/resources/win32/server_sm.exe +0 -0
  14. fmu_manipulation_toolbox/resources/win64/client_sm.dll +0 -0
  15. fmu_manipulation_toolbox/resources/win64/container.dll +0 -0
  16. fmu_manipulation_toolbox/resources/win64/server_sm.exe +0 -0
  17. fmu_manipulation_toolbox/split.py +8 -0
  18. {fmu_manipulation_toolbox-1.9rc0.dist-info → fmu_manipulation_toolbox-1.9rc2.dist-info}/METADATA +1 -1
  19. {fmu_manipulation_toolbox-1.9rc0.dist-info → fmu_manipulation_toolbox-1.9rc2.dist-info}/RECORD +23 -22
  20. {fmu_manipulation_toolbox-1.9rc0.dist-info → fmu_manipulation_toolbox-1.9rc2.dist-info}/WHEEL +0 -0
  21. {fmu_manipulation_toolbox-1.9rc0.dist-info → fmu_manipulation_toolbox-1.9rc2.dist-info}/entry_points.txt +0 -0
  22. {fmu_manipulation_toolbox-1.9rc0.dist-info → fmu_manipulation_toolbox-1.9rc2.dist-info}/licenses/LICENSE.txt +0 -0
  23. {fmu_manipulation_toolbox-1.9rc0.dist-info → fmu_manipulation_toolbox-1.9rc2.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
1
1
  import csv
2
2
  import html
3
+ import logging
3
4
  import os
4
5
  import re
5
6
  import shutil
@@ -10,13 +11,16 @@ import hashlib
10
11
  from pathlib import Path
11
12
  from typing import *
12
13
 
14
+ logger = logging.getLogger("fmu_manipulation_toolbox")
13
15
 
14
16
  class FMU:
15
17
  """Unpack and Repack facilities for FMU package. Once unpacked, we can process Operation on
16
18
  modelDescription.xml file."""
17
19
 
18
20
  FMI2_TYPES = ('Real', 'Integer', 'String', 'Boolean', 'Enumeration')
19
- FMI3_TYPES = ('Float64')
21
+ FMI3_TYPES = ('Float64', 'Float32',
22
+ 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64',
23
+ 'String', 'Boolean', 'Enumeration')
20
24
 
21
25
  def __init__(self, fmu_filename):
22
26
  self.fmu_filename = fmu_filename
@@ -51,6 +55,54 @@ class FMU:
51
55
  manipulation.manipulate(self.descriptor_filename, apply_on)
52
56
 
53
57
 
58
+ class FMUPort:
59
+ def __init__(self):
60
+ self.fmi_type = None
61
+ self.attrs_list: List[Dict] = []
62
+ self.dimension = None
63
+
64
+ def dict_level(self, nb):
65
+ return " ".join([f'{key}="{value}"' for key, value in self.attrs_list[nb].items()])
66
+
67
+ def write_xml(self, fmi_version: int, file):
68
+ if fmi_version == 2:
69
+ print(f" <ScalarVariable {self.dict_level(0)}>", file=file)
70
+ print(f" <{self.fmi_type} {self.dict_level(1)}/>", file=file)
71
+ print(f" </ScalarVariable>", file=file)
72
+ elif fmi_version == 3:
73
+ print(f" <{self.fmi_type} {self.dict_level(0)}/>", file=file)
74
+ else:
75
+ raise FMUError(f"FMUPort writing: unsupported FMI version {fmi_version}")
76
+
77
+ def __contains__(self, item):
78
+ for attrs in self.attrs_list:
79
+ if item in attrs:
80
+ return True
81
+ return False
82
+
83
+ def __getitem__(self, item):
84
+ for attrs in self.attrs_list:
85
+ if item in attrs:
86
+ return attrs[item]
87
+ raise KeyError
88
+
89
+ def __setitem__(self, key, value):
90
+ for attrs in self.attrs_list:
91
+ if key in attrs:
92
+ attrs[key] = value
93
+ return
94
+ raise KeyError
95
+
96
+ def get(self, item, default_value):
97
+ try:
98
+ return self[item]
99
+ except KeyError:
100
+ return default_value
101
+
102
+ def push_attrs(self, attrs):
103
+ self.attrs_list.append(attrs)
104
+
105
+
54
106
  class FMUError(Exception):
55
107
  def __init__(self, reason):
56
108
  self.reason = reason
@@ -73,9 +125,12 @@ class Manipulation:
73
125
  self.operation.set_fmu(fmu)
74
126
  self.fmu = fmu
75
127
 
76
- self.current_port: int = 0
77
- self.port_translation: List[int] = []
128
+ self.current_port: Optional[FMUPort] = None
129
+
130
+ self.current_port_number: int = 0
131
+ self.port_translation: List[Optional[int]] = []
78
132
  self.port_names_list: List[str] = []
133
+ self.port_removed_vr: Set[str] = set()
79
134
  self.apply_on = None
80
135
 
81
136
  @staticmethod
@@ -85,48 +140,55 @@ class Manipulation:
85
140
  else:
86
141
  return value
87
142
 
88
- def start_variable(self, attrs):
89
- causality = OperationAbstract.scalar_get_causality(attrs)
90
- port_name = attrs['name']
143
+ def handle_port(self):
144
+ causality = self.current_port.get('causality', 'local')
145
+ port_name = self.current_port['name']
146
+ vr = self.current_port['valueReference']
91
147
  if not self.apply_on or causality in self.apply_on:
92
- if self.operation.scalar_attrs(attrs):
93
- self.remove_port(port_name)
148
+ if self.operation.port_attrs(self.current_port):
149
+ self.remove_port(port_name, vr)
150
+ # Exception is raised by remove port !
94
151
  else:
95
152
  self.keep_port(port_name)
96
153
  else: # Keep ScalarVariable as it is.
97
154
  self.keep_port(port_name)
98
155
 
99
-
100
156
  def start_element(self, name, attrs):
101
157
  if self.skip_until:
102
158
  return
103
159
  try:
104
- if name == 'ScalarVariable':
105
- self.start_variable(attrs)
106
- elif name in self.fmu.FMI3_TYPES:
107
- attrs['type_name'] = name
108
- self.start_variable(attrs)
160
+ if name == 'ScalarVariable': # FMI 2.0 only
161
+ self.current_port = FMUPort()
162
+ self.current_port.push_attrs(attrs)
163
+ elif self.fmu.fmi_version == 2 and name in self.fmu.FMI2_TYPES:
164
+ self.current_port.fmi_type = name
165
+ self.current_port.push_attrs(attrs)
166
+ elif self.fmu.fmi_version == 3 and name in self.fmu.FMI3_TYPES:
167
+ self.current_port = FMUPort()
168
+ self.current_port.fmi_type = name
169
+ self.current_port.push_attrs(attrs)
109
170
  elif name == 'CoSimulation':
110
171
  self.operation.cosimulation_attrs(attrs)
111
172
  elif name == 'DefaultExperiment':
112
173
  self.operation.experiment_attrs(attrs)
113
174
  elif name == 'fmiModelDescription':
175
+ self.fmu.fmi_version = int(float(attrs["fmiVersion"]))
114
176
  self.operation.fmi_attrs(attrs)
115
- elif name == 'Unknown':
177
+ elif name == 'Unknown': # FMI-2.0 only
116
178
  self.unknown_attrs(attrs)
117
- elif name in self.fmu.FMI2_TYPES:
118
- self.operation.scalar_type(name, attrs)
179
+ elif name == 'Output' or name == "ContinuousStateDerivative" or "InitialUnknown":
180
+ self.handle_structure(attrs)
119
181
 
120
182
  except ManipulationSkipTag:
121
183
  self.skip_until = name
122
184
  return
123
185
 
124
- if attrs:
125
- attrs.pop('fmi_type', None) # FMI 3.0: this attr was added during manipulation
126
- attrs_list = [f'{key}="{self.escape(value)}"' for (key, value) in attrs.items()]
127
- print(f"<{name}", " ".join(attrs_list), ">", end='', file=self.out)
128
- else:
129
- print(f"<{name}>", end='', file=self.out)
186
+ if self.current_port is None:
187
+ if attrs:
188
+ attrs_list = [f'{key}="{self.escape(value)}"' for (key, value) in attrs.items()]
189
+ print(f"<{name}", " ".join(attrs_list), ">", end='', file=self.out)
190
+ else:
191
+ print(f"<{name}>", end='', file=self.out)
130
192
 
131
193
  def end_element(self, name):
132
194
  if self.skip_until:
@@ -134,21 +196,31 @@ class Manipulation:
134
196
  self.skip_until = None
135
197
  return
136
198
  else:
137
- print(f"</{name}>", end='', file=self.out)
199
+ if name == "ScalarVariable" or (self.fmu.fmi_version == 3 and name in FMU.FMI3_TYPES):
200
+ try:
201
+ self.handle_port()
202
+ self.current_port.write_xml(self.fmu.fmi_version, self.out)
203
+ except ManipulationSkipTag:
204
+ logger.info(f"Port '{self.current_port['name']}' is removed.")
205
+ self.current_port = None
206
+
207
+ elif self.current_port is None:
208
+ print(f"</{name}>", end='', file=self.out)
138
209
 
139
210
  def char_data(self, data):
140
211
  if not self.skip_until:
141
212
  print(data, end='', file=self.out)
142
213
 
143
- def remove_port(self, name):
214
+ def remove_port(self, name, vr):
144
215
  self.port_names_list.append(name)
145
216
  self.port_translation.append(None)
217
+ self.port_removed_vr.add(vr)
146
218
  raise ManipulationSkipTag
147
219
 
148
220
  def keep_port(self, name):
149
221
  self.port_names_list.append(name)
150
- self.current_port += 1
151
- self.port_translation.append(self.current_port)
222
+ self.current_port_number += 1
223
+ self.port_translation.append(self.current_port_number)
152
224
 
153
225
  def unknown_attrs(self, attrs):
154
226
  index = int(attrs['index']) - 1
@@ -156,9 +228,29 @@ class Manipulation:
156
228
  if new_index:
157
229
  attrs['index'] = self.port_translation[int(attrs['index']) - 1]
158
230
  else:
159
- print(f"WARNING: Removed port '{self.port_names_list[index]}' is involved in dependencies tree.")
231
+ logger.warning(f"Removed port '{self.port_names_list[index]}' is involved in dependencies tree.")
160
232
  raise ManipulationSkipTag
161
233
 
234
+ def handle_structure(self, attrs):
235
+ try:
236
+ vr = attrs['valueReference']
237
+ if vr in self.port_removed_vr:
238
+ raise ManipulationSkipTag
239
+ except KeyError:
240
+ return
241
+
242
+ try:
243
+ dependencies = attrs['dependencies']
244
+ new_dependencies = []
245
+ for dependency in dependencies.split(" "):
246
+ if dependency in self.port_removed_vr:
247
+ logger.warning(f"Removed port 'vr={dependency}' was involved in dependencies tree.")
248
+ else:
249
+ new_dependencies.append(dependency)
250
+ attrs['dependencies'] = " ".join(new_dependencies)
251
+ except KeyError:
252
+ return
253
+
162
254
  def manipulate(self, descriptor_filename, apply_on=None):
163
255
  self.apply_on = apply_on
164
256
  with open(self.output_filename, "w", encoding="utf-8") as self.out, open(descriptor_filename, "rb") as file:
@@ -181,31 +273,19 @@ class OperationAbstract:
181
273
  def fmi_attrs(self, attrs):
182
274
  pass
183
275
 
184
- def scalar_attrs(self, attrs) -> int:
185
- """ return 0 to keep port, otherwise remove it"""
186
- return 0
187
-
188
276
  def cosimulation_attrs(self, attrs):
189
277
  pass
190
278
 
191
279
  def experiment_attrs(self, attrs):
192
280
  pass
193
281
 
194
- def scalar_type(self, type_name, attrs):
195
- pass
282
+ def port_attrs(self, fmu_port) -> int:
283
+ """ return 0 to keep port, otherwise remove it"""
284
+ return 0
196
285
 
197
286
  def closure(self):
198
287
  pass
199
288
 
200
- @staticmethod
201
- def scalar_get_causality(attrs) -> str:
202
- try:
203
- causality = attrs['causality']
204
- except KeyError:
205
- causality = 'local' # Default value according to FMI Specifications.
206
-
207
- return causality
208
-
209
289
 
210
290
  class OperationSaveNamesToCSV(OperationAbstract):
211
291
  def __repr__(self):
@@ -217,48 +297,29 @@ class OperationSaveNamesToCSV(OperationAbstract):
217
297
  self.writer = csv.writer(self.csvfile, delimiter=';', quotechar="'", quoting=csv.QUOTE_MINIMAL)
218
298
  self.writer.writerow(['name', 'newName', 'valueReference', 'causality', 'variability', 'scalarType',
219
299
  'startValue'])
220
- self.name = None
221
- self.vr = None
222
- self.variability = None
223
- self.causality = None
224
-
225
- def reset(self):
226
- self.name = None
227
- self.vr = None
228
- self.variability = None
229
- self.causality = None
230
300
 
231
301
  def closure(self):
232
302
  self.csvfile.close()
233
303
 
234
- def scalar_attrs(self, attrs):
235
- self.name = attrs['name']
236
- self.vr = attrs['valueReference']
237
- self.causality = self.scalar_get_causality(attrs)
238
-
239
- try:
240
- self.variability = attrs['variability']
241
- except KeyError:
242
- self.variability = 'continuous' # Default value according to FMI Specifications.
304
+ def port_attrs(self, fmu_port: FMUPort) -> int:
305
+ self.writer.writerow([fmu_port["name"],
306
+ fmu_port["name"],
307
+ fmu_port["valueReference"],
308
+ fmu_port.get("causality", "local"),
309
+ fmu_port.get("variability", "continuous"),
310
+ fmu_port.fmi_type,
311
+ fmu_port.get("start", "")])
243
312
 
244
313
  return 0
245
314
 
246
- def scalar_type(self, type_name, attrs):
247
- if "start" in attrs:
248
- start = attrs["start"]
249
- else:
250
- start = ""
251
- self.writer.writerow([self.name, self.name, self.vr, self.causality, self.variability, type_name, start])
252
- self.reset()
253
-
254
315
 
255
316
  class OperationStripTopLevel(OperationAbstract):
256
317
  def __repr__(self):
257
318
  return "Remove Top Level Bus"
258
319
 
259
- def scalar_attrs(self, attrs):
260
- new_name = attrs['name'].split('.', 1)[-1]
261
- attrs['name'] = new_name
320
+ def port_attrs(self, fmu_port):
321
+ new_name = fmu_port['name'].split('.', 1)[-1]
322
+ fmu_port['name'] = new_name
262
323
  return 0
263
324
 
264
325
 
@@ -266,9 +327,9 @@ class OperationMergeTopLevel(OperationAbstract):
266
327
  def __repr__(self):
267
328
  return "Merge Top Level Bus with signal names"
268
329
 
269
- def scalar_attrs(self, attrs):
270
- old = attrs['name']
271
- attrs['name'] = old.replace('.', '_', 1)
330
+ def port_attrs(self, fmu_port):
331
+ old = fmu_port['name']
332
+ fmu_port['name'] = old.replace('.', '_', 1)
272
333
  return 0
273
334
 
274
335
 
@@ -279,27 +340,26 @@ class OperationRenameFromCSV(OperationAbstract):
279
340
  def __init__(self, csv_filename):
280
341
  self.csv_filename = csv_filename
281
342
  self.translations = {}
282
- self.current_port = 0
283
- self.port_translation = []
343
+
284
344
  try:
285
345
  with open(csv_filename, newline='') as csvfile:
286
346
  reader = csv.reader(csvfile, delimiter=';', quotechar="'")
287
347
  for row in reader:
288
348
  self.translations[row[0]] = row[1]
289
349
  except FileNotFoundError:
290
- raise OperationException(f"file '{csv_filename}' is not found")
350
+ raise OperationError(f"file '{csv_filename}' is not found")
291
351
  except KeyError:
292
- raise OperationException(f"file '{csv_filename}' should contain two columns")
352
+ raise OperationError(f"file '{csv_filename}' should contain two columns")
293
353
 
294
- def scalar_attrs(self, attrs):
295
- name = attrs['name']
354
+ def port_attrs(self, fmu_port):
355
+ name = fmu_port['name']
296
356
  try:
297
- new_name = self.translations[attrs['name']]
357
+ new_name = self.translations[fmu_port['name']]
298
358
  except KeyError:
299
359
  new_name = name # if port is not in CSV file, keep old name
300
360
 
301
361
  if new_name:
302
- attrs['name'] = new_name
362
+ fmu_port['name'] = new_name
303
363
  return 0
304
364
  else:
305
365
  # we want to delete this name!
@@ -313,6 +373,10 @@ class OperationAddRemotingWinAbstract(OperationAbstract):
313
373
  def __repr__(self):
314
374
  return f"Add '{self.bitness_to}' remoting on '{self.bitness_from}' FMU"
315
375
 
376
+ def fmi_attrs(self, attrs):
377
+ if not attrs["fmiVersion"] == "2.0":
378
+ raise OperationError(f"Adding remoting is only available for FMI-2.0")
379
+
316
380
  def cosimulation_attrs(self, attrs):
317
381
  fmu_bin = {
318
382
  "win32": os.path.join(self.fmu.tmp_directory, "binaries", f"win32"),
@@ -320,10 +384,10 @@ class OperationAddRemotingWinAbstract(OperationAbstract):
320
384
  }
321
385
 
322
386
  if not os.path.isdir(fmu_bin[self.bitness_from]):
323
- raise OperationException(f"{self.bitness_from} interface does not exist")
387
+ raise OperationError(f"{self.bitness_from} interface does not exist")
324
388
 
325
389
  if os.path.isdir(fmu_bin[self.bitness_to]):
326
- print(f"INFO: {self.bitness_to} already exists. Add front-end.")
390
+ logger.info(f"{self.bitness_to} already exists. Add front-end.")
327
391
  shutil.move(os.path.join(fmu_bin[self.bitness_to], attrs['modelIdentifier'] + ".dll"),
328
392
  os.path.join(fmu_bin[self.bitness_to], attrs['modelIdentifier'] + "-remoted.dll"))
329
393
  else:
@@ -368,11 +432,11 @@ class OperationRemoveRegexp(OperationAbstract):
368
432
  def __init__(self, regex_string):
369
433
  self.regex_string = regex_string
370
434
  self.regex = re.compile(regex_string)
371
- self.current_port = 0
435
+ self.current_port_number = 0
372
436
  self.port_translation = []
373
437
 
374
- def scalar_attrs(self, attrs):
375
- name = attrs['name']
438
+ def port_attrs(self, fmu_port):
439
+ name = fmu_port['name']
376
440
  if self.regex.match(name):
377
441
  return 1 # Remove port
378
442
  else:
@@ -387,8 +451,8 @@ class OperationKeepOnlyRegexp(OperationAbstract):
387
451
  self.regex_string = regex_string
388
452
  self.regex = re.compile(regex_string)
389
453
 
390
- def scalar_attrs(self, attrs):
391
- name = attrs['name']
454
+ def port_attrs(self, fmu_port):
455
+ name = fmu_port['name']
392
456
  if self.regex.match(name):
393
457
  return 0
394
458
  else:
@@ -403,34 +467,34 @@ class OperationSummary(OperationAbstract):
403
467
  return f"FMU Summary"
404
468
 
405
469
  def fmi_attrs(self, attrs):
406
- print(f"| fmu filename = {self.fmu.fmu_filename}")
407
- print(f"| temporary directory = {self.fmu.tmp_directory}")
470
+ logger.info(f"| fmu filename = {self.fmu.fmu_filename}")
471
+ logger.info(f"| temporary directory = {self.fmu.tmp_directory}")
408
472
  hash_md5 = hashlib.md5()
409
473
  with open(self.fmu.fmu_filename, "rb") as f:
410
474
  for chunk in iter(lambda: f.read(4096), b""):
411
475
  hash_md5.update(chunk)
412
476
  digest = hash_md5.hexdigest()
413
- print(f"| MD5Sum = {digest}")
477
+ logger.info(f"| MD5Sum = {digest}")
414
478
 
415
- print(f"|\n| FMI properties: ")
479
+ logger.info(f"|\n| FMI properties: ")
416
480
  for (k, v) in attrs.items():
417
- print(f"| - {k} = {v}")
418
- print(f"|")
481
+ logger.info(f"| - {k} = {v}")
482
+ logger.info(f"|")
419
483
 
420
484
  def cosimulation_attrs(self, attrs):
421
- print("| Co-Simulation capabilities: ")
485
+ logger.info("| Co-Simulation capabilities: ")
422
486
  for (k, v) in attrs.items():
423
- print(f"| - {k} = {v}")
424
- print(f"|")
487
+ logger.info(f"| - {k} = {v}")
488
+ logger.info(f"|")
425
489
 
426
490
  def experiment_attrs(self, attrs):
427
- print("| Default Experiment values: ")
491
+ logger.info("| Default Experiment values: ")
428
492
  for (k, v) in attrs.items():
429
- print(f"| - {k} = {v}")
430
- print(f"|")
493
+ logger.info(f"| - {k} = {v}")
494
+ logger.info(f"|")
431
495
 
432
- def scalar_attrs(self, attrs) -> int:
433
- causality = self.scalar_get_causality(attrs)
496
+ def port_attrs(self, fmu_port) -> int:
497
+ causality = fmu_port.get("causality", "local")
434
498
 
435
499
  try:
436
500
  self.nb_port_per_causality[causality] += 1
@@ -440,33 +504,33 @@ class OperationSummary(OperationAbstract):
440
504
  return 0
441
505
 
442
506
  def closure(self):
443
- print("| Supported platforms: ")
507
+ logger.info("| Supported platforms: ")
444
508
  try:
445
509
  for platform in os.listdir(os.path.join(self.fmu.tmp_directory, "binaries")):
446
- print(f"| - {platform}")
510
+ logger.info(f"| - {platform}")
447
511
  except FileNotFoundError:
448
512
  pass # no binaries
449
513
 
450
514
  if os.path.isdir(os.path.join(self.fmu.tmp_directory, "sources")):
451
- print(f"| - RT (sources available)")
515
+ logger.info(f"| - RT (sources available)")
452
516
 
453
517
  resource_dir = os.path.join(self.fmu.tmp_directory, "resources")
454
518
  if os.path.isdir(resource_dir):
455
- print("|\n| Embedded resources:")
519
+ logger.info("|\n| Embedded resources:")
456
520
  for resource in os.listdir(resource_dir):
457
- print(f"| - {resource}")
521
+ logger.info(f"| - {resource}")
458
522
 
459
523
  extra_dir = os.path.join(self.fmu.tmp_directory, "extra")
460
524
  if os.path.isdir(extra_dir):
461
- print("|\n| Additional (meta-)data:")
525
+ logger.info("|\n| Additional (meta-)data:")
462
526
  for extra in os.listdir(extra_dir):
463
- print(f"| - {extra}")
527
+ logger.info(f"| - {extra}")
464
528
 
465
- print("|\n| Number of signals")
529
+ logger.info("|\n| Number of ports")
466
530
  for causality, nb_ports in self.nb_port_per_causality.items():
467
- print(f"| {causality} : {nb_ports}")
531
+ logger.info(f"| {causality} : {nb_ports}")
468
532
 
469
- print("|\n| [End of report]")
533
+ logger.info("|\n| [End of report]")
470
534
 
471
535
 
472
536
  class OperationRemoveSources(OperationAbstract):
@@ -477,7 +541,7 @@ class OperationRemoveSources(OperationAbstract):
477
541
  try:
478
542
  shutil.rmtree(os.path.join(self.fmu.tmp_directory, "sources"))
479
543
  except FileNotFoundError:
480
- print("This FMU does not embed sources.")
544
+ logger.info("This FMU does not embed sources.")
481
545
 
482
546
 
483
547
  class OperationTrimUntil(OperationAbstract):
@@ -487,17 +551,17 @@ class OperationTrimUntil(OperationAbstract):
487
551
  def __repr__(self):
488
552
  return f"Trim names until (and including) '{self.separator}'"
489
553
 
490
- def scalar_attrs(self, attrs) -> int:
491
- name = attrs['name']
554
+ def port_attrs(self, fmu_port) -> int:
555
+ name = fmu_port['name']
492
556
  try:
493
- attrs['name'] = name[name.index(self.separator)+len(self.separator):-1]
557
+ fmu_port['name'] = name[name.index(self.separator)+len(self.separator):-1]
494
558
  except KeyError:
495
559
  pass # no separator
496
560
 
497
561
  return 0
498
562
 
499
563
 
500
- class OperationException(Exception):
564
+ class OperationError(Exception):
501
565
  def __init__(self, reason):
502
566
  self.reason = reason
503
567
 
@@ -198,7 +198,15 @@ class FMUSplitterDescription:
198
198
  self.config["candidate_fmu"] = []
199
199
 
200
200
  for i in range(nb_fmu):
201
+ # format is
202
+ # filename.fmu
203
+ # or
204
+ # filename.fmu fmi_version
201
205
  fmu_filename = self.get_line(file)
206
+ if ' ' in fmu_filename:
207
+ fmu_filename = fmu_filename.split(' ')[0]
208
+ # fmi version is not needed for further operations
209
+
202
210
  base_directory = "/".join(txt_filename.split("/")[0:-1])
203
211
 
204
212
  directory = f"{base_directory}/{fmu_filename}"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fmu_manipulation_toolbox
3
- Version: 1.9rc0
3
+ Version: 1.9rc2
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,14 +1,14 @@
1
- fmu_manipulation_toolbox/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
2
- fmu_manipulation_toolbox/__main__.py,sha256=mAzrtkil506DS0F3g3CEbHdtZsZotzntcNhIn_lNJkw,344
3
- fmu_manipulation_toolbox/__version__.py,sha256=pIetL3-rgAy__3Y9bhoI5aPvTCG8a1qRIBr7IZdM-aA,12
4
- fmu_manipulation_toolbox/assembly.py,sha256=1jlNc_Rfls2Nah22sd9IL11rC0J5MWs0slT4Bc3sjOw,26364
5
- fmu_manipulation_toolbox/checker.py,sha256=836wCri6aEl0M6_xHPZ94JRngFjsy8Ee-_t8bzclxBs,2332
6
- fmu_manipulation_toolbox/container.py,sha256=DjzRgSGNth50V-8eQ107mbYZQq1Q5-ZPsO6E-oZG4KE,32831
7
- fmu_manipulation_toolbox/gui.py,sha256=tVTPLbGZlD5P0WYqaD5B4crG2nHjBGe73yAJrzRXpYE,29218
8
- fmu_manipulation_toolbox/gui_style.py,sha256=uzEruJumnC5Vf2cfHXVa_c-SHAQoTvDWemro3-b9Mpc,6492
1
+ fmu_manipulation_toolbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ fmu_manipulation_toolbox/__main__.py,sha256=FpG0ITBz5q-AvIbXplVh_1g1zla5souFGtpiDdECxEw,352
3
+ fmu_manipulation_toolbox/__version__.py,sha256=Z-9JT4Rjt43p25I55xHJame93p0nfRXYoSRRq-Je6wY,11
4
+ fmu_manipulation_toolbox/assembly.py,sha256=XQ_1sB6K1Dk2mnNe-E3_6Opoeub7F9Qaln0EUDzsop8,26553
5
+ fmu_manipulation_toolbox/checker.py,sha256=jw1omfrMMIMHlIpHXpWBcQgIiS9hnHe5T9CZ5KlbVGs,2422
6
+ fmu_manipulation_toolbox/container.py,sha256=8Wf16sgUPkY-ByWeKt-3TD_4vNRQuLwH9Gs7D2Q6tAk,44959
7
+ fmu_manipulation_toolbox/gui.py,sha256=iOJ3F_zfw3mU34VofZrYdaffljTmYfuy33fJXlLaOwg,29045
8
+ fmu_manipulation_toolbox/gui_style.py,sha256=s6WdrnNd_lCMWhuBf5LKK8wrfLXCU7pFTLUfvqkJVno,6633
9
9
  fmu_manipulation_toolbox/help.py,sha256=aklKiLrsE0adSzQ5uoEB1sBDmI6s4l231gavu4XxxzA,5856
10
- fmu_manipulation_toolbox/operations.py,sha256=p0e6OgNRT0JrQaDjhdHk1rxVoRXbdhPHueVvn021UdM,16346
11
- fmu_manipulation_toolbox/split.py,sha256=lHIct-ANlFB0p7MgViUaSF8jlOlD1-M7TP-I-x9kkpI,13061
10
+ fmu_manipulation_toolbox/operations.py,sha256=b7N5AVHLIpQO8od4BYasb9CppHJ-ZmW8mu0ZdhndoHI,19472
11
+ fmu_manipulation_toolbox/split.py,sha256=NVkfdTRR0jj_VOdgtxHQoKptkAg5TFVUA7nUx3_o9Pg,13336
12
12
  fmu_manipulation_toolbox/version.py,sha256=OhBLkZ1-nhC77kyvffPNAf6m8OZe1bYTnNf_PWs1NvM,392
13
13
  fmu_manipulation_toolbox/resources/checkbox-checked-disabled.png,sha256=FWIuyrXlaNLLePHfXj7j9ca5rT8Hgr14KCe1EqTCZyk,2288
14
14
  fmu_manipulation_toolbox/resources/checkbox-checked-hover.png,sha256=KNlV-d_aJNTTvUVXKGT9DBY30sIs2LwocLJrFKNKv8k,2419
@@ -27,6 +27,7 @@ fmu_manipulation_toolbox/resources/icon_fmu.png,sha256=EuygB2xcoM2WAfKKdyKG_UvTL
27
27
  fmu_manipulation_toolbox/resources/license.txt,sha256=5ODuU8g8pIkK-NMWXu_rjZ6k7gM7b-N2rmg87-2Kmqw,1583
28
28
  fmu_manipulation_toolbox/resources/mask.png,sha256=px1U4hQGL0AmZ4BQPknOVREpMpTSejbah3ntkpqAzFA,3008
29
29
  fmu_manipulation_toolbox/resources/model.png,sha256=EAf_HnZJe8zYGZygerG1MMt2U-tMMZlifzXPj4_iORA,208788
30
+ fmu_manipulation_toolbox/resources/darwin64/container.dylib,sha256=G6ABYe2mBmI_0pGU6HJly3yhKh6VEirgN4RFAThUES4,161496
30
31
  fmu_manipulation_toolbox/resources/fmi-2.0/fmi2Annotation.xsd,sha256=OGfyJtaJntKypX5KDpuZ-nV1oYLZ6HV16pkpKOmYox4,2731
31
32
  fmu_manipulation_toolbox/resources/fmi-2.0/fmi2AttributeGroups.xsd,sha256=HwyV7LBse-PQSv4z1xjmtzPU3Hjnv4mluq9YdSBNHMQ,3704
32
33
  fmu_manipulation_toolbox/resources/fmi-2.0/fmi2ModelDescription.xsd,sha256=JM4j_9q-pc40XYHb28jfT3iV3aYM5JLqD5aRjO72K1E,18939
@@ -49,16 +50,16 @@ fmu_manipulation_toolbox/resources/fmi-3.0/fmi3VariableDependency.xsd,sha256=YQS
49
50
  fmu_manipulation_toolbox/resources/linux32/client_sm.so,sha256=xVdY2zy13pa2DcvFiweSNpp7E6DiONqeoBdlcJHrW_k,35940
50
51
  fmu_manipulation_toolbox/resources/linux32/server_sm,sha256=1TLGqNPyM5UVOrCfzNqWyF6ClLksY3EiY3CSsrnp6c0,22836
51
52
  fmu_manipulation_toolbox/resources/linux64/client_sm.so,sha256=EhY1XHo1YcQn6yqZ7wk5okqtZyp0MrcCsGcudqE-aIM,37000
52
- fmu_manipulation_toolbox/resources/linux64/container.so,sha256=0hpVEgJkGxbgMeoVAgeqL73aewZ8j-tfzXlf0A0UBpM,85064
53
+ fmu_manipulation_toolbox/resources/linux64/container.so,sha256=KtvL1rmCFE6FA2mFGoHEhIYqAYd47ZmJLK5YsyO7TqM,135464
53
54
  fmu_manipulation_toolbox/resources/linux64/server_sm,sha256=ulfoPvmaYe9nInYcVEyj7mD9zDzGk56OUoWx1mPKLiE,22768
54
- fmu_manipulation_toolbox/resources/win32/client_sm.dll,sha256=ZF0W5N4ZZgMWVnyYrLrEgxamj3WNw667QK5pqK4HvnA,17920
55
- fmu_manipulation_toolbox/resources/win32/server_sm.exe,sha256=KnUM49rDTpTHjVr-J2kfBsYnQnPsX7ho6H7vTlF8i-E,15872
56
- fmu_manipulation_toolbox/resources/win64/client_sm.dll,sha256=58N8xOmJ9XU_oe2rC9JP95lzR-IhDzbwD9FDPaQ7VtM,22016
57
- fmu_manipulation_toolbox/resources/win64/container.dll,sha256=bvxsESgpzAn7IyLnf5Oc41pBPCM7tQz0LJrlXaSpTJQ,57856
58
- fmu_manipulation_toolbox/resources/win64/server_sm.exe,sha256=ftJC5fBoCnlzrcbLJBIfniOAieWGFHZ5klv5UFL9LEE,19968
59
- fmu_manipulation_toolbox-1.9rc0.dist-info/licenses/LICENSE.txt,sha256=c_862mzyk6ownO3Gt6cVs0-53IXLi_-ZEQFNDVabESw,1285
60
- fmu_manipulation_toolbox-1.9rc0.dist-info/METADATA,sha256=kWBmPNMw9UYn11B144bSf7H0inSSo6uD-Cpe0h2OyQ4,1156
61
- fmu_manipulation_toolbox-1.9rc0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
62
- fmu_manipulation_toolbox-1.9rc0.dist-info/entry_points.txt,sha256=HjOZkflbI1IuSY8BpOZre20m24M4GDQGCJfPIa7NrlY,264
63
- fmu_manipulation_toolbox-1.9rc0.dist-info/top_level.txt,sha256=9D_h-5BMjSqf9z-XFkbJL_bMppR2XNYW3WNuPkXou0k,25
64
- fmu_manipulation_toolbox-1.9rc0.dist-info/RECORD,,
55
+ fmu_manipulation_toolbox/resources/win32/client_sm.dll,sha256=rL9OCeoOmCvzf88mFubyPvTDImKxO26fNHoX5a_wuaI,17920
56
+ fmu_manipulation_toolbox/resources/win32/server_sm.exe,sha256=NGBZkTqSBFg8Wja_BYqoumk6qKmQoND4n8tDcPvKj8g,15872
57
+ fmu_manipulation_toolbox/resources/win64/client_sm.dll,sha256=UZi61eVctdZ0jLEsC5GWAG4zM6LTq6firPYNByz39LQ,22016
58
+ fmu_manipulation_toolbox/resources/win64/container.dll,sha256=6-HLcAhtd68PMD0SVloSrfpFJlUdSJLp58hqjzCLsHQ,97792
59
+ fmu_manipulation_toolbox/resources/win64/server_sm.exe,sha256=wWZuT98XkCraZNNlWsnxoxoYABsXiJbxVDXg5zirnjI,19968
60
+ fmu_manipulation_toolbox-1.9rc2.dist-info/licenses/LICENSE.txt,sha256=c_862mzyk6ownO3Gt6cVs0-53IXLi_-ZEQFNDVabESw,1285
61
+ fmu_manipulation_toolbox-1.9rc2.dist-info/METADATA,sha256=CAh7QGHMed2PqNbtoLGwhn46FEwESV4uXEMaAPIPkJY,1156
62
+ fmu_manipulation_toolbox-1.9rc2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
63
+ fmu_manipulation_toolbox-1.9rc2.dist-info/entry_points.txt,sha256=HjOZkflbI1IuSY8BpOZre20m24M4GDQGCJfPIa7NrlY,264
64
+ fmu_manipulation_toolbox-1.9rc2.dist-info/top_level.txt,sha256=9D_h-5BMjSqf9z-XFkbJL_bMppR2XNYW3WNuPkXou0k,25
65
+ fmu_manipulation_toolbox-1.9rc2.dist-info/RECORD,,