Hopki analyzes split Hopkinson (Kolsky) bar experiments in compression and
tension. It is a from-scratch Python port of a legacy MATLAB GUI (twobar_g),
validated to reproduce that code's reference outputs to within ~1×10-8.
It does two things: convert raw Nicolet oscilloscope .WFT captures
into text waveforms, and turn the incident / reflected / transmitted gauge signals into
forces, velocities, displacements, strain rate, and engineering & true stress–strain.
Internally it is a two-stage pipeline. Stage 1 parses raw Nicolet
.WFT binary captures into .FLT text. Stage 2 runs the
analysis. The numeric core is completely GUI-free and deterministic: every
human-in-the-loop choice from the original MATLAB GUI is an explicit function
parameter, so a run is fully reproducible and unit-testable — the GUI only collects
your picks and redraws.
The whole pipeline is validated to reproduce the original's reference outputs to
within ~1×10-8. The core / CLI install is light (numpy + scipy +
matplotlib); the desktop GUI is an optional extra (uv sync --extra gui).
Dependencies and Python 3.12 are managed with uv.
uv sync # core + CLI tools
uv sync --extra gui # also the desktop GUI (PySide6, pyqtgraph)
uv run hopki-gui # launch the GUI
uv run hopki-gui tests/analysis # ...auto-loading an experiment
wft-to-csv input.WFT out.FLT — convert one (or many, with --out-dir) Nicolet .WFT files to .FLT text.twobar-analyze DIR --tim-cut 2.83e-5 --reflect-shift 3 --invert --out OUT — run the analysis on an experiment directory, writing MATLAB-style output vectors.figcorr curve --cut 256 --straighten X1 Y1 X2 Y2 --zero — scriptable stress–strain curve cleanup.Add --help to any tool for the full flag list.
No Python needed — download a desktop build for your OS from the project's
Releases page (macOS .app, Windows .exe, Linux binary).
They are unsigned, so on first launch: macOS → right-click the app →
Open; Windows → SmartScreen → More info → Run anyway.
Tests use the stdlib unittest runner; address modules by dotted path
(GUI tests run headless):
uv run python -m unittest tests.analysis.test_twobar
QT_QPA_PLATFORM=offscreen uv run python -m unittest tests.gui.test_controller
uv sync --extra gui --extra packaging
uv run python packaging/build.py # macOS/Windows/Linux (Nuitka)
An experiment directory holds three config files (incid.exp, incid.spec,
DAMP_F) and two signal files (incident bar gauge & transmitted bar gauge).
The pipeline is four stages, each driven by an operator choice you make in the GUI:
2·x1/c0, transmitted after (x1+x2)/c0.DAMP_F.incid.exp — nlong, npoint, tpp (s), bar Ø, E, x1, x2, c0, gauge factor, bridge V.incid.spec — specimen Ø, length, acquisition delay (µs), pre-trigger (%).DAMP_F — a single damping coefficient.All of these are editable live in the GUI (Analysis tab) with a Revert button to reload them from disk.
±2πf·x·(1/c0 − 1/c(f)) from the Bancroft
phase-velocity table, plus an amplitude term exp(±DAMP_F·x).4·v / (gfact·vbridge); forces,
velocities and displacements (cumulative-trapezoid integration) follow from there.tpp (sampling interval) always comes from the signal's own
time column. x1/x2 (gauge→specimen
distances) are auto-estimated from the signals when config omits them:
x1 is robust (matched-filter the incident window against the bar channel to
find the reflected return at 2·x1/c0); x2 is
best-effort — the transmitted pulse is weak, so its onset is biased late. The GUI
flags an estimated x2 with a confidence (SNR) so you can verify it,
re-estimate, or set it by 2 clicks on the Signals plot.
tim_cut (it can move anywhere on the record; an out-of-range pulse window is reported in the status line).Plot any derived quantity (strain rate, velocities, displacements, forces, striker velocity, stresses) against time or true strain. Flip the x-axis, negate either axis, and send the shown curve to Curve cleanup or Figures.
Pull a σ–ε curve from the analysis (or load a file), then
zero, cut/crop (drag the pointer), smooth (Butterworth cutoff),
straighten the toe (two clicks), read a slope (two clicks), negate an
axis, undo, and save <name>_corr. Send the result to Figures.
Assemble publication figures from one or more curves.
%.2f,
%.1e), and limits..npz (all curves + metadata, reloadable); Export a PNG
plus its .npz sidecar.hopki.toml of just the fields you changed.| File | What |
|---|---|
.WFT | Raw Nicolet oscilloscope binary waveform (input). |
.FLT / .inc / .tra | Two-column value time text signals. |
| output vectors | MATLAB-style -ascii text (f_in, s_e_true, e_dot…). |
.npz figure | Curves + styling/metadata, reloadable into the Figures tab. |
Config-file layout. The legacy files are whitespace-delimited, one value per
line: incid.exp is positional (nlong, npoint, tpp, Øbar, E, x1,
x2, c0, gfact, vbridge) and incid.spec is
(Øspec, Lspec, tdelayµs, pretrig%), with optional inline
%comments. The two-line .FLT header is dropped in the
.inc/.tra form (the data rows are identical).
Layered TOML. A hopki.toml can live next to an experiment (and a
shared one higher up a campaign tree); the per-experiment file overrides the campaign one,
and Save config writes only the fields you actually changed.
tim_cut from its file, reflect_shift = 3, and invert on.x2 as a starting
point: confirm it against the transmitted arrival (or set it with Pick x2)
before trusting the stresses.Hopki is released under the MIT License — free to use, modify, and distribute (including commercially), provided the copyright notice is kept.
© 2026 Shmuel Osovski
MIT License
Copyright (c) 2026 Shmuel Osovski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.