PyChOpMarg 0.1__tar.gz → 0.1.2__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.
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/PKG-INFO +1 -1
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/pyproject.toml +2 -2
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/src/PyChOpMarg.egg-info/PKG-INFO +1 -1
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/src/PyChOpMarg.egg-info/SOURCES.txt +3 -1
- PyChOpMarg-0.1.2/src/PyChOpMarg.egg-info/entry_points.txt +2 -0
- PyChOpMarg-0.1.2/src/pychopmarg/__init__.py +23 -0
- PyChOpMarg-0.1.2/src/pychopmarg/cli.py +50 -0
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/src/pychopmarg/com.py +43 -21
- PyChOpMarg-0.1.2/src/pychopmarg/view.py +62 -0
- PyChOpMarg-0.1/src/PyChOpMarg.egg-info/entry_points.txt +0 -2
- PyChOpMarg-0.1/src/pychopmarg/__init__.py +0 -0
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/LICENSE +0 -0
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/README.md +0 -0
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/setup.cfg +0 -0
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/src/PyChOpMarg.egg-info/dependency_links.txt +0 -0
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/src/PyChOpMarg.egg-info/requires.txt +0 -0
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/src/PyChOpMarg.egg-info/top_level.txt +0 -0
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/src/pychopmarg/common.py +0 -0
- {PyChOpMarg-0.1 → PyChOpMarg-0.1.2}/src/pychopmarg/utility.py +0 -0
|
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "PyChOpMarg"
|
|
7
7
|
description = "Python implementation of COM, as per IEEE 802.3-22 Annex 93A."
|
|
8
|
-
version = "0.1"
|
|
8
|
+
version = "0.1.2"
|
|
9
9
|
authors = [{name = "David Banas", email = "capn.freako@gmail.com"}]
|
|
10
10
|
# urls = { documentation = "https://github.com/capn-freako/PyBERT/wiki"}
|
|
11
11
|
readme = "README.md"
|
|
@@ -40,7 +40,7 @@ classifiers=[
|
|
|
40
40
|
]
|
|
41
41
|
|
|
42
42
|
[project.scripts]
|
|
43
|
-
pychopmarg = "pychopmarg
|
|
43
|
+
pychopmarg = "pychopmarg:cli"
|
|
44
44
|
|
|
45
45
|
[tool.setuptools.packages.find]
|
|
46
46
|
where = ["src"]
|
|
@@ -8,6 +8,8 @@ src/PyChOpMarg.egg-info/entry_points.txt
|
|
|
8
8
|
src/PyChOpMarg.egg-info/requires.txt
|
|
9
9
|
src/PyChOpMarg.egg-info/top_level.txt
|
|
10
10
|
src/pychopmarg/__init__.py
|
|
11
|
+
src/pychopmarg/cli.py
|
|
11
12
|
src/pychopmarg/com.py
|
|
12
13
|
src/pychopmarg/common.py
|
|
13
|
-
src/pychopmarg/utility.py
|
|
14
|
+
src/pychopmarg/utility.py
|
|
15
|
+
src/pychopmarg/view.py
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A Python implementation of COM, as per IEEE 802.3-22 Annex 93A.
|
|
3
|
+
|
|
4
|
+
.. moduleauthor:: David Banas <capn.freako@gmail.com>
|
|
5
|
+
|
|
6
|
+
Original Author: David Banas <capn.freako@gmail.com>
|
|
7
|
+
|
|
8
|
+
Original Date: 29 February 2024
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2024 by David Banas; all rights reserved World wide.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from importlib.metadata import version as _get_version
|
|
14
|
+
|
|
15
|
+
# Set PEP396 version attribute
|
|
16
|
+
try:
|
|
17
|
+
__version__ = _get_version("PyChOpMarg")
|
|
18
|
+
except:
|
|
19
|
+
__version__ = "(dev)"
|
|
20
|
+
|
|
21
|
+
__date__ = "March 25, 2024"
|
|
22
|
+
__authors__ = "David Banas"
|
|
23
|
+
__copy__ = "Copyright (c) 2024 David Banas"
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Main Entry Point for PyChOpMarg when using the CLI.
|
|
3
|
+
|
|
4
|
+
Original author: David Banas <capn.freako@gmail.com>
|
|
5
|
+
|
|
6
|
+
Original date: March 25, 2024
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2024 David Banas; all rights reserved World wide.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import click
|
|
14
|
+
|
|
15
|
+
from pychopmarg import __version__
|
|
16
|
+
from pychopmarg.view import traits_view
|
|
17
|
+
from pychopmarg.com import COM
|
|
18
|
+
|
|
19
|
+
@click.group(invoke_without_command=True, context_settings=dict(help_option_names=["-h", "--help"]))
|
|
20
|
+
@click.pass_context
|
|
21
|
+
@click.version_option(version=__version__)
|
|
22
|
+
def cli(ctx):
|
|
23
|
+
"""
|
|
24
|
+
PyChOpMarg GUI.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
if ctx.invoked_subcommand is None: # No sub-command like `sim` given open the GUI like default.
|
|
28
|
+
theCOM = COM()
|
|
29
|
+
|
|
30
|
+
# Show the GUI.
|
|
31
|
+
theCOM.configure_traits(view=traits_view)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@cli.command(context_settings=dict(help_option_names=["-h", "--help"]))
|
|
35
|
+
@click.argument("config-file", type=click.Path(exists=True))
|
|
36
|
+
@click.option("--results", "-r", type=click.Path(), help="Override the results filename.")
|
|
37
|
+
def run(config_file, results):
|
|
38
|
+
"""
|
|
39
|
+
Run a COM calculation without opening the GUI.
|
|
40
|
+
|
|
41
|
+
Will load the CONFIG_FILE from the given filepath, run the
|
|
42
|
+
COM calculation and then save the results into a file with the same name
|
|
43
|
+
but a different extension as the configuration file.
|
|
44
|
+
"""
|
|
45
|
+
theCOM = COM()
|
|
46
|
+
theCOM.load_configuration(config_file)
|
|
47
|
+
theCOM.simulate(initial_run=True, update_plots=True)
|
|
48
|
+
if not results:
|
|
49
|
+
results = Path(config_file).with_suffix(".pychopmarg_results")
|
|
50
|
+
theCOM.save_results(results)
|
|
@@ -155,6 +155,26 @@ class COM(HasTraits):
|
|
|
155
155
|
|
|
156
156
|
# Reserved functions
|
|
157
157
|
|
|
158
|
+
def __init__(self):
|
|
159
|
+
"""
|
|
160
|
+
Instance creation only! Must still initialize.
|
|
161
|
+
|
|
162
|
+
Notes:
|
|
163
|
+
1. In order to support multi-mode operation (i.e. - library, CLI, and GUI),
|
|
164
|
+
we have to separate instance *creation* from instance *initialization*.
|
|
165
|
+
Therefore, at this point you still need to call one of the 3 initializers:
|
|
166
|
+
- `init_lib()`,
|
|
167
|
+
- `init_cli()`, or
|
|
168
|
+
- `init_gui()`.
|
|
169
|
+
(See their docstrings, below, for more detail.)
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
# Super-class initialization is ABSOLUTELY NECESSARY, in order
|
|
173
|
+
# to get all the Traits/UI machinery setup correctly.
|
|
174
|
+
super().__init__()
|
|
175
|
+
|
|
176
|
+
self.initialized = False
|
|
177
|
+
|
|
158
178
|
def __call__(self, do_opt_eq=True, tx_taps: Rvec = None):
|
|
159
179
|
"""
|
|
160
180
|
Calculate the COM value.
|
|
@@ -166,6 +186,8 @@ class COM(HasTraits):
|
|
|
166
186
|
Default: None
|
|
167
187
|
"""
|
|
168
188
|
|
|
189
|
+
assert self.initialized, RuntimeError(
|
|
190
|
+
"You must initialize the instance before you can call it!")
|
|
169
191
|
assert self.opt_eq(do_opt_eq=do_opt_eq, tx_taps=tx_taps), RuntimeError(
|
|
170
192
|
"EQ optimization failed!")
|
|
171
193
|
self.gDC = self.rslts['gDC']
|
|
@@ -181,31 +203,31 @@ class COM(HasTraits):
|
|
|
181
203
|
self.cursor_ix = cursor_ix
|
|
182
204
|
return com
|
|
183
205
|
|
|
184
|
-
|
|
185
|
-
|
|
206
|
+
# Initializers
|
|
207
|
+
|
|
208
|
+
def init_lib(self, params: COMParams, chnl_files: list[str], vic_chnl_ix: int,
|
|
209
|
+
zp_sel: int = 1, num_ui: int = 100):
|
|
186
210
|
"""
|
|
187
|
-
COM class initializer.
|
|
211
|
+
COM class initializer for use as a library.
|
|
188
212
|
|
|
189
213
|
Args:
|
|
190
214
|
params: COM configuration parameters for desired standard.
|
|
191
215
|
Note: Assumed immutable. ToDo: Can we encode this assumption, using type annotations?
|
|
192
216
|
chnl_files: Touchstone file(s) representing channel, either:
|
|
193
|
-
1.
|
|
217
|
+
1. N s4p files: [victim, N-1 aggressors], or
|
|
194
218
|
2. 1 s32p file, according to VITA 68.2 convention.
|
|
195
|
-
vic_chnl_ix: Victim channel index (from 1).
|
|
219
|
+
vic_chnl_ix: Victim channel index (from 1) for option 2.
|
|
196
220
|
|
|
197
221
|
KeywordArgs:
|
|
198
222
|
zp_sel: User selection of package T-line length option (from 1).
|
|
199
223
|
Default: 1
|
|
200
224
|
num_ui: Number of unit intervals to include in system time vector.
|
|
201
225
|
Default: 100
|
|
202
|
-
gui: Set to `False` for script/CLI based usage.
|
|
203
|
-
Default: True
|
|
204
|
-
"""
|
|
205
226
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
227
|
+
Notes:
|
|
228
|
+
1. Use this initializer when you want to import from *PyChOpMarg*
|
|
229
|
+
into a larger Python script and/or Jupyter notebook.
|
|
230
|
+
"""
|
|
209
231
|
|
|
210
232
|
# Set default parameter values, as necessary.
|
|
211
233
|
if 'zc' not in params:
|
|
@@ -216,7 +238,7 @@ class COM(HasTraits):
|
|
|
216
238
|
# Stash function parameters.
|
|
217
239
|
self.params = params
|
|
218
240
|
self.chnl_files = chnl_files
|
|
219
|
-
self.gui =
|
|
241
|
+
self.gui = False
|
|
220
242
|
|
|
221
243
|
# Calculate intermediate variable values.
|
|
222
244
|
self.rslts = {}
|
|
@@ -349,11 +371,11 @@ class COM(HasTraits):
|
|
|
349
371
|
r0 = self.params['R0']
|
|
350
372
|
zp = self.params['zp'][zp_opt - 1]
|
|
351
373
|
|
|
352
|
-
f_GHz = self.freqs / 1e9
|
|
353
|
-
a1 = 1.734e-3 # sqrt(ns)/mm
|
|
354
|
-
a2 = 1.455e-4 # ns/mm
|
|
355
|
-
tau = 6.141e-3 # ns/mm
|
|
356
|
-
rho = (zc - 2 * r0) / (zc + 2 * r0)
|
|
374
|
+
f_GHz = self.freqs / 1e9 # noqa E221
|
|
375
|
+
a1 = 1.734e-3 # sqrt(ns)/mm # noqa E221
|
|
376
|
+
a2 = 1.455e-4 # ns/mm # noqa E221
|
|
377
|
+
tau = 6.141e-3 # ns/mm # noqa E221
|
|
378
|
+
rho = (zc - 2 * r0) / (zc + 2 * r0) # noqa E221
|
|
357
379
|
gamma0 = 0 # 1/mm
|
|
358
380
|
gamma1 = a1 * (1 + 1j)
|
|
359
381
|
|
|
@@ -672,7 +694,7 @@ class COM(HasTraits):
|
|
|
672
694
|
self.params['dfe_max'],
|
|
673
695
|
(vic_pulse_resp_post_samps[:nDFE] / vic_curs_val)))
|
|
674
696
|
hISI = vic_pulse_resp_isi_samps \
|
|
675
|
-
- vic_curs_val * np.pad(dfe_tap_weights,
|
|
697
|
+
- vic_curs_val * np.pad(dfe_tap_weights, # noqa E127
|
|
676
698
|
(n_pre, len(vic_pulse_resp_post_samps) - nDFE),
|
|
677
699
|
mode='constant',
|
|
678
700
|
constant_values=0) # (93A-27)
|
|
@@ -849,8 +871,8 @@ class COM(HasTraits):
|
|
|
849
871
|
"""
|
|
850
872
|
(93A-39)
|
|
851
873
|
"""
|
|
852
|
-
return 1 / L * sum([np.roll(delta, int((2 *
|
|
853
|
-
for
|
|
874
|
+
return 1 / L * sum([np.roll(delta, int((2 * el / (L - 1) - 1) * hn / ystep))
|
|
875
|
+
for el in range(L)])
|
|
854
876
|
|
|
855
877
|
def p(h_samps: Rvec) -> Rvec:
|
|
856
878
|
"""
|
|
@@ -910,7 +932,7 @@ class COM(HasTraits):
|
|
|
910
932
|
self.params['dfe_max'],
|
|
911
933
|
(vic_pulse_resp_post_samps[:nDFE] / vic_curs_val)))
|
|
912
934
|
hISI = vic_pulse_resp_isi_samps \
|
|
913
|
-
- vic_curs_val * np.pad(dfe_tap_weights,
|
|
935
|
+
- vic_curs_val * np.pad(dfe_tap_weights, # noqa E127
|
|
914
936
|
(n_pre, len(vic_pulse_resp_post_samps) - nDFE),
|
|
915
937
|
mode='constant',
|
|
916
938
|
constant_values=0) # (93A-27)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Default view definition for `PyChOpMarg.COM` class.
|
|
3
|
+
|
|
4
|
+
Original author: David Banas <capn.freako@gmail.com>
|
|
5
|
+
|
|
6
|
+
Original date: March 26, 2024
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2024 David Banas; all rights reserved World wide.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from enable.component_editor import ComponentEditor
|
|
12
|
+
from numpy import log10, array
|
|
13
|
+
from pyface.image_resource import ImageResource
|
|
14
|
+
from traitsui.api import ( # CloseAction,
|
|
15
|
+
Action,
|
|
16
|
+
CheckListEditor,
|
|
17
|
+
FileEditor,
|
|
18
|
+
Group,
|
|
19
|
+
HGroup,
|
|
20
|
+
Item,
|
|
21
|
+
Menu,
|
|
22
|
+
MenuBar,
|
|
23
|
+
NoButtons,
|
|
24
|
+
ObjectColumn,
|
|
25
|
+
RangeEditor,
|
|
26
|
+
Separator,
|
|
27
|
+
TableEditor,
|
|
28
|
+
TextEditor,
|
|
29
|
+
VGroup,
|
|
30
|
+
View,
|
|
31
|
+
spring,
|
|
32
|
+
)
|
|
33
|
+
from traitsui.ui_editors.array_view_editor import ArrayViewEditor
|
|
34
|
+
|
|
35
|
+
# Main window layout definition.
|
|
36
|
+
traits_view = View(
|
|
37
|
+
Group( # Members correspond to top-level tabs.
|
|
38
|
+
VGroup( # "Config." tab
|
|
39
|
+
HGroup(
|
|
40
|
+
Item(
|
|
41
|
+
name="ui",
|
|
42
|
+
label="UI",
|
|
43
|
+
tooltip="Unit Interval (ps)",
|
|
44
|
+
show_label=True,
|
|
45
|
+
enabled_when="True",
|
|
46
|
+
editor=TextEditor(auto_set=False, enter_set=True, evaluate=float),
|
|
47
|
+
),
|
|
48
|
+
Item(label="ps")
|
|
49
|
+
),
|
|
50
|
+
label="Config."
|
|
51
|
+
),
|
|
52
|
+
layout="tabbed",
|
|
53
|
+
springy=True,
|
|
54
|
+
id="tabs",
|
|
55
|
+
),
|
|
56
|
+
resizable=True,
|
|
57
|
+
handler=MyHandler(),
|
|
58
|
+
buttons=NoButtons,
|
|
59
|
+
# statusbar="status_str",
|
|
60
|
+
title="PyChOpMarg",
|
|
61
|
+
# icon=ImageResource("icon.png"),
|
|
62
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|