Skip to main content

steam-roxie-parser

Parser for ROXIE files that builds the 2D coil and iron-yoke geometry of superconducting accelerator magnets. It is part of the STEAM framework and provides the geometry input consumed by FiQuS, PySIGMA and LEDET via steam-sdk.

Note: the parser supports so-called multipole magnets (cos-theta, block-coil, common-coil) defined in ROXIE. It is not applicable to CCT magnets, solenoids, or conductor-only models.

Concepts

The parser has two distinct stages:

  1. Input parsing — the ROXIE input files are parsed into a raw data structure (RoxieRawData): .cadata → cable database, .data → coil winding definition, .iron → iron yoke definition. This stage is bidirectional: the raw data structure can be written to / read from a yaml file, and written back to the ROXIE input files, closing the round trip ROXIE files ↔ RoxieRawData ↔ yaml.
  2. Geometry building — the raw data structure is turned into the magnet geometry (RoxieData): half-turn corner positions (bare and insulated), strand positions, wedges, and the iron-yoke outline. This is the .geom content consumed by FiQuS and PySIGMA.

ParserRoxie.get_data(...) orchestrates both stages; parse_roxie_input_files(...) and build_geometry(...) expose them separately.

Features

  • Parse ROXIE input files: .data (coil), .cadata (cable database), .iron (iron yoke), .map2d (field maps)
  • Raw data structure RoxieRawData ↔ yaml (utils.raw_data_file.write_raw_data_yaml / read_raw_data_yaml)
  • Raw data structure → ROXIE files (parsers.roxie_file_writers.write_roxie_input_files, and the per-file write_data_file / write_cadata_file / write_iron_file)
  • Build the magnet cross-section geometry into a versioned pydantic data model (RoxieData)
  • Write and read the .geom geometry file (utils.geom_file.write_geom_file / read_geom_file)
  • Solenoid geometry from a coil definition (parsers.solenoids.Solenoid_magnet)
  • Plot the parsed geometry, or save it as SVG/PNG (steam_roxie_parser.plotters.plotter_roxie)

Installation

pip install steam-roxie-parser

For development:

git clone https://gitlab.cern.ch/steam/steam-roxie-parser.git
cd steam-roxie-parser
pip install -e .[test]

Test model library (steam_models submodule)

The magnet input models used by the tests live in the shared steam_models repository, included here as a git submodule at tests/input_from_steam_models/ (magnets are under tests/input_from_steam_models/magnets/<MAGNET>/input/). It is pinned to a specific steam_models commit and configured as a shallow submodule (only the pinned revision is fetched, not the full history — steam_models is several GB).

First checkout — get the submodule

Clone the repo with its submodule in one step:

git clone --recurse-submodules ssh://git@gitlab.cern.ch:7999/steam/steam-roxie-parser.git

Already cloned without it? Initialise it (shallow):

git submodule update --init --recommend-shallow tests/input_from_steam_models

PyCharm: on first opening a project with a submodule, PyCharm asks “Would you like to check out the submodules?” — click Yes. If you dismissed it, run Git ▸ Update Project… (Ctrl+T / ⌘T) and PyCharm checks the submodule out to the pinned commit.

Sync the submodule to the pinned commit

After pulling changes where someone moved the submodule pointer, put your working copy on the pinned commit:

git submodule update --init --recommend-shallow tests/input_from_steam_models

PyCharm: Git ▸ Update Project… (Ctrl+T / ⌘T) — it updates submodules to the pinned commit as part of the project update.

Update the submodule to the latest steam_models

To pull the newest magnet models (move the pin to the current steam_models master):

git submodule update --remote tests/input_from_steam_models   # fetch steam_models master and check it out
git add steam_models                          # record the new pin in this repo
git commit -m "Bump steam_models submodule"

PyCharm: there is no one-click “advance submodule to latest” button — use the built-in Terminal (Alt+F12) for the commands above, or open steam_models/ as its own project, git pull there, then commit the moved pointer in this repo (Git ▸ Commit, then Git ▸ Push).

The submodule uses a relative URL (../steam_models.git), so it resolves over whatever transport you cloned this repo with (SSH for developers, HTTPS for CI) — no per-user URL tweaking.

Running the tests

The tests are plain unittest.TestCase classes. Run them in parallel across all cores with unittest-parallel (installed by the [test] extra):

python -m unittest_parallel -t . -s tests -p "test_*.py" --level=test -j 0

-j 0 uses all CPUs and --level=test distributes at the individual test-method level (each magnet is its own test method, so they fan out across processes). Expect Ran 187 tests ... OK in ~2 minutes on a many-core machine.

Or run serially with only the standard library (no extra tools):

python -m unittest discover -s tests -t . -p "test_*.py"

In PyCharm

Add a Python run configuration (not the "Python tests" type, since unittest-parallel is a custom runner):

  1. Run | Edit Configurations… | + | Python
  2. In the target dropdown switch from "Script path" to Module name, and enter unittest_parallel
  3. Parameters: -t . -s tests -p test_*.py --level=test -j 0
  4. Working directory: the project root
  5. Python interpreter: the environment where unittest-parallel is installed (the [test] extra)
  6. OK, then run it with ▶

A ready-made copy of this configuration is at .idea/runConfigurations/Tests_unittest_parallel.xml. Note that .idea/ is gitignored, so on a fresh checkout recreate it with the steps above.

Usage

Multipole magnets (parsed from ROXIE files)

from pathlib import Path
from steam_roxie_parser.parsers.parser_roxie import ParserRoxie

parser = ParserRoxie()
roxie_data = parser.get_data(
    dir_data=Path("MQXA.data"),        # coil definition
    dir_cadata=Path("roxie.cadata"),   # cable database
    dir_iron=Path("MQXA.iron"),        # iron yoke (optional)
    path_to_yaml_model_data="modelData_MQXA.yaml",  # optional, needed for ribbon cables
)

# Write the .geom file used by FiQuS and PySIGMA
from steam_roxie_parser.utils.geom_file import write_geom_file
write_geom_file(roxie_data, "MQXA_FiQuS.geom")

get_data runs the two stages; you can also run them separately, e.g. to dump the parsed ROXIE file content to yaml, edit it, and rebuild the geometry:

from steam_roxie_parser.utils.raw_data_file import write_raw_data_yaml_files, read_raw_data_yaml_files

parser = ParserRoxie()

# Stage 1: parse the .data / .cadata / .iron files into the raw data structure
raw = parser.parse_roxie_input_files(dir_data=Path("MQXA.data"),
                                  dir_cadata=Path("roxie.cadata"),
                                  dir_iron=Path("MQXA.iron"))

# Dump the content of each ROXIE file to its own separate yaml file (and read them back)
write_raw_data_yaml_files(raw, dir_cadata_yaml="MQXA_cadata.yaml",
                          dir_data_yaml="MQXA_data.yaml", dir_iron_yaml="MQXA_iron.yaml")
raw = read_raw_data_yaml_files(dir_cadata_yaml="MQXA_cadata.yaml",
                               dir_data_yaml="MQXA_data.yaml", dir_iron_yaml="MQXA_iron.yaml")

# Stage 2: build the geometry from the (possibly yaml-roundtripped) raw data structure
roxie_data = parser.build_geometry(raw_data=raw)

Solenoids (built from a coil definition, not from ROXIE files)

Solenoid geometry does not come from ROXIE input files — it is built directly from a coil definition. This capability moved here from steam_sdk.builders.Solenoids. Solenoid_magnet turns per-section coil dimensions (SolenoidCoilInfo) and conductor data (ConductorInfo) into the same RoxieData geometry the multipole parser produces, so it writes an identical .geom file for FiQuS / PySIGMA. Field-map and self-inductance calculations use pysoleno (install the solenoid extra); the geometry itself works without it.

from steam_roxie_parser.data.data_model_info import CableInfo, ConductorInfo, SolenoidCoilInfo, StrandInfo
from steam_roxie_parser.parsers.solenoids import Solenoid_magnet
from steam_roxie_parser.utils.geom_file import write_geom_file

# one SolenoidCoilInfo per coil section: inner/outer radius (a1/a2), axial extent (b1/b2),
# turns-per-layer (ntpl) and number of layers (nl)
coil = SolenoidCoilInfo(name="ColSol", a1=0.09175, a2=0.11095, b1=0.0, b2=0.200134,
                        conductor_name="HEL_W1", ntpl=121, nl=16, section=1)
conductor = ConductorInfo(name="HEL_W1",
                          cable=CableInfo(th_insulation_along_width=1.075e-4, th_insulation_along_height=2e-5),
                          strand=StrandInfo(bare_width=0.00101, bare_height=0.00161))

roxie_data = Solenoid_magnet(coils=[coil], conductors=[conductor], Iref=100.0).build_geom_object()
write_geom_file(roxie_data, "MLEC_FiQuS.geom")   # same .geom format as the multipole magnets

Field maps and plotting

from steam_roxie_parser.parsers.parser_map2d import ParserMap2dFile
parameters = ParserMap2dFile(map2dFile=Path("MQXA.map2d")).get_parameters_from_map2d(headerLines=1)

from steam_roxie_parser.plotters import plotter_roxie
plotter_roxie.plot_all(roxie_data)
plotter_roxie.save_svg(roxie_data, "MQXA.svg")   # or save_png(...) for a quick image

STEAM

This repository is part of the STEAM framework maintained by the TE-MPE-PE section at CERN. Contact: steam-team@cern.ch

License

This project is licensed under the GNU General Public License v3.0 — see the LICENSE file for details.

Metadata

Release files for steam-roxie-parser 2026.7.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for steam-roxie-parser 2026.7.9
File Size Uploaded Provenance
steam_roxie_parser-2026.7.9.tar.gz 102.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for steam-roxie-parser 2026.7.9
File Interpreter ABI Platform
steam_roxie_parser-2026.7.9-py3-none-any.whl Python 3 none any Details

Total release size: 189.6 kB

Release files / steam_roxie_parser-2026.7.9.tar.gz

Download URL steam_roxie_parser-2026.7.9.tar.gz
Size 102.7 kB
Tags Source
SHA-256 checksum
How to use checksums
b80686f0b694807e9ae1053c2f0d21deb81a265e9999a1a0f2cd590ef62683f6
BLAKE2b-256 checksum
How to use checksums
918d3cc1907a048f6496c43801ca2b8d904d0d83b3b389cd2e0e700f0fd516a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.8

Release files / steam_roxie_parser-2026.7.9-py3-none-any.whl

Download URL steam_roxie_parser-2026.7.9-py3-none-any.whl
Size 86.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b18895c5dc50f9a2a6a328728a8e4a3725915b1e6ab966d415105c69ccdc1901
BLAKE2b-256 checksum
How to use checksums
aa2b8299e5a23106d2f88b7be2211fe0094ac7eb4670aa861a8d35f97e62c2b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.8

Security for steam-roxie-parser 2026.7.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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