Skip to main content

scuq

pipeline status coverage report PyPI version Python versions documentation

Overview

scuq is a Python package for calculations with real and complex physical quantities, units, uncertainties, and correlations. It lets a measurement model remain ordinary Python or NumPy code while carrying the metrological meaning of its values through the calculation.

A scuq Quantity combines a numerical or uncertainty-aware value with a physical unit. Arithmetic derives the resulting unit, compatible units can be converted explicitly or automatically, and a Context evaluates propagated uncertainties and correlations. Complex quantities use covariance matrices for their real and imaginary components.

This makes scuq useful for:

  • scientific and engineering calculations with traceable units;
  • uncertainty propagation according to measurement models;
  • correlated real and complex input quantities;
  • NumPy-based numerical models;
  • retaining value, uncertainty, and unit in exported measurement results.

The uncertainty model follows the concepts of the Guide to the Expression of Uncertainty in Measurement (GUM).

Core concepts

Quantities and units

scuq.quantities.Quantity is the main public value type. The units in scuq.si cover common SI quantities, while scuq.units provides base, derived, alternate, product, compound, and transformed units. Multiplication, division, powers, and compatible conversions preserve the associated unit.

from scuq.quantities import Quantity
from scuq.si import AMPERE, METER, SECOND, VOLT

voltage = Quantity(VOLT, 12.0)
current = Quantity(AMPERE, 0.25)
resistance = voltage / current

distance = Quantity(METER, 10.0)
duration = Quantity(SECOND, 2.0)
speed = distance / duration

print(resistance)  # 48.0 V*A^(-1)
print(speed)       # 5 m*s^(-1)

Uncertain inputs and contexts

scuq.ucomponents.UncertainInput represents a real uncertain input. Arithmetic builds a measurement model from these inputs instead of discarding their uncertainty. A Context evaluates that model and stores correlations.

from scuq.quantities import Quantity
from scuq.si import VOLT
from scuq.ucomponents import Context, UncertainInput

u1 = Quantity(VOLT, UncertainInput(1.0, 0.2))
u2 = Quantity(VOLT, UncertainInput(2.0, 0.1))
voltage_sum = u1 + u2

context = Context()
value, uncertainty, unit = context.value_uncertainty_unit(voltage_sum)

print(value)        # 3
print(uncertainty)  # 0.223606797749979
print(unit)         # V

context.set_correlation(u1, u2, 0.5)
print(context.uncertainty(voltage_sum))  # 0.2645751311064591 V

The same input used twice remains fully correlated. Consequently, the uncertainty of u1 + u1 is twice the uncertainty of u1, rather than the root-sum-square of two independent inputs.

Physical constants

scuq.constants provides a small, reviewed set of physical constants as SCUQ quantities. The defining SI constants are exact and have zero uncertainty. The fine-structure constant uses the pinned 2022 CODATA value and standard uncertainty; mu_0, epsilon_0, and Z_0 are derived from that same input so their physical dependence is retained.

from scuq.constants import SPEED_OF_LIGHT, alpha, mu_0
from scuq.ucomponents import Context

context = Context()
print(SPEED_OF_LIGHT)  # 299792458.0 m*s^(-1)
print(context.value_uncertainty_unit(alpha))
print(context.value_uncertainty_unit(mu_0))

The public module objects reject in-place mutation, while ordinary arithmetic returns usable Quantity expressions. The curated module has no SciPy runtime or test dependency. Values and provenance are documented in the scuq.constants API page.

Strict mode

Strict mode is enabled by default. It prevents implicit conversion when an operation requires equal units. This can expose accidental mixing of units or of dimensionless quantities that have different physical meanings. Disable it when automatic conversion between compatible units is intended.

from scuq.qexceptions import ConversionException
from scuq.quantities import Quantity, set_strict
from scuq.si import VOLT
from scuq.units import AlternateUnit

MILLIVOLT = AlternateUnit("mV", VOLT / 1000)

set_strict(True)
try:
    Quantity(VOLT, 2.0) + Quantity(MILLIVOLT, 500.0)
except ConversionException:
    print("explicit conversion required")

set_strict(False)
signal = Quantity(VOLT, 2.0) + Quantity(MILLIVOLT, 500.0)
print(signal)  # 2.5 V

The result of addition or subtraction is expressed in the unit of the left operand. reduce_to() always performs the requested compatible conversion, independently of strict mode.

Contexts and the [NC] marker

An uncertain expression may print with [NC], meaning "no context". The string representation then uses a temporary default context and assumes no additional correlations. Assign the expression to the intended context when a stable context-aware representation is needed:

from scuq.quantities import Quantity
from scuq.si import VOLT
from scuq.ucomponents import Context, UncertainInput

u1 = Quantity(VOLT, UncertainInput(1.0, 0.2))
u2 = Quantity(VOLT, UncertainInput(2.0, 0.1))
context = Context()
voltage_sum = context.value_of(u1 + u2)
print(voltage_sum)  # 3.0 +/- 0.223606797749979 V

For data processing and export, prefer the explicit context.value_uncertainty_unit(quantity) interface.

Complex quantities and NumPy

scuq.cucomponents extends the same model to complex values. NumPy ufuncs can operate on scuq expressions, allowing numerical code to remain close to its mathematical form.

import numpy as np

from scuq import cucomponents
from scuq.quantities import Quantity
from scuq.si import AMPERE, OHM, RADIAN, VOLT
from scuq.units import ONE

context = cucomponents.Context()
j = Quantity(ONE, context.gaussian(1j, 0.0, 0.0))
voltage = Quantity(VOLT, context.gaussian(4.9990, 0.003209, 0.0))
current = Quantity(AMPERE, context.gaussian(19.661e-3, 0.00947e-3, 0.0))
phase = Quantity(RADIAN, context.gaussian(1.04446, 0.0007521, 0.0))

impedance = (voltage / current * np.exp(j * phase)).reduce_to(OHM)

print(impedance)
print(context.uncertainty(impedance))  # 2 x 2 covariance matrix

scuq and mpylab

mpylab uses scuq consistently for physical measurement values and evaluated results. Instrument readings, calibration data, path corrections, powers, voltages, field strengths, and their uncertainties remain quantities instead of being reduced prematurely to plain floats.

In particular, mpylab uses scuq while combining measurement paths, converting between linear and logarithmic representations, interpolating calibration data, evaluating TEM/GTEM and mode-stirred chamber measurements, and writing traceable result files. mpylab is therefore also a substantial real-world example of using scuq in laboratory automation.

Project links:

Installation

Install the current release from PyPI:

python -m pip install scuq

Alternatively, install directly from GitLab:

python -m pip install git+https://gitlab.hrz.tu-chemnitz.de/chair-of-electromagnetic-theory-and-compatibility-at-tu-dresden/mpylab/scuq.git

This requires git. Append a branch or tag to the URL to select a particular revision, for example @main or @v1.0.5.

For an editable development installation from a local checkout:

python -m pip install -e ".[dev]"

Interactive cheat sheet

The repository contains a Marimo cheat sheet with additional executable examples, including strict mode, correlations, probability distributions, and conversion of quantities into tabular value/uncertainty/unit columns:

python -m pip install -e ".[notebook]"
marimo run marimo/cheat-sheet.py

The optional notebook extra requires Python 3.10 or newer because current Marimo releases no longer support older Python versions. It is kept separate from SCUQ's runtime dependencies.

The same material is also available as a Jupyter notebook. More focused examples are collected in the Sphinx examples and the Examples/ directory.

Command line

The package installs a small diagnostic command:

scuq-info

It reports the installed scuq, Python, and NumPy versions, the package path, the strict-mode setting, and several smoke-check results. Use scuq-info --json for machine-readable output.

Documentation

The complete API and examples are published with GitLab Pages:

https://scuq-b5d96a.gp.hrz.tu-chemnitz.de/

License

scuq is distributed under the GPL-3.0-or-later license. See LICENSE for details.

Repository

https://gitlab.hrz.tu-chemnitz.de/chair-of-electromagnetic-theory-and-compatibility-at-tu-dresden/mpylab/scuq.git

Contact

Prof. Dr. Hans Georg Krauthäuser (hgk@ieee.org)
Chair for Electromagnetic Theory and Compatibility
Technische Universität Dresden, Dresden, Germany

Download files

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

Source Distribution

scuq-1.0.10.tar.gz (131.0 kB view details)

Uploaded Source

Built Distribution

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

scuq-1.0.10-py3-none-any.whl (93.1 kB view details)

Uploaded Python 3

File details

Details for the file scuq-1.0.10.tar.gz.

File metadata

  • Download URL: scuq-1.0.10.tar.gz
  • Upload date:
  • Size: 131.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.5

File hashes

Hashes for scuq-1.0.10.tar.gz
Algorithm Hash digest
SHA256 20ff7ff3eec6a841b3a384a4ab6b4e6d002d7c206e10ab63c19479538776830f
MD5 731c5f6a8e52d2d0c32ac62d0e39f483
BLAKE2b-256 f9950d0143b4bb7a1d04278f4e501f48ad6798a53c6010965b66eaff75824a47

See more details on using hashes here.

File details

Details for the file scuq-1.0.10-py3-none-any.whl.

File metadata

  • Download URL: scuq-1.0.10-py3-none-any.whl
  • Upload date:
  • Size: 93.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.5

File hashes

Hashes for scuq-1.0.10-py3-none-any.whl
Algorithm Hash digest
SHA256 987b071ab96a1cfc00a0affbc859b7444c74e18ed82bfa5c18a434c739f70bfd
MD5 9d071c8b8a9d70823c429301b85b045d
BLAKE2b-256 32f1aa5c6f3f381db7f56ea13eed0651ee8e4dab926093b0b605aa66fc9e9c44

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

1.0.10 This release

2 files

1.0.9

2 files

1.0.8

2 files

1.0.7

2 files

1.0.6

2 files

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.1

2 files

1.0.0

2 files

0.9.1

2 files

0.9

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