Compatibility
2.9.0 release target; newly frozen Windows CUS review candidate
Package applicability is under review; follow the stated version and platform limits.
Download Complete nested waveform hierarchy, SI sample converter and independent checker (ZIP)Includes main.cir, lib/drivers.cir, lib/Measured wave (A),1.txt, samples.csv, prepare_samples.py, check_custom.py, README.txt. Exact checked input files plus instructions; final-release/platform applicability remains pending.

Keep amplitude data separate from the time grid

CUS loads an external amplitude row and uses the supplied Ts to assign its sample spacing. The data file is not a time/voltage CSV: it contains exactly one nonempty data line of amplitude values. The three teaching values are 0, 1m and 0, which mean 0 V, 1 mV and 0 V for these voltage sources. Comments can be separate lines beginning with an asterisk.

Use a compatible JoSIM 2.9 build containing the maintained quoted-filename repair. The checked Windows candidate is distinct from older installed/review binaries and still needs final-package verification. A normal product licence is required for simulation; no licence file is included in the example.

Extract the complete download, preserving lib/drivers.cir and lib/Measured wave (A),1.txt below main.cir. The sample filename deliberately contains spaces, parentheses and a comma. Its quoted path is relative to the defining include, not the caller’s current directory. Preserve filename case and matching quotes.

Open and run the complete example

  1. Open main.cir in JoSIM®-Pro. Keep the lib directory alongside it. Open lib/drivers.cir to inspect the seven CUS declarations and their loads.
  2. Read each source as CUS(file Ts Sf Im Td periodic). Supply Ts explicitly. The supported selectors are 0 hold, 1 linear and 2 cubic. This guide uses explicit values for the intended route and retains omitted/default and time-valued periodic arguments only as diagnostic comparisons.
  3. Save any source changes, choose an existing writable result destination, and request Run. The complete example uses a 1 ps integration/output step and a 75 ps stop time. Expect 76 samples and seven named voltage traces.
  4. Inspect V(HOLD), V(LINEAR), V(CUBIC), V(DEFAULT), V(DELAY), V(REPEAT) and V(PERIOD). Use each axis label: most teaching plots display mV, while the 0.5 mV delayed signal is shown as 500 microvolts. The raw CLI CSV is in seconds and volts.
  5. The source image below deliberately shows KB-CUS-003: six static argument errors on valid quoted-path source lines. The current runtime and independent numerical check pass. Diagnose this bounded disagreement using the complete files and a simple-filename control; do not dismiss unrelated errors or remove necessary quoting.
Actual drivers.cir editor contains the seven complete quoted CUS sources and six reproduced static argument errors despite successful independently checked runtime results.
Actual complete source with the reported static argument errors retained. This is a reproduced editor/runtime disagreement, not a clean editor state. Open full-size screenshot

Check what the controls mean in this candidate

Choose the interpolation by the waveform you intend to apply, then verify its timing. A smoother curve is not automatically a better representation of measured data. Explicit defaults avoid relying on the unresolved reference-table wording.

Control or traceChecked interpretation
Ts = 10pSample spacing is 10 ps. The runtime clamps a smaller requested spacing to its integration step; a smaller output step alone does not restore lost sample timing.
Sf = 1, or 0.5 for DELAYMultiply amplitude values once. 1m with Sf = 0.5 is 0.0005 V, not 0.5 V.
Im = 0 / HOLDHold the current sample within each interval. The nonzero 1 mV interval lies between 10 and 20 ps.
Im = 1 / LINEARThis implementation ramps from the previous amplitude to the current one over an interval, starting from zero. For this row the ramp peak is at 20 ps rather than the cubic sample peak at 10 ps.
Im = 2 / CUBICThe exercised spline passes through the three sample values with a natural left boundary and zero right slope. It can overshoot: the 1 ps teaching grid reaches about 1.02214 mV for a 1 mV input maximum.
DEFAULTOmitting Im selects linear in the exercised runtime. It exactly matches LINEAR, despite the manual table listing default 0 (KB-DOC-005).
Td = 5p / DELAYShift the half-scale held waveform by 5 ps. Before that delay its value is zero.
periodic = 1 / REPEATEnable repetition. Three samples at 10 ps give a 30 ps cycle; set zero for no repetition.
periodic = 30p / PERIODThis time-valued argument rounds to false and does not request a 30 ps cycle. The manual’s Repeat period label conflicts with the flag semantics (KB-DOC-005).
Actual seven current CUS plots compare hold, linear, cubic, omitted interpolation, delay/scale, repeat flag and a time-valued nonrepeating argument. Each axis states its own display units.
Seven actual current plots. HOLD, LINEAR and CUBIC have different timing/shapes; DEFAULT matches LINEAR, and the final time-valued argument does not enable repetition. Open full-size screenshot

Run and check the raw numerical CSV from an agent

In PowerShell, set $JoSIM to the full path of the compatible CLI and $Python to a Python 3 interpreter, then work in the extracted example directory. Use a new results-first directory; the script deliberately refuses a reused result directory.

The independent teaching checker requires the exact eight raw-SI columns and 76 finite rows. It compares 60 interior time samples with separate piecewise equations using 2e-12 V absolute and 1e-9 relative tolerances. It avoids deciding discontinuity sides from floating-point rounding at sample boundaries. These tolerances test this synthetic source-transfer example; they are not a general solver or device-accuracy target.

An unsupported selector such as 9 can complete with a zero waveform on this candidate (KB-CUS-001). The checker rejects that result. Process exit 0, a finite matrix or a plausible plot alone does not establish the requested stimulus.

New-Item -ItemType Directory -Path results-first -ErrorAction Stop | Out-Null
& $JoSIM -P 17 -o .\results-first\waveforms.csv .\main.cir
if ($LASTEXITCODE -ne 0) { throw 'JoSIM did not complete; inspect its first diagnostic.' }
& $Python -B .\check_custom.py --csv .\results-first\waveforms.csv --report .\results-first\check.json
if ($LASTEXITCODE -ne 0) { throw 'The teaching waveform reference did not pass.' }

Convert an explicitly declared uniform CSV

The supplied samples.csv has exactly time_s,voltage_V columns with a zero-based, uniformly spaced time axis. prepare_samples.py is a small teaching utility supplied with this guide, not a claim that CUS directly imports tabular CSV. It writes one new amplitude row and reports Ts_seconds; it never overwrites an existing destination.

The command creates lib/converted.txt. To use it, change the CUS references in your saved working copy to converted.txt, retain Ts = 1e-11 s and Sf = 1 for the supplied SI values, then request a new Run. The checked converted row reproduces the original teaching arrays.

For your own data, convert physical units explicitly and require uniform sampling. This utility refuses an irregular grid, nonfinite data, another header/unit declaration or a nonzero starting time. It does not silently resample or shift measurements. Decide on a resampling method elsewhere and use Td explicitly for any intended delay.

check_custom.py contains the fixed teaching reference. It is expected to reject a different measured waveform; provide an appropriate independent reference and acceptance criteria for that data rather than weakening the teaching check.

& $Python -B .\prepare_samples.py --csv .\samples.csv --output .\lib\converted.txt
if ($LASTEXITCODE -ne 0) { throw 'Sample conversion was refused; check units and the time grid.' }

Rerun after changing external sample data

Preserve the amplitude file with the source and result. In KB-CUS-002, changing its row from 0 1m 0 to 0 2m 0 left the existing arrays unchanged and the GUI still said Results current. The netlist itself was neither modified nor semantically dirty.

Request Run explicitly after changing the sample file. The native check rereads it and doubles all seven waveforms; restoring the original bytes and running again recovers the original arrays. A second process explicitly reopening the saved hierarchy reproduces them. This is saved-file reproducibility, not automatic GUI-session restoration.

Changing the external file after a run does not retroactively change that run’s data. Treat the current indicator and the preserved sample-file revision as separate evidence, particularly when sharing or comparing results.

Recover from a failed or misleading waveform

Observed problemNext check
File could not be found/openedPreserve lib and resolve the filename against the defining source/include. Use matching quotes, correct case and readable files. Older binaries may lack the maintained quoted-path repair.
Exactly one data line / no waveform dataUse a single nonempty amplitude row. A normal multirow time/voltage CSV needs explicit conversion.
Bad numeric valueRead the actual file, physical line and sample index in the diagnostic. Preserve the original measured data before correcting it.
Too few CUS valuesSupply a filename and Ts; the checked argument guard requires both.
Static Invalid waveform arguments, runtime passesKB-CUS-003: retain this candidate’s quoted-path parser disagreement; inspect the actual path and numerical output, then use a complete simple-filename copy as a diagnostic control.
No repeat, unexpected linear timing or zero stimulusUse explicit supported Im/Td/periodic values and the table above. A time period is not the final flag; an unsupported Im can silently produce zeros.
Old plot after a sample editKB-CUS-002: request a new Run and compare the actual current-generation data with the intended sample bytes.

Scope of the recorded workflow

The fresh isolated Windows candidate passes 25 CLI/client/static-API checks and 20 independent native/source/output checks. It includes quoted special filenames in an included directory, unrelated process working directories, both quote styles, complete SI conversion, expected failures and numerical recovery. Four fresh native simulations across two normal app processes retain separate current CSVs.

KB-DOC-005 and KB-CUS-001/002/003 remain findings, not repairs. Case-sensitive filesystems, other platforms, final distributed packages, physical picker/pointer paths, arbitrary waveform grammars and measured-device accuracy still need their own qualification.

Save main.cir

* Synthetic CUS comparison; retain the complete lib directory
.INCLUDE "lib/drivers.cir"
.OPTION ANALYSIS=VOLTAGE INTEGRATION=BDF
.TRAN 1p 75p 0 1p
.PRINT V(HOLD) V(LINEAR) V(CUBIC) V(DEFAULT) V(DELAY) V(REPEAT) V(PERIOD)
.END

Save lib/drivers.cir

* The waveform path belongs to this include, not the caller's working directory
VHold HOLD 0 CUS("Measured wave (A),1.txt" 10p 1 0 0 0)
VLinear LINEAR 0 CUS("Measured wave (A),1.txt" 10p 1 1 0 0)
VCubic CUBIC 0 CUS("Measured wave (A),1.txt" 10p 1 2 0 0)
VDefault DEFAULT 0 CUS("Measured wave (A),1.txt" 10p)
VDelay DELAY 0 CUS("Measured wave (A),1.txt" 10p 0.5 0 5p 0)
VRepeat REPEAT 0 CUS("Measured wave (A),1.txt" 10p 1 0 0 1)
VPeriod PERIOD 0 CUS("Measured wave (A),1.txt" 10p 1 0 0 30p)
RHold HOLD 0 50
RLinear LINEAR 0 50
RCubic CUBIC 0 50
RDefault DEFAULT 0 50
RDelay DELAY 0 50
RRepeat REPEAT 0 50
RPeriod PERIOD 0 50

Save lib/Measured wave (A),1.txt

* Voltage amplitudes in V; exactly one data line, no time column
0 1m 0

Save samples.csv

time_s,voltage_V
0,0
1e-11,0.001
2e-11,0

Save prepare_samples.py

"""Convert an explicit uniform time_s,voltage_V CSV to one CUS amplitude row.

This preserves the supplied values. It does not guess units, resample an
irregular axis, remove an initial time offset, or qualify measurement quality.
"""
import argparse
import csv
import json
import math
from pathlib import Path
import sys


def main():
    p = argparse.ArgumentParser(description=__doc__)
    p.add_argument('--csv', required=True, type=Path)
    p.add_argument('--output', required=True, type=Path, help='New amplitude filename in an existing directory')
    args = p.parse_args()
    try:
        if args.output.exists() or not args.output.parent.is_dir():
            raise ValueError('Choose a new amplitude filename in an existing directory.')
        with args.csv.open(encoding='utf-8-sig', newline='') as stream:
            reader = csv.reader(stream)
            if next(reader) != ['time_s', 'voltage_V']:
                raise ValueError('Declare the two columns exactly as time_s,voltage_V; convert other units explicitly first.')
            rows = [[float(v) for v in row] for row in reader if row]
        if len(rows) < 2 or any(len(row) != 2 or not all(math.isfinite(v) for v in row) for row in rows):
            raise ValueError('Provide at least two finite time/voltage pairs.')
        if rows[0][0] != 0:
            raise ValueError('Start the supplied time axis at zero; choose any physical CUS delay explicitly.')
        step = rows[1][0] - rows[0][0]
        if step <= 0 or any(b[0] <= a[0] or not math.isclose(b[0] - a[0], step, rel_tol=1e-9, abs_tol=abs(step) * 1e-12)
                            for a, b in zip(rows, rows[1:])):
            raise ValueError('CUS requires a strictly increasing uniform sample grid; explicitly resample irregular data elsewhere.')
        text = ' '.join(format(row[1], '.17g') for row in rows) + '\n'
        with args.output.open('x', encoding='utf-8', newline='\n') as stream:
            stream.write(text)
        print(json.dumps({'status': 'converted', 'samples': len(rows), 'Ts_seconds': step, 'Sf': 1,
                          'first_sample_time_s': 0, 'last_sample_time_s': rows[-1][0],
                          'limit': 'One voltage-amplitude row; choose interpolation, delay and repeat flag explicitly and verify the result.'}))
        return 0
    except (OSError, ValueError, StopIteration) as error:
        print(str(error), file=sys.stderr)
        return 2


if __name__ == '__main__':
    raise SystemExit(main())

Save check_custom.py

"""Check only the complete synthetic CUS teaching deck's raw-SI CLI CSV.

The reference is independent piecewise mathematics for the exercised 2.9
semantics. It is not a general measured-waveform, model or accuracy validator.
The cubic reference uses a natural left end and zero first derivative at the
right end; its three-point coefficients follow those four boundary equations.
"""
import argparse
import csv
import json
import math
from pathlib import Path
import sys

NAMES = ('HOLD', 'LINEAR', 'CUBIC', 'DEFAULT', 'DELAY', 'REPEAT', 'PERIOD')
ABS_TOL_V = 2e-12
REL_TOL = 1e-9


def hold(x):
    return 1e-3 if 1 <= x < 2 else 0.0


def linear(x):
    if 1 <= x < 2:
        return 1e-3 * (x - 1)
    if 2 <= x <= 3:
        return 1e-3 * (3 - x)
    return 0.0


def cubic(x):
    if x < 0 or x > 3:
        return 0.0
    if x <= 1:
        return 1e-3 * (x - (5 / 7) * (x ** 3 - x))
    if x <= 2:
        u = x - 1
        return 1e-3 * (1 - u - (5 / 7) * ((1 - u) ** 3 - (1 - u))
                       + (6 / 7) * (u ** 3 - u))
    # Its clamped zero right slope gives constant extrapolation in the tail.
    return 0.0


def expected(t):
    x = t / 1e-11
    return dict(HOLD=hold(x), LINEAR=linear(x), CUBIC=cubic(x), DEFAULT=linear(x),
                DELAY=0.5 * hold((t - 5e-12) / 1e-11), REPEAT=hold(x % 3), PERIOD=hold(x))


def main():
    p = argparse.ArgumentParser(description=__doc__)
    p.add_argument('--csv', required=True, type=Path)
    p.add_argument('--report', required=True, type=Path, help='New JSON result in an existing directory')
    args = p.parse_args()
    try:
        if args.report.exists() or not args.report.parent.is_dir():
            raise ValueError('Choose a new report filename in an existing directory.')
        with args.csv.open(encoding='utf-8-sig', newline='') as stream:
            reader = csv.reader(stream)
            columns = next(reader)
            if columns != ['time', *['V(' + n + ')' for n in NAMES]]:
                raise ValueError('Expected the complete teaching deck raw-SI CLI columns; GUI-formatted exports can use different axes or labels.')
            rows = [[float(v) for v in row] for row in reader if row]
        if len(rows) != 76 or any(len(row) != 8 or not all(math.isfinite(v) for v in row) for row in rows):
            raise ValueError('Expected 76 finite rows and eight complete columns.')
        if not (rows[0][0] == 0 and math.isclose(rows[-1][0], 75e-12, rel_tol=1e-12, abs_tol=1e-23)
                and all(a[0] < b[0] for a, b in zip(rows, rows[1:]))):
            raise ValueError('Expected an increasing raw-seconds axis from 0 to 75 ps.')
        errors = {n: 0.0 for n in NAMES}
        compared = 0
        for row in rows:
            # Do not decide left/right continuity from floating-point rounding
            # at a sample boundary. Compare the interior physical samples.
            if min(abs(row[0] / 5e-12 - round(row[0] / 5e-12)), 1.0) < 1e-7:
                continue
            values = expected(row[0])
            for name, value in zip(NAMES, row[1:]):
                error = abs(value - values[name])
                errors[name] = max(errors[name], error)
                if not math.isclose(value, values[name], rel_tol=REL_TOL, abs_tol=ABS_TOL_V):
                    raise ValueError('Teaching waveform mismatch for ' + name + ' at ' + str(row[0]) + ' s.')
            compared += 1
        if compared < 50:
            raise ValueError('Too few independent interior samples.')
        report = {'status': 'passed', 'samples': len(rows), 'interior_samples_compared': compared,
                  'quantities': {'time': 's', 'voltages': 'V'}, 'max_absolute_error_V': errors,
                  'absolute_tolerance_V': ABS_TOL_V, 'relative_tolerance': REL_TOL,
                  'scope': 'Complete synthetic teaching deck on recorded 2.9 CUS semantics. Default interpolation and final periodic flag are explicitly checked; the cubic clamped tail is included. No arbitrary measured data or physical-device accuracy qualification.'}
        with args.report.open('x', encoding='utf-8', newline='\n') as stream:
            json.dump(report, stream, indent=2)
            stream.write('\n')
        print(json.dumps({'status': 'passed', 'samples': len(rows), 'interior_samples_compared': compared}))
        return 0
    except (OSError, ValueError, StopIteration) as error:
        print(str(error), file=sys.stderr)
        return 2


if __name__ == '__main__':
    raise SystemExit(main())
Sources and verification details

Recorded inputs/builds only. Complete walkthrough and final-package acceptance remain separate.

VAL-062 · Frozen current-source Windows JoSIM®-Pro 2.9 CUS review candidate
25 independent checks cover a complete nested source/sample hierarchy, quoted special filenames, unrelated working directory, seven raw-SI waveforms, piecewise reference, explicit SI CSV conversion and error guards. Default/repeat documentation, unsupported-selector zero output and six static argument false positives remain explicit. Actual downloaded inputs repeat these checks; twelve download comparisons and both literal commands pass.
No case-sensitive filesystem, non-Windows/final package or arbitrary measured-device accuracy qualification.

VAL-063 · Frozen current-source Windows JoSIM®-Pro 2.9 CUS review candidate
20 independent checks cover two normal app processes, four fresh successful runs, seven current plots/CSVs, raw-SI reference agreement, external sample change/rerun/restore and missing-file rejection. The prior plot can remain labelled current after its external data changes. Actual downloaded inputs repeat these checks; twelve download comparisons and both literal commands pass.
No product repair, physical picker/pointer, automatic session restoration, case-sensitive filesystem, other platform/final package or arbitrary measured-device accuracy qualification.

josim-cus-source
Current-source Windows JoSIM 2.9 native CUS teaching scenario, reviewed 4 November 2026
Recorded teaching source/result state only. Static false positives remain visible; plots have scaled axes and do not establish arbitrary physical accuracy or final-package acceptance.

josim-cus-waveforms
Current-source Windows JoSIM 2.9 native CUS teaching scenario, reviewed 4 November 2026
Recorded teaching source/result state only. Static false positives remain visible; plots have scaled axes and do not establish arbitrary physical accuracy or final-package acceptance.

  • josim-pro:docs/manual_source/sections/syntax.tex · Waveform and source functions / Custom Waveform; explicit current default/repeat mismatch remains tracked
  • validation:custom-waveform-20261104 · VAL-062 full CLI/static/client checks; VAL-063 normal native source/result/rerun recovery
  • Four reproduced limits remain explicit: KB-DOC-005 and KB-CUS-001/002/003. The runtime includes the maintained filename repair; final distributed-package/platform and physical-operator checks remain open.
Read MarkdownRead structured articleBrowse all guides