Metadata-Version: 2.4
Name: fmu_manipulation_toolbox
Version: 2.0b3
Summary: FMU Manipulation Toolbox is a python package which helps to analyze, modify, validate, combine or split Functional Mock-up Units (FMUs) without recompilation, through a GUI, a CLI or a Python API.
Author-email: Nicolas LAURENT <Nicolas.LAURENT@Renault.com>
License-Expression: BSD-2-Clause
Project-URL: Homepage, https://github.com/grouperenault/fmu_manipulation_toolbox/
Project-URL: Documentation, https://grouperenault.github.io/fmu_manipulation_toolbox/
Project-URL: Source, https://github.com/grouperenault/fmu_manipulation_toolbox/
Project-URL: Changelog, https://github.com/grouperenault/fmu_manipulation_toolbox/blob/main/CHANGELOG.md
Project-URL: Bug Tracker, https://github.com/grouperenault/fmu_manipulation_toolbox/issues
Keywords: FMI,FMU,co-simulation,Functional Mock-up Interface,Functional Mock-up Unit,model-based systems engineering,simulation
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: xmlschema>=3.3.1
Requires-Dist: elementpath>=4.4.0
Requires-Dist: colorama>=0.4.6
Provides-Extra: mcp
Requires-Dist: fastmcp<5,>=4.0.3; extra == "mcp"
Requires-Dist: uvicorn>=0.30; extra == "mcp"
Provides-Extra: gui
Requires-Dist: PySide6>=6.8.0; extra == "gui"
Provides-Extra: test
Requires-Dist: PySide6>=6.8.0; extra == "test"
Requires-Dist: pytest>=9.0.3; extra == "test"
Requires-Dist: pytest-qt>=4.4.0; extra == "test"
Requires-Dist: pytest-cov>=7.0.0; extra == "test"
Requires-Dist: coverage-badge>=1.1.2; extra == "test"
Requires-Dist: fmpy>=0.3.20; extra == "test"
Requires-Dist: numpy; extra == "test"
Provides-Extra: all
Requires-Dist: fmu_manipulation_toolbox[gui,mcp,test]; extra == "all"
Dynamic: license-file

![](https://raw.githubusercontent.com/grouperenault/fmu_manipulation_toolbox/main/fmu_manipulation_toolbox/resources/fmu_manipulation_toolbox.png)

![](https://raw.githubusercontent.com/grouperenault/fmu_manipulation_toolbox/refs/heads/badges/.github/badges/python-version.svg)
![](https://raw.githubusercontent.com/grouperenault/fmu_manipulation_toolbox/refs/heads/badges/.github/badges/fmi-version.svg)
![](https://raw.githubusercontent.com/grouperenault/fmu_manipulation_toolbox/refs/heads/badges/.github/badges/coverage.svg)
[![PyPI version](https://img.shields.io/pypi/v/fmu-manipulation-toolbox)](https://pypi.org/project/fmu-manipulation-toolbox/)
[![License: BSD-2-Clause](https://img.shields.io/badge/License-BSD--2--Clause-blue.svg)](LICENSE.txt)

---

## Table of Contents

- [Overview](#-overview)
- [Installation](#-installation)
- [Graphical User Interface](#-graphical-user-interface)
- [Command Line Interface](#-command-line-interface)
- [API](#-api)
- [Project Architecture](#-project-architecture)
- [Development](#-development)
- [Contributing](#-contributing)
- [Changelog](#-changelog)
- [License](#-license)

---

# 👀 Overview

FMU Manipulation Toolbox is a python package which helps to analyze, modify or combine
[Functional Mock-up Units (FMUs)](http://fmi-standard.org/) without recompilation. It is highly customizable and comes with
a Python API.

FMU Manipulation Toolbox can be used in different ways:
- Using a Graphical User Interface: suitable for end users
- Using a Command Line Interface: useful for scripting and automation
- Using a Python API: the most efficient option for automation (CI/CD, transformation scripts, ...)

Major features:
- Analyze FMU content: list ports and their attributes, check compliance of `ModelDescription.xml` with XSD, etc.
- Alter FMU by modifying its `modelDescription.xml` file. NOTE: manipulating this file can be risky.
  When possible, it is preferable to communicate with the FMU developer and adapt the FMU generation process.
- Add binary interfaces. Typical use case is porting 32-bit FMUs to 64-bit systems (or vice versa). 
- Combine FMUs into [FMU Containers](https://grouperenault.github.io/fmu_manipulation_toolbox/user-guide/fmucontainer/container/) and allow your favourite FMI tool to orchestrate complex assembly of FMUs.

FMI versions 2.0 and 3.0 are supported.

# ⚙️ Installation

Two options available to install FMU Manipulation Toolbox:

- (*Easiest option*) Install from PyPI: `pip install fmu-manipulation-toolbox`. This will install the latest
  version of FMU Manipulation Toolbox and all its dependencies. See [PyPI page](https://pypi.org/project/fmu-manipulation-toolbox/).
- Compile and install from [GitHub repository](https://github.com/grouperenault/fmu_manipulation_toolbox). You will need 
  - pip ≥ 21.3. The Python dependencies are declared in [`pyproject.toml`](https://github.com/grouperenault/fmu_manipulation_toolbox/blob/main/pyproject.toml)
    and installed by `pip install .` (see [Development](#-development)).
  - C compiler with C23 support (for the container) or C99 (for remoting)
  - CMake ≥ 3.21

By default, `pip install fmu-manipulation-toolbox` only installs the **CLI** and **Python API** (no GUI toolkit
required). If you also want the **Graphical User Interfaces** (`fmutoolbox`, `fmutool-gui`, `fmueditor`,
`fmucontainer-gui`), install the `gui` extra, which pulls in [PySide6](https://pypi.org/project/PySide6/):

```bash
pip install "fmu-manipulation-toolbox[gui]"
```

To let an AI agent assemble FMU containers for you through a
[Model Context Protocol](https://modelcontextprotocol.io/) server
(`fmutool-mcp`, or the Container Builder's *AI Assistant* menu), install the `mcp`
extra:

```bash
pip install "fmu-manipulation-toolbox[mcp]"
```


### Supported platforms

FMU Manipulation Toolbox is packaged for:
- Windows 10/11 (primary platform)
- Linux (Ubuntu 22.04)
- Darwin


# 🖥️ Graphical User Interface

FMU Manipulation Toolbox is released with a GUI. It requires the `gui` extra
(`pip install "fmu-manipulation-toolbox[gui]"`) to pull in [PySide6](https://pypi.org/project/PySide6/).
You can launch it with the following command `fmutoolbox`

![GUI](https://raw.githubusercontent.com/grouperenault/fmu_manipulation_toolbox/main/docs/gui-launcher.png "GUI")

Button color descriptions:
- red: remove information from the `modelDescription.xml`
- orange: alter `modelDescription.xml`
- green: add component into the FMU or check it
- violet: extract and save
- blue: filter actions scope or exit

**Original FMU is never modified**. Use `Save` button to get modified copy of the original FMU.


# 🔧 Command Line Interface

FMU Manipulation Toolbox comes with the following commands:
- `fmutool`: a versatile analysis and manipulation tool for FMUs. 
- `fmutool-gui`: a graphical interface for `fmutool`.
- `fmucontainer`: to combine FMUs inside FMU Containers.
- `fmusplit`: to extract FMUs from a FMU Container.
- (experimental) `datalog2pcap`: to convert logs from FMU containers to PCAP files.


# 🚀 API

You can write your own FMU manipulation scripts. Once you have installed the fmutool module, 
adding the `import` statement lets you access the API:

```python
from fmu_manipulation_toolbox.operations import ...
```


## Remove Top-Level Bus (if any)

Given an FMU with the following I/O structure
```
├── Parameters
│   ├── Foo
│   │   ├── param_A
│   ├── Bar
├── Generator
│   ├── Input_A
│   ├── Output_B
```

The following transformation will result in:
```
├── Foo
│   ├── param_A
├── Bar
├── Input_A
├── Output_B
```

**Note:** removing the top-level bus can lead to name collisions!

The following code will do this transformation: 
```python
from fmu_manipulation_toolbox.operations import FMU, OperationStripTopLevel

fmu = FMU(r"bouncing_ball.fmu")
operation = OperationStripTopLevel()
fmu.apply_operation(operation)
fmu.repack(r"bouncing_ball-modified.fmu")
```

### Extract Names and Write a CSV

The following code will dump all FMU scalar names into a CSV:

```python
from fmu_manipulation_toolbox.operations import FMU, OperationSaveNamesToCSV

fmu = FMU(r"bouncing_ball.fmu")
operation = OperationSaveNamesToCSV(r"bouncing_ball.csv")
fmu.apply_operation(operation)
```

The produced CSV contains 2 columns so it can be reused in the next transformation.
The 2 columns are identical.

```csv
name;newName;valueReference;causality;variability
h;h;0;local;continuous
der(h);der(h);1;local;continuous
v;v;2;local;continuous
der(v);der(v);3;local;continuous
g;g;4;parameter;fixed
e;e;5;parameter;tunable
```


## Read CSV and Rename FMU Ports

The CSV file should contain 2 columns:
1. the current name
2. the new name

```python
from fmu_manipulation_toolbox.operations import FMU, OperationRenameFromCSV

fmu = FMU(r"bouncing_ball.fmu")
operation = OperationRenameFromCSV(r"bouncing_ball-modified.csv")
fmu.apply_operation(operation)
fmu.repack(r"bouncing_ball-renamed.fmu")
```

### Available Operations

All operations are located in [`operations.py`](https://github.com/grouperenault/fmu_manipulation_toolbox/blob/main/fmu_manipulation_toolbox/operations.py):

| Operation | Description |
|---|---|
| `OperationStripTopLevel` | Remove the top-level bus from the FMU I/O structure |
| `OperationMergeTopLevel` | Merge the top-level bus into the FMU I/O structure |
| `OperationSaveNamesToCSV` | Dump all scalar names into a CSV file |
| `OperationRenameFromCSV` | Rename FMU ports according to a CSV mapping |
| `OperationRemoveRegexp` | Remove variables matching a regular expression |
| `OperationKeepOnlyRegexp` | Keep only variables matching a regular expression |
| `OperationSummary` | Print a summary of the FMU |
| `OperationRemoveSources` | Remove source files embedded in the FMU |
| `OperationTrimUntil` | Trim variable names up to a given separator |

> 📖 Full documentation is available on the [documentation website](https://grouperenault.github.io/fmu_manipulation_toolbox/).


# 🏗️ Project Architecture

```
fmu_manipulation_toolbox/      # Python package
├── cli/                       #   Command Line Interface modules
├── gui/                       #   Graphical User Interface (PySide6)
├── resources/                 #   Pre-built binaries, XSD schemas, icons
├── operations.py              #   FMU operations (rename, filter, etc.)
├── container/                 #   FMU Container builder (writes container.txt for the C runtime)
├── assembly.py                #   Assembly description parsing
├── checker.py                 #   FMU compliance checker
├── remoting.py                #   32/64-bit remoting support
└── ...
container/                     # C source code for FMU Container runtime
remoting/                      # C source code for Remoting (client/server)
fmi/                           # FMI C headers (2.0 & 3.0)
tests/                         # Test suite (pytest)
docs/                          # Documentation source (MkDocs Material)
```

Key design points:
- **Pure Python manipulation**: analyzing and altering FMUs is done entirely in Python — no compilation required.
- **Native C code**: the FMU Container runtime is implemented in C (C23) and the Remoting feature in C (C99). These are compiled with CMake and shipped as pre-built binaries in `resources/`.
- **FMI 2.0 & 3.0**: both FMI standards are supported across all features.


# 🧑‍💻 Development

### Prerequisites

- Python ≥ 3.10
- C compiler with C23 support (for the container) or C99 (for remoting) — only needed for building the container/remoting binaries
- CMake ≥ 3.21 — only needed for building the C code

### Setup

```bash
# Clone the repository
git clone https://github.com/grouperenault/fmu_manipulation_toolbox.git
cd fmu_manipulation_toolbox

# Install the package in editable mode, with every extra (GUI, MCP, tests); needs pip >= 21.3
pip install -e ".[all]"
```

> **Note:** the tests run against the installed package: without this step, pytest stops with
> `ModuleNotFoundError: No module named 'fmu_manipulation_toolbox'`. `pip install -r requirements.txt` is
> equivalent (the file only contains `-e .[all]`). If you only need the CLI/API dependencies, use
> `pip install -e .` (add `[gui]`, `[mcp]` and/or `[test]` as needed, e.g. `pip install -e ".[gui,test]"`).

### Building C code (optional)

The container and remoting binaries can be built with CMake:

```bash
cd container
mkdir -p build && cd build
cmake ..
cmake --build .
```

Same process applies for the `remoting/` directory.

### Running tests

```bash
cd tests
pytest
```

With coverage report:
```bash
pytest --cov=fmu_manipulation_toolbox --cov-report=html
```

### Building documentation locally

The documentation uses [MkDocs Material](https://squidfunk.github.io/mkdocs-material/):

```bash
pip install mkdocs-material
mkdocs serve
```

Then open [http://127.0.0.1:8000](http://127.0.0.1:8000) in your browser.


# 🤝 Contributing

Contributions are welcome! Please read the [Contributing Guide](https://github.com/grouperenault/fmu_manipulation_toolbox/blob/main/CONTRIBUTING.md) for details on
how to report issues, suggest improvements, and interact with the development team.

> **Note:** For legal reasons, pull requests cannot be accepted. If you have ideas for improvements,
> please create an issue or get in touch with the development team.


# 📋 Changelog

See the [Changelog](https://github.com/grouperenault/fmu_manipulation_toolbox/blob/main/CHANGELOG.md) for a detailed list of changes across versions.


# 📄 License

This project is licensed under the **BSD-2-Clause** license. See [LICENSE.txt](https://github.com/grouperenault/fmu_manipulation_toolbox/blob/main/LICENSE.txt) for details.

Copyright © 2024-2026 Renault SAS
