Disclaimer: These tools and their outputs are for reference and preliminary evaluation only, not design, manufacturing, qualification or commercial approval; verify all results with the responsible supplier or engineer.
These are offline CLI wrappers, not website dependencies or upload services. The browser RF/GDS tools remain separate, original JavaScript implementations. Python adds a broader, deliberately restricted Touchstone reader and an optional GDSII/OASIS metadata reader and a restricted STDF V4 wafer CSV converter. Nothing here provides a server, network call or automatic transfer of input files or reports. Installation requires package access; report execution does not.
Tested on Windows x64 with Python 3.12.8, scikit-rf 2.1.0 and gdstk 1.0.1.
All direct and resolved dependencies are pinned in requirements.txt.
Open Command Prompt in the extracted tompw-engineering-checks/python/ directory.
Every command below assumes that python/ is the current directory.
python -m venv .audit\venv
.audit\venv\Scripts\python.exe -m pip install --disable-pip-version-check --no-cache-dir --only-binary=:all: -r requirements.txt
.audit\venv\Scripts\python.exe -m pip checkIf ensurepip fails after creating the venv, an existing base pip that supports
--python can target it without installing reporting libraries into base Python:
python -X utf8 -m pip --python .audit\venv install --disable-pip-version-check --no-cache-dir --only-binary=:all: -r requirements.txt
python -X utf8 -m pip --python .audit\venv checkThe .audit environment is ignored. Do not add it to source control or a website
bundle. Neither wrapper imports its optional backend until a valid input is read;
--help works without installing the dependencies.
The STDF converter has a separate optional dependency set. Install it only if needed;
Semi-ATE STDF is distributed as a source package, so do not use --only-binary here.
.audit\venv\Scripts\python.exe -m pip install --disable-pip-version-check --no-cache-dir -r requirements-stdf.txt
.audit\venv\Scripts\python.exe -m pip checkAll three --help commands work without their optional backends.
Replace the example input paths with approved, existing local files. Output must
be a new file in an existing private local directory. Omit --output for JSON
on stdout. Both wrappers refuse existing outputs and input/output aliases.
.audit\venv\Scripts\python.exe -B rf_report.py "C:\private\input.s2p" --output "C:\private\new-rf-report.json"
.audit\venv\Scripts\python.exe -B layout_report.py "C:\private\input.gds" --output "C:\private\new-layout-report.json"
.audit\venv\Scripts\python.exe -B layout_report.py "C:\private\input.oas" --redact-cell-names --output "C:\private\new-oasis-report.json"Prefer --output over shell redirection: a shell can truncate a redirected input
before the wrapper gets a chance to reject it. Exit code 0 means a report was
generated, not design acceptance. 2 means an input, backend, integrity or
output error; RF code 3 means comparison was blocked (individual reports remain).
Errors are generic JSON; backend diagnostics, full paths and comments are not
exported. Any backend warning/diagnostic fails closed instead of accepting a
potentially partial parse.
rf_report.py reports frequency in Hz, complex S traces, magnitude in dB, wrapped
phase in degrees and frequency/port-indexed complex z0 in ohms. Port indices are
one-based: response_port=i, excitation_port=j denotes S_ij. Zero amplitude is
null for both dB magnitude and undefined phase. JSON never uses nonfinite numeric
constants. Phase is not unwrapped.
Supported: .sNp (including more than two ports) and .ts, single-ended full
S matrices, RI/MA/DB, Hz/kHz/MHz/GHz, strictly increasing nonnegative grids, and a
restricted version 2.0/2.1 header set. Version 2 per-port [Reference] values must
be complete on one line. Upstream HFSS impedance annotations can supply complex
frequency-dependent scalar per-port z0; they are preserved, not renormalized.
Terminal exports and full impedance matrices are refused rather than reduced to a
diagonal. Mixed mode, noise,
triangular matrices, unsupported keywords, non-S parameters and serialized network
objects are refused. There is no interpolation, extrapolation, calibration,
reference-plane move, port reordering, symmetry inference or parameter conversion.
To compare, explicitly declare each input's reference plane, ordered ports and measurement/simulation conditions in two local JSON files. Example for a two-port network (these are assertions you must establish, not facts inferred from data):
{
"reference_plane": ["input_connector_face", "output_connector_face"],
"port_order": ["input", "output"],
"conditions": {"temperature_c": 25, "bias_v": 0, "fixture": "same_calibration"}
}.audit\venv\Scripts\python.exe -B rf_report.py "C:\private\baseline.s2p" --compare "C:\private\candidate.s2p" --declarations "C:\private\baseline-conditions.json" --compare-declarations "C:\private\candidate-conditions.json" --output "C:\private\new-comparison.json"Port count, frequency grids and complex z0 must be exactly equal (no tolerance).
The backend's S-definition values must also match. Both declarations must exist;
reference-plane, ordered-port and condition JSON must match exactly after object
key ordering, without unit conversion or equivalence inference. Conditions must be
nonempty. Missing declarations or any mismatch produce comparison.status=blocked
and no deltas. Aligned results contain comparison-minus-primary dB and wrapped phase
deltas, with null where either amplitude is zero. Declaration values are not
echoed; hashes and alignment checks are included. Calibration truth, completeness
of conditions, passivity, causality, large-signal performance and design acceptance
are not validated. A matching null S-definition is not proof of wave convention.
Default RF guards: 16 MiB/file, 10,000 frequency points, 16 ports and 1,000,000
complex S samples per input. Overrides: --max-bytes, --max-points, --max-ports,
--max-s-samples. Declaration JSON has a fixed 64 KiB cap and rejects duplicate
keys and nonfinite values. Samples are not silently truncated.
layout_report.py reads .gds/.gdsii or .oas/.oasis through gdstk with no
requested unit conversion. It reports reader unit/precision, top cell names,
geometry layer/datatype and label layer/texttype pairs, cell/element counts,
reference targets/transforms/repetition metadata, and top-cell/global envelopes in
reader user units and meters. Label text, library names, properties and polygon
coordinates are not exported. Cell names are exported by default as requested;
use --redact-cell-names to replace them with aliases. Repetition metadata gives
array vectors/dimensions or explicit-offset counts; explicit offsets are not
expanded or exported.
Empty cells have a null bbox. Cycles, unresolved references or an excessive depth
skip bbox computation; excessive estimated expansion skips the affected top bbox.
Check bbox_complete, each bbox_status and hierarchy_issues before using a
result. A global bbox is an envelope of independent top-cell coordinate systems,
not an inferred die boundary. OASIS preserves a coordinate precision, not the
writer's independent user-unit setting; use reader units and meter extents, not
an assumption that GDS and OASIS raw coordinates are identical. Reader-derived
envelopes can involve upstream path/curve representation and are not inspection
measurements. No flattening, cell/reference mutation, geometry rewrite or layout
export is performed. No DRC, LVS, PDK/foundry-rule, tapeout or manufacturability
validation is performed.
Default layout guards: 64 MiB/file, 5,000 cells, 250,000 elements, 50,000 references,
64 hierarchy levels, 250,000 estimated expanded elements before bbox calculation.
See --help for override names. File size is checked before native decoding;
cell/element/hierarchy guards run after decoding. Compressed OASIS and native
parsers can consume more memory/time than the input size suggests. These are not
hard resource limits or a sandbox for malicious files. Use small approved local
inputs; isolate untrusted parsing with OS-level controls separately.
stdf_to_wafer.py accepts one uncompressed STDF V4 file, CPU type 1 (big-endian)
or 2 (little-endian), with exactly one matching WIR/WRR wafer and PRR records.
Provide an operator-chosen ASCII wafer ID, an explicit bin-map JSON and a retest
policy (error, first or last). No bin number is implicitly treated as PASS.
{"source": "hard", "bins": {"1": "PASS", "2": "FAIL", "3": "EXCLUDE"}}Choose hard or soft for the bin source. Unmapped/invalid bins block. Abnormal
or invalid-test flags become EXCLUDE; a valid PRR pass/fail flag that conflicts with
the supplied map blocks. ID-based supersession and reserved flag bits are unsupported.
Coordinate-based supersession requires last; duplicate coordinates otherwise follow
the explicitly selected policy, using input record order, not timestamps.
.audit\venv\Scripts\python.exe -B stdf_to_wafer.py input.stdf --wafer-id WAFER_A --bin-map bin-map.json --retest error --csv-output new-wafer.csv
.audit\venv\Scripts\python.exe -B stdf_to_wafer.py input.stdf --wafer-id WAFER_A --bin-map bin-map.json --retest last --output new-stdf-report.jsonCSV columns are wafer,x,y,bin,status, ready for the existing website CSV checker.
--csv-output emits a new CSV and a JSON receipt on stdout without the CSV body;
--output stores a new JSON report including csv_text. Both refuse overwrites.
Output creation is exclusive, not atomic: an I/O failure can leave a partial new
output file; discard it and retry with a fresh name. Inputs remain read-only.
Limits: 20 MB, 100,000 framed records and 50,000 PRRs. Coordinates, head/site-group association and WRR PART_CNT must satisfy this restricted contract. Other framed record types are skipped and counted, not semantically validated. Multi-wafer files, compression, test-value analysis, vendor-specific extensions and general STDF repair are not supported. This is not ATE/prober certification or yield qualification.
The converter does not export PART_ID/PART_TXT, embedded wafer names or absolute paths. Its provenance retains selected record indexes, head/site numbers, bins, coordinate data, hashes and the operator wafer ID, which can still be confidential.
Regular input files are opened read-only; successful reads get SHA256 before and after processing, including declaration JSON. Hash mismatch or an unavailable after-hash discards the report. Oversized/unreadable inputs may have null hashes and explicit verification status rather than being read past the guard. This is a before/after check, not a filesystem lock or detection of every transient race; do not edit inputs during execution. Reports also cannot prove that another process did not access files.
Input names are omitted by default; --include-input-names opts into basenames
only. Paths, Touchstone comments and embedded port names are never intentionally
exported. RF traces, layout cell names/metadata and hashes can still be confidential.
Name omission is not anonymization or publication approval. Keep inputs, temporary
storage and outputs private, outside public website assets/cloud-sync folders.
The wrappers make no network requests. Native diagnostics are captured in temporary
storage and discarded; set TEMP/TMP to a private writable local directory if
the machine's temporary directory is inaccessible. CLI descriptor redirection is
process-wide: these entrypoints are not a thread-safe embedded web service API.
.audit\venv\Scripts\python.exe -X utf8 -B -m unittest discover -s tests -vTests create only synthetic Touchstone/GDS/OASIS/STDF fixtures in temporary directories
under the ignored local .audit folder, then remove them. No client files are used.
Backend tests skip if optional dependencies are absent; that is not full validation.
Actual verification on Windows x64 / Python 3.12.8: 54 tests passed, 0 skipped,
including RF/GDS/OASIS CLI smoke checks, strict JSON, unchanged SHA256 checks,
comparison gating and output/input alias refusal. Dependency checks reported no
broken requirements. Verified installed versions:
| Package | Version |
|---|---|
| scikit-rf | 2.1.0 |
| gdstk | 1.0.1 |
| Semi-ATE-STDF | 0.1.28 |
| XlsxWriter | 3.2.9 |
| numpy | 2.4.4 |
| scipy | 1.17.1 |
| pandas | 3.0.6 |
| python-dateutil | 2.9.0.post0 |
| six | 1.17.0 |
| typing-extensions | 4.16.0 |
| tzdata | 2026.5 |
All three --help commands also worked without the optional backends. These pins are
compatibility-tested, not a vulnerability audit or a guarantee against malicious
inputs. No production/client-file validation, Linux/macOS validation, or
resource-exhaustion fuzzing was performed. Native decoding is not a hard memory/time
sandbox; comparison declarations remain operator assertions, and metadata reports
are not DRC/LVS/tapeout or design acceptance.
Original wrappers: MIT (LICENSE). Upstream packages retain their own licenses:
scikit-rf BSD-3-Clause, gdstk Boost-1.0, Semi-ATE STDF MIT and XlsxWriter BSD-2-Clause;
see NOTICE. No vendor code is included.