Skip to content
Merged

Joss #107

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test_coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.13
- name: Set up Python 3.14
uses: actions/setup-python@v4
with:
python-version: 3.13
python-version: 3.14

- name: Install dependencies
run: |
Expand Down
39 changes: 21 additions & 18 deletions .github/workflows/test_linux.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Tests on Linux
name: Linux Tests

on:
push:
Expand All @@ -9,36 +9,39 @@ jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-22.04
- ubuntu-24.04
python-version: ["3.10", "3.11", "3.12", "3.13"]
os: [ubuntu-22.04, ubuntu-24.04]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Clean untracked files & bytecode
shell: pwsh
run: |
git clean -xfd
run: git clean -xfd

# --- Setup Python ---
- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements_dev.txt
# --- Install UV (replaces pip + virtualenv) ---
- name: Install uv
run: pip install uv

- name: Install pyPLUTO in editable mode
# --- Create virtual environment with uv ---
- name: Create uv environment
run: |
pip uninstall -y pyPLUTO || true
pip install -e .
uv venv .venv
source .venv/bin/activate

# --- Sync environment (fast + reproducible) ---
- name: Install dependencies with uv
run: uv pip install -r requirements_dev.txt

# --- Run tests ---
- name: Run Tests
run: pytest -v
working-directory: ./Tests
run: uv run pytest -v ./Tests

2 changes: 1 addition & 1 deletion .github/workflows/test_macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
os:
- macOS-14
- macOS-15
python-version: ["3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- name: Checkout repository
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
os:
- windows-2022
- windows-2025
python-version: ["3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- name: Checkout repository
Expand Down
12 changes: 6 additions & 6 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ repos:
# files: \.py$

# 2. Docformatter (formats docstrings)
- repo: https://github.com/PyCQA/docformatter
rev: v1.7.7
hooks:
- id: docformatter
args: ["--in-place", "--black", "--blank"]
files: \.py$
#- repo: https://github.com/PyCQA/docformatter
# rev: v1.7.7
# hooks:
# - id: docformatter
# args: ["--in-place", "--black", "--blank"]
# files: \.py$

# 3. Blackened-docs (formats code in docstrings)
- repo: https://github.com/adamchainz/blacken-docs
Expand Down
91 changes: 67 additions & 24 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -1,25 +1,68 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
cff-version: "1.2.0"
authors:
- name: Giancarlo Mattia
orcid: 0000-0003-1454-6226
- name: Daniele Crocco
orcid: 0009-0001-4284-9446
- name: David Melon Fuksman
orcid: 0000-0002-1697-6433
- name: Matteo Bugli
orcid: 0000-0002-7834-0422
- name: Vittoria Berta
orcid: 0000-0001-6305-6931
- name: Eleonora Puzzoni
orcid: 0009-0009-5314-348X
- name: Andrea Mignone
orcid: 0000-0002-8352-6635
- name: Bhargav Vaidya
orcid: 0000-0001-5424-0059

title: 'PyPLUTO: a data analysis Python package for the PLUTO code'
version: 1.0.0
doi: 10.48550/arXiv.2501.09748
date-released: 2025-12-17
url: "https://github.com/GiMattia/PyPLUTO"
- family-names: Mattia
given-names: Giancarlo
orcid: "https://orcid.org/0000-0003-1454-6226"
- family-names: Crocco
given-names: Daniele
orcid: "https://orcid.org/0009-0001-4284-9446"
- family-names: Melon Fuksman
given-names: David
orcid: "https://orcid.org/0000-0002-1697-6433"
- family-names: Bugli
given-names: Matteo
orcid: "https://orcid.org/0000-0002-7834-0422"
- family-names: Berta
given-names: Vittoria
orcid: "https://orcid.org/0000-0001-6305-6931"
- family-names: Puzzoni
given-names: Eleonora
orcid: "https://orcid.org/0009-0009-5314-348X"
- family-names: Mignone
given-names: Andrea
orcid: "https://orcid.org/0000-0002-8352-6635"
- family-names: Vaidya
given-names: Bhargav
orcid: "https://orcid.org/0000-0001-5424-0059"
doi: 10.5281/zenodo.17137196
message: If you use this software, please cite our article in the
Journal of Open Source Software.
preferred-citation:
authors:
- family-names: Mattia
given-names: Giancarlo
orcid: "https://orcid.org/0000-0003-1454-6226"
- family-names: Crocco
given-names: Daniele
orcid: "https://orcid.org/0009-0001-4284-9446"
- family-names: Melon Fuksman
given-names: David
orcid: "https://orcid.org/0000-0002-1697-6433"
- family-names: Bugli
given-names: Matteo
orcid: "https://orcid.org/0000-0002-7834-0422"
- family-names: Berta
given-names: Vittoria
orcid: "https://orcid.org/0000-0001-6305-6931"
- family-names: Puzzoni
given-names: Eleonora
orcid: "https://orcid.org/0009-0009-5314-348X"
- family-names: Mignone
given-names: Andrea
orcid: "https://orcid.org/0000-0002-8352-6635"
- family-names: Vaidya
given-names: Bhargav
orcid: "https://orcid.org/0000-0001-5424-0059"
date-published: 2025-09-17
doi: 10.21105/joss.08448
issn: 2475-9066
issue: 113
journal: Journal of Open Source Software
publisher:
name: Open Journals
start: 8448
title: "PyPLUTO: a data analysis Python package for the PLUTO code"
type: article
url: "https://joss.theoj.org/papers/10.21105/joss.08448"
volume: 10
title: "PyPLUTO: a data analysis Python package for the PLUTO code"
Binary file not shown.
Binary file not shown.
Binary file modified Docs/Figures/pluto_ot_full.mp4
Binary file not shown.
Binary file modified Docs/Figures/pluto_ot_gui.mp4
Binary file not shown.
Binary file modified Docs/Figures/pluto_sod_full.mp4
Binary file not shown.
Binary file modified Docs/Figures/pluto_sod_gui.mp4
Binary file not shown.
2 changes: 1 addition & 1 deletion Docs/Figures/test_gui_ot.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def postprocess_video():
"-t",
"23",
"-vf",
"crop=1180:750:40:47",
"crop=1185:750:50:50",
"-c:a",
"copy",
"pluto_ot_gui.mp4",
Expand Down
2 changes: 1 addition & 1 deletion Docs/Figures/test_gui_sod.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def postprocess_video():
"-t",
"18",
"-vf",
"crop=1180:750:40:47",
"crop=1185:750:50:50",
"-c:a",
"copy",
"pluto_sod_gui.mp4",
Expand Down
Binary file modified Docs/source/_static/pluto_ot_gui.mp4
Binary file not shown.
Binary file modified Docs/source/_static/pluto_sod_gui.mp4
Binary file not shown.
2 changes: 1 addition & 1 deletion Examples/test01_sod.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@
# Saving the image and showing the plot in the Examples folder
# (i.e., where the file test01_sod.py is located)
Image.savefig("test01_sod.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test02_ot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test02_ot.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@

# Saving the image and showing the plot
Image.savefig("test02_ot.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test03_rti.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test03_rti.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@

# Saving the image and showing the plots
Image.savefig("test03_rti.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test04_rotor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test04_rotor.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,4 @@

# Saving the image and showing the plots
Image.savefig("test04_rotor.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test05_fieldloop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test05_fieldloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,4 @@

# Saving the image and showing the plots
Image.savefig("test05_fieldloop.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test06_diskplanet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test06_diskplanet.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@

# Saving the image and showing the plots
Image.savefig("test06_diskplanet.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test07_khi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test07_khi.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,4 @@

# Saving the image and showing the plots
Image.savefig("test07_khi.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test08_torus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test08_torus.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@

# Saving the image and showing the plots
Image.savefig("test08_torus.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test09_blast.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test09_blast.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@ def plot_frame(Data, ax_idx: int, time_label: str):

# Saving and showing
Image.savefig("test09_blast.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test11_xpoint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test11_xpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,4 @@ def compute_gamma(dp):

# --- Save and show ---
Image.savefig("test11_xpoint.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test12_riemannlp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test12_riemannlp.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@ class simultaneously and how to produce a scatter plot on a omplex axes

# Saving the image and showing the plot
Image.savefig("test12_riemannlp.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
Binary file modified Examples/test13_flowpastcyl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion Examples/test13_flowpastcyl.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@

# Save and show the figure
Image.savefig("test13_flowpastcyl.png", script_relative=True)
pyPLUTO.show()
# pyPLUTO.show()
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,13 @@
| --- | --- |
| Package | [![Project Status: Active](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) ![Python Versions](https://img.shields.io/badge/Python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-3776AB.svg?style=flat&logo=python&logoColor=white) ![GitHub release](https://img.shields.io/github/v/release/GiMattia/PyPLUTO?include_prereleases&label=Github%20Release) [![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause) |
| Tests | [![Windows Tests](https://github.com/GiMattia/PyPLUTO/actions/workflows/test_windows.yml/badge.svg)](https://github.com/GiMattia/PyPLUTO/actions/workflows/test_windows.yml) [![MacOS Tests](https://github.com/GiMattia/PyPLUTO/actions/workflows/test_macos.yml/badge.svg)](https://github.com/GiMattia/PyPLUTO/actions/workflows/test_macos.yml) [![Linux Tests](https://github.com/GiMattia/PyPLUTO/actions/workflows/test_linux.yml/badge.svg)](https://github.com/GiMattia/PyPLUTO/actions/workflows/test_linux.yml) ![Coverage Report](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/GiMattia/384b1f3a3a3b74cdbd65c4e3dce0632f/raw/pytest-coverage-comment__main.json) |
| Style | [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com//GiMattia/PyPLUTO/actions/workflows/pre-commit.yml) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) ![Pylint](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/GiMattia/8fc3a521f1c5e59e41eb16d1197bf8c8/raw/pylint-score.json) ![Mypy](https://img.shields.io/badge/type_checking-mypy-brightgreen) |
| Distribution | [![Arxiv](https://img.shields.io/badge/arXiv-2501.09748-8F1515?style=flat&logo=arxiv&logoColor=red)](https://doi.org/10.48550/arXiv.2501.09748) [![Documentation](https://readthedocs.org/projects/pypluto/badge/?version=latest)](https://pypluto.readthedocs.io/en/latest/?badge=latest) |
| Style | [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com//GiMattia/PyPLUTO/actions/workflows/pre-commit.yml) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) ![Pylint](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/GiMattia/8fc3a521f1c5e59e41eb16d1197bf8c8/raw/pylint-score.json) ![Mypy](https://img.shields.io/badge/type_checking-mypy-brightgreen) [![Documentation](https://readthedocs.org/projects/pypluto/badge/?version=latest)](https://pypluto.readthedocs.io/en/latest/?badge=latest) |
| Distribution | [![DOI](https://joss.theoj.org/papers/10.21105/joss.08448/status.svg)](https://doi.org/10.21105/joss.08448) [![Arxiv](https://img.shields.io/badge/arXiv-2501.09748-8F1515?style=flat&logo=arxiv&logoColor=red)](https://doi.org/10.48550/arXiv.2501.09748) [![Zenodo](https://zenodo.org/badge/DOI/10.5281/zenodo.17137196.svg)](https://doi.org/10.5281/zenodo.17137196) |

<!-- ![Doc Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/GiMattia/cc212934fc58b93ddebda8c669dbb171/raw/interrogate-badge.svg) -->

<!-- ![PyPI](https://img.shields.io/pypi/v/PyPLUTO) -->
<!-- ![Conda](https://img.shields.io/badge/conda-available-brightgreen) -->
<!-- ![Zenodo](https://img.shields.io/badge/zenodo-DATA-brightgreen) -->
<!-- [![DOI](https://joss.theoj.org/papers/.../status.svg)](https://doi.org/...) -->



PyPLUTO is a Python library which loads and plots the data obtain from the
PLUTO code simulations.
Expand Down
61 changes: 61 additions & 0 deletions Tests/0test_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import subprocess
from pathlib import Path

import pytest
from PIL import Image, ImageChops

EXAMPLES_DIR = (Path(__file__).parent / "../Examples").resolve()
REFERENCE_DIR = (Path(__file__).parent / "Ref_figs").resolve()


def list_example_scripts():
"""Return a list of Python scripts in ../Examples."""
scripts = sorted(EXAMPLES_DIR.glob("*.py"))
if not scripts:
pytest.skip("No example scripts found in ../Examples")
return scripts


def run_example(script: Path):
"""Run a single Python example script."""
subprocess.run(["python", str(script)], check=True)


def images_identical(img1_path, img2_path) -> bool:
"""Return True if two images are pixel-identical."""
with Image.open(img1_path) as img1, Image.open(img2_path) as img2:
if img1.size != img2.size or img1.mode != img2.mode:
return False
diff = ImageChops.difference(img1, img2)
return diff.getbbox() is None


@pytest.mark.parametrize("script", list_example_scripts())
def test_example(script):
"""
Run one example script and compare its generated images
with the reference ones in the current directory.
Each example appears as a separate pytest test.
"""
run_example(script)

generated_images = sorted(EXAMPLES_DIR.glob("*.png"))
reference_images = sorted(REFERENCE_DIR.glob("*.png"))

assert generated_images, f"No images generated by {script.name}"
assert reference_images, "No reference images found in current directory"
assert len(generated_images) == len(reference_images), (
f"{script.name}: different number of images "
f"({len(generated_images)} generated vs {len(reference_images)} reference)"
)

mismatches = []
for gen_img, ref_img in zip(
generated_images, reference_images, strict=False
):
if not images_identical(gen_img, ref_img):
mismatches.append(gen_img.name)

assert (
not mismatches
), f"{script.name}: mismatched images {', '.join(mismatches)}"
Binary file modified Tests/Ref_figs/test01_sod.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tests/Ref_figs/test02_ot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tests/Ref_figs/test03_rti.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tests/Ref_figs/test05_fieldloop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tests/Ref_figs/test07_khi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tests/Ref_figs/test08_torus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tests/Ref_figs/test09_blast.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tests/Ref_figs/test11_xpoint.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Tests/Ref_figs/test12_riemannlp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed Tests/test01_sod.png
Binary file not shown.
Binary file removed Tests/test02_ot.png
Binary file not shown.
Binary file removed Tests/test03_rti.png
Binary file not shown.
Binary file removed Tests/test04_rotor.png
Binary file not shown.
Binary file removed Tests/test05_fieldloop.png
Binary file not shown.
Binary file removed Tests/test06_diskplanet.png
Diff not rendered.
Binary file removed Tests/test07_khi.png
Diff not rendered.
Binary file removed Tests/test08_torus.png
Diff not rendered.
Binary file removed Tests/test09_blast.png
Diff not rendered.
Binary file removed Tests/test10_riemann2d.gif
Diff not rendered.
Binary file removed Tests/test11_xpoint.png
Diff not rendered.
Binary file removed Tests/test12_riemannlp.png
Diff not rendered.
Binary file removed Tests/test13_flowpastcyl.png
Diff not rendered.
Loading