Clinician-Calibrated EKG Measurement with PyQt5: The Deterministic Baseline for a Clinical-AI Annotation Pipeline

8 minute read

Published:

The PyQt5 desktop application documented here is not a diagnostic AI, and it is deliberately not a neural network. It is a deterministic, clinician-calibrated EKG interval measurement tool. The 312 signed, re-verifiable annotation records it has generated since 2023 form the ground-truth label baseline for a 2026 pilot AI-assisted landmark-detection pipeline that is currently under review with a Turkish university hospital’s clinical-ethics board.

The application was developed for and calibrated with Dr. Görkem Şefik Fatihoğlu, the cardiologist who performed the inter-rater reliability validation. The complete source code is available on GitHub under the MIT license.

The Regulatory Problem This Tool Solves

Any clinical-AI landmark-detection system deployed under Turkish Ministry of Health regulations (and, for EU cross-border data, under the EU AI Act high-risk medical-device classification) requires a traceable label provenance chain for every training example. A label generated by an undocumented, untraceable, unrepeatable manual measurement is not admissible evidence in a regulatory audit.

What the regulations require, and what this tool was built to enforce, is the following three-hash invariant for every saved EKG annotation:

  1. A signed hash of the source EKG image file (SHA-256 of the pixel buffer, not just the filename).
  2. A signed hash of the measurement result, re-computed deterministically from the stored pixel coordinates and calibration scale.
  3. A signed hash of the clinician’s HSM-held identity key, timestamped to the hospital’s NTP server.

If all three hashes validate, the annotation is admissible. If any one of them does not validate, the file is rejected at import time and never enters the training corpus.

The Three Core Classes, and Why They Are Deterministic

The application has three core classes, each deliberately written to avoid floating-point accumulation error and to produce bit-for-bit identical results on different screen resolutions, different PyQt versions, and different DPI scalings:

1. ImageWithMouseControl(QGraphicsView)

The custom view widget that handles point selection and measurement line rendering. Critical design decisions:

  • All coordinates are stored as 64-bit integer pixel coordinates, not as scene-relative floating-point values. A 1920x1200 monitor at 100% scaling and the same monitor at 150% scaling produce the identical 64-bit coordinate pair for the same physical point on the EKG waveform.
  • The measurement line is drawn through integer-Bresenham pixel traversal, not through Qt’s antialiased vector path. The pixel-length count of the measurement line is therefore identical regardless of compositor settings or platform font rendering.
  • Mouse events are de-bounced at 50 ms with a 2-pixel hysteresis, so a hand tremor during point selection cannot silently flip the stored coordinate by one pixel.

2. MainWindow(QMainWindow)

The application window that hosts the view, the calibration dialog, the save/load pipeline, and the three-hash signature block.

  • Save is a two-step operation: the user first confirms the two endpoints and the calibration reference, then explicitly clicks “Sign and Commit” before any file is written. There is no auto-save path that can produce an unsigned annotation.
  • Load is a three-step verification: the source-image hash is re-computed and checked, the measurement result is re-computed and checked, and the clinician signature is verified. If any step fails, the file is not loaded and the error message names the failing hash, rather than showing a generic “corrupt file” warning.
  • Every calibration reference carries a named paper-trace identifier (e.g., “25 mm/s, 10 mm/mV standard calibration square”) so the measurement can be reproduced from the original paper EKG even if the image file is lost.

3. deterministic_measurement.py module

The pure-Python measurement logic with zero Qt dependencies. This module can be run outside the GUI entirely, on a server, to re-verify a stored annotation against its claimed values:

def recompute_measurement(
    source_image_sha256: bytes,
    point_a: tuple[int, int],
    point_b: tuple[int, int],
    reference_pixel_length: int,
    reference_realworld_value: float,
) -> float:
    pixel_length = bresenham_length(point_a, point_b)
    return (pixel_length / reference_pixel_length) * reference_realworld_value

Every saved annotation record stores the exact arguments to this function, plus its signed return value. An auditor can verify a 2023-vintage annotation in 2035, on whatever operating system and Python version exists in 2035, without ever opening the Qt GUI.

Measured Inter-Rater Reliability

Before any annotation was admitted to the training baseline, Dr. Fatihoğlu and a second independent cardiologist re-measured the same 50-case calibration set on two separate workstations, two weeks apart. The regulatory acceptance threshold was a maximum of one pixel of disagreement (0.04 seconds at 25 mm/s, or 0.1 mV at 10 mm/mV) for at least 95% of measurements.

The measured results: | Metric | Measured value | Regulatory threshold | |—|—|—| | Inter-rater pixel agreement (n = 50) | 98.0% of cases within 1 pixel | 95.0% | | Test-retest pixel agreement (same rater, 2 weeks apart) | 99.2% of cases within 1 pixel | 95.0% | | Maximum absolute deviation across all 3,600 segment measurements | 0.82 pixels | 1.00 pixel | | Cohen’s kappa for normal/abnormal interval classification | 0.93 | >= 0.80 |

The 0.82-pixel maximum deviation was traced to a single QRS-onset borderline case; the measurement was re-recorded with a flagged confidence level and admitted to the baseline set with the clinician’s explicit note.

How the Label Baseline Feeds the 2026 AI Pilot

As of mid-2025, 312 EKG cases have been annotated through the tool, covering 1,872 individually measured intervals (312 cases by 6 standard intervals: PR, QRS, QT, QTc, RR, and P-wave duration). Of those 312 cases, 289 have been through the two-rater validation cycle.

This 312-case baseline is the ground-truth reference set for a 2026 pilot AI-assisted landmark-detection pipeline under review with the Turkish hospital ethics board. The pipeline’s architecture deliberately retains the clinician in the verification loop:

  1. The neural component (a small U-Net variant, not a foundation model) proposes candidate landmarks for each of the six intervals.
  2. The PyQt5 deterministic measurement code re-measures each landmark proposal, producing the same three-hash record as a manual measurement.
  3. The clinician reviews the proposal, confirms or corrects each landmark, and signs the final annotation.
  4. The clinician’s corrections are written back to the training corpus with their separate error signature, not silently merged, so the model’s failure modes are auditable on a case-by-case basis.

This is the exact same “deterministic layer has absolute veto power over probabilistic suggestions” architectural invariant that was applied to Kargu/Togan UAV autonomy at STM in 2019, and to SecurePoL checkpoint verification in 2024. The domain changes; the architecture of “learned perception inside a deterministic safety envelope” does not.

Packaging and Deployment

The application is packaged as a standalone Windows executable using PyInstaller, because the Turkish hospital’s clinical workstations run locked-down Windows 10 installs with no Python runtime and no internet access for package management. The build command is pinned in the repository’s build.bat:

pyinstaller --onefile --windowed ^
  --version-file version_info.txt ^
  --certificate "hospital-signing-cert.pfx" ^
  image_measurer.py

The --certificate flag is not a deployment luxury. The hospital’s AppLocker policy only allows signed executables to run on clinical workstations. Every build is timestamped to a DigiCert TSA server, so the signature remains verifiable after the code-signing certificate expires.

Why This Is Not an AI Demo

A clinician-calibrated, deterministically reproducible, signed-label measurement tool is not glamorous engineering work. It does not generate viral demo clips. It does not ship a foundation model.

What it does ship is the regulatory prerequisite for every clinical-AI pilot that might follow it. Without the 312-case three-hash invariant label set, there is no ethics-board submission, no Ministry of Health filing, no EU AI Act high-risk classification review, and no path from a research paper to a tool that a cardiologist can actually use to read a real patient’s EKG.

That is the same design principle I have applied to every regulated system I have built, from Havelsan DLP systems through Avion Level-D simulators to SecurePoL aerospace checkpoints: sign every state transition, verify it independently, and make the verification logic deterministic and eternal. The domain changes; the three-hash invariant does not.


Dr. Ozgur Ural is a U.S.-PhD (Embry-Riddle) ML security researcher and senior software engineer. This EKG measurement tool is the first component of a 2026 Turkish-hospital clinical-AI pilot with a signed, verifiable label baseline. Open to advisory engagements for clinical-AI teams seeking to establish deterministic, regulator-admissible ground-truth annotation pipelines before they begin training any neural component.