pyibis-ami 7.2.3__py3-none-any.whl → 7.2.4__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.
pyibisami/ibis/file.py CHANGED
@@ -1,325 +1,325 @@
1
- """A class for encapsulating IBIS model files.
2
-
3
- Original Author: David Banas <capn.freako@gmail.com>
4
-
5
- Original Date: November 1, 2019
6
-
7
- For information regarding the IBIS modeling standard, visit:
8
- https://ibis.org/
9
-
10
- **Note:** The ``IBISModel`` class, defined here, needs to be kept separate from the
11
- other IBIS-related classes, defined in the ``model`` module, in order to
12
- avoid circular imports.
13
-
14
- Copyright (c) 2019 by David Banas; All rights reserved World wide.
15
- """
16
-
17
- import platform
18
- from datetime import datetime
19
-
20
- from traits.api import (
21
- Any,
22
- Dict,
23
- Enum,
24
- Float,
25
- HasTraits,
26
- List,
27
- Property,
28
- String,
29
- Trait,
30
- cached_property,
31
- )
32
- from traitsui.api import HGroup, Item, ModalButtons, VGroup, View, spring
33
- from traitsui.message import message
34
-
35
- from pyibisami.ibis.parser import parse_ibis_file
36
-
37
-
38
- class IBISModel(HasTraits): # pylint: disable=too-many-instance-attributes
39
- """HasTraits subclass for wrapping and interacting with an IBIS model.
40
-
41
- This class can be configured to present a customized GUI to the user
42
- for interacting with a particular IBIS model (i.e. - selecting components,
43
- pins, and models).
44
-
45
- The intended use model is as follows:
46
-
47
- 1. Instantiate this class only once per IBIS model file.
48
- When instantiating, provide the unprocessed contents of the IBIS
49
- file, as a single string. This class will take care of getting
50
- that string parsed properly, and report any errors or warnings
51
- it encounters, in its ``ibis_parsing_errors`` property.
52
-
53
- 2. When you want to let the user select a particular component/pin/model,
54
- call the newly created instance, as if it were a function, passing
55
- no arguments.
56
- The instance will then present a GUI to the user,
57
- allowing him to select a particular component/pin/model, which may then
58
- be retrieved, via the ``model`` property.
59
- The latest user selections will be remembered,
60
- as long as the instance remains in scope.
61
-
62
- Any errors or warnings encountered while parsing are available, in
63
- the ``ibis_parsing_errors`` property.
64
-
65
- The complete dictionary containing all parsed models may be retrieved,
66
- via the ``model_dict`` property.
67
- """
68
-
69
- _log = ""
70
-
71
- pin_ = Property(Any, depends_on=["pin"])
72
- pin_rlcs = Property(Dict, depends_on=["pin"])
73
- model = Property(Any, depends_on=["mod"])
74
- pins = List # Always holds the list of valid pin selections, given a component selection.
75
- models = List # Always holds the list of valid model selections, given a pin selection.
76
-
77
- def get_models(self, mname):
78
- """Return the list of models associated with a particular name."""
79
- model_dict = self._model_dict
80
- if "model_selectors" in model_dict and mname in model_dict["model_selectors"]:
81
- return list(map(lambda pr: pr[0], model_dict["model_selectors"][mname]))
82
- return [mname]
83
-
84
- def get_pins(self):
85
- """Get the list of appropriate pins, given our type (i.e. - Tx or Rx)."""
86
- pins = self.comp_.pins
87
-
88
- def pin_ok(pname):
89
- (mname, _) = pins[pname]
90
- mods = self.get_models(mname)
91
- mod = self._models[mods[0]]
92
- mod_type = mod.mtype.lower()
93
- tx_ok = mod_type in ("output", "i/o")
94
- if self._is_tx:
95
- return tx_ok
96
- return not tx_ok
97
-
98
- return list(filter(pin_ok, list(pins)))
99
-
100
- def __init__(self, ibis_file_name, is_tx, debug=False, gui=True):
101
- """
102
- Args:
103
- ibis_file_name (str): The name of the IBIS file.
104
- is_tx (bool): True if this is a Tx model.
105
-
106
- Keyword Args:
107
- debug (bool): Output debugging info to console when true.
108
- Default = False
109
- gui (bool): Set to `False` for command line and/or script usage.
110
- Default = True.
111
- """
112
-
113
- # Super-class initialization is ABSOLUTELY NECESSARY, in order
114
- # to get all the Traits/UI machinery setup correctly.
115
- super().__init__()
116
-
117
- self.debug = debug
118
- self.GUI = gui
119
- if debug:
120
- self.log("pyibisami.ibis_file.IBISModel initializing in debug mode...")
121
- else:
122
- self.log("pyibisami.ibis_file.IBISModel initializing in non-debug mode...")
123
-
124
- # Parse the IBIS file contents, storing any errors or warnings, and validate it.
125
- with open(ibis_file_name, "r", encoding="utf-8") as file:
126
- ibis_file_contents_str = file.read()
127
- err_str, model_dict = parse_ibis_file(ibis_file_contents_str, debug=debug)
128
- self.log("IBIS parsing errors/warnings:\n" + err_str)
129
- if "components" not in model_dict or not model_dict["components"]:
130
- print(f":\n{model_dict}", flush=True)
131
- raise ValueError("This IBIS model has no components!")
132
- components = model_dict["components"]
133
- if "models" not in model_dict or not model_dict["models"]:
134
- raise ValueError("This IBIS model has no models!")
135
- models = model_dict["models"]
136
- self._model_dict = model_dict
137
- self._models = models
138
- self._is_tx = is_tx
139
-
140
- # Add Traits for various attributes found in the IBIS file.
141
- self.add_trait("comp", Trait(list(components)[0], components)) # Doesn't need a custom mapper, because
142
- self.pins = self.get_pins() # the thing above it (file) can't change.
143
- self.add_trait("pin", Enum(self.pins[0], values="pins"))
144
- (mname, _) = self.pin_
145
- self.models = self.get_models(mname)
146
- self.add_trait("mod", Enum(self.models[0], values="models"))
147
- self.add_trait("ibis_ver", Float(model_dict["ibis_ver"]))
148
- self.add_trait("file_name", String(model_dict["file_name"]))
149
- self.add_trait("file_rev", String(model_dict["file_rev"]))
150
- if "date" in model_dict:
151
- self.add_trait("date", String(model_dict["date"]))
152
- else:
153
- self.add_trait("date", String("(n/a)"))
154
-
155
- self._ibis_parsing_errors = err_str
156
- self._os_type = platform.system() # These 2 are used, to choose
157
- self._os_bits = platform.architecture()[0] # the correct AMI executable.
158
-
159
- self._comp_changed(list(components)[0]) # Wasn't being called automatically.
160
- self._pin_changed(self.pins[0]) # Wasn't being called automatically.
161
-
162
- self.log("Done.")
163
-
164
- def __str__(self):
165
- return f"IBIS Model '{self._model_dict['file_name']}'"
166
-
167
- def info(self):
168
- """Basic information about the IBIS model."""
169
- res = ""
170
- try:
171
- for k in ["ibis_ver", "file_name", "file_rev"]:
172
- res += k + ":\t" + str(self._model_dict[k]) + "\n"
173
- except Exception as err:
174
- print(f"{err}")
175
- print(self._model_dict)
176
- raise
177
- res += "date" + ":\t\t" + str(self._model_dict["date"]) + "\n"
178
- res += "\nComponents:"
179
- res += "\n=========="
180
- for c in list(self._model_dict["components"]):
181
- res += "\n" + c + ":\n" + "---\n" + str(self._model_dict["components"][c]) + "\n"
182
- res += "\nModel Selectors:"
183
- res += "\n===============\n"
184
- for s in list(self._model_dict["model_selectors"]):
185
- res += f"{s}\n"
186
- res += "\nModels:"
187
- res += "\n======"
188
- for m in list(self._model_dict["models"]):
189
- res += "\n" + m + ":\n" + "---\n" + str(self._model_dict["models"][m])
190
- return res
191
-
192
- def __call__(self):
193
- """Present a customized GUI to the user, for model selection, etc."""
194
- self.edit_traits(kind="livemodal")
195
-
196
- # Logger & Pop-up
197
- def log(self, msg, alert=False):
198
- """Log a message to the console and, optionally, to terminal and/or
199
- pop-up dialog."""
200
- _msg = msg.strip()
201
- txt = f"\n[{datetime.now()}]: IBISModel: {_msg}\n"
202
- self._log += txt
203
- if self.debug:
204
- print(txt, flush=True)
205
- if alert and self.GUI:
206
- message(_msg, "PyAMI Alert")
207
-
208
- def default_traits_view(self):
209
- "Default Traits/UI view definition."
210
- view = View(
211
- VGroup(
212
- HGroup(
213
- Item("file_name", label="File name", style="readonly"),
214
- spring,
215
- Item("file_rev", label="rev", style="readonly"),
216
- ),
217
- HGroup(
218
- Item("ibis_ver", label="IBIS ver", style="readonly"),
219
- spring,
220
- Item("date", label="Date", style="readonly"),
221
- ),
222
- HGroup(
223
- Item("comp", label="Component"),
224
- Item("pin", label="Pin"),
225
- Item("mod", label="Model"),
226
- ),
227
- ),
228
- resizable=False,
229
- buttons=ModalButtons,
230
- title="PyBERT IBIS Model Selector",
231
- id="pybert.pybert_ami.model_selector",
232
- )
233
- return view
234
-
235
- @cached_property
236
- def _get_pin_(self):
237
- return self.comp_.pins[self.pin]
238
-
239
- @cached_property
240
- def _get_pin_rlcs(self):
241
- (_, pin_rlcs) = self.pin_
242
- return pin_rlcs
243
-
244
- @cached_property
245
- def _get_model(self):
246
- return self._models[self.mod]
247
-
248
- @property
249
- def ibis_parsing_errors(self):
250
- """Any errors or warnings encountered, while parsing the IBIS file
251
- contents."""
252
- return self._ibis_parsing_errors
253
-
254
- @property
255
- def log_txt(self):
256
- """The complete log since instantiation."""
257
- return self._log
258
-
259
- @property
260
- def model_dict(self):
261
- "Dictionary of all model keywords."
262
- return self._model_dict
263
-
264
- @property
265
- def dll_file(self):
266
- "Shared object file."
267
- return self._dll_file
268
-
269
- @property
270
- def ami_file(self):
271
- "AMI file."
272
- return self._ami_file
273
-
274
- def _comp_changed(self, new_value):
275
- del new_value
276
- self.pins = self.get_pins()
277
- self.pin = self.pins[0]
278
-
279
- def _pin_changed(self, new_value):
280
- # (mname, rlc_dict) = self.pin_ # Doesn't work. Because ``pin_`` is a cached property and hasn't yet been marked "dirty"?
281
- (mname, _) = self.comp_.pins[new_value]
282
- self.models = self.get_models(mname)
283
- self.mod = self.models[0]
284
-
285
- def _mod_changed(self, new_value):
286
- model = self._models[new_value]
287
- os_type = self._os_type
288
- os_bits = self._os_bits
289
- fnames = []
290
- dll_file = ""
291
- ami_file = ""
292
- if os_type.lower() == "windows":
293
- if os_bits == "64bit":
294
- fnames = model._exec64Wins # pylint: disable=protected-access
295
- else:
296
- fnames = model._exec32Wins # pylint: disable=protected-access
297
- else:
298
- if os_bits == "64bit":
299
- fnames = model._exec64Lins # pylint: disable=protected-access
300
- else:
301
- fnames = model._exec32Lins # pylint: disable=protected-access
302
- if fnames:
303
- dll_file = fnames[0]
304
- ami_file = fnames[1]
305
- self.log(
306
- "There was an [Algorithmic Model] keyword in this model.\n \
307
- If you wish to use the AMI model associated with this IBIS model,\n \
308
- please, go the 'Equalization' tab and enable it now.",
309
- alert=True,
310
- )
311
- elif "algorithmic_model" in model._subDict: # pylint: disable=protected-access
312
- self.log(
313
- f"There was an [Algorithmic Model] keyword for this model,\n \
314
- but no executable for your platform: {os_type}-{os_bits};\n \
315
- PyBERT native equalization modeling being used instead.",
316
- alert=True,
317
- )
318
- else:
319
- self.log(
320
- "There was no [Algorithmic Model] keyword for this model;\n \
321
- PyBERT native equalization modeling being used instead.",
322
- alert=True,
323
- )
324
- self._dll_file = dll_file # pylint: disable=attribute-defined-outside-init
325
- self._ami_file = ami_file # pylint: disable=attribute-defined-outside-init
1
+ """A class for encapsulating IBIS model files.
2
+
3
+ Original Author: David Banas <capn.freako@gmail.com>
4
+
5
+ Original Date: November 1, 2019
6
+
7
+ For information regarding the IBIS modeling standard, visit:
8
+ https://ibis.org/
9
+
10
+ **Note:** The ``IBISModel`` class, defined here, needs to be kept separate from the
11
+ other IBIS-related classes, defined in the ``model`` module, in order to
12
+ avoid circular imports.
13
+
14
+ Copyright (c) 2019 by David Banas; All rights reserved World wide.
15
+ """
16
+
17
+ import platform
18
+ from datetime import datetime
19
+
20
+ from traits.api import (
21
+ Any,
22
+ Dict,
23
+ Enum,
24
+ Float,
25
+ HasTraits,
26
+ List,
27
+ Property,
28
+ String,
29
+ Trait,
30
+ cached_property,
31
+ )
32
+ from traitsui.api import HGroup, Item, ModalButtons, VGroup, View, spring
33
+ from traitsui.message import message
34
+
35
+ from pyibisami.ibis.parser import parse_ibis_file
36
+
37
+
38
+ class IBISModel(HasTraits): # pylint: disable=too-many-instance-attributes
39
+ """HasTraits subclass for wrapping and interacting with an IBIS model.
40
+
41
+ This class can be configured to present a customized GUI to the user
42
+ for interacting with a particular IBIS model (i.e. - selecting components,
43
+ pins, and models).
44
+
45
+ The intended use model is as follows:
46
+
47
+ 1. Instantiate this class only once per IBIS model file.
48
+ When instantiating, provide the unprocessed contents of the IBIS
49
+ file, as a single string. This class will take care of getting
50
+ that string parsed properly, and report any errors or warnings
51
+ it encounters, in its ``ibis_parsing_errors`` property.
52
+
53
+ 2. When you want to let the user select a particular component/pin/model,
54
+ call the newly created instance, as if it were a function, passing
55
+ no arguments.
56
+ The instance will then present a GUI to the user,
57
+ allowing him to select a particular component/pin/model, which may then
58
+ be retrieved, via the ``model`` property.
59
+ The latest user selections will be remembered,
60
+ as long as the instance remains in scope.
61
+
62
+ Any errors or warnings encountered while parsing are available, in
63
+ the ``ibis_parsing_errors`` property.
64
+
65
+ The complete dictionary containing all parsed models may be retrieved,
66
+ via the ``model_dict`` property.
67
+ """
68
+
69
+ _log = ""
70
+
71
+ pin_ = Property(Any, depends_on=["pin"])
72
+ pin_rlcs = Property(Dict, depends_on=["pin"])
73
+ model = Property(Any, depends_on=["mod"])
74
+ pins = List # Always holds the list of valid pin selections, given a component selection.
75
+ models = List # Always holds the list of valid model selections, given a pin selection.
76
+
77
+ def get_models(self, mname):
78
+ """Return the list of models associated with a particular name."""
79
+ model_dict = self._model_dict
80
+ if "model_selectors" in model_dict and mname in model_dict["model_selectors"]:
81
+ return list(map(lambda pr: pr[0], model_dict["model_selectors"][mname]))
82
+ return [mname]
83
+
84
+ def get_pins(self):
85
+ """Get the list of appropriate pins, given our type (i.e. - Tx or Rx)."""
86
+ pins = self.comp_.pins
87
+
88
+ def pin_ok(pname):
89
+ (mname, _) = pins[pname]
90
+ mods = self.get_models(mname)
91
+ mod = self._models[mods[0]]
92
+ mod_type = mod.mtype.lower()
93
+ tx_ok = mod_type in ("output", "i/o")
94
+ if self._is_tx:
95
+ return tx_ok
96
+ return not tx_ok
97
+
98
+ return list(filter(pin_ok, list(pins)))
99
+
100
+ def __init__(self, ibis_file_name, is_tx, debug=False, gui=True):
101
+ """
102
+ Args:
103
+ ibis_file_name (str): The name of the IBIS file.
104
+ is_tx (bool): True if this is a Tx model.
105
+
106
+ Keyword Args:
107
+ debug (bool): Output debugging info to console when true.
108
+ Default = False
109
+ gui (bool): Set to `False` for command line and/or script usage.
110
+ Default = True.
111
+ """
112
+
113
+ # Super-class initialization is ABSOLUTELY NECESSARY, in order
114
+ # to get all the Traits/UI machinery setup correctly.
115
+ super().__init__()
116
+
117
+ self.debug = debug
118
+ self.GUI = gui
119
+ if debug:
120
+ self.log("pyibisami.ibis_file.IBISModel initializing in debug mode...")
121
+ else:
122
+ self.log("pyibisami.ibis_file.IBISModel initializing in non-debug mode...")
123
+
124
+ # Parse the IBIS file contents, storing any errors or warnings, and validate it.
125
+ with open(ibis_file_name, "r", encoding="utf-8") as file:
126
+ ibis_file_contents_str = file.read()
127
+ err_str, model_dict = parse_ibis_file(ibis_file_contents_str, debug=debug)
128
+ self.log("IBIS parsing errors/warnings:\n" + err_str)
129
+ if "components" not in model_dict or not model_dict["components"]:
130
+ print(f":\n{model_dict}", flush=True)
131
+ raise ValueError("This IBIS model has no components!")
132
+ components = model_dict["components"]
133
+ if "models" not in model_dict or not model_dict["models"]:
134
+ raise ValueError("This IBIS model has no models!")
135
+ models = model_dict["models"]
136
+ self._model_dict = model_dict
137
+ self._models = models
138
+ self._is_tx = is_tx
139
+
140
+ # Add Traits for various attributes found in the IBIS file.
141
+ self.add_trait("comp", Trait(list(components)[0], components)) # Doesn't need a custom mapper, because
142
+ self.pins = self.get_pins() # the thing above it (file) can't change.
143
+ self.add_trait("pin", Enum(self.pins[0], values="pins"))
144
+ (mname, _) = self.pin_
145
+ self.models = self.get_models(mname)
146
+ self.add_trait("mod", Enum(self.models[0], values="models"))
147
+ self.add_trait("ibis_ver", Float(model_dict["ibis_ver"]))
148
+ self.add_trait("file_name", String(model_dict["file_name"]))
149
+ self.add_trait("file_rev", String(model_dict["file_rev"]))
150
+ if "date" in model_dict:
151
+ self.add_trait("date", String(model_dict["date"]))
152
+ else:
153
+ self.add_trait("date", String("(n/a)"))
154
+
155
+ self._ibis_parsing_errors = err_str
156
+ self._os_type = platform.system() # These 2 are used, to choose
157
+ self._os_bits = platform.architecture()[0] # the correct AMI executable.
158
+
159
+ self._comp_changed(list(components)[0]) # Wasn't being called automatically.
160
+ self._pin_changed(self.pins[0]) # Wasn't being called automatically.
161
+
162
+ self.log("Done.")
163
+
164
+ def __str__(self):
165
+ return f"IBIS Model '{self._model_dict['file_name']}'"
166
+
167
+ def info(self):
168
+ """Basic information about the IBIS model."""
169
+ res = ""
170
+ try:
171
+ for k in ["ibis_ver", "file_name", "file_rev"]:
172
+ res += k + ":\t" + str(self._model_dict[k]) + "\n"
173
+ except Exception as err:
174
+ print(f"{err}")
175
+ print(self._model_dict)
176
+ raise
177
+ res += "date" + ":\t\t" + str(self._model_dict["date"]) + "\n"
178
+ res += "\nComponents:"
179
+ res += "\n=========="
180
+ for c in list(self._model_dict["components"]):
181
+ res += "\n" + c + ":\n" + "---\n" + str(self._model_dict["components"][c]) + "\n"
182
+ res += "\nModel Selectors:"
183
+ res += "\n===============\n"
184
+ for s in list(self._model_dict["model_selectors"]):
185
+ res += f"{s}\n"
186
+ res += "\nModels:"
187
+ res += "\n======"
188
+ for m in list(self._model_dict["models"]):
189
+ res += "\n" + m + ":\n" + "---\n" + str(self._model_dict["models"][m])
190
+ return res
191
+
192
+ def __call__(self):
193
+ """Present a customized GUI to the user, for model selection, etc."""
194
+ self.edit_traits(kind="livemodal")
195
+
196
+ # Logger & Pop-up
197
+ def log(self, msg, alert=False):
198
+ """Log a message to the console and, optionally, to terminal and/or
199
+ pop-up dialog."""
200
+ _msg = msg.strip()
201
+ txt = f"\n[{datetime.now()}]: IBISModel: {_msg}\n"
202
+ self._log += txt
203
+ if self.debug:
204
+ print(txt, flush=True)
205
+ if alert and self.GUI:
206
+ message(_msg, "PyAMI Alert")
207
+
208
+ def default_traits_view(self):
209
+ "Default Traits/UI view definition."
210
+ view = View(
211
+ VGroup(
212
+ HGroup(
213
+ Item("file_name", label="File name", style="readonly"),
214
+ spring,
215
+ Item("file_rev", label="rev", style="readonly"),
216
+ ),
217
+ HGroup(
218
+ Item("ibis_ver", label="IBIS ver", style="readonly"),
219
+ spring,
220
+ Item("date", label="Date", style="readonly"),
221
+ ),
222
+ HGroup(
223
+ Item("comp", label="Component"),
224
+ Item("pin", label="Pin"),
225
+ Item("mod", label="Model"),
226
+ ),
227
+ ),
228
+ resizable=False,
229
+ buttons=ModalButtons,
230
+ title="PyBERT IBIS Model Selector",
231
+ id="pybert.pybert_ami.model_selector",
232
+ )
233
+ return view
234
+
235
+ @cached_property
236
+ def _get_pin_(self):
237
+ return self.comp_.pins[self.pin]
238
+
239
+ @cached_property
240
+ def _get_pin_rlcs(self):
241
+ (_, pin_rlcs) = self.pin_
242
+ return pin_rlcs
243
+
244
+ @cached_property
245
+ def _get_model(self):
246
+ return self._models[self.mod]
247
+
248
+ @property
249
+ def ibis_parsing_errors(self):
250
+ """Any errors or warnings encountered, while parsing the IBIS file
251
+ contents."""
252
+ return self._ibis_parsing_errors
253
+
254
+ @property
255
+ def log_txt(self):
256
+ """The complete log since instantiation."""
257
+ return self._log
258
+
259
+ @property
260
+ def model_dict(self):
261
+ "Dictionary of all model keywords."
262
+ return self._model_dict
263
+
264
+ @property
265
+ def dll_file(self):
266
+ "Shared object file."
267
+ return self._dll_file
268
+
269
+ @property
270
+ def ami_file(self):
271
+ "AMI file."
272
+ return self._ami_file
273
+
274
+ def _comp_changed(self, new_value):
275
+ del new_value
276
+ self.pins = self.get_pins()
277
+ self.pin = self.pins[0]
278
+
279
+ def _pin_changed(self, new_value):
280
+ # (mname, rlc_dict) = self.pin_ # Doesn't work. Because ``pin_`` is a cached property and hasn't yet been marked "dirty"?
281
+ (mname, _) = self.comp_.pins[new_value]
282
+ self.models = self.get_models(mname)
283
+ self.mod = self.models[0]
284
+
285
+ def _mod_changed(self, new_value):
286
+ model = self._models[new_value]
287
+ os_type = self._os_type
288
+ os_bits = self._os_bits
289
+ fnames = []
290
+ dll_file = ""
291
+ ami_file = ""
292
+ if os_type.lower() == "windows":
293
+ if os_bits == "64bit":
294
+ fnames = model._exec64Wins # pylint: disable=protected-access
295
+ else:
296
+ fnames = model._exec32Wins # pylint: disable=protected-access
297
+ else:
298
+ if os_bits == "64bit":
299
+ fnames = model._exec64Lins # pylint: disable=protected-access
300
+ else:
301
+ fnames = model._exec32Lins # pylint: disable=protected-access
302
+ if fnames:
303
+ dll_file = fnames[0]
304
+ ami_file = fnames[1]
305
+ self.log(
306
+ "There was an [Algorithmic Model] keyword in this model.\n \
307
+ If you wish to use the AMI model associated with this IBIS model,\n \
308
+ please, go the 'Equalization' tab and enable it now.",
309
+ alert=True,
310
+ )
311
+ elif "algorithmic_model" in model._subDict: # pylint: disable=protected-access
312
+ self.log(
313
+ f"There was an [Algorithmic Model] keyword for this model,\n \
314
+ but no executable for your platform: {os_type}-{os_bits};\n \
315
+ PyBERT native equalization modeling being used instead.",
316
+ alert=True,
317
+ )
318
+ else:
319
+ self.log(
320
+ "There was no [Algorithmic Model] keyword for this model;\n \
321
+ PyBERT native equalization modeling being used instead.",
322
+ alert=True,
323
+ )
324
+ self._dll_file = dll_file # pylint: disable=attribute-defined-outside-init
325
+ self._ami_file = ami_file # pylint: disable=attribute-defined-outside-init