sdf-xarray 0.8.0__tar.gz → 0.10.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.8.0 → sdf_xarray-0.10.0}/.github/workflows/build_publish.yml +1 -1
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/.github/workflows/tests.yml +1 -1
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/PKG-INFO +1 -1
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/animation.md +16 -20
- sdf_xarray-0.10.0/docs/figures/voxel_plot_high_res.png +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/index.md +1 -0
- sdf_xarray-0.10.0/docs/known_issues.md +8 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/loading_data.md +32 -17
- sdf_xarray-0.10.0/docs/plotting.md +95 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/understanding_datasets.md +51 -18
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/why_sdf_xarray.md +1 -1
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/pyproject.toml +8 -2
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/src/sdf_xarray/__init__.py +138 -43
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/src/sdf_xarray/_version.py +3 -3
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/src/sdf_xarray/csdf.pxd +2 -0
- sdf_xarray-0.10.0/src/sdf_xarray/dataarray_accessor.py +226 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/src/sdf_xarray/download.py +18 -11
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/src/sdf_xarray/plotting.py +247 -10
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/src/sdf_xarray/sdf_interface.pyx +110 -14
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/tests/test_cython.py +46 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/tests/test_dataset.py +87 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/tests/test_epoch_dataarray_accessor.py +252 -29
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/uv.lock +141 -0
- sdf_xarray-0.8.0/docs/known_issues.md +0 -15
- sdf_xarray-0.8.0/src/sdf_xarray/dataarray_accessor.py +0 -74
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/.github/workflows/lint.yml +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/.gitignore +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/.gitmodules +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/.readthedocs.yaml +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/CITATION.cff +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/CMakeLists.txt +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/CONTRIBUTING.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/LICENCE +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/README.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/.gitignore +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/_static/BEAM.png +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/_static/PlasmaFAIR.svg +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/_static/force_render_dark_xarray_objects.css +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/_static/sdf-xarray-logo-dark.svg +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/_static/sdf-xarray-logo-light.svg +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/_templates/custom-class-template.rst +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/_templates/custom-module-template.rst +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/api.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/conf.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/contributing.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/animating/animate_1D_density.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/animating/animate_1D_poynting_flux.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/animating/animate_2D_dist_fn_multispecies.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/animating/animate_2D_dist_fn_multispecies_alternative.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/animating/animate_2D_poynting_flux.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/animations.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/histograms/plot_hist_ke.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/histograms/plot_hist_ke_probe.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/histograms/plot_hist_px.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/histograms.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/live_demo.ipynb +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/plots.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/plotting/plot_1D_density.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/plotting/plot_1D_poynting_flux.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/plotting/plot_2D_density.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/plotting/plot_2D_dist_fn_multispecies.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/plotting/plot_2D_poynting_flux.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/plotting/plot_time_temperature.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/plotting/plot_x_px_scatter.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/epoch_workshop_2026/workshop_details.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/installation.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/make.bat +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/docs/unit_conversion.md +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/src/sdf_xarray/dataset_accessor.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/tests/test_datatree.py +0 -0
- {sdf_xarray-0.8.0 → sdf_xarray-0.10.0}/tests/test_epoch_dataset_accessor.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sdf-xarray
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.10.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>, Sviatoslav Shekhanov <sviatoslav.shekhanov@york.ac.uk>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -12,7 +12,6 @@ mimic <inv:#xarray.DataArray.plot>.
|
|
|
12
12
|
|
|
13
13
|
```{code-cell} ipython3
|
|
14
14
|
import sdf_xarray as sdfxr
|
|
15
|
-
import xarray as xr
|
|
16
15
|
import matplotlib.pyplot as plt
|
|
17
16
|
from matplotlib.animation import FuncAnimation
|
|
18
17
|
from IPython.display import HTML
|
|
@@ -35,9 +34,10 @@ resolved data has 2 dimensions.
|
|
|
35
34
|
|
|
36
35
|
| Dimensions | Plotting function | Notes |
|
|
37
36
|
| ---------- | ----------------------------- | --------------------- |
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
|
|
|
37
|
+
| 2 | <inv:#xarray.plot.line> | |
|
|
38
|
+
| 3 | <inv:#xarray.plot.pcolormesh> | |
|
|
39
|
+
| 4 | <inv:#mpl_toolkits.mplot3d.axes3d.Axes3D.voxels>| WIP |
|
|
40
|
+
| >4 | <inv:#xarray.plot.hist> | Not fully implemented |
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
### 1D simulation
|
|
@@ -103,6 +103,10 @@ anim.show()
|
|
|
103
103
|
|
|
104
104
|
### 3D simulation
|
|
105
105
|
|
|
106
|
+
```{warning}
|
|
107
|
+
[Voxel](./plotting.md#voxel-plots) animations are not currently implemented.
|
|
108
|
+
```
|
|
109
|
+
|
|
106
110
|
Opening a 3D simulation as a multi-file dataset and plotting it will
|
|
107
111
|
return a <inv:#xarray.plot.hist>. However, this may not be
|
|
108
112
|
desirable. We can plot a 3D simulation along a certain plane in the
|
|
@@ -134,31 +138,23 @@ EPOCH allows for simulations that have a moving simulation window
|
|
|
134
138
|
`move_window` and change the x-axis limits accordingly.
|
|
135
139
|
|
|
136
140
|
```{warning}
|
|
137
|
-
|
|
138
|
-
|
|
141
|
+
Importing some datasets with moving windows can cause vertical banding
|
|
142
|
+
in the <inv:#xarray.Dataset>, which will affect the animation. Each output stores
|
|
143
|
+
its own x grid, and the same position can differ by floating point rounding between
|
|
144
|
+
outputs. Both values are then kept on the combined x axis, so each time step has
|
|
145
|
+
nan values in some columns. Setting `join = "override"` in
|
|
146
|
+
<inv:#xarray.open_mfdataset> does not fix this for moving window data, as it
|
|
147
|
+
relabels every time step with the first output's x grid.
|
|
139
148
|
```
|
|
140
149
|
|
|
141
150
|
```{code-cell} ipython3
|
|
142
|
-
ds =
|
|
143
|
-
"tutorial_dataset_2d_moving_window/*.sdf",
|
|
144
|
-
preprocess = sdfxr.SDFPreprocess(),
|
|
145
|
-
combine = "nested",
|
|
146
|
-
join = "outer",
|
|
147
|
-
compat="no_conflicts",
|
|
148
|
-
concat_dim="time",
|
|
149
|
-
)
|
|
151
|
+
ds = sdfxr.open_mfdataset("tutorial_dataset_2d_moving_window/*.sdf")
|
|
150
152
|
|
|
151
153
|
da = ds["Derived_Number_Density_Beam_Electrons"]
|
|
152
154
|
anim = da.epoch.animate(move_window = True, fps = 5)
|
|
153
155
|
anim.show()
|
|
154
156
|
```
|
|
155
157
|
|
|
156
|
-
```{warning}
|
|
157
|
-
Importing some datasets with moving windows can cause vertical banding
|
|
158
|
-
in the <inv:#xarray.Dataset>, which will affect the animation. The cause for
|
|
159
|
-
this is unknown but can be circumvented by setting `join = "override"`.
|
|
160
|
-
```
|
|
161
|
-
|
|
162
158
|
## Customisation
|
|
163
159
|
|
|
164
160
|
The animation can be customised in much the same way as <inv:#xarray.DataArray.plot>,
|
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Known Issues
|
|
2
|
+
|
|
3
|
+
These are the known 'quirks' in `sdf_xarray`:
|
|
4
|
+
|
|
5
|
+
- [Issue #112](https://github.com/epochpic/sdf-xarray/issues/112) Due to the
|
|
6
|
+
way [cylindrical EPOCH](https://github.com/epochpic/cylindrical_epoch) sets up
|
|
7
|
+
grids we can't currently load it's SDF files. If there is enough interest in this
|
|
8
|
+
we will attempt to find a solution otherwise it shall remain low priority.
|
|
@@ -85,7 +85,11 @@ is by using the <project:#sdf_xarray.open_mfdataset>.
|
|
|
85
85
|
```{tip}
|
|
86
86
|
If your simulation includes multiple `output` blocks that specify different variables
|
|
87
87
|
for output at various time steps, variables not present at a specific step will default
|
|
88
|
-
to a nan value.
|
|
88
|
+
to a nan value. This includes distribution functions and particle data that are only
|
|
89
|
+
output at some time steps. Grids that change between outputs (such as a moving window,
|
|
90
|
+
or a distribution function with an automatic range) are combined onto the union of
|
|
91
|
+
every output's grid points, with nan values outside the part of the grid each output
|
|
92
|
+
covers. To remove these nan values we suggest using the <inv:#xarray.DataArray.dropna>
|
|
89
93
|
function or following our implmentation in [](#loading-sparse-data).
|
|
90
94
|
```
|
|
91
95
|
|
|
@@ -98,13 +102,20 @@ sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf")
|
|
|
98
102
|
Alternatively, files can be loaded using <inv:#xarray.open_mfdataset>. However, when loading in
|
|
99
103
|
all the files we have do some processing of the data so that we can correctly align it along
|
|
100
104
|
the time dimension; This is done via the `preprocess` parameter utilising the
|
|
101
|
-
<project:#sdf_xarray.SDFPreprocess> function.
|
|
105
|
+
<project:#sdf_xarray.SDFPreprocess> function. Passing `combine="nested"` and
|
|
106
|
+
`concat_dim="time"` makes sure the files are only joined along time. Otherwise
|
|
107
|
+
<inv:#xarray> treats any coordinate that differs between files (such as a moving
|
|
108
|
+
window's x grid) as another dimension to concatenate along, which can fail or request
|
|
109
|
+
far more memory than needed. Unlike <project:#sdf_xarray.open_mfdataset>, this does
|
|
110
|
+
not handle particle positions that are missing from some files.
|
|
102
111
|
|
|
103
112
|
```{code-cell} ipython3
|
|
104
113
|
import xarray as xr
|
|
105
114
|
|
|
106
115
|
xr.open_mfdataset(
|
|
107
116
|
"tutorial_dataset_1d/*.sdf",
|
|
117
|
+
combine="nested",
|
|
118
|
+
concat_dim="time",
|
|
108
119
|
join="outer",
|
|
109
120
|
compat="no_conflicts",
|
|
110
121
|
preprocess=sdfxr.SDFPreprocess()
|
|
@@ -123,6 +134,9 @@ sdfxr.open_mfdatatree("tutorial_dataset_1d/*.sdf")
|
|
|
123
134
|
|
|
124
135
|
## Loading sparse data
|
|
125
136
|
|
|
137
|
+
By default, <project:#sdf_xarray.open_mfdataset> puts every variable on a single
|
|
138
|
+
time dimension, and a variable missing from an output (including distribution
|
|
139
|
+
functions and particle data) is filled with nan values at that time step.
|
|
126
140
|
When dealing with sparse data (where different variables are saved at different,
|
|
127
141
|
non-overlapping time steps) you can optimize memory usage by loading the data with
|
|
128
142
|
<project:#sdf_xarray.open_mfdataset> using the parameter `separate_times=True`. This
|
|
@@ -140,12 +154,17 @@ sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf", separate_times=True)
|
|
|
140
154
|
## Loading particle data
|
|
141
155
|
|
|
142
156
|
```{warning}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
157
|
+
<project:#sdf_xarray.open_mfdataset> can load particle data from multiple
|
|
158
|
+
SDF outputs, and outputs that don't include particles are filled with nan
|
|
159
|
+
values. However, every output that does include a species must contain the
|
|
160
|
+
same number of particles of that species. The number of particles often
|
|
161
|
+
varies between outputs (for example with particle injection, losses or probes),
|
|
162
|
+
in which case loading fails with a conflicting dimension sizes error, and you
|
|
163
|
+
should load each file individually instead.
|
|
164
|
+
|
|
165
|
+
The `ID_<species>` dimension is the position in each output's particle array,
|
|
166
|
+
not a particle identity, so the same index at two time steps is not
|
|
167
|
+
necessarily the same particle.
|
|
149
168
|
```
|
|
150
169
|
|
|
151
170
|
```{note}
|
|
@@ -157,7 +176,7 @@ Failing to do so will result in dimension name conflicts.
|
|
|
157
176
|
|
|
158
177
|
By default, particle data isn't kept as it takes up a lot of space.
|
|
159
178
|
Pass `keep_particles=True` as a keyword argument to
|
|
160
|
-
<
|
|
179
|
+
<project:#sdf_xarray.open_dataset> (for single files) or <project:#sdf_xarray.open_mfdataset> (for
|
|
161
180
|
multiple files).
|
|
162
181
|
|
|
163
182
|
```{code-cell} ipython3
|
|
@@ -168,14 +187,10 @@ sdfxr.open_dataset("tutorial_dataset_1d/0010.sdf", keep_particles=True)
|
|
|
168
187
|
|
|
169
188
|
## Loading specific variables
|
|
170
189
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
In this instance, you can optimize memory usage by loading only the data
|
|
176
|
-
you need using the keyword argument `data_vars` and passing one or more
|
|
177
|
-
variables. This creates a dataset consisting only of the given variable(s)
|
|
178
|
-
and the relevant coordinates/dimensions, significantly reducing memory
|
|
190
|
+
If you only need some of the variables, you can load just those using the
|
|
191
|
+
keyword argument `data_vars` and passing one or more variables to
|
|
192
|
+
<project:#sdf_xarray.open_mfdataset>. This creates a dataset consisting only of
|
|
193
|
+
the given variable(s) and the relevant coordinates/dimensions, reducing memory
|
|
179
194
|
consumption.
|
|
180
195
|
|
|
181
196
|
```{code-cell} ipython3
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
---
|
|
2
|
+
file_format: mystnb
|
|
3
|
+
kernelspec:
|
|
4
|
+
name: python3
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Plotting
|
|
8
|
+
|
|
9
|
+
You can plot datasets using
|
|
10
|
+
[`xarray.DataArray.epoch.plot`](project:#sdf_xarray.dataarray_accessor.EpochAccessor.plot).
|
|
11
|
+
This is a custom <project:#sdf_xarray> plotting routine that builds on top of
|
|
12
|
+
<inv:#xarray.DataArray.plot>, so you keep the familiar <inv:#xarray> plotting
|
|
13
|
+
behaviour while using <project:#sdf_xarray> conveniences (see
|
|
14
|
+
[here](project:#sdf_xarray.dataarray_accessor.EpochAccessor.plot) for details).
|
|
15
|
+
Under the hood, plotting is still handled by <inv:#matplotlib>, which means you
|
|
16
|
+
can use the full <inv:#matplotlib> API to customise your figure.
|
|
17
|
+
|
|
18
|
+
| Dimensions | Base plotting function | Notes |
|
|
19
|
+
| ---------- | ----------------------------- | --------------------- |
|
|
20
|
+
| 1 | <inv:#xarray.plot.line> | |
|
|
21
|
+
| 2 | <inv:#xarray.plot.pcolormesh> | |
|
|
22
|
+
| 3 | <inv:#mpl_toolkits.mplot3d.axes3d.Axes3D.voxels>| Custom functionality built for <project:#sdf_xarray> |
|
|
23
|
+
| >3 | <inv:#xarray.plot.hist> | Not fully implemented |
|
|
24
|
+
|
|
25
|
+
## Line plots
|
|
26
|
+
|
|
27
|
+
One dimensional data will be plotted as a line. Multiple lines can be easily
|
|
28
|
+
plotted at the same time.
|
|
29
|
+
|
|
30
|
+
```{code-cell} ipython3
|
|
31
|
+
import sdf_xarray as sdfxr
|
|
32
|
+
import matplotlib.pyplot as plt
|
|
33
|
+
ds = sdfxr.open_dataset("tutorial_dataset_1d/0010.sdf")
|
|
34
|
+
da_1 = ds["Derived_Number_Density_Electron"]
|
|
35
|
+
da_2 = ds["Derived_Number_Density_Ion"]
|
|
36
|
+
da_1.epoch.plot(label = "Electron")
|
|
37
|
+
da_2.epoch.plot(label = "Ion")
|
|
38
|
+
plt.legend()
|
|
39
|
+
plt.show()
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Mesh plots
|
|
43
|
+
|
|
44
|
+
Two dimensional data will be plotted as a mesh.
|
|
45
|
+
|
|
46
|
+
```{code-cell} ipython3
|
|
47
|
+
ds = sdfxr.open_dataset("tutorial_dataset_2d/0010.sdf")
|
|
48
|
+
da = ds["Derived_Number_Density_Electron"]
|
|
49
|
+
da.epoch.plot()
|
|
50
|
+
plt.show()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Voxel plots
|
|
54
|
+
|
|
55
|
+
Three dimensional data will be plotted using voxels. This behaviour is not native
|
|
56
|
+
to <inv:#xarray>, it has been custom built specifically for this package.
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
ds = sdfxr.open_dataset("tutorial_dataset_3d/0000.sdf")
|
|
60
|
+
da = ds["Derived_Number_Density"]
|
|
61
|
+
da.epoch.plot(vmin = 1e27)
|
|
62
|
+
plt.show()
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+

|
|
66
|
+
|
|
67
|
+
```{warning}
|
|
68
|
+
Voxel plots can be extremely computationally expensive and may take longer than
|
|
69
|
+
expected to plot.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Because voxel plots are very expensive, even with relatively small data arrays,
|
|
73
|
+
plotting can be sped up by using [`xarray.DataArray.epoch.resize`](project:#sdf_xarray.dataarray_accessor.EpochAccessor.resize),
|
|
74
|
+
which uses interpolation to reduce the resolution.
|
|
75
|
+
|
|
76
|
+
```{code-cell} ipython3
|
|
77
|
+
ds = sdfxr.open_dataset("tutorial_dataset_3d/0005.sdf")
|
|
78
|
+
da = ds["Derived_Number_Density"]
|
|
79
|
+
da_resized = da.epoch.resize((20, 20, 20))
|
|
80
|
+
da_resized.epoch.plot(vmin = 1e27)
|
|
81
|
+
plt.show()
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Histograms
|
|
85
|
+
|
|
86
|
+
When the data array has four or more dimensions (or is specified by the user), it will
|
|
87
|
+
be plotted as a histogram.
|
|
88
|
+
|
|
89
|
+
```{code-cell} ipython3
|
|
90
|
+
ds = sdfxr.open_dataset("tutorial_dataset_3d/0005.sdf")
|
|
91
|
+
da = ds["Derived_Number_Density"]
|
|
92
|
+
|
|
93
|
+
da.epoch.plot(hist = True)
|
|
94
|
+
plt.show()
|
|
95
|
+
```
|
|
@@ -29,23 +29,10 @@ ds = sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf")
|
|
|
29
29
|
ds["Electric_Field_Ex"]
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## Visualisation
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
[
|
|
36
|
-
This is a custom <project:#sdf_xarray> plotting routine that builds on top of
|
|
37
|
-
<inv:#xarray.DataArray.plot>, so you keep the familiar <inv:#xarray> plotting
|
|
38
|
-
behaviour while using <project:#sdf_xarray> conveniences (see
|
|
39
|
-
[here](project:#sdf_xarray.dataarray_accessor.EpochAccessor.plot) for details).
|
|
40
|
-
Under the hood, plotting is still handled by <inv:#matplotlib>, which means you
|
|
41
|
-
can use the full <inv:#matplotlib> API to customise your figure.
|
|
42
|
-
|
|
43
|
-
```{code-cell} ipython3
|
|
44
|
-
# This is discretized in both space and time
|
|
45
|
-
ds["Electric_Field_Ex"].epoch.plot()
|
|
46
|
-
plt.title("Electric field along the x-axis")
|
|
47
|
-
plt.show()
|
|
48
|
-
```
|
|
34
|
+
`sdf-xarray` has built-in plotting and animation functionality, more details can
|
|
35
|
+
be found on [](./plotting.md) and [](./animation.md).
|
|
49
36
|
|
|
50
37
|
## Dimension slicing
|
|
51
38
|
|
|
@@ -56,6 +43,7 @@ for easy indexing. To quickly determine the number of time steps available,
|
|
|
56
43
|
you can check the size of the time dimension.
|
|
57
44
|
|
|
58
45
|
```{code-cell} ipython3
|
|
46
|
+
ds = sdfxr.open_mfdataset("tutorial_dataset_1d/*.sdf")
|
|
59
47
|
# This corresponds to the number of individual SDF files loaded
|
|
60
48
|
print(f"There are a total of {ds['time'].size} time steps")
|
|
61
49
|
|
|
@@ -66,7 +54,7 @@ print(f"The time at the 20th simulation step is {sim_time:.2e} s")
|
|
|
66
54
|
|
|
67
55
|
You can select and extract a single simulation snapshot using the integer
|
|
68
56
|
index of the time step with the <inv:#xarray.Dataset.isel> function. This can be
|
|
69
|
-
done by
|
|
57
|
+
done by passing the index to the `time` parameter (e.g., `time=0` for
|
|
70
58
|
the first snapshot).
|
|
71
59
|
|
|
72
60
|
```{code-cell} ipython3
|
|
@@ -74,7 +62,7 @@ ds["Electric_Field_Ex"].isel(time=20)
|
|
|
74
62
|
```
|
|
75
63
|
|
|
76
64
|
We can also use the <inv:#xarray.Dataset.sel> function if you wish to pass a
|
|
77
|
-
value
|
|
65
|
+
value instead of an index.
|
|
78
66
|
|
|
79
67
|
```{tip}
|
|
80
68
|
If you know roughly what time you wish to select but not the exact value
|
|
@@ -122,6 +110,51 @@ print(f"Total particle energy absorbed: {ds["Total_Particle_Energy_in_Simulation
|
|
|
122
110
|
print(f"The laser absorption fraction: {ds["Laser_Absorption_Fraction_in_Simulation"][-1].values:.1f} %")
|
|
123
111
|
```
|
|
124
112
|
|
|
113
|
+
## Limit
|
|
114
|
+
|
|
115
|
+
The `.epoch` accessor has the ability to "limit" data arrays. This is a helper
|
|
116
|
+
function which applies <inv:#xarray.DataArray.where> to the upper and lower bounds
|
|
117
|
+
of each dimension. You can use `None` to preserve the existing limit.
|
|
118
|
+
|
|
119
|
+
```{code-cell} ipython3
|
|
120
|
+
ds = sdfxr.open_dataset("tutorial_dataset_2d/0020.sdf")
|
|
121
|
+
da = ds["Derived_Number_Density_Electron"]
|
|
122
|
+
da.epoch.plot()
|
|
123
|
+
print(f"Orignal shape: {da.shape}")
|
|
124
|
+
plt.show()
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```{code-cell} ipython3
|
|
128
|
+
da_limit = da.epoch.limit(((-2e-6, 2e-6), (None, 0)))
|
|
129
|
+
da_limit.epoch.plot()
|
|
130
|
+
print(f"New shape: {da_limit.shape}")
|
|
131
|
+
plt.show()
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Resize
|
|
135
|
+
|
|
136
|
+
The data arrays can be interpolated with <project:#sdf_xarray.dataarray_accessor.EpochAccessor.resize>
|
|
137
|
+
to either increase or decrease the resolution while mantaining the general structure.
|
|
138
|
+
Decreasing the size may be useful to download large data from HPCs to local machines
|
|
139
|
+
or ploting with [](./plotting.md#voxel-plots). Be aware that the original
|
|
140
|
+
data will not be preserved.
|
|
141
|
+
|
|
142
|
+
```{code-cell} ipython3
|
|
143
|
+
ds = sdfxr.open_dataset("tutorial_dataset_2d/0020.sdf")
|
|
144
|
+
da = ds["Derived_Number_Density_Electron"]
|
|
145
|
+
|
|
146
|
+
da.epoch.plot()
|
|
147
|
+
print(f"Orignal shape: {da.shape}")
|
|
148
|
+
plt.show()
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
```{code-cell} ipython3
|
|
152
|
+
da_resized = da.epoch.resize((50, 50))
|
|
153
|
+
da_resized.epoch.plot()
|
|
154
|
+
print(f"New shape: {da_resized.shape}")
|
|
155
|
+
plt.show()
|
|
156
|
+
```
|
|
157
|
+
|
|
125
158
|
## Visualisation on HPC Machines
|
|
126
159
|
|
|
127
160
|
In many cases you will be running EPOCH simulations via a HPC cluster and your
|
|
@@ -7,7 +7,7 @@ There are several benefits to using this package over the [`sdf_helper`](https:/
|
|
|
7
7
|
- [data to numpy and pandas](https://docs.xarray.dev/en/stable/user-guide/pandas.html) - Data can be easily converted to [numpy](https://www.numpy.org/) or [pandas](https://pandas.pydata.org/) if you prefer to work with raw data.
|
|
8
8
|
- [data labelling](project:understanding_datasets.md) - All SDF files come with a bunch of information about them such as the `dimensions`, `units` and `name` of the variable. In <inv:#xarray> these are added to each variable making it much easier to read.
|
|
9
9
|
- [lazy/partial loading](https://docs.xarray.dev/en/stable/internals/internal-design.html#lazy-loading) - This reduces the RAM requirements when loading large SDF files as we only load the actual array values when they are needed.
|
|
10
|
-
- [plotting](project:
|
|
10
|
+
- [plotting](project:plotting.md) - You can easily plot variables across several dimensions including time using built in <inv:#matplotlib> support.
|
|
11
11
|
- [animating](project:animation.md) - Visualise your data across time or slice through another dimension and make beautiful GIFs for your presentations.
|
|
12
12
|
- [deck loading](loading-input-deck) - <project:#sdf_xarray> automatically loads in the associated `input.deck` utilised when creating the simulation so that you can access setup variables.
|
|
13
13
|
- [easier unit conversion](project:unit_conversion.md) - Convert dimensions and variable units to other types with the help of [`pint`](https://pint.readthedocs.io/en/stable).
|
|
@@ -69,6 +69,7 @@ docs = [
|
|
|
69
69
|
"sphinx-design>=0.7.0",
|
|
70
70
|
"pooch>=1.8.2",
|
|
71
71
|
"tqdm",
|
|
72
|
+
"scipy",
|
|
72
73
|
]
|
|
73
74
|
build = ["cibuildwheel[uv]"]
|
|
74
75
|
lint = ["ruff"]
|
|
@@ -80,6 +81,7 @@ test = [
|
|
|
80
81
|
"tqdm",
|
|
81
82
|
"pint",
|
|
82
83
|
"pint-xarray",
|
|
84
|
+
"scipy",
|
|
83
85
|
]
|
|
84
86
|
|
|
85
87
|
[project.entry-points."xarray.backends"]
|
|
@@ -133,6 +135,10 @@ ignore = [
|
|
|
133
135
|
"PLR2004", # magic-comparison
|
|
134
136
|
"B9", # flake8-bugbear opinionated warnings
|
|
135
137
|
"PLR0913", # remove maximum number of arguments in a function
|
|
138
|
+
"PLR0917", # remove maximum number of positional arguments in a function
|
|
139
|
+
"BLE001", # allow capturing of base exception
|
|
136
140
|
]
|
|
137
|
-
exclude = ["**/_version.py"]
|
|
138
|
-
|
|
141
|
+
exclude = ["**/_version.py"] # Auto-generated file
|
|
142
|
+
|
|
143
|
+
[tool.pytest.ini_options]
|
|
144
|
+
filterwarnings = ['ignore::UserWarning']
|