Name | psf-utils JSON |
Version |
1.8
JSON |
| download |
home_page | |
Summary | Cadence PSF file utilities |
upload_time | 2024-01-16 05:24:14 |
maintainer | |
docs_url | None |
author | Ken Kundert |
requires_python | >=3.6 |
license | |
keywords |
cadence
spectre
psf
simulation
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
|
PSF Utilities — Read Spectre Data Files
=======================================
.. image::
https://github.com/KenKundert/psf_utils/actions/workflows/build.yaml/badge.svg
:target: https://github.com/KenKundert/psf_utils/actions/workflows/build.yaml
.. image:: https://pepy.tech/badge/psf_utils/month
:target: https://pepy.tech/project/psf_utils
.. image:: https://img.shields.io/pypi/v/psf_utils.svg
:target: https://pypi.python.org/pypi/psf_utils
.. image:: https://img.shields.io/pypi/pyversions/psf_utils.svg
:target: https://pypi.python.org/pypi/psf_utils/
:Author: Ken Kundert
:Version: 1.8
:Released: 2024-01-15
What?
-----
*psf_utils* is a library that allows you to read data from a Spectre PSF ASCII
file. Spectre is a commercial circuit simulator produced by Cadence Design
Systems. PSF files contain signals generated by Spectre. This package also
contains two programs that are useful in their own right, but also act as
demonstrators as to how to use the library. They are *list-psf* and *show-psf*.
The first lists the available signals in a file, and the other displays them.
Accessing the Results
---------------------
You can use the PSF class to read ASCII Parameter Storage Format files. When
instantiating the class you pass in the path to the file and then the resulting
PSF object contains the signals. For example, the following lists the signals
present in a ASCII PSF file::
from psf_utils import PSF
from inform import Error, display
kinds = {
'float double': 'real',
'float complex': 'complex',
}
try:
psf = PSF('adc.raw/tran.tran')
for signal in psf.all_signals():
kind = signal.type.kind
kind = kinds.get(kind, kind)
display(f'{signal.name:<15} {signal.units:<12} {kind}')
except Error as e:
e.terminate()
This example plots the output signal::
from psf_utils import PSF
from inform import Error, display
import matplotlib.pyplot as plt
try:
psf = PSF('adc.raw/tran.tran')
sweep = psf.get_sweep()
out = psf.get_signal('out')
figure = plt.figure()
axes = figure.add_subplot(1,1,1)
axes.plot(sweep.abscissa, out.ordinate, linewidth=2, label=out.name)
axes.set_title('ADC Output')
axes.set_xlabel(f'{sweep.name} ({PSF.units_to_unicode(sweep.units)})')
axes.set_ylabel(f'{out.name} ({PSF.units_to_unicode(out.units)})')
plt.show()
except Error as e:
e.terminate()
*abscissa* and *ordinate* are NumPy arrays. As such, you can perform
computation with them::
out = out_p.ordinate - out_n.ordinate
from numpy import sin
sine = sin(sweep.abscissa)
Reading large ASCII data files is slow, so *psf_utils* reads the PSF file once,
then pickles the data and writes it to disk. On subsequent runs the pickled data
is used if the pickle file is newer that the corresponding PSF file.
Things are a bit different for DC operating point results. In this case, *sweep*
is None and the results are scalar `quantities
<https://quantiphy.readthedocs.io>`_::
from psf_utils import PSF, Quantity
psf = PSF('opamp.raw/op.dc')
with Quantity.prefs(map_sf=Quantity.map_sf_to_greek):
for signal in sorted(psf.all_signals(), key=lambda s: s.name):
name = f'{signal.access}({signal.name})'
print(f'{name:>20} = {signal.ordinate}')
Utility Programs
----------------
Two utility programs are installed along with the *psf_utils* library:
*list-psf* and *show-psf*. The first lists the signals available from a PSF
file, and the second displays them. They both employ caching to speed up access
to the data. They also cache the name of the PSF file so that it need not be
given every time. *show-psf* also caches its arguments, so if you run it again
with no arguments it will simply repeat what it did last time. For example, here
is a typical session::
# list the signals in noise PSF file
> list-psf -f resistor.raw/pnoise.pnoise
Using resistor.raw/pnoise.pnoise.
R1:flicker R1:total R2:fn out
R1:thermal R2:rn R2:total
# list them again, this time in long form
> list-psf -l
Using resistor.raw/pnoise.pnoise.
R1:flicker A²/Hz real (12042 points)
R1:thermal A²/Hz real (12042 points)
R1:total A²/Hz real (12042 points)
R2:fn A²/Hz real (12042 points)
R2:rn A²/Hz real (12042 points)
R2:total A²/Hz real (12042 points)
out A/√Hz real (12042 points)
# list only those that match R1:* (assumes nonomatch variable is set in shell)
> list-psf -l R1:*
Using resistor.raw/pnoise.pnoise.
R1:flicker A²/Hz real (12042 points)
R1:thermal A²/Hz real (12042 points)
R1:total A²/Hz real (12042 points)
# show a graph containing signals that start with R1:
> show-psf R1:*
# show the thermal noise of R1, and then the total noise minus the flicker noise
> show-psf R1:thermal R1:total-R1:flicker
> show-psf out # show a graph containing only out
> show-psf # show out again, exactly as in previous run
> show-psf -M out # show out again, this time include point markers
> show-psf -P out # show out again, this time only show point markers
> show-psf -s out.svg out # send graph of out to svg file
# list signals in a PSF file from a DC operating point file:
> list-psf -f diffamp.raw/tran.dc
Using diffamp.raw/pnoise.pnoise.
in_n in_p out_n out_p Vdd Vdd:p
# show the DC voltages
> show-psf \*
V(in_n) = 47.678 µV
V(in_p) = 47.623 µV
V(out_n) = 876.16 µV
V(out_p) = 876.16 µV
V(Vdd) = 2.5 V
I(Vdd:p) = −10.05 µA
# list signals in transient PSF file
> list-psf -f diffamp.raw/tran.tran
Using diffamp.raw/pnoise.pnoise.
in_n in_p out_n out_p Vdd Vdd:p
# display differential output and differential input
> show-psf out_p-out_n in_p-in_n
Converting to PSF ASCII
-----------------------
*psf_utils* only supports PSF ASCII files. As an alternative, `libpsf
<https://pypi.org/project/libpsf>`_ is a Python package that can read both ASCII
and binary PSF files. Or, you can use the Cadence *psf* program to convert
various types of simulation results files into PSF ASCII format. To use it,
simply specify the input and output files::
> psf -i adc.raw/tran.tran -o adc.raw/tran.psfascii
> list-psf -f adc.raw/tran.psfascii
In this example there is nothing special about the 'psfascii' suffix, it is
simply mnemonic. Rather, the output is in ASCII format because the ``-b``
(binary) option is not specified.
*psf_utils* does not support SST files, which are generated by AMS Designer,
Cadence's mixed-signal simulator. You can recognize SST files in that they come
in pairs, and the two files have ``.dsn`` and ``.trn`` suffixes. In this case,
Cadence's PSF utility cannot help you either. However, you can use the
*simvisdbutil* to convert the data to a CSV file, which would allow you to
access the data, though not with *psf_utils*. For example, the following
converts all waveforms contained in ldo.trn into CSV data::
simvisdbutil ldo.trn -csv -timeunits s -output ldo.csv
Examples
--------
`Flicker Noise <https://github.com/KenKundert/flicker-noise>`_ is a simulation
script that shows how to write simple Python scripts that run Spectre and use
*psf_utils* to extract and display the desired results.
Releases
--------
Latest development release
''''''''''''''''''''''''''
| Version: 1.8
| Released: 2024-01-15
1.8 (2024-01-15)
''''''''''''''''
- Fixed issue with *NaN*
1.7 (2023-12-13)
''''''''''''''''
- fixed units on terminal currents
- add support for *inf*
- add support for *PZ* and *STB* files
1.6 (2022-09-18)
''''''''''''''''
- changed ``--no-cache`` command line option to ``--refresh-cache``.
1.5 (2021-11-11)
''''''''''''''''
- Renamed *plot-psf* to *show-psf*.
- Improved support of DC operating points.
- Suppress access function names when printing members of PSF structures.
- Correct invalid units produced by Spectre on oppoint files (I, R, C).
1.4 (2021-10-21)
''''''''''''''''
- Allow signal names to contain backslashes.
1.3 (2021-03-21)
- Improve support for DC operating points.
1.2 (2021-01-07)
''''''''''''''''
- Support PSF files that contain DC operating points.
- Support PSF files where values are given in a group.
1.1 (2021-01-30)
''''''''''''''''
- Allow, but ignore, properties on traces.
1.0 (2020-11-03)
''''''''''''''''
- Production release
.. hide the pre-production releases
**0.7 (2020-09-23)**:
- Add ability to show individual points
- Improve the cursor values display
- Increase precision of both cursor values and axis labels
**0.6 (2020-04-16)**:
- modest refinements
**0.5 (2020-01-08)**:
- beta release
**0.4 (2019-09-26)**:
- Allow glob patterns to be passed to both *list-psf* and *show-psf*.
**0.3 (2019-09-25)**:
- Fix import errors in *show-psf* command.
**0.2 (2019-09-25)**:
- Fix dependencies.
**0.1 (2019-09-25)**:
- Initial version
Raw data
{
"_id": null,
"home_page": "",
"name": "psf-utils",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "",
"keywords": "cadence,spectre,PSF,simulation",
"author": "Ken Kundert",
"author_email": "psf_utils@nurdletech.com",
"download_url": "https://files.pythonhosted.org/packages/64/8d/dbecff62a830ae06bc1755e62913458f15dfc3864bbb97392a2b3afc2895/psf_utils-1.8.tar.gz",
"platform": null,
"description": "PSF Utilities \u2014 Read Spectre Data Files\n=======================================\n\n.. image::\n https://github.com/KenKundert/psf_utils/actions/workflows/build.yaml/badge.svg\n :target: https://github.com/KenKundert/psf_utils/actions/workflows/build.yaml\n\n.. image:: https://pepy.tech/badge/psf_utils/month\n :target: https://pepy.tech/project/psf_utils\n\n.. image:: https://img.shields.io/pypi/v/psf_utils.svg\n :target: https://pypi.python.org/pypi/psf_utils\n\n.. image:: https://img.shields.io/pypi/pyversions/psf_utils.svg\n :target: https://pypi.python.org/pypi/psf_utils/\n\n:Author: Ken Kundert\n:Version: 1.8\n:Released: 2024-01-15\n\n\nWhat?\n-----\n\n*psf_utils* is a library that allows you to read data from a Spectre PSF ASCII \nfile. Spectre is a commercial circuit simulator produced by Cadence Design \nSystems. PSF files contain signals generated by Spectre. This package also \ncontains two programs that are useful in their own right, but also act as \ndemonstrators as to how to use the library. They are *list-psf* and *show-psf*. \nThe first lists the available signals in a file, and the other displays them.\n\n\nAccessing the Results\n---------------------\n\nYou can use the PSF class to read ASCII Parameter Storage Format files. When\ninstantiating the class you pass in the path to the file and then the resulting\nPSF object contains the signals. For example, the following lists the signals \npresent in a ASCII PSF file::\n\n from psf_utils import PSF\n from inform import Error, display\n\n kinds = {\n 'float double': 'real',\n 'float complex': 'complex',\n }\n\n try:\n psf = PSF('adc.raw/tran.tran')\n\n for signal in psf.all_signals():\n kind = signal.type.kind\n kind = kinds.get(kind, kind)\n display(f'{signal.name:<15} {signal.units:<12} {kind}')\n except Error as e:\n e.terminate()\n\nThis example plots the output signal::\n\n from psf_utils import PSF\n from inform import Error, display\n import matplotlib.pyplot as plt\n\n try:\n psf = PSF('adc.raw/tran.tran')\n sweep = psf.get_sweep()\n out = psf.get_signal('out')\n\n figure = plt.figure()\n axes = figure.add_subplot(1,1,1)\n axes.plot(sweep.abscissa, out.ordinate, linewidth=2, label=out.name)\n axes.set_title('ADC Output')\n axes.set_xlabel(f'{sweep.name} ({PSF.units_to_unicode(sweep.units)})')\n axes.set_ylabel(f'{out.name} ({PSF.units_to_unicode(out.units)})')\n plt.show()\n except Error as e:\n e.terminate()\n\n*abscissa* and *ordinate* are NumPy arrays. As such, you can perform \ncomputation with them::\n\n out = out_p.ordinate - out_n.ordinate\n\n from numpy import sin\n sine = sin(sweep.abscissa)\n\nReading large ASCII data files is slow, so *psf_utils* reads the PSF file once,\nthen pickles the data and writes it to disk. On subsequent runs the pickled data\nis used if the pickle file is newer that the corresponding PSF file.\n\nThings are a bit different for DC operating point results. In this case, *sweep* \nis None and the results are scalar `quantities \n<https://quantiphy.readthedocs.io>`_::\n\n from psf_utils import PSF, Quantity\n\n psf = PSF('opamp.raw/op.dc')\n with Quantity.prefs(map_sf=Quantity.map_sf_to_greek):\n for signal in sorted(psf.all_signals(), key=lambda s: s.name):\n name = f'{signal.access}({signal.name})'\n print(f'{name:>20} = {signal.ordinate}')\n\n\nUtility Programs\n----------------\n\nTwo utility programs are installed along with the *psf_utils* library:\n*list-psf* and *show-psf*. The first lists the signals available from a PSF\nfile, and the second displays them. They both employ caching to speed up access\nto the data. They also cache the name of the PSF file so that it need not be\ngiven every time. *show-psf* also caches its arguments, so if you run it again\nwith no arguments it will simply repeat what it did last time. For example, here\nis a typical session::\n\n # list the signals in noise PSF file\n > list-psf -f resistor.raw/pnoise.pnoise\n Using resistor.raw/pnoise.pnoise.\n R1:flicker R1:total R2:fn out\n R1:thermal R2:rn R2:total\n\n # list them again, this time in long form\n > list-psf -l\n Using resistor.raw/pnoise.pnoise.\n R1:flicker A\u00b2/Hz real (12042 points)\n R1:thermal A\u00b2/Hz real (12042 points)\n R1:total A\u00b2/Hz real (12042 points)\n R2:fn A\u00b2/Hz real (12042 points)\n R2:rn A\u00b2/Hz real (12042 points)\n R2:total A\u00b2/Hz real (12042 points)\n out A/\u221aHz real (12042 points)\n\n # list only those that match R1:* (assumes nonomatch variable is set in shell)\n > list-psf -l R1:*\n Using resistor.raw/pnoise.pnoise.\n R1:flicker A\u00b2/Hz real (12042 points)\n R1:thermal A\u00b2/Hz real (12042 points)\n R1:total A\u00b2/Hz real (12042 points)\n\n # show a graph containing signals that start with R1:\n > show-psf R1:*\n\n # show the thermal noise of R1, and then the total noise minus the flicker noise\n > show-psf R1:thermal R1:total-R1:flicker\n\n > show-psf out # show a graph containing only out\n\n > show-psf # show out again, exactly as in previous run\n\n > show-psf -M out # show out again, this time include point markers\n\n > show-psf -P out # show out again, this time only show point markers\n\n > show-psf -s out.svg out # send graph of out to svg file\n\n # list signals in a PSF file from a DC operating point file:\n > list-psf -f diffamp.raw/tran.dc\n Using diffamp.raw/pnoise.pnoise.\n in_n in_p out_n out_p Vdd Vdd:p\n\n # show the DC voltages\n > show-psf \\*\n V(in_n) = 47.678 \u00b5V\n V(in_p) = 47.623 \u00b5V\n V(out_n) = 876.16 \u00b5V\n V(out_p) = 876.16 \u00b5V\n V(Vdd) = 2.5 V\n I(Vdd:p) = \u221210.05 \u00b5A\n\n # list signals in transient PSF file\n > list-psf -f diffamp.raw/tran.tran\n Using diffamp.raw/pnoise.pnoise.\n in_n in_p out_n out_p Vdd Vdd:p\n\n # display differential output and differential input\n > show-psf out_p-out_n in_p-in_n\n\n\nConverting to PSF ASCII\n-----------------------\n\n*psf_utils* only supports PSF ASCII files. As an alternative, `libpsf\n<https://pypi.org/project/libpsf>`_ is a Python package that can read both ASCII\nand binary PSF files. Or, you can use the Cadence *psf* program to convert\nvarious types of simulation results files into PSF ASCII format. To use it,\nsimply specify the input and output files::\n\n > psf -i adc.raw/tran.tran -o adc.raw/tran.psfascii\n > list-psf -f adc.raw/tran.psfascii\n\nIn this example there is nothing special about the 'psfascii' suffix, it is\nsimply mnemonic. Rather, the output is in ASCII format because the ``-b``\n(binary) option is not specified.\n\n*psf_utils* does not support SST files, which are generated by AMS Designer, \nCadence's mixed-signal simulator. You can recognize SST files in that they come \nin pairs, and the two files have ``.dsn`` and ``.trn`` suffixes. In this case, \nCadence's PSF utility cannot help you either. However, you can use the \n*simvisdbutil* to convert the data to a CSV file, which would allow you to \naccess the data, though not with *psf_utils*. For example, the following\nconverts all waveforms contained in ldo.trn into CSV data::\n\n simvisdbutil ldo.trn -csv -timeunits s -output ldo.csv\n\n\nExamples\n--------\n\n`Flicker Noise <https://github.com/KenKundert/flicker-noise>`_ is a simulation \nscript that shows how to write simple Python scripts that run Spectre and use \n*psf_utils* to extract and display the desired results.\n\n\nReleases\n--------\n\nLatest development release\n''''''''''''''''''''''''''\n\n| Version: 1.8\n| Released: 2024-01-15\n\n\n1.8 (2024-01-15)\n''''''''''''''''\n\n- Fixed issue with *NaN*\n\n\n1.7 (2023-12-13)\n''''''''''''''''\n\n- fixed units on terminal currents\n- add support for *inf*\n- add support for *PZ* and *STB* files\n\n\n1.6 (2022-09-18)\n''''''''''''''''\n\n- changed ``--no-cache`` command line option to ``--refresh-cache``.\n\n\n1.5 (2021-11-11)\n''''''''''''''''\n\n- Renamed *plot-psf* to *show-psf*.\n- Improved support of DC operating points.\n- Suppress access function names when printing members of PSF structures.\n- Correct invalid units produced by Spectre on oppoint files (I, R, C).\n\n\n1.4 (2021-10-21)\n''''''''''''''''\n\n- Allow signal names to contain backslashes.\n\n\n1.3 (2021-03-21)\n\n- Improve support for DC operating points.\n\n\n1.2 (2021-01-07)\n''''''''''''''''\n\n- Support PSF files that contain DC operating points.\n- Support PSF files where values are given in a group.\n\n\n1.1 (2021-01-30)\n''''''''''''''''\n\n- Allow, but ignore, properties on traces.\n\n\n1.0 (2020-11-03)\n''''''''''''''''\n\n- Production release\n\n\n.. hide the pre-production releases\n\n **0.7 (2020-09-23)**:\n - Add ability to show individual points\n - Improve the cursor values display\n - Increase precision of both cursor values and axis labels\n\n **0.6 (2020-04-16)**:\n - modest refinements\n\n **0.5 (2020-01-08)**:\n - beta release\n\n **0.4 (2019-09-26)**:\n - Allow glob patterns to be passed to both *list-psf* and *show-psf*.\n\n **0.3 (2019-09-25)**:\n - Fix import errors in *show-psf* command.\n\n **0.2 (2019-09-25)**:\n - Fix dependencies.\n\n **0.1 (2019-09-25)**:\n - Initial version\n\n",
"bugtrack_url": null,
"license": "",
"summary": "Cadence PSF file utilities",
"version": "1.8",
"project_urls": {
"repository": "https://github.com/kenkundert/psf_utils"
},
"split_keywords": [
"cadence",
"spectre",
"psf",
"simulation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "fa445544a10485f2ec7ec722b92a64b1c8200103aac7d06484147a630c020f29",
"md5": "3d7099f307d1ac7f6ddafd94ec6c1fb8",
"sha256": "e046c862c25e9ef9d4a75841e4d16e283a3dc2f9780319f46cdcd38019ef802c"
},
"downloads": -1,
"filename": "psf_utils-1.8-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3d7099f307d1ac7f6ddafd94ec6c1fb8",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 17514,
"upload_time": "2024-01-16T05:24:13",
"upload_time_iso_8601": "2024-01-16T05:24:13.128172Z",
"url": "https://files.pythonhosted.org/packages/fa/44/5544a10485f2ec7ec722b92a64b1c8200103aac7d06484147a630c020f29/psf_utils-1.8-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "648ddbecff62a830ae06bc1755e62913458f15dfc3864bbb97392a2b3afc2895",
"md5": "bbc25573b0b2de0f63bfcd82a4d2f033",
"sha256": "cd669ede1a713dbf08992e14b1775f72359647e1c795c94977bfb9dfc3183164"
},
"downloads": -1,
"filename": "psf_utils-1.8.tar.gz",
"has_sig": false,
"md5_digest": "bbc25573b0b2de0f63bfcd82a4d2f033",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 17012,
"upload_time": "2024-01-16T05:24:14",
"upload_time_iso_8601": "2024-01-16T05:24:14.625257Z",
"url": "https://files.pythonhosted.org/packages/64/8d/dbecff62a830ae06bc1755e62913458f15dfc3864bbb97392a2b3afc2895/psf_utils-1.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-01-16 05:24:14",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "kenkundert",
"github_project": "psf_utils",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"tox": true,
"lcname": "psf-utils"
}