Coverage for ebcpy/modelica/__init__.py: 98%
65 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-09-19 12:21 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-09-19 12:21 +0000
1"""
2This package aims to help manipulate simulation files (dsfinal.txt or dsin.txt)
3or to load simulation result files (.mat) efficiently into a pandas.DataFrame
4"""
5import re
6from typing import Union, List
9def get_expressions(filepath_model: str,
10 get_protected: bool = False,
11 modelica_type: Union[str, List] = "parameters",
12 excludes: List = None):
13 """
14 This function extracts specific expressions out of modelica models.
16 :param str,os.path.normpath filepath_model:
17 Full path of modelica model on the given os
18 e.g. path_model = "C://MyLibrary//TestModel.mo"
19 :param str,list modelica_type:
20 Type you want to have matched. "parameters" and "variables"
21 have a special regex pattern.
22 For other models, you can parse a string like:
23 "replaceable package Medium" and it will yield all
24 afflicted lines. You can also give a list of strings if
25 multiple strings are relevant to you.
26 Special cases:
27 parameters:
28 - include: ["parameter"]
29 - excludes: ["final", "in", "of", "replaceable"]
30 variables: Note: The case for already imported SIUnits is not considered here.
31 - include: ["Modelica.SIunits", "Real", "Boolean", "Integer"]
32 - excludes: ["parameter", "import", "constant"]
33 :param list excludes:
34 List of strings to exclude from expression. Default is None.
35 :param Boolean get_protected:
36 Whether to extract protected parameters or not. Default is false
38 :return: list matches
39 List with all lines matching the given expression.
40 """
41 if excludes is None:
42 excludes = []
43 if modelica_type == "parameters":
44 _includes = ["parameter"]
45 _excludes = ["final", "in", "of", "replaceable"] + excludes
46 elif modelica_type == "variables":
47 _includes = ["Modelica.SIunits", "Real", "Boolean", "Integer"]
48 _excludes = ["parameter", "import", "constant"] + excludes
49 else:
50 _includes = [modelica_type]
51 _excludes = excludes
52 if _excludes:
53 _exclude_str = r"(?<!" + r"\s)(?<!".join(_excludes) + r"\s)"
54 else: # Case if list is empty
55 _exclude_str = ""
56 _pattern = r'((?:\s.+)?{}({})(.|\n)*?;)'.format(_exclude_str,
57 "|".join(_includes))
59 # Open the file
60 with open(filepath_model, "r") as file:
61 file.seek(0)
62 script = file.read()
64 # Find desired expression in modelica script
65 expr = re.findall(_pattern, script, re.MULTILINE)
67 expr_filtered = [" ".join(expr_unfiltered[0].split()) for expr_unfiltered in expr]
69 if not get_protected:
70 return expr_filtered
72 # Get position of expressions
73 pos_expr = []
74 for match in re.finditer(_pattern, script, re.MULTILINE):
75 pos_expr.append(match.span()[0])
77 # Check if parameter are protected
78 expr_unprotected = []
79 expr_protected = []
81 # Get position of "protected"-expression
82 protected = re.search(r'protected', script)
84 if protected:
85 pos_protected = protected.span()[0]
86 for i, temp_expr in enumerate(expr):
87 # If expressions is before 'proteceted' --> refer to expr_unprotected
88 if pos_expr[i] < pos_protected:
89 expr_unprotected.append(temp_expr)
90 # If expressions is after 'proteceted' --> refer to expr_protected
91 else:
92 expr_protected.append(temp_expr)
93 else:
94 expr_unprotected = expr
96 return expr_unprotected, expr_protected
99def get_names_and_values_of_lines(lines: List[str]) -> dict:
100 """
101 All unnecessary code is deleted (annotations, doc).
102 Only the name of the variable and the value is extracted.
104 :param List[str] lines:
105 List of strings with lines from a modelica file.
107 :return:
108 dict: Containing the names as key and values as value.
110 Example:
112 >>> lines = ['parameter Boolean my_boolean=true "Some description"',
113 >>> 'parameter Real my_real=12.0 "Some description" annotation("Some annotation")']
114 >>> output = get_names_and_values_of_lines(lines=lines)
115 >>> print(output)
116 {'my_boolean': True, 'my_real': 12.0}
117 """
118 res = {}
119 for line in lines:
120 line = line.replace(";", "")
122 # Check if line is a commented line and if so, skip the line:
123 if line.startswith("//"):
124 continue
126 # Remove part behind possible annotation:
127 loc = line.find("annotation")
128 if loc >= 0:
129 line = line[:loc]
130 # Remove possible brackets, like "param(min=0, start=5)
131 line = re.sub(r'[\(\[].*?[\)\]]', '', line)
132 # And now any quotes / doc / strings
133 line = re.sub(r'".*"', '', line)
134 # If a value is present (e.g. for parameters, one = sign is still present (always)
135 if line.find("=") >= 0:
136 name_str, val_str = line.split("=")
137 name_str = name_str.strip()
138 name = name_str.split(" ")[-1].replace(" ", "")
139 val_str_stripped = val_str.replace(" ", "")
140 if val_str_stripped in ["true", "false"]:
141 value = val_str_stripped == "true"
142 else:
143 try:
144 value = float(val_str_stripped)
145 except ValueError:
146 # Neither float, integer nor boolean, hence None
147 value = None
148 # else no value is stored in the line
149 else:
150 line = line.strip()
151 name = line.split(" ")[-1].replace(" ", "")
152 value = None
153 res.update({name: value})
155 return res