Metadata-Version: 2.4
Name: steam-tfm
Version: 2026.7.0
Summary: Transfer Function Model (TFM) of superconducting magnets: computes the passive coupling effects (persistent currents, IFCC, ISCC, eddy currents, wedges, cold bore, cold pipe support, aluminium ring, beam screen) and writes the equivalent frequency-dependent circuit library used by the STEAM tools
Author-email: "STEAM Team, CERN" <steam-team@cern.ch>
License: GPL-3.0-only
Project-URL: Homepage, https://gitlab.cern.ch/steam/steam-tfm
Keywords: TFM,superconducting magnets,CERN,STEAM,coupling losses,circuit model
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy
Requires-Dist: scipy
Requires-Dist: pandas
Requires-Dist: pydantic>=2
Requires-Dist: matplotlib
Requires-Dist: sympy==1.13.3
Requires-Dist: numba==0.60.0
Requires-Dist: STEAM-materials
Requires-Dist: steam-magnetic-calculations
Provides-Extra: test
Requires-Dist: unittest-parallel; extra == "test"
Dynamic: license-file

# steam-tfm

Transfer Function Model (TFM) of superconducting magnets, part of the [STEAM](https://espace.cern.ch/steam/)
framework at CERN.

Given a built LEDET magnet model, the TFM computes the magnet's passive coupling effects and writes an
equivalent frequency-dependent circuit library (`.lib`) that a circuit simulator (PSPICE / XYCE) can use
in place of a plain inductor:

- persistent currents (PC)
- inter-filament coupling currents (IFCC)
- inter-strand coupling currents (ISCC)
- eddy currents (ED)
- coupling with the passive structures: wedges, cold bore (CB), cold pipe support (CPS), aluminium
  ring (AlRing) and beam screen (BS)
- inter-turn shorts and capacitance to ground

This package was extracted from `steam_sdk` (`steam_sdk.builders.BuilderTFM` and
`steam_sdk.data.DataTFM`) so the model, its tests and its release cycle stand on their own, the same way
`steam-roxie-parser` was split out earlier.

## Installation

```bash
pip install steam-tfm
```

For development, install the pinned environment first (the pins are kept in lock-step with
`steam_sdk/requirements.txt` so both packages coexist in one environment):

```bash
pip install -r requirements.txt
pip install -e .[test]
```

## Usage

The model takes plain data, not a `steam_sdk` object. `steam_sdk` supplies it through
`steam_sdk.builders.adapter_TFM.ledet_to_tfm_input(builder_ledet)`:

```python
from steam_tfm.builders.builder_tfm import BuilderTFM

builder_tfm = BuilderTFM(
    ledet_input=ledet_input,            # steam_tfm.data.tfm_input.TFM_LEDET_Input
    TFM_inputs=tfm_inputs,              # TFMClass: flags, temperature, B_nom_center, ...
    magnet_data=magnet_data,            # Magnet_TFM: apertures, C_ground, passive structures, ...
    local_library_path=library_path,    # magnet folder holding TFM_input/Field_Map_*.csv
    output_path=output_path,            # where the .lib is written
    library_name='MBRD_TFM',            # name of the generated .lib subcircuit
    domain='frequency',                 # or 'transient'
    flag_build=True,
)
```

Layout:

| module | contents |
|---|---|
| `steam_tfm.builders.builder_tfm` | `BuilderTFM`, the model itself |
| `steam_tfm.data.data_tfm` | TFM dataclasses (General, Turns, HalfTurns, Strands, the effect classes) and the LEDET→TFM lookup tables |
| `steam_tfm.data.data_tfm_circuit` | circuit-side models: `TFMClass`, `Magnet_TFM`, `TFM_Couplings`, `Component` |
| `steam_tfm.data.tfm_input` | `TFM_LEDET_Input`, the input contract |
| `steam_tfm.parsers.tfm_library_writer` | writes the `.lib` |

## Tests

The suite is written with `unittest.TestCase` and runs with
[unittest-parallel](https://pypi.org/project/unittest-parallel/) (not pytest):

```bash
python -m unittest discover -s tests -p "test_*.py" -t .
# or in parallel (module level, about half the cores: every worker re-imports numba/sympy/scipy)
python -m unittest_parallel -t . -s tests -p "test_*.py" --level=module -j 4
```

The tests build `BuilderTFM` from a snapshot fixture (`tests/input/MBRD_tfm_input.pkl`) rather than from a
`steam_sdk` model build, so they need neither `steam_sdk` nor a magnet library. Regenerate the fixture
with `python scripts/make_tfm_fixture.py [path-to-steam_sdk]` after changing the input contract.

Tests that evaluate the coupling effects additionally read the per-magnet TFM field maps
(`TFM_input/Field_Map_*.csv`, several GB) from the `steam_models` library, which is too large to vendor
here. They locate it via `STEAM_MODELS_PATH`, a `tests/input_from_steam_models` submodule, a sibling
`steam_models` checkout or a sibling `steam_sdk` checkout, and skip themselves when none is present.

## License

GPL-3.0-only. Contact: steam-team@cern.ch
