Skip to content

Commit

Permalink
Restructure to separate code of different FMI versions (#290)
Browse files Browse the repository at this point in the history
  • Loading branch information
PeterMeisrimelModelon authored Feb 5, 2025
1 parent dc699ed commit 6e52a62
Show file tree
Hide file tree
Showing 29 changed files with 11,002 additions and 10,354 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
--- CHANGELOG ---
--- PyFMI-FUTURE ---
* Refactored internal files. This should NOT affect imports.


--- PyFMI-2.16.3 ---
Expand Down
9 changes: 9 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,9 +220,18 @@ def check_extensions():
"""
incl_path = [".", "src", os.path.join("src", "pyfmi")]
#FMI PYX
ext_list += cythonize([os.path.join("src", "pyfmi", "fmi_base.pyx")],
include_path = incl_path,
compiler_directives={'language_level' : "3str"})
ext_list += cythonize([os.path.join("src", "pyfmi", "fmi.pyx")],
include_path = incl_path,
compiler_directives={'language_level' : "3str"})
ext_list += cythonize([os.path.join("src", "pyfmi", "fmi1.pyx")],
include_path = incl_path,
compiler_directives={'language_level' : "3str"})
ext_list += cythonize([os.path.join("src", "pyfmi", "fmi2.pyx")],
include_path = incl_path,
compiler_directives={'language_level' : "3str"})

#FMI UTIL
ext_list += cythonize([os.path.join("src", "pyfmi", "fmi_util.pyx")],
Expand Down
2 changes: 1 addition & 1 deletion src/common/diagnostics.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

## This file contains various components for the 'dynamics_diagnostics' options

from pyfmi.fmi import FMUModelME2
from pyfmi.fmi2 import FMUModelME2
import numpy as np
import numbers

Expand Down
21 changes: 11 additions & 10 deletions src/common/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@
else:
from scipy.io.matlab.mio4 import MatFile4Reader, VarReader4, convert_dtypes, mdtypes_template, mxSPARSE_CLASS

import pyfmi.fmi as fmi
import pyfmi.fmi as fmi # TODO
import pyfmi.fmi_util as fmi_util
from pyfmi.common import encode, decode
from pyfmi.common.diagnostics import DIAGNOSTICS_PREFIX, DiagnosticsBase
from pyfmi.exceptions import FMUException

SYS_LITTLE_ENDIAN = sys.byteorder == 'little'
NCP_LARGE = 5000
Expand Down Expand Up @@ -826,7 +827,7 @@ def get_variable_data(self,name):
else:
try:
var = self.vars[name]
except KeyError as ex:
except KeyError:
raise VariableNotFoundError("Cannot find variable " +
name + " in data file.")

Expand Down Expand Up @@ -1989,7 +1990,7 @@ def simulation_start(self):
self.file_open = True
else:
if not hasattr(self.file_name, 'write'):
raise fmi.FMUException("Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports writing to through the 'write' method.")
raise FMUException("Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports writing to through the 'write' method.")
f = self.file_name #assume it is a stream
self.file_open = False
self._file = f
Expand Down Expand Up @@ -2126,7 +2127,7 @@ def simulation_start(self):
f = codecs.open(self.file_name,'w','utf-8')
else:
if not (hasattr(self.file_name, 'write') and hasattr(self.file_name, 'seek')):
raise fmi.FMUException("Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write' and 'seek'.")
raise FMUException("Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write' and 'seek'.")
f = self.file_name #assume it is a stream
self._is_stream = True
self.file_open = True
Expand Down Expand Up @@ -2697,7 +2698,7 @@ def simulation_start(self, diagnostics_params={}, diagnostics_vars={}):
msg += " and"
if self.nof_diag_vars < 1:
msg += " 'diagnostics_vars'."
raise fmi.FMUException(msg)
raise FMUException(msg)

self.file_name = opts["result_file_name"]
try:
Expand All @@ -2706,7 +2707,7 @@ def simulation_start(self, diagnostics_params={}, diagnostics_vars={}):
self.parameters = False

if self.parameters:
raise fmi.FMUException("Storing sensitivity results are not supported using this format. Use the file format instead.")
raise FMUException("Storing sensitivity results are not supported using this format. Use the file format instead.")

if self.file_name == "":
self.file_name=self.model.get_identifier() + '_result.mat'
Expand All @@ -2717,7 +2718,7 @@ def simulation_start(self, diagnostics_params={}, diagnostics_vars={}):
self._file = open(file_name,'wb')
else:
if not (hasattr(self.file_name, 'write') and hasattr(self.file_name, 'seek') and (hasattr(self.file_name, 'tell'))):
raise fmi.FMUException("Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write', 'tell' and 'seek'.")
raise FMUException("Failed to write the result file. Option 'result_file_name' needs to be a filename or a class that supports 'write', 'tell' and 'seek'.")
self._file = self.file_name #assume it is a stream
self._is_stream = True
self.file_open = True
Expand Down Expand Up @@ -2929,15 +2930,15 @@ def get_result_handler(model, opts):
elif opts["result_handling"] == "custom":
result_handler = opts["result_handler"]
if result_handler is None:
raise fmi.FMUException("The result handler needs to be specified when using a custom result handling.")
raise FMUException("The result handler needs to be specified when using a custom result handling.")
if not isinstance(result_handler, ResultHandler):
raise fmi.FMUException("The result handler needs to be a subclass of ResultHandler.")
raise FMUException("The result handler needs to be a subclass of ResultHandler.")
elif (opts["result_handling"] is None) or (opts["result_handling"] == 'none'): #No result handling (for performance)
if opts["result_handling"] == 'none': ## TODO: Future; remove this
logging_module.warning("result_handling = 'none' is deprecated. Please use None instead.")
result_handler = ResultHandlerDummy(model)
else:
raise fmi.FMUException("Unknown option to result_handling.")
raise FMUException("Unknown option to result_handling.")

if (opts.get("result_max_size", 0) > 0) and not result_handler.supports.get("result_max_size", False):
logging_module.warning("The chosen result handler does not support limiting the result size. Ignoring option 'result_max_size'.")
Expand Down
2 changes: 1 addition & 1 deletion src/common/log/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import numpy as np
from distutils.util import strtobool
from pyfmi.common.log.tree import Node, Comment
from pyfmi.fmi import FMUException
from pyfmi.exceptions import FMUException

## Leaf parser ##

Expand Down
18 changes: 4 additions & 14 deletions src/common/plotting/plot_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,10 @@
print("WX-Python not found. The GUI will not work.")

#JModelica related imports
try:
from pyfmi.common.io import ResultDymolaTextual
from pyfmi.common.io import ResultDymolaBinary
from pyfmi.common.io import ResultCSVTextual
from pyfmi.common.io import JIOError
except ImportError:
try:
from pyjmi.common.io import ResultDymolaTextual
from pyjmi.common.io import ResultDymolaBinary
from pyjmi.common.io import ResultCSVTextual
from pyjmi.common.io import JIOError
except ImportError:
print("JModelica Python package was not found.")

from pyfmi.common.io import ResultDymolaTextual
from pyfmi.common.io import ResultDymolaBinary
from pyfmi.common.io import ResultCSVTextual
from pyfmi.common.io import JIOError

ID_GRID = 15001
ID_LICENSE = 15002
Expand Down
5 changes: 3 additions & 2 deletions src/pyfmi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
__all__ = ['fmi_algorithm_drivers', 'examples', 'fmi', 'common']

#Import the model class allowing for users to type e.g.,: from pyfmi import FMUModelME1
from pyfmi.fmi import load_fmu, FMUModelME1, FMUModelME2
from pyfmi.fmi import FMUModelCS1, FMUModelCS2
from pyfmi.fmi import load_fmu
from pyfmi.fmi1 import FMUModelME1, FMUModelCS1
from pyfmi.fmi2 import FMUModelME2, FMUModelCS2
from pyfmi.fmi_coupled import CoupledFMUModelME2
from pyfmi.master import Master
from pyfmi.fmi_extended import FMUModelME1Extended
Expand Down
63 changes: 63 additions & 0 deletions src/pyfmi/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (C) 2025 Modelon AB
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

# This file contains the various exceptions classes used in PyFMI

class FMUException(Exception):
"""
An FMU exception.
"""
pass

class IOException(FMUException):
"""
Exception covering issues related to writing/reading data.
"""
pass

class InvalidOptionException(FMUException):
"""
Exception covering issues related to invalid choices of options.
"""
pass

class TimeLimitExceeded(FMUException):
pass

class InvalidFMUException(FMUException):
"""
Exception covering problems with the imported FMU.
"""
pass

class InvalidXMLException(InvalidFMUException):
"""
Exception covering problem with the XML-file in the imported FMU.
"""
pass

class InvalidBinaryException(InvalidFMUException):
"""
Exception covering problem with the binary in the imported FMU.
"""
pass

class InvalidVersionException(InvalidFMUException):
"""
Exception covering problem with the version of the imported FMU.
"""
pass
Loading

0 comments on commit 6e52a62

Please sign in to comment.