Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

CI Coverage PyPI License

dls_motor_scanning

Tools for characterising the motion performance of EPICS motors.

Two commands are provided:

  • scan drives a motor through a range in fixed steps, recording the position actually reached and the time each move took, then reports the positioning error and move time as statistics, a data file and a plot.
  • calibrate fits a 5th order polynomial that converts an unscaled feedback device, such as a potentiometer read as raw ADC counts, into engineering units, and emits it as an EPICS calc record and an Excel formula.
What Where
Source https://github.com/DiamondLightSource/dls-motor-scanning
PyPI pip install dls-motor-scanning
Docker docker run ghcr.io/diamondlightsource/dls-motor-scanning:latest
Releases https://github.com/DiamondLightSource/dls-motor-scanning/releases

Scanning a motor

dls-motor-scanning scan MOTOR START STOP STEP DELAY [options]

START, STOP and STEP are in the motor's engineering units, and DELAY is the settling time in seconds to wait after each move before reading back. Scan PS-MO-WIRE-01:Y from 40 to 45 in half-EGU steps, with no settling time:

dls-motor-scanning scan PS-MO-WIRE-01:Y 40 45 0.5 0

The scan direction follows START and STOP, so a reverse scan needs no sign on the step:

dls-motor-scanning scan PS-MO-WIRE-01:Y 45 40 0.5 0

Each run writes Scan_<motor>_<date>_<start>_<stop>_<step>.txt and .png into the current directory, and prints a summary of the move times and position errors.

Option Effect
--extra-pv PV Read PV at each step and add it as a column and a third plot panel
--trigger-pv PV Pulse PV high then low after each move, for example to fire a detector
--trigger-width SECS How long the trigger is held high (default 1.0)
--trigger-post-delay SECS How long to wait after the trigger returns low (default 0.0)
--timestamp Add a UTC timestamp column taken from the EPICS timestamp of the readback
--no-txt Do not write the data file
--no-png Do not save the plot
--no-plot Do not open a plot window

The output file

The data file is space separated, with a header row naming the columns:

Desired Actual MoveTime Timestamp(UTC)
40.5 40.499 1.1394305229187012 2026-08-14T09:15:56.375000Z
41.0 40.9992 1.1742472648620605 2026-08-14T09:15:57.625000Z

Timestamp(UTC) is the timestamp the IOC put on the readback record, not the time the client received it, which makes it directly comparable with archiver data. It appears only when --timestamp is given, as does the --extra-pv column.

Plotting on a remote machine

--plot needs a working display. Over a slow link, or on a headless machine, prefer:

dls-motor-scanning scan PS-MO-WIRE-01:Y 40 45 0.5 0 --no-plot

which selects matplotlib's Agg backend before any GUI toolkit is loaded and just writes the png.

A note on backends. cothread integrates with Qt and not with Tk, and the two segfault if combined. PyQt5 is therefore a dependency so that matplotlib resolves to qtagg rather than falling back to tkagg. If you see the tool die silently after printing its statistics, check python -c "import matplotlib; print(matplotlib.get_backend())".

Calibrating a feedback device

dls-motor-scanning calibrate CSV_PATH [options]

The CSV needs one integer column, taken as the raw feedback, and one float column, taken as the scaled position to calibrate against:

raw,encoder
0,2.0
200,2.5
400,3.0
dls-motor-scanning calibrate pot.csv --raw-input-pv BL01I-MO-POT-01:ADC --excel-cell C2

This prints the six coefficients, a Builder records.calc entry with them loaded into fields B to G, and an equivalent Excel formula referencing --excel-cell.

Development

uv sync
uv run pytest

The scan code reaches EPICS through cothread.catools, which is imported lazily so the tests, --help and the calibrate command all work without an IOC. The test suite substitutes a fake Channel Access layer, so a full scan can be exercised without hardware.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dls_motor_scanning-1.0.0b1.tar.gz (111.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dls_motor_scanning-1.0.0b1-py3-none-any.whl (21.2 kB view details)

Uploaded Python 3

File details

Details for the file dls_motor_scanning-1.0.0b1.tar.gz.

File metadata

  • Download URL: dls_motor_scanning-1.0.0b1.tar.gz
  • Upload date:
  • Size: 111.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for dls_motor_scanning-1.0.0b1.tar.gz
Algorithm Hash digest
SHA256 d705c2c8d146a5174e35a080d25835115d71a900424d9bfd0e73e045c61a6bca
MD5 1b04cbe6c8eb2da12eed7955f6971ca2
BLAKE2b-256 304283afe941948b25ab75464825893f0deb2996c85ba23e516cf36a66bdd14b

See more details on using hashes here.

File details

Details for the file dls_motor_scanning-1.0.0b1-py3-none-any.whl.

File metadata

File hashes

Hashes for dls_motor_scanning-1.0.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 f4e08a23638e1fcf0061a661015e899413acd406d375b5a8f485678d3636b23d
MD5 539e740099087f56aa9a3ccb5d134104
BLAKE2b-256 5063102ce3043ffca7f96da4c4d4e27c9c7a8caf33b6b0cab352c5e965a5b5b8

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.0b1 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page