Metadata-Version: 2.4
Name: pymfx
Version: 1.0.1
Summary: Parse, validate, analyse and convert UAV mission data in the open .mfx (Mission Flight Exchange) format
Author: pymfx contributors
License: Creative Commons Attribution 4.0 International (CC BY 4.0)
        
        Copyright (c) 2026 pymfx contributors
        
        You are free to:
          Share — copy and redistribute the material in any medium or format
          Adapt — remix, transform, and build upon the material for any purpose, even commercially.
        
        Under the following terms:
          Attribution — You must give appropriate credit, provide a link to the license,
          and indicate if changes were made.
        
        Full license text: https://creativecommons.org/licenses/by/4.0/legalcode
        
Project-URL: Homepage, https://github.com/jabahm/pymfx
Project-URL: Documentation, https://jabahm.github.io/pymfx
Project-URL: Repository, https://github.com/jabahm/pymfx
Project-URL: Changelog, https://github.com/jabahm/pymfx/blob/main/CHANGELOG.md
Project-URL: Bug Tracker, https://github.com/jabahm/pymfx/issues
Keywords: uav,drone,mfx,mission,flight,FAIR,UAV,remote-sensing
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: folium>=0.14
Requires-Dist: matplotlib>=3.7
Requires-Dist: pandas>=1.5
Requires-Dist: textual>=0.50
Provides-Extra: viz
Requires-Dist: folium>=0.14; extra == "viz"
Requires-Dist: matplotlib>=3.7; extra == "viz"
Provides-Extra: ds
Requires-Dist: pandas>=1.5; extra == "ds"
Provides-Extra: notebooks
Requires-Dist: jupyter>=1.0; extra == "notebooks"
Requires-Dist: ipykernel>=6.0; extra == "notebooks"
Requires-Dist: folium>=0.14; extra == "notebooks"
Requires-Dist: matplotlib>=3.7; extra == "notebooks"
Requires-Dist: pandas>=1.5; extra == "notebooks"
Provides-Extra: tui
Requires-Dist: textual>=0.50; extra == "tui"
Provides-Extra: docs
Requires-Dist: mkdocs-material>=9.0; extra == "docs"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Requires-Dist: mypy>=1.8; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Requires-Dist: folium>=0.14; extra == "dev"
Requires-Dist: matplotlib>=3.7; extra == "dev"
Requires-Dist: pandas>=1.5; extra == "dev"
Requires-Dist: textual>=0.50; extra == "dev"
Dynamic: license-file

# pymfx

[![CI](https://github.com/jabahm/pymfx/actions/workflows/ci.yml/badge.svg)](https://github.com/jabahm/pymfx/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/pymfx)](https://pypi.org/project/pymfx/)
[![Coverage](https://codecov.io/gh/jabahm/pymfx/branch/main/graph/badge.svg)](https://codecov.io/gh/jabahm/pymfx)
[![Docs](https://img.shields.io/badge/docs-jabahm.github.io%2Fpymfx-blue)](https://jabahm.github.io/pymfx)

Parse, validate, analyse and convert UAV mission data using the open [`.mfx`](https://github.com/jabahm/pymfx) format — plain text, self-describing, FAIR-compliant, single file per flight.

```bash
pip install pymfx
```

---

## Package

```python
import pymfx

mfx = pymfx.parse("flight.mfx")
pymfx.validate(mfx)
```

| Function | Description |
|---|---|
| `parse(src)` | Parse a `.mfx` file or string |
| `validate(mfx)` | Run V01–V21 validation rules |
| `flight_stats(mfx)` | Duration, distance, alt, speed |
| `fair_score(mfx)` | FAIR compliance score (F/A/I/R) |
| `detect_anomalies(mfx)` | Speed spikes, GPS jumps, altitude cliffs |
| `write(mfx, dest)` | Write with auto SHA-256 checksum |

**Convert**

```python
mfx = pymfx.convert.from_gpx("track.gpx")
pymfx.convert.to_geojson(mfx)
```

| | Import | Export |
|---|---|---|
| GPX 1.1 | `from_gpx` | `to_gpx` |
| GeoJSON | `from_geojson` | `to_geojson` |
| CSV | `from_csv` | `to_csv` |
| DJI / AirData | `from_dji_csv` | |
| KML | | `to_kml` |

**Visualize**

```python
import pymfx.viz as viz
viz.flight_profile(mfx)
```

| Function | Output |
|---|---|
| `trajectory_map(mfx)` | Folium map, speed gradient |
| `speed_heatmap(mfx)` | Folium map, heat overlay |
| `compare_map([...])` | Multi-flight overlay |
| `flight_profile(mfx)` | Alt / speed / heading chart |
| `flight_3d(mfx)` | 3D trajectory |
| `events_timeline(mfx)` | Events on flight axis |

![flight profile](docs/img/flight_profile.png)

**DataFrame**

```python
df = mfx.trajectory.to_dataframe(events=mfx.events)
```

---

## TUI

```bash
pymfx flight.mfx --tui
```

![TUI Overview](docs/img/tui_overview.svg)

| Key | Tab |
|---|---|
| `1` | Overview |
| `2` | Trajectory |
| `3` | Events |
| `4` | Statistics + FAIR |
| `5` | Anomalies |
| `6` | Raw |
| `e` | Export |

![TUI Trajectory](docs/img/tui_trajectory.svg)

---

## CLI

```bash
pymfx flight.mfx --validate
```

| Flag | Action |
|---|---|
| `--validate` | Check V01–V21 rules |
| `--info` | File summary |
| `--stats` | Flight statistics |
| `--checksum` | Verify SHA-256 |
| `--anomalies` | Detect anomalies |
| `--diff other.mfx` | Compare two files |
| `--export fmt -o out` | Export to gpx/kml/csv/geojson |
| `--import fmt -o out` | Import from gpx/csv/dji/geojson |
| `--repair -o out` | Rebuild checksum + index |
| `--tui` | Open interactive viewer |

---

## Format

```
@mfx 1.0
@encoding UTF-8

[meta]
id         : uuid:f47ac10b-58cc-4372-a567-0e02b2c3d479
drone_id   : drone:DJI-Mini3-SN8273
pilot_id   : pilot:ahmed-jabrane
date_start : 2025-06-15T08:30:00Z
status     : complete
license    : CC-BY-4.0

[trajectory]
frequency_hz : 1.0
@checksum sha256:b1f2bc...
@schema point: {t:float [no_null], lat:float [no_null], lon:float [no_null], alt_m:float32, speed_ms:float32}
data[]:
0.000 | 48.7733 | 2.2858 | 52.1 | 3.2
1.000 | 48.7734 | 2.2859 | 54.3 | 4.1

[index]
bbox      : (2.2858, 48.7733, 2.2901, 48.7751)
anomalies : 0
```

---

## License

MIT
