osiris-utils 1.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. osiris_utils-1.2.3/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  2. osiris_utils-1.2.3/.github/workflows/ci.yml +56 -0
  3. osiris_utils-1.2.3/.github/workflows/publish.yml +54 -0
  4. osiris_utils-1.2.3/.gitignore +7 -0
  5. osiris_utils-1.2.3/.pre-commit-config.yaml +7 -0
  6. osiris_utils-1.2.3/.readthedocs.yaml +27 -0
  7. osiris_utils-1.2.3/CONTRIBUTING.rst +277 -0
  8. osiris_utils-1.2.3/LICENSE.txt +21 -0
  9. osiris_utils-1.2.3/PKG-INFO +166 -0
  10. osiris_utils-1.2.3/README.rst +123 -0
  11. osiris_utils-1.2.3/benchmarks/benchmark_hdf5_io.py +46 -0
  12. osiris_utils-1.2.3/benchmarks/benchmark_load_all.py +54 -0
  13. osiris_utils-1.2.3/docs/Makefile +20 -0
  14. osiris_utils-1.2.3/docs/make.bat +35 -0
  15. osiris_utils-1.2.3/docs/source/_static/Imagem1.png +0 -0
  16. osiris_utils-1.2.3/docs/source/_static/custom.css +69 -0
  17. osiris_utils-1.2.3/docs/source/_static/quick_start_ez.png +0 -0
  18. osiris_utils-1.2.3/docs/source/api/decks.rst +48 -0
  19. osiris_utils-1.2.3/docs/source/api/postprocess.rst +380 -0
  20. osiris_utils-1.2.3/docs/source/api/sim_diag.rst +264 -0
  21. osiris_utils-1.2.3/docs/source/api/utilities.rst +254 -0
  22. osiris_utils-1.2.3/docs/source/conf.py +208 -0
  23. osiris_utils-1.2.3/docs/source/contrib.rst +1 -0
  24. osiris_utils-1.2.3/docs/source/examples/example_Derivatives.md +78 -0
  25. osiris_utils-1.2.3/docs/source/examples/example_FFT.md +152 -0
  26. osiris_utils-1.2.3/docs/source/examples/example_InputDeck.md +149 -0
  27. osiris_utils-1.2.3/docs/source/examples/example_Simulation_Diagnostic.md +213 -0
  28. osiris_utils-1.2.3/docs/source/examples/quick_start.md +51 -0
  29. osiris_utils-1.2.3/docs/source/examples.rst +14 -0
  30. osiris_utils-1.2.3/docs/source/index.rst +43 -0
  31. osiris_utils-1.2.3/examples/edited-deck.1d +107 -0
  32. osiris_utils-1.2.3/examples/example_Derivatives.ipynb +206 -0
  33. osiris_utils-1.2.3/examples/example_FFT.ipynb +272 -0
  34. osiris_utils-1.2.3/examples/example_InputDeck.ipynb +267 -0
  35. osiris_utils-1.2.3/examples/example_Simulation_Diagnostic.ipynb +389 -0
  36. osiris_utils-1.2.3/examples/example_data/HIST/fld_ene +15 -0
  37. osiris_utils-1.2.3/examples/example_data/HIST/par01_ene +15 -0
  38. osiris_utils-1.2.3/examples/example_data/HIST/par01_temp +14 -0
  39. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000000.h5 +0 -0
  40. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000001.h5 +0 -0
  41. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000002.h5 +0 -0
  42. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000003.h5 +0 -0
  43. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000004.h5 +0 -0
  44. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000005.h5 +0 -0
  45. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000006.h5 +0 -0
  46. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000007.h5 +0 -0
  47. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000008.h5 +0 -0
  48. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000009.h5 +0 -0
  49. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000010.h5 +0 -0
  50. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000011.h5 +0 -0
  51. osiris_utils-1.2.3/examples/example_data/MS/DENSITY/electrons/charge/charge-electrons-000012.h5 +0 -0
  52. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000000.h5 +0 -0
  53. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000001.h5 +0 -0
  54. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000002.h5 +0 -0
  55. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000003.h5 +0 -0
  56. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000004.h5 +0 -0
  57. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000005.h5 +0 -0
  58. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000006.h5 +0 -0
  59. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000007.h5 +0 -0
  60. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000008.h5 +0 -0
  61. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000009.h5 +0 -0
  62. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000010.h5 +0 -0
  63. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000011.h5 +0 -0
  64. osiris_utils-1.2.3/examples/example_data/MS/FLD/e3/e3-000012.h5 +0 -0
  65. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000000.h5 +0 -0
  66. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000001.h5 +0 -0
  67. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000002.h5 +0 -0
  68. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000003.h5 +0 -0
  69. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000004.h5 +0 -0
  70. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000005.h5 +0 -0
  71. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000006.h5 +0 -0
  72. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000007.h5 +0 -0
  73. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000008.h5 +0 -0
  74. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000009.h5 +0 -0
  75. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000010.h5 +0 -0
  76. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000011.h5 +0 -0
  77. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/T11/T11-electrons-000012.h5 +0 -0
  78. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000000.h5 +0 -0
  79. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000001.h5 +0 -0
  80. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000002.h5 +0 -0
  81. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000003.h5 +0 -0
  82. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000004.h5 +0 -0
  83. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000005.h5 +0 -0
  84. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000006.h5 +0 -0
  85. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000007.h5 +0 -0
  86. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000008.h5 +0 -0
  87. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000009.h5 +0 -0
  88. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000010.h5 +0 -0
  89. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000011.h5 +0 -0
  90. osiris_utils-1.2.3/examples/example_data/MS/UDIST/electrons/vfl1/vfl1-electrons-000012.h5 +0 -0
  91. osiris_utils-1.2.3/examples/example_data/MS/run-info +132 -0
  92. osiris_utils-1.2.3/examples/example_data/TIMINGS/timings-final +31 -0
  93. osiris_utils-1.2.3/examples/example_data/run-info +132 -0
  94. osiris_utils-1.2.3/examples/example_data/thermal.1d +108 -0
  95. osiris_utils-1.2.3/examples/quick_start.ipynb +112 -0
  96. osiris_utils-1.2.3/examples/quick_start.py +41 -0
  97. osiris_utils-1.2.3/osiris_utils/__init__.py +96 -0
  98. osiris_utils-1.2.3/osiris_utils/cli/__init__.py +6 -0
  99. osiris_utils-1.2.3/osiris_utils/cli/__main__.py +85 -0
  100. osiris_utils-1.2.3/osiris_utils/cli/export.py +199 -0
  101. osiris_utils-1.2.3/osiris_utils/cli/info.py +156 -0
  102. osiris_utils-1.2.3/osiris_utils/cli/plot.py +189 -0
  103. osiris_utils-1.2.3/osiris_utils/cli/validate.py +247 -0
  104. osiris_utils-1.2.3/osiris_utils/data/__init__.py +15 -0
  105. osiris_utils-1.2.3/osiris_utils/data/data.py +695 -0
  106. osiris_utils-1.2.3/osiris_utils/data/diagnostic.py +1115 -0
  107. osiris_utils-1.2.3/osiris_utils/data/simulation.py +236 -0
  108. osiris_utils-1.2.3/osiris_utils/decks/__init__.py +4 -0
  109. osiris_utils-1.2.3/osiris_utils/decks/decks.py +347 -0
  110. osiris_utils-1.2.3/osiris_utils/decks/species.py +58 -0
  111. osiris_utils-1.2.3/osiris_utils/postprocessing/__init__.py +28 -0
  112. osiris_utils-1.2.3/osiris_utils/postprocessing/derivative.py +557 -0
  113. osiris_utils-1.2.3/osiris_utils/postprocessing/fft.py +489 -0
  114. osiris_utils-1.2.3/osiris_utils/postprocessing/field_centering.py +212 -0
  115. osiris_utils-1.2.3/osiris_utils/postprocessing/heatflux_correction.py +229 -0
  116. osiris_utils-1.2.3/osiris_utils/postprocessing/mft.py +218 -0
  117. osiris_utils-1.2.3/osiris_utils/postprocessing/postprocess.py +62 -0
  118. osiris_utils-1.2.3/osiris_utils/postprocessing/pressure_correction.py +164 -0
  119. osiris_utils-1.2.3/osiris_utils/utils.py +297 -0
  120. osiris_utils-1.2.3/osiris_utils/vis/__init__.py +3 -0
  121. osiris_utils-1.2.3/osiris_utils/vis/plot3d.py +150 -0
  122. osiris_utils-1.2.3/osiris_utils.egg-info/PKG-INFO +166 -0
  123. osiris_utils-1.2.3/osiris_utils.egg-info/SOURCES.txt +142 -0
  124. osiris_utils-1.2.3/osiris_utils.egg-info/dependency_links.txt +1 -0
  125. osiris_utils-1.2.3/osiris_utils.egg-info/entry_points.txt +2 -0
  126. osiris_utils-1.2.3/osiris_utils.egg-info/requires.txt +22 -0
  127. osiris_utils-1.2.3/osiris_utils.egg-info/top_level.txt +5 -0
  128. osiris_utils-1.2.3/pyproject.toml +117 -0
  129. osiris_utils-1.2.3/requirements-dev.txt +10 -0
  130. osiris_utils-1.2.3/requirements.txt +6 -0
  131. osiris_utils-1.2.3/setup.cfg +4 -0
  132. osiris_utils-1.2.3/tests/__init__.py +0 -0
  133. osiris_utils-1.2.3/tests/test_cli.py +161 -0
  134. osiris_utils-1.2.3/tests/test_data.py +83 -0
  135. osiris_utils-1.2.3/tests/test_decks.py +100 -0
  136. osiris_utils-1.2.3/tests/test_derivative_slicing.py +104 -0
  137. osiris_utils-1.2.3/tests/test_derivatives.py +234 -0
  138. osiris_utils-1.2.3/tests/test_imports.py +4 -0
  139. osiris_utils-1.2.3/tests/test_performance.py +110 -0
  140. osiris_utils-1.2.3/tests/test_postprocessing.py +120 -0
  141. osiris_utils-1.2.3/tests/test_simulation.py +87 -0
  142. osiris_utils-1.2.3/tests/test_utils.py +167 -0
  143. osiris_utils-1.2.3/tests/test_version.py +6 -0
  144. osiris_utils-1.2.3/tests/test_vis.py +108 -0
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear and concise description of what the bug is.
12
+
13
+ **To Reproduce**
14
+ Steps to reproduce the behavior:
15
+ 1. Go to '...'
16
+ 2. Click on '....'
17
+ 3. Scroll down to '....'
18
+ 4. See error
19
+
20
+ **Expected behavior**
21
+ A clear and concise description of what you expected to happen.
22
+
23
+ **Screenshots**
24
+ If applicable, add screenshots to help explain your problem.
25
+
26
+ **Desktop (please complete the following information):**
27
+ - OS: [e.g. iOS]
28
+ - Browser [e.g. chrome, safari]
29
+ - Version [e.g. 22]
30
+
31
+ **Smartphone (please complete the following information):**
32
+ - Device: [e.g. iPhone6]
33
+ - OS: [e.g. iOS8.1]
34
+ - Browser [e.g. stock browser, safari]
35
+ - Version [e.g. 22]
36
+
37
+ **Additional context**
38
+ Add any other context about the problem here.
@@ -0,0 +1,56 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ['3.10', '3.11', '3.12']
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v4
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+
23
+ - name: Install dependencies
24
+ run: |
25
+ python -m pip install --upgrade pip
26
+ # install the package and dev extras in one shot
27
+ pip install .[dev]
28
+
29
+ - name: Run pre-commit
30
+ uses: pre-commit/action@v3.0.1
31
+
32
+ - name: Run test suite
33
+ run: |
34
+ pytest --cov=osiris_utils --cov-report=term-missing
35
+
36
+ - name: Upload coverage reports to Codecov
37
+ uses: codecov/codecov-action@v5
38
+ with:
39
+ token: ${{ secrets.CODECOV_TOKEN }}
40
+ docs:
41
+ runs-on: ubuntu-latest
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+
45
+ - uses: actions/setup-python@v4
46
+ with: { python-version: '3.11' }
47
+
48
+ - name: Install docs dependencies
49
+ run: |
50
+ python -m pip install --upgrade pip
51
+ # dev + docs extras include sphinx, myst‑nb, sphinx_copybutton, nbsphinx, …
52
+ pip install -e '.[dev,docs]'
53
+
54
+ - name: Build docs
55
+ run: |
56
+ make -C docs html
@@ -0,0 +1,54 @@
1
+ name: Publish Python 🐍 distribution 📦 to PyPI
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ build:
7
+ name: Build distribution 📦
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ with:
13
+ persist-credentials: false
14
+ - name: Set up Python
15
+ uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ - name: Install pypa/build
19
+ run: >-
20
+ python3 -m
21
+ pip install
22
+ build
23
+ --user
24
+ - name: Build a binary wheel and a source tarball
25
+ run: python3 -m build
26
+ - name: Store the distribution packages
27
+ uses: actions/upload-artifact@v4
28
+ with:
29
+ name: python-package-distributions
30
+ path: dist/
31
+ publish-to-pypi:
32
+ name: >-
33
+ Publish Python 🐍 distribution 📦 to PyPI
34
+ if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
35
+ needs:
36
+ - build
37
+ runs-on: ubuntu-latest
38
+ environment:
39
+ name: pypi
40
+ url: https://pypi.org/p/osiris-utils
41
+ permissions:
42
+ id-token: write # IMPORTANT: mandatory for trusted publishing
43
+ steps:
44
+ - name: Download all the dists
45
+ uses: actions/download-artifact@v4
46
+ with:
47
+ name: python-package-distributions
48
+ path: dist/
49
+ - name: Publish distribution 📦 to PyPI
50
+ uses: pypa/gh-action-pypi-publish@release/v1
51
+ with:
52
+ user: __token__
53
+ password: ${{ secrets.PYPI_TOKEN }}
54
+ packages: dist/*
@@ -0,0 +1,7 @@
1
+ build/
2
+ osiris_utils.egg-info/
3
+ osiris_utils/__pycache__/
4
+ *.pyc
5
+ .DS_Store
6
+ dist/
7
+ osiris_utils/.DS_Store
@@ -0,0 +1,7 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.4.8 # pin the latest stable
4
+ hooks:
5
+ - id: ruff
6
+ args: ["--fix", "--select", "F,E,I,W,B,C90"] # auto‑apply safe fixes (TCH rules disabled here)
7
+ - id: ruff-format
@@ -0,0 +1,27 @@
1
+ # .readthedocs.yaml
2
+ # Read the Docs configuration file
3
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4
+
5
+ # Required
6
+ version: 2
7
+
8
+ # Set the OS, Python version and other tools you might need
9
+ build:
10
+ os: ubuntu-24.04
11
+ tools:
12
+ python: "3.12"
13
+
14
+ # Build documentation in the "docs/" directory with Sphinx
15
+ sphinx:
16
+ configuration: docs/source/conf.py
17
+ builder: html
18
+ fail_on_warning: true
19
+
20
+ # Optionally build your docs in additional formats such as PDF and ePub
21
+ # formats:
22
+ # - pdf
23
+
24
+
25
+ python:
26
+ install:
27
+ - requirements: requirements-dev.txt
@@ -0,0 +1,277 @@
1
+ Contributing to OSIRIS Utils
2
+ ============================
3
+
4
+ Thank you for contributing!
5
+
6
+ This document contains guidelines (not strict rules) for contributing to
7
+ **osiris_utils**. If something here doesn't fit your use case, use your best
8
+ judgment — and feel free to open an issue to discuss improvements.
9
+
10
+ Reporting Bugs
11
+ ~~~~~~~~~~~~~~
12
+
13
+ How do I submit a good bug report?
14
+ ----------------------------------
15
+
16
+ Bugs are tracked as GitHub issues:
17
+ `https://github.com/joaopedrobiu6/osiris_utils/issues/`
18
+
19
+ To help maintainers reproduce (and fix) the problem quickly, please include:
20
+
21
+ - **A clear and descriptive title**.
22
+ - **Exact steps to reproduce**, in order.
23
+ - **A minimal example** (copy/pasteable snippet) whenever possible.
24
+ - **What you observed**, including the full traceback or error message.
25
+ - **What you expected to happen**, and why.
26
+ - **Relevant context**, such as:
27
+ - OS / Python version
28
+ - osiris_utils version or commit hash
29
+ - input deck details if relevant
30
+ - **Plots** if the bug is about “wrong-looking” physics or unexpected results.
31
+
32
+ If the bug involves post-processing or arithmetic with diagnostics, it helps a
33
+ lot to include a small snippet like:
34
+
35
+ .. code-block:: python
36
+
37
+ import osiris_utils as ou
38
+ sim = ou.Simulation("path/to/input_deck.txt")
39
+
40
+ # reproduce here
41
+ diag = sim["electrons"]["n"]
42
+ out = diag[0]
43
+ print(out.shape, out.dtype)
44
+
45
+ Adding Post-Processing routines
46
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47
+
48
+ Post-processing routines in **osiris_utils** are implemented as wrappers around
49
+ the existing ``Simulation`` / ``Diagnostic`` interface.
50
+
51
+ **Core idea**
52
+
53
+ - Indexing must behave consistently across all diagnostics:
54
+
55
+ - ``diag[i]`` returns a single timestep ``np.ndarray``
56
+ - ``diag[i:j]`` returns a stacked array over time (shape ``(t, ...)``)
57
+ - ``diag[i, :, 10:20]`` must work (tuple indexing with spatial slicing)
58
+
59
+ - Post-processed diagnostics should remain compatible with diagnostic operations:
60
+
61
+ - ``diag + other``, ``diag * other``, etc.
62
+
63
+ - Spatial slicing should be efficient when possible: pass the ``data_slice`` down
64
+ to the base diagnostic (so HDF5 can load only the requested region).
65
+
66
+ The recommended structure is:
67
+
68
+ 1) ``NameOfPostProcess_Simulation`` (simulation wrapper)
69
+ 2) ``NameOfPostProcess_Diagnostic`` (diagnostic wrapper)
70
+ 3) ``NameOfPostProcess_Species_Handler`` (species wrapper)
71
+
72
+ 1) Simulation-level wrapper: ``NameOfPostProcess_Simulation``
73
+ -------------------------------------------------------------
74
+
75
+ Implement a wrapper class that behaves like a ``Simulation``.
76
+
77
+ **Requirements**
78
+
79
+ - Inherits from ``PostProcess``
80
+ - Stores the wrapped simulation in ``self._simulation``
81
+ - Implements ``__getitem__`` that:
82
+
83
+ - returns a *species handler* when ``key`` is a species name
84
+ - returns a *post-processed diagnostic* when ``key`` is a quantity name
85
+
86
+ - Uses caches (dicts) to avoid rebuilding wrappers repeatedly
87
+
88
+ Typical skeleton:
89
+
90
+ .. code-block:: python
91
+
92
+ class MyPost_Simulation(PostProcess):
93
+ def __init__(self, simulation: Simulation, ...):
94
+ super().__init__("MyPost", simulation)
95
+ self._computed = {}
96
+ self._species_handler = {}
97
+
98
+ def __getitem__(self, key):
99
+ if key in self._simulation._species:
100
+ if key not in self._species_handler:
101
+ self._species_handler[key] = MyPost_Species_Handler(self._simulation[key], ...)
102
+ return self._species_handler[key]
103
+
104
+ if key not in self._computed:
105
+ self._computed[key] = MyPost_Diagnostic(self._simulation[key], ...)
106
+ return self._computed[key]
107
+
108
+ **Note on “chainable” post-processes**
109
+
110
+ Some post-processes (e.g. derivatives) should be chainable:
111
+
112
+ .. code-block:: python
113
+
114
+ d1 = ou.Derivative_Simulation(sim, "x1")
115
+ d2 = ou.Derivative_Simulation(d1, "t")
116
+
117
+ If your post-process needs to be chainable, avoid hard checks like:
118
+
119
+ - ``isinstance(simulation, Simulation)``
120
+
121
+ Instead, validate by capability:
122
+
123
+ - has ``__getitem__``
124
+ - has ``species`` or ``_species``
125
+
126
+ 2) Diagnostic-level wrapper: ``NameOfPostProcess_Diagnostic``
127
+ -------------------------------------------------------------
128
+
129
+ This class performs the actual post-processing while still behaving like a
130
+ ``Diagnostic``.
131
+
132
+ **Requirements**
133
+
134
+ - Inherits from ``Diagnostic``
135
+ - Wraps a base diagnostic in ``self._diag``
136
+ - Copies relevant metadata (e.g. ``_dt``, ``_dx``, ``_dim``, ``_maxiter``, etc.)
137
+ - Implements:
138
+
139
+ - ``load_all()``: eager computation into ``self._data`` (shape ``(t, ...)``)
140
+ - ``_frame(index, data_slice=None)``: lazy single-timestep computation
141
+
142
+ **Important:** you generally do **not** need to implement ``__getitem__``.
143
+ The base ``Diagnostic.__getitem__`` already supports:
144
+
145
+ - int indexing
146
+ - time slices
147
+ - tuple indexing ``(time_index, spatial_slices...)``
148
+
149
+ and it calls:
150
+
151
+ - ``self._frame(time_index, data_slice=data_slice)``
152
+
153
+ So the minimal contract is:
154
+
155
+ .. code-block:: python
156
+
157
+ class MyPost_Diagnostic(Diagnostic):
158
+ def load_all(self) -> np.ndarray:
159
+ ...
160
+
161
+ def _frame(self, index: int, data_slice: tuple | None = None) -> np.ndarray:
162
+ ...
163
+
164
+ **Shape conventions**
165
+
166
+ - ``load_all()`` returns ``(t, x, y, z)`` (or lower dimensions depending on ``dim``)
167
+ - ``_frame()`` returns one timestep ``(x, y, z)`` (or lower dimensions)
168
+
169
+ **Slicing support**
170
+
171
+ If your base diagnostic supports efficient disk slicing, pass it through:
172
+
173
+ .. code-block:: python
174
+
175
+ f = self._diag._frame(index, data_slice=data_slice)
176
+
177
+ That ensures ``diag[10, :, 100:200]`` loads only the requested region.
178
+
179
+ 3) Species handler: ``NameOfPostProcess_Species_Handler``
180
+ ---------------------------------------------------------
181
+
182
+ Species handlers are thin wrappers for dictionary-like access.
183
+
184
+ **Requirements**
185
+
186
+ - Does **not** inherit from anything
187
+ - Stores the wrapped species handler in ``self._species_handler``
188
+ - Lazily builds post-processed diagnostics per key and caches them
189
+
190
+ Example:
191
+
192
+ .. code-block:: python
193
+
194
+ class MyPost_Species_Handler:
195
+ def __init__(self, species_handler, ...):
196
+ self._species_handler = species_handler
197
+ self._computed = {}
198
+
199
+ def __getitem__(self, key):
200
+ if key not in self._computed:
201
+ self._computed[key] = MyPost_Diagnostic(self._species_handler[key], ...)
202
+ return self._computed[key]
203
+
204
+ Rules and common pitfalls
205
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
206
+
207
+ - **Indexing should return only** ``np.ndarray``.
208
+ If you need multiple arrays (e.g., MFT average + fluctuations), create
209
+ auxiliary diagnostic classes and expose them via an additional layer:
210
+
211
+ .. code-block:: python
212
+
213
+ mft = ou.MFT_Simulation(sim, axis=1)["e3"]
214
+ avg = mft["avg"][0]
215
+ flt = mft["delta"][0]
216
+
217
+ - **Avoid overriding ``Diagnostic.__getitem__``**.
218
+ If you override it, you must re-implement tuple slicing and time slicing
219
+ correctly, or indexing will break in subtle ways.
220
+
221
+ - **Implement ``_frame(index, data_slice=None)``** for lazy access.
222
+ This is what enables:
223
+
224
+ - tuple indexing and spatial slicing
225
+ - arithmetic operation diagnostics (``diag + other``)
226
+ - consistent interaction with ``load_all``
227
+
228
+ - **Time FFT cannot be computed from a single timestep**.
229
+ If your transform includes axis 0 (time), you must require ``load_all()``
230
+ (or implement a different algorithm explicitly designed for streaming).
231
+ A “per-timestep” FFT can only work for *spatial* axes.
232
+
233
+ Consistent usage examples
234
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
235
+
236
+ .. code-block:: python
237
+
238
+ import osiris_utils as ou
239
+
240
+ sim = ou.Simulation("path/to/input_deck.txt")
241
+
242
+ pp = MyPost_Simulation(sim, ...)
243
+
244
+ # Non-species diagnostic
245
+ arr = pp["e3"][10]
246
+
247
+ # Species diagnostic
248
+ arr = pp["electrons"]["n"][10]
249
+
250
+ # Spatial slicing
251
+ arr = pp["e3"][10, :, 100:200]
252
+ arr = pp["electrons"]["n"][0:10, :, 50:]
253
+
254
+ Pull Requests
255
+ ~~~~~~~~~~~~~
256
+
257
+ General expectations for PRs:
258
+
259
+ - Keep PRs focused: one feature/fix per PR if possible.
260
+ - Include an explanation of *why* the change is needed (not only what changed).
261
+ - If you introduce a new post-process:
262
+ - follow the structure described above
263
+ - include at least a small usage example
264
+ - add/update documentation if user-facing behavior changes
265
+ - If the PR changes physics / normalization / conventions, include a plot or a
266
+ small validation test case.
267
+
268
+ If you're unsure about design choices (especially around performance or API
269
+ consistency), open an issue first to discuss.
270
+
271
+ Contact
272
+ ~~~~~~~
273
+
274
+ If you need help, open an issue or contact João Biu via email:
275
+ ``joaopedrofbiu@tecnico.ulisboa.pt``
276
+ or GitHub:
277
+ ``https://github.com/joaopedrobiu6``
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 João Biu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: osiris_utils
3
+ Version: 1.2.3
4
+ Summary: Utilities to manipulate and visualise OSIRIS plasma PIC output data
5
+ Author-email: João Pedro Ferreira Biu <joaopedrofbiu@tecnico.ulisboa.pt>
6
+ License: MIT
7
+ Project-URL: Source Code, https://github.com/joaopedrobiu6/osiris_utils
8
+ Project-URL: Issues Tracker, https://github.com/joaopedrobiu6/osiris_utils/issues
9
+ Project-URL: Documentation, https://osiris-utils.readthedocs.io
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Natural Language :: English
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/x-rst
21
+ License-File: LICENSE.txt
22
+ Requires-Dist: numpy>=1.25
23
+ Requires-Dist: matplotlib>=3.8
24
+ Requires-Dist: pandas>=2.0
25
+ Requires-Dist: scipy>=1.11
26
+ Requires-Dist: h5py>=3.10
27
+ Requires-Dist: tqdm>=4.66
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.1; extra == "dev"
30
+ Requires-Dist: pytest-cov; extra == "dev"
31
+ Requires-Dist: pre-commit>=3.7; extra == "dev"
32
+ Requires-Dist: ruff>=0.4; extra == "dev"
33
+ Requires-Dist: types-tqdm; extra == "dev"
34
+ Requires-Dist: types-Pillow; extra == "dev"
35
+ Provides-Extra: docs
36
+ Requires-Dist: sphinx>=8; extra == "docs"
37
+ Requires-Dist: ipykernel; extra == "docs"
38
+ Requires-Dist: myst-parser; extra == "docs"
39
+ Requires-Dist: sphinx-copybutton<=0.5.2; extra == "docs"
40
+ Requires-Dist: sphinx-rtd-theme<3.0.3; extra == "docs"
41
+ Requires-Dist: sphinx-github-style<=1.2.2; extra == "docs"
42
+ Dynamic: license-file
43
+
44
+ OSIRIS_UTILS
45
+ ============
46
+ .. image:: https://raw.githubusercontent.com/joaopedrobiu6/osiris_utils/main/docs/source/_static/Imagem1.png
47
+ :width: 200px
48
+ :align: right
49
+
50
+
51
+ |Pypi|
52
+
53
+ .. image:: https://github.com/joaopedrobiu6/osiris_utils/actions/workflows/ci.yml/badge.svg
54
+ :target: https://github.com/joaopedrobiu6/osiris_utils/actions
55
+ :alt: CI status
56
+
57
+ .. image:: https://codecov.io/gh/joaopedrobiu6/osiris_utils/branch/main/graph/badge.svg
58
+ :target: https://codecov.io/gh/joaopedrobiu6/osiris_utils
59
+ :alt: Coverage
60
+
61
+ .. image:: https://zenodo.org/badge/889119723.svg
62
+ :target: https://doi.org/10.5281/zenodo.17382244
63
+
64
+ This package contains a set of utilities to open and analyze OSIRIS output files, using Python. All the methods implemented are fully integrated with `NumPy`, and use `np.ndarray` as the main data structure.
65
+ High-level functions are provided to manipulate data from OSIRIS, from reading the data of the diagnostics, to making post-processing calculations.
66
+
67
+ All code is written in Python. To contact the dev team, please send an email to João Biu: `joaopedrofbiu@tecnico.ulisboa.pt <mailto:joaopedrofbiu@tecnico.ulisboa.pt>`_.
68
+ The full dev team can be found below in the Authors and Contributors section.
69
+
70
+ How to install it?
71
+ ------------------
72
+
73
+ To install this package, you can use `pip`::
74
+
75
+ pip install osiris_utils
76
+
77
+ To install it from source, you can clone this repository and run (in the folder containing ``setup.py``)::
78
+
79
+ git clone https://github.com/joaopedrobiu6/osiris_utils.git
80
+ pip install .
81
+
82
+ Finally, you can install it in editor mode if you want to contribute to the code::
83
+
84
+ git clone https://github.com/joaopedrobiu6/osiris_utils.git
85
+ pip install -e .
86
+
87
+ Quick-start
88
+ -----------
89
+
90
+ .. image:: https://mybinder.org/badge_logo.svg
91
+ :target: https://mybinder.org/v2/gh/joaopedrobiu6/osiris_utils/main?filepath=examples%2Fquick_start.ipynb
92
+ :alt: Launch quick-start on Binder
93
+
94
+ .. code-block:: bash
95
+
96
+ pip install osiris_utils # from PyPI
97
+ python -m pip install matplotlib # plotting backend (optional)
98
+ git clone https://github.com/joaopedrobiu6/osiris_utils # sample data
99
+ cd osiris_utils
100
+ python examples/quick_start.py examples/example_data/thermal.1d
101
+
102
+ Command-Line Interface
103
+ ----------------------
104
+
105
+ osiris_utils includes a command-line interface for common operations. After installation, the ``osiris`` command becomes available::
106
+
107
+ osiris --version # Check version
108
+ osiris --help # Show available commands
109
+
110
+ **Available Commands:**
111
+
112
+ - ``osiris info`` - Display metadata about OSIRIS files and simulations
113
+ - ``osiris export`` - Convert data to CSV, JSON, or NumPy formats
114
+ - ``osiris plot`` - Create quick visualizations
115
+ - ``osiris validate`` - Check file integrity
116
+
117
+ **Examples:**
118
+
119
+ Show simulation information::
120
+
121
+ osiris info path/to/simulation
122
+ osiris info path/to/file.h5 --brief
123
+
124
+ Export data to different formats::
125
+
126
+ osiris export file.h5 --format csv --output data.csv
127
+ osiris export diagnostic/dir --format npy --output data.npy
128
+
129
+ Generate quick plots::
130
+
131
+ osiris plot file.h5 --save plot.png
132
+ osiris plot file.h5 --save plot.png --title "Ez Field" --cmap viridis
133
+
134
+ Validate simulation data::
135
+
136
+ osiris validate path/to/simulation
137
+ osiris validate path/to/simulation --check-missing
138
+
139
+ For detailed help on any command::
140
+
141
+ osiris <command> --help
142
+
143
+
144
+ Documentation
145
+ -------------
146
+
147
+ The documentation is available at https://osiris-utils.readthedocs.io or via this link: `osiris-utils.readthedocs.io <https://osiris-utils.readthedocs.io>`_.
148
+
149
+ .. |Pypi| image:: https://img.shields.io/pypi/v/osiris-utils
150
+ :target: https://pypi.org/project/osiris-utils/
151
+ :alt: Pypi
152
+
153
+ .. _authors:
154
+
155
+ Author
156
+ ------
157
+
158
+ - João Biu
159
+
160
+ Contributors
161
+ ------------
162
+
163
+ - Diogo Carvalho
164
+ - João Cândido
165
+ - Margarida Pereira
166
+