sdf-xarray 0.4.0__tar.gz → 0.5.0__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.
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/.github/workflows/build_publish.yml +7 -0
- sdf_xarray-0.5.0/.github/workflows/lint.yml +30 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/.github/workflows/tests.yml +7 -1
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/.gitignore +48 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/CONTRIBUTING.md +18 -10
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/PKG-INFO +4 -5
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/README.md +2 -2
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/animation.rst +64 -66
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/getting_started.rst +20 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/key_functionality.rst +55 -2
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/pyproject.toml +10 -10
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/src/sdf_xarray/__init__.py +273 -13
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/src/sdf_xarray/_version.py +3 -3
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/src/sdf_xarray/dataset_accessor.py +53 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/src/sdf_xarray/download.py +3 -2
- sdf_xarray-0.5.0/src/sdf_xarray/plotting.py +567 -0
- sdf_xarray-0.4.0/tests/test_basic.py → sdf_xarray-0.5.0/tests/test_dataset.py +6 -0
- sdf_xarray-0.5.0/tests/test_datatree.py +313 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/tests/test_epoch_dataset_accessor.py +107 -7
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/uv.lock +114 -711
- sdf_xarray-0.4.0/.github/workflows/black.yml +0 -40
- sdf_xarray-0.4.0/.github/workflows/lint.yml +0 -11
- sdf_xarray-0.4.0/src/sdf_xarray/plotting.py +0 -293
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/.gitmodules +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/.readthedocs.yaml +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/BEAM.png +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/CITATION.cff +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/CMakeLists.txt +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/LICENCE +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/PlasmaFAIR.svg +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/.gitignore +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/_static/force_render_dark_xarray_objects.css +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/_templates/custom-class-template.rst +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/_templates/custom-module-template.rst +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/api.rst +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/conf.py +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/contributing.rst +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/index.rst +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/known_issues.rst +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/make.bat +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/docs/unit_conversion.rst +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/src/sdf_xarray/csdf.pxd +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/src/sdf_xarray/sdf_interface.pyx +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/tests/test_cython.py +0 -0
- {sdf_xarray-0.4.0 → sdf_xarray-0.5.0}/tests/test_epoch_dataarray_accessor.py +0 -0
|
@@ -19,6 +19,13 @@ jobs:
|
|
|
19
19
|
fetch-depth: 0
|
|
20
20
|
submodules: "recursive"
|
|
21
21
|
|
|
22
|
+
- name: Cache Zenodo datasets
|
|
23
|
+
uses: actions/cache@v4
|
|
24
|
+
with:
|
|
25
|
+
enableCrossOsArchive: true
|
|
26
|
+
path: ~/.cache/sdf_datasets
|
|
27
|
+
key: sdf-datasets-17991042
|
|
28
|
+
|
|
22
29
|
- name: Setup uv
|
|
23
30
|
id: setup-uv
|
|
24
31
|
uses: astral-sh/setup-uv@v3
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: lint
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
paths:
|
|
6
|
+
- '**.py'
|
|
7
|
+
pull_request:
|
|
8
|
+
paths:
|
|
9
|
+
- '**.py'
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
lint:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
|
|
19
|
+
# Providing 'args' prevents the action from running 'ruff check .'
|
|
20
|
+
# immediately after installing ruff.
|
|
21
|
+
- name: Install Ruff
|
|
22
|
+
uses: astral-sh/ruff-action@v3
|
|
23
|
+
with:
|
|
24
|
+
args: "--version"
|
|
25
|
+
|
|
26
|
+
- name: Check
|
|
27
|
+
run: ruff check --output-format=github src tests
|
|
28
|
+
|
|
29
|
+
- name: Format
|
|
30
|
+
run: ruff format --check --diff src tests
|
|
@@ -8,7 +8,7 @@ jobs:
|
|
|
8
8
|
strategy:
|
|
9
9
|
fail-fast: false
|
|
10
10
|
matrix:
|
|
11
|
-
python-version: ["3.
|
|
11
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
12
12
|
|
|
13
13
|
steps:
|
|
14
14
|
- uses: actions/checkout@v4
|
|
@@ -30,5 +30,11 @@ jobs:
|
|
|
30
30
|
uv python install ${{ matrix.python-version }}
|
|
31
31
|
uv sync --python ${{ matrix.python-version }} --frozen
|
|
32
32
|
|
|
33
|
+
- name: Cache Zenodo datasets
|
|
34
|
+
uses: actions/cache@v4
|
|
35
|
+
with:
|
|
36
|
+
path: ~/.cache/sdf_datasets
|
|
37
|
+
key: sdf-datasets-17991042
|
|
38
|
+
|
|
33
39
|
- name: Test with pytest
|
|
34
40
|
run: uv run pytest
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# -*- mode: gitignore; -*-
|
|
2
|
+
# https://github.com/github/gitignore/blob/main/Global/Emacs.gitignore
|
|
3
|
+
# --------------------------------------------------------------------
|
|
2
4
|
*~
|
|
3
5
|
\#*\#
|
|
4
6
|
/.emacs.desktop
|
|
@@ -47,6 +49,9 @@ flycheck_*.el
|
|
|
47
49
|
# network security
|
|
48
50
|
/network-security.data
|
|
49
51
|
|
|
52
|
+
# https://github.com/github/gitignore/blob/main/Global/Linux.gitignore
|
|
53
|
+
# --------------------------------------------------------------------
|
|
54
|
+
|
|
50
55
|
*~
|
|
51
56
|
|
|
52
57
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
|
@@ -60,6 +65,10 @@ flycheck_*.el
|
|
|
60
65
|
|
|
61
66
|
# .nfs files are created when an open file is removed but is still being accessed
|
|
62
67
|
.nfs*
|
|
68
|
+
|
|
69
|
+
# https://github.com/github/gitignore/blob/main/Python.gitignore
|
|
70
|
+
# --------------------------------------------------------------
|
|
71
|
+
|
|
63
72
|
# Byte-compiled / optimized / DLL files
|
|
64
73
|
__pycache__/
|
|
65
74
|
*.py[cod]
|
|
@@ -222,6 +231,37 @@ cython_debug/
|
|
|
222
231
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
223
232
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
224
233
|
#.idea/
|
|
234
|
+
|
|
235
|
+
# Abstra
|
|
236
|
+
# Abstra is an AI-powered process automation framework.
|
|
237
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
238
|
+
# Learn more at https://abstra.io/docs
|
|
239
|
+
.abstra/
|
|
240
|
+
|
|
241
|
+
# Visual Studio Code
|
|
242
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
243
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
244
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
245
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
246
|
+
.vscode/
|
|
247
|
+
|
|
248
|
+
# Ruff stuff:
|
|
249
|
+
.ruff_cache/
|
|
250
|
+
|
|
251
|
+
# PyPI configuration file
|
|
252
|
+
.pypirc
|
|
253
|
+
|
|
254
|
+
# Marimo
|
|
255
|
+
marimo/_static/
|
|
256
|
+
marimo/_lsp/
|
|
257
|
+
__marimo__/
|
|
258
|
+
|
|
259
|
+
# Streamlit
|
|
260
|
+
.streamlit/secrets.toml
|
|
261
|
+
|
|
262
|
+
# https://github.com/github/gitignore/blob/main/CMake.gitignore
|
|
263
|
+
# ------------------------------------------------------------
|
|
264
|
+
|
|
225
265
|
CMakeLists.txt.user
|
|
226
266
|
CMakeCache.txt
|
|
227
267
|
CMakeFiles
|
|
@@ -233,6 +273,11 @@ install_manifest.txt
|
|
|
233
273
|
compile_commands.json
|
|
234
274
|
CTestTestfile.cmake
|
|
235
275
|
_deps
|
|
276
|
+
CMakeUserPresets.json
|
|
277
|
+
|
|
278
|
+
# https://github.com/github/gitignore/blob/main/C.gitignore
|
|
279
|
+
# ---------------------------------------------------------
|
|
280
|
+
|
|
236
281
|
# Prerequisites
|
|
237
282
|
*.d
|
|
238
283
|
|
|
@@ -286,6 +331,9 @@ Module.symvers
|
|
|
286
331
|
Mkfile.old
|
|
287
332
|
dkms.conf
|
|
288
333
|
|
|
334
|
+
# sdf-xarray specific ignores
|
|
335
|
+
# ---------------------------
|
|
336
|
+
|
|
289
337
|
# Generated version file
|
|
290
338
|
src/sdf_xarray/_version.py
|
|
291
339
|
|
|
@@ -28,14 +28,8 @@ pip install .
|
|
|
28
28
|
|
|
29
29
|
### Style
|
|
30
30
|
|
|
31
|
-
We
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- [ruff](https://github.com/astral-sh/ruff) for linting
|
|
35
|
-
- [black](https://black.readthedocs.io/en/stable/) for formatting
|
|
36
|
-
- [isort](https://pycqa.github.io/isort/) for sorting imports
|
|
37
|
-
|
|
38
|
-
To run these tools locally, install the `lint` dependency group:
|
|
31
|
+
We use [Ruff](https://docs.astral.sh/ruff/) to maintain code quality and
|
|
32
|
+
formatting. This can be installed locally via the `lint` dependency group:
|
|
39
33
|
|
|
40
34
|
```bash
|
|
41
35
|
pip install --group lint
|
|
@@ -53,6 +47,20 @@ Alternatively, `uv` users can do this in one step with `uv run`:
|
|
|
53
47
|
uv run ruff check src tests
|
|
54
48
|
```
|
|
55
49
|
|
|
50
|
+
Many of the issues raised by Ruff can be fixed automatically:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
ruff check --fix src tests
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Ruff may also be used to format the code to a style similar to that enforced by
|
|
57
|
+
[Black](https://black.readthedocs.io/en/stable/), which (almost) matches the
|
|
58
|
+
[PEP-8 standard](https://peps.python.org/pep-0008/):
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
ruff format src tests
|
|
62
|
+
```
|
|
63
|
+
|
|
56
64
|
### Running and adding tests
|
|
57
65
|
|
|
58
66
|
We use [pytest](https://docs.pytest.org/en/stable/) to run tests.
|
|
@@ -130,8 +138,8 @@ Then open http://localhost:8000 in your browser to view the documentation.
|
|
|
130
138
|
|
|
131
139
|
All pull requests are automatically checked using GitHub Actions for:
|
|
132
140
|
|
|
133
|
-
- Linting (`ruff`)
|
|
134
|
-
- Formatting (`black` and `isort`)
|
|
141
|
+
- Linting and formatting (`ruff`)
|
|
135
142
|
- Testing (`pytest`)
|
|
143
|
+
- Cross-platform building (`cibuildwheel`)
|
|
136
144
|
|
|
137
145
|
These checks must pass before a pull request can be merged.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sdf-xarray
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Provides a backend for xarray to read SDF files as created by the EPOCH plasma PIC code.
|
|
5
5
|
Author-Email: Peter Hill <peter.hill@york.ac.uk>, Joel Adams <joel.adams@york.ac.uk>, Shaun Doherty <shaun.doherty@york.ac.uk>, Chris Herdman <chris.herdman@york.ac.uk>, Liam Pattinson <liam.pattinson@york.ac.uk>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -10,12 +10,11 @@ Classifier: Topic :: Scientific/Engineering
|
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
11
|
Classifier: Programming Language :: Python
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
-
Requires-Python: <3.15,>=3.
|
|
17
|
+
Requires-Python: <3.15,>=3.11
|
|
19
18
|
Requires-Dist: numpy>=2.0.0
|
|
20
19
|
Requires-Dist: xarray>=2024.1.0
|
|
21
20
|
Requires-Dist: dask>=2024.7.1
|
|
@@ -35,7 +34,7 @@ Description-Content-Type: text/markdown
|
|
|
35
34
|

|
|
36
35
|

|
|
37
36
|
[](https://sdf-xarray.readthedocs.io)
|
|
38
|
-
[](https://github.com/astral-sh/ruff)
|
|
39
38
|
|
|
40
39
|
|
|
41
40
|
sdf-xarray provides a backend for [xarray](https://xarray.dev) to read SDF files as created by
|
|
@@ -148,4 +147,4 @@ To run checks locally before opening a pull request, see [CONTRIBUTING.md](CONTR
|
|
|
148
147
|
|
|
149
148
|

|
|
150
149
|
|
|
151
|
-
Originally developed by [PlasmaFAIR](https://plasmafair.github.io), EPSRC Grant EP/V051822/1
|
|
150
|
+
Originally developed by [PlasmaFAIR](https://plasmafair.github.io), EPSRC Grant EP/V051822/1
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|

|
|
7
7
|

|
|
8
8
|
[](https://sdf-xarray.readthedocs.io)
|
|
9
|
-
[](https://github.com/astral-sh/ruff)
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
sdf-xarray provides a backend for [xarray](https://xarray.dev) to read SDF files as created by
|
|
@@ -119,4 +119,4 @@ To run checks locally before opening a pull request, see [CONTRIBUTING.md](CONTR
|
|
|
119
119
|
|
|
120
120
|

|
|
121
121
|
|
|
122
|
-
Originally developed by [PlasmaFAIR](https://plasmafair.github.io), EPSRC Grant EP/V051822/1
|
|
122
|
+
Originally developed by [PlasmaFAIR](https://plasmafair.github.io), EPSRC Grant EP/V051822/1
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
.. |animate_accessor| replace:: `xarray.DataArray.epoch.animate
|
|
4
4
|
<sdf_xarray.plotting.animate>`
|
|
5
5
|
|
|
6
|
+
.. |animate_multiple_accessor| replace:: `xarray.Dataset.epoch.animate_multiple
|
|
7
|
+
<sdf_xarray.plotting.animate_multiple>`
|
|
8
|
+
|
|
6
9
|
==========
|
|
7
10
|
Animations
|
|
8
11
|
==========
|
|
@@ -131,10 +134,8 @@ Moving window
|
|
|
131
134
|
-------------
|
|
132
135
|
|
|
133
136
|
EPOCH allows for simulations that have a moving simulation window
|
|
134
|
-
(changing x-axis over time). |animate_accessor|
|
|
135
|
-
|
|
136
|
-
for NaNs in the `xarray.DataArray` and change the x-axis limits
|
|
137
|
-
accordingly.
|
|
137
|
+
(changing x-axis over time). |animate_accessor| can accept the boolean parameter
|
|
138
|
+
``move_window`` and change the x-axis limits accordingly.
|
|
138
139
|
|
|
139
140
|
.. warning::
|
|
140
141
|
`sdf_xarray.open_mfdataset` does not currently function with moving window data.
|
|
@@ -152,7 +153,7 @@ accordingly.
|
|
|
152
153
|
)
|
|
153
154
|
|
|
154
155
|
da = ds["Derived_Number_Density_Beam_Electrons"]
|
|
155
|
-
anim = da.epoch.animate(fps = 5)
|
|
156
|
+
anim = da.epoch.animate(move_window=True, fps = 5)
|
|
156
157
|
anim.show()
|
|
157
158
|
|
|
158
159
|
.. warning::
|
|
@@ -191,73 +192,70 @@ before plotting as in :ref:`sec-unit-conversion`. Some functionality such as
|
|
|
191
192
|
)
|
|
192
193
|
anim.show()
|
|
193
194
|
|
|
194
|
-
|
|
195
|
-
|
|
195
|
+
Combining multiple animations
|
|
196
|
+
-----------------------------
|
|
196
197
|
|
|
197
|
-
|
|
198
|
-
|
|
198
|
+
|animate_multiple_accessor| creates a `matplotlib.animation.FuncAnimation`
|
|
199
|
+
that contains multiple plots layered on top of each other.
|
|
200
|
+
|
|
201
|
+
1D simulation
|
|
202
|
+
~~~~~~~~~~~~~
|
|
199
203
|
|
|
200
204
|
What follows is an example of how to combine multiple animations on the
|
|
201
|
-
same axis.
|
|
202
|
-
a future update.
|
|
205
|
+
same axis.
|
|
203
206
|
|
|
204
207
|
.. jupyter-execute::
|
|
205
208
|
|
|
206
|
-
# Open the SDF files
|
|
207
209
|
ds = sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf")
|
|
208
210
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
# Extract the update functions from the animations
|
|
218
|
-
update_1 = anim_1._func
|
|
219
|
-
update_2 = anim_2._func
|
|
220
|
-
|
|
221
|
-
# Create axes details for new animation
|
|
222
|
-
x_min, x_max = update_1(0)[0].axes.get_xlim()
|
|
223
|
-
y_min_1, y_max_1 = update_1(0)[0].axes.get_ylim()
|
|
224
|
-
y_min_2, y_max_2 = update_2(0)[0].axes.get_ylim()
|
|
225
|
-
y_min = min(y_min_1, y_min_2)
|
|
226
|
-
y_max = max(y_max_1, y_max_2)
|
|
227
|
-
x_label = update_1(0)[0].axes.get_xlabel()
|
|
228
|
-
y_label = "Number Density [m$^{-3}$]"
|
|
229
|
-
label_1 = "Electron"
|
|
230
|
-
label_2 = "Ion"
|
|
231
|
-
|
|
232
|
-
# Create new update function
|
|
233
|
-
def update_combined(frame):
|
|
234
|
-
anim_1_fig = update_1(frame)[0]
|
|
235
|
-
anim_2_fig = update_2(frame)[0]
|
|
236
|
-
|
|
237
|
-
title = anim_1_fig.axes.title._text
|
|
238
|
-
|
|
239
|
-
ax.clear()
|
|
240
|
-
plot = ax.plot(anim_1_fig._x, anim_1_fig._y, label = label_1)
|
|
241
|
-
ax.plot(anim_2_fig._x, anim_2_fig._y, label = label_2)
|
|
242
|
-
ax.set_title(title)
|
|
243
|
-
ax.set_xlim(x_min, x_max)
|
|
244
|
-
ax.set_ylim(y_min, y_max)
|
|
245
|
-
ax.set_xlabel(x_label)
|
|
246
|
-
ax.set_ylabel(y_label)
|
|
247
|
-
ax.legend(loc = "upper left")
|
|
248
|
-
return plot
|
|
249
|
-
|
|
250
|
-
N_frames = anim_1._save_count
|
|
251
|
-
interval = anim_1._interval
|
|
252
|
-
|
|
253
|
-
# Create combined animation
|
|
254
|
-
anim_combined = FuncAnimation(
|
|
255
|
-
fig,
|
|
256
|
-
update_combined,
|
|
257
|
-
frames=range(N_frames),
|
|
258
|
-
interval = interval,
|
|
259
|
-
repeat=True,
|
|
260
|
-
)
|
|
211
|
+
anim = ds.epoch.animate_multiple(
|
|
212
|
+
ds["Derived_Number_Density_Electron"],
|
|
213
|
+
ds["Derived_Number_Density_Ion"],
|
|
214
|
+
datasets_kwargs=[{"label": "Electron"}, {"label": "Ion"}],
|
|
215
|
+
ylim=(0e27,4e27),
|
|
216
|
+
ylabel="Derived Number Density [1/m$^3$]"
|
|
217
|
+
)
|
|
261
218
|
|
|
262
|
-
|
|
263
|
-
|
|
219
|
+
anim.show()
|
|
220
|
+
|
|
221
|
+
2D simulation
|
|
222
|
+
~~~~~~~~~~~~~
|
|
223
|
+
|
|
224
|
+
.. tip::
|
|
225
|
+
To correctly display 2D data on top of one another you need to specify
|
|
226
|
+
the ``alpha`` value which sets the opacity of the plot.
|
|
227
|
+
|
|
228
|
+
This also works with 2 dimensional data.
|
|
229
|
+
|
|
230
|
+
.. jupyter-execute::
|
|
231
|
+
|
|
232
|
+
import numpy as np
|
|
233
|
+
from matplotlib.colors import LogNorm
|
|
234
|
+
|
|
235
|
+
ds = sdfxr.open_mfdataset("tutorial_dataset_2d/*.sdf")
|
|
236
|
+
|
|
237
|
+
flux_magnitude = np.sqrt(
|
|
238
|
+
ds["Derived_Poynting_Flux_x"]**2 +
|
|
239
|
+
ds["Derived_Poynting_Flux_y"]**2 +
|
|
240
|
+
ds["Derived_Poynting_Flux_z"]**2
|
|
241
|
+
)
|
|
242
|
+
flux_magnitude.attrs["long_name"] = "Poynting Flux Magnitude"
|
|
243
|
+
flux_magnitude.attrs["units"] = "W/m$^2$"
|
|
244
|
+
|
|
245
|
+
# Cut-off low energy values so that they will be rendered as transparent
|
|
246
|
+
# in the plot as they've been set to NaN
|
|
247
|
+
flux_masked = flux_magnitude.where(flux_magnitude > 0.2e23)
|
|
248
|
+
flux_norm = LogNorm(
|
|
249
|
+
vmin=float(flux_masked.min()),
|
|
250
|
+
vmax=float(flux_masked.max())
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
anim = ds.epoch.animate_multiple(
|
|
254
|
+
ds["Derived_Number_Density_Electron"],
|
|
255
|
+
flux_masked,
|
|
256
|
+
datasets_kwargs=[
|
|
257
|
+
{"alpha": 1.0},
|
|
258
|
+
{"cmap": "hot", "norm": flux_norm, "alpha": 0.9},
|
|
259
|
+
],
|
|
260
|
+
)
|
|
261
|
+
anim.show()
|
|
@@ -64,6 +64,16 @@ Loading single files
|
|
|
64
64
|
|
|
65
65
|
xr.open_dataset("tutorial_dataset_1d/0010.sdf")
|
|
66
66
|
|
|
67
|
+
Alternatively, you can load the data in as a `xarray.DataTree`, which organises the data
|
|
68
|
+
hierarchically into ``groups`` (for example grouping related quantities such as the individual
|
|
69
|
+
components of the electric and magnetic fields) while keeping each item as a `xarray.Dataset`.
|
|
70
|
+
|
|
71
|
+
.. jupyter-execute::
|
|
72
|
+
|
|
73
|
+
import sdf_xarray as sdfxr
|
|
74
|
+
|
|
75
|
+
sdfxr.open_datatree("tutorial_dataset_1d/0010.sdf")
|
|
76
|
+
|
|
67
77
|
Loading multiple files
|
|
68
78
|
----------------------
|
|
69
79
|
|
|
@@ -73,6 +83,16 @@ Loading multiple files
|
|
|
73
83
|
|
|
74
84
|
sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf")
|
|
75
85
|
|
|
86
|
+
Alternatively, you can load the data in as a `xarray.DataTree`, which organises the data
|
|
87
|
+
hierarchically into ``groups`` (for example grouping related quantities such as the individual
|
|
88
|
+
components of the electric and magnetic fields) while keeping each item as a `xarray.Dataset`.
|
|
89
|
+
|
|
90
|
+
.. jupyter-execute::
|
|
91
|
+
|
|
92
|
+
import sdf_xarray as sdfxr
|
|
93
|
+
|
|
94
|
+
sdfxr.open_mfdatatree("tutorial_dataset_1d/*.sdf")
|
|
95
|
+
|
|
76
96
|
.. _loading-raw-files-getting-started:
|
|
77
97
|
|
|
78
98
|
Loading raw files
|
|
@@ -15,8 +15,8 @@ Loading SDF files
|
|
|
15
15
|
-----------------
|
|
16
16
|
There are several ways to load SDF files:
|
|
17
17
|
|
|
18
|
-
- To load a single file, use `xarray.open_dataset
|
|
19
|
-
- To load multiple files, use `sdf_xarray.open_mfdataset` or `
|
|
18
|
+
- To load a single file, use `xarray.open_dataset`, `sdf_xarray.open_datatree` or `xarray.open_datatree`
|
|
19
|
+
- To load multiple files, use `sdf_xarray.open_mfdataset`, `xarray.open_mfdataset` or `sdf_xarray.open_mfdatatree`.
|
|
20
20
|
- To access the raw contents of a single SDF file, use `sdf_xarray.sdf_interface.SDFFile`.
|
|
21
21
|
|
|
22
22
|
.. note::
|
|
@@ -41,6 +41,13 @@ Loading single files
|
|
|
41
41
|
|
|
42
42
|
xr.open_dataset("tutorial_dataset_1d/0010.sdf")
|
|
43
43
|
|
|
44
|
+
Alternatively, you can load the data in as a `xarray.DataTree`, which organises the data
|
|
45
|
+
hierarchically into ``groups`` (for example grouping related quantities such as the individual
|
|
46
|
+
components of the electric and magnetic fields) while keeping each item as a `xarray.Dataset`.
|
|
47
|
+
|
|
48
|
+
.. jupyter-execute::
|
|
49
|
+
|
|
50
|
+
sdfxr.open_datatree("tutorial_dataset_1d/0010.sdf")
|
|
44
51
|
|
|
45
52
|
.. _loading-raw-files:
|
|
46
53
|
|
|
@@ -72,6 +79,14 @@ is by using the `sdf_xarray.open_mfdataset`.
|
|
|
72
79
|
|
|
73
80
|
sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf")
|
|
74
81
|
|
|
82
|
+
Alternatively, you can load the data in as a `xarray.DataTree`, which organises the data
|
|
83
|
+
hierarchically into ``groups`` (for example grouping related quantities such as the individual
|
|
84
|
+
components of the electric and magnetic fields) while keeping each item as a `xarray.Dataset`.
|
|
85
|
+
|
|
86
|
+
.. jupyter-execute::
|
|
87
|
+
|
|
88
|
+
sdfxr.open_mfdatatree("tutorial_dataset_1d/*.sdf")
|
|
89
|
+
|
|
75
90
|
Alternatively files can be loaded using `xarray.open_mfdataset` however when loading in
|
|
76
91
|
all the files we have do some processing of the data so that we can correctly align it along
|
|
77
92
|
the time dimension; This is done via the ``preprocess`` parameter utilising the
|
|
@@ -219,6 +234,44 @@ value intead of an index.
|
|
|
219
234
|
|
|
220
235
|
ds["Electric_Field_Ex"].sel(time=sim_time)
|
|
221
236
|
|
|
237
|
+
Visualisation on HPCs
|
|
238
|
+
---------------------
|
|
239
|
+
|
|
240
|
+
In many cases you will be running EPOCH simulations via a HPC cluster and your
|
|
241
|
+
subsequent SDF files will probably be rather large and cumbersome to interact with
|
|
242
|
+
via traditional Jupyter notebooks. In some cases your HPC may outright block the
|
|
243
|
+
use of Jupyter notebooks entirely. To circumvent this issue you can use a Terminal
|
|
244
|
+
User Interface (TUI) which renders the contents of SDF files directly in a Terminal
|
|
245
|
+
and allows for you to do some simple data analysis and visualisation. To do this we
|
|
246
|
+
shall leverage the `xr-tui <https://github.com/samueljackson92/xr-tui>`_ package
|
|
247
|
+
which can be installed to either a venv or globally using:
|
|
248
|
+
|
|
249
|
+
.. code-block:: bash
|
|
250
|
+
|
|
251
|
+
pip install xr-tui sdf-xarray
|
|
252
|
+
|
|
253
|
+
or if you are using ``uv``
|
|
254
|
+
|
|
255
|
+
.. code-block:: bash
|
|
256
|
+
|
|
257
|
+
uv tool install xr-tui --with sdf-xarray
|
|
258
|
+
|
|
259
|
+
Once installed you can visualise SDF files by simply writing in the command line
|
|
260
|
+
|
|
261
|
+
.. code-block:: bash
|
|
262
|
+
|
|
263
|
+
xr path/to/simulation/0000.sdf
|
|
264
|
+
# OR
|
|
265
|
+
xr path/to/simulation/*.sdf
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
Below is an example gif of how this interfacing looks as seen on
|
|
269
|
+
`xr-tui <https://github.com/samueljackson92/xr-tui>`_ ``README.md``:
|
|
270
|
+
|
|
271
|
+
.. image:: https://raw.githubusercontent.com/samueljackson92/xr-tui/main/demo.gif
|
|
272
|
+
:alt: xr-tui interfacing gif
|
|
273
|
+
:align: center
|
|
274
|
+
|
|
222
275
|
Manipulating data
|
|
223
276
|
-----------------
|
|
224
277
|
|
|
@@ -19,7 +19,7 @@ authors = [
|
|
|
19
19
|
{ name = "Chris Herdman", email = "chris.herdman@york.ac.uk" },
|
|
20
20
|
{ name = "Liam Pattinson", email = "liam.pattinson@york.ac.uk" },
|
|
21
21
|
]
|
|
22
|
-
requires-python = ">=3.
|
|
22
|
+
requires-python = ">=3.11,<3.15"
|
|
23
23
|
dependencies = ["numpy>=2.0.0", "xarray>=2024.1.0", "dask>=2024.7.1"]
|
|
24
24
|
description = "Provides a backend for xarray to read SDF files as created by the EPOCH plasma PIC code."
|
|
25
25
|
classifiers = [
|
|
@@ -29,7 +29,6 @@ classifiers = [
|
|
|
29
29
|
"Operating System :: OS Independent",
|
|
30
30
|
"Programming Language :: Python",
|
|
31
31
|
"Programming Language :: Python :: 3",
|
|
32
|
-
"Programming Language :: Python :: 3.10",
|
|
33
32
|
"Programming Language :: Python :: 3.11",
|
|
34
33
|
"Programming Language :: Python :: 3.12",
|
|
35
34
|
"Programming Language :: Python :: 3.13",
|
|
@@ -42,10 +41,10 @@ pint = ["pint", "pint-xarray"]
|
|
|
42
41
|
|
|
43
42
|
[dependency-groups]
|
|
44
43
|
dev = [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
{ include-group = "build" },
|
|
45
|
+
{ include-group = "docs" },
|
|
46
|
+
{ include-group = "lint" },
|
|
47
|
+
{ include-group = "test" },
|
|
49
48
|
]
|
|
50
49
|
docs = [
|
|
51
50
|
"sphinx>=5.3",
|
|
@@ -76,6 +75,9 @@ test = [
|
|
|
76
75
|
[project.entry-points."xarray.backends"]
|
|
77
76
|
sdf_engine = "sdf_xarray:SDFEntrypoint"
|
|
78
77
|
|
|
78
|
+
[project.entry-points."xr_tui.backends"]
|
|
79
|
+
"*.sdf" = "sdf_xarray:XrTUIEntrpoint"
|
|
80
|
+
|
|
79
81
|
[tool.scikit-build]
|
|
80
82
|
metadata.version.provider = "scikit_build_core.metadata.setuptools_scm"
|
|
81
83
|
sdist.include = ["src/sdf_xarray/_version.py"]
|
|
@@ -94,7 +96,6 @@ cache-keys = [{ file = "pyproject.toml" }, { git = true }]
|
|
|
94
96
|
|
|
95
97
|
[tool.ruff]
|
|
96
98
|
line-length = 88
|
|
97
|
-
target-version = "py310"
|
|
98
99
|
|
|
99
100
|
[tool.ruff.lint]
|
|
100
101
|
extend-select = [
|
|
@@ -123,6 +124,5 @@ ignore = [
|
|
|
123
124
|
"B9", # flake8-bugbear opinionated warnings
|
|
124
125
|
"PLR0913", # remove maximum number of arguments in a function
|
|
125
126
|
]
|
|
126
|
-
exclude = [
|
|
127
|
-
|
|
128
|
-
]
|
|
127
|
+
exclude = ["**/_version.py"]
|
|
128
|
+
# Auto-generated file
|