sdf-xarray 0.7.2__tar.gz → 0.7.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.
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/.gitignore +1 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/PKG-INFO +1 -1
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/conf.py +26 -1
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/animating/animate_1D_density.py +19 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/animating/animate_1D_poynting_flux.py +33 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/animating/animate_2D_dist_fn_multispecies.py +25 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/animating/animate_2D_dist_fn_multispecies_alternative.py +56 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/animating/animate_2D_poynting_flux.py +33 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/animations.md +48 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/histograms/plot_hist_ke.py +38 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/histograms/plot_hist_ke_probe.py +47 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/histograms/plot_hist_px.py +26 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/histograms.md +34 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/live_demo.ipynb +38628 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/plots.md +70 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/plotting/plot_1D_density.py +18 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/plotting/plot_1D_poynting_flux.py +32 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/plotting/plot_2D_density.py +18 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/plotting/plot_2D_dist_fn_multispecies.py +26 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/plotting/plot_2D_poynting_flux.py +33 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/plotting/plot_time_temperature.py +29 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/plotting/plot_x_px_scatter.py +24 -0
- sdf_xarray-0.7.3/docs/epoch_workshop_2026/workshop_details.md +7 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/index.md +9 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/loading_data.md +4 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/src/sdf_xarray/_version.py +3 -3
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/src/sdf_xarray/download.py +13 -18
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/.github/workflows/build_publish.yml +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/.github/workflows/lint.yml +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/.github/workflows/tests.yml +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/.gitmodules +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/.readthedocs.yaml +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/CITATION.cff +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/CMakeLists.txt +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/CONTRIBUTING.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/LICENCE +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/README.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/.gitignore +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/_static/BEAM.png +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/_static/PlasmaFAIR.svg +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/_static/force_render_dark_xarray_objects.css +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/_static/sdf-xarray-logo-dark.svg +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/_static/sdf-xarray-logo-light.svg +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/_templates/custom-class-template.rst +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/_templates/custom-module-template.rst +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/animation.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/api.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/contributing.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/installation.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/known_issues.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/make.bat +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/understanding_datasets.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/unit_conversion.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/docs/why_sdf_xarray.md +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/pyproject.toml +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/src/sdf_xarray/__init__.py +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/src/sdf_xarray/csdf.pxd +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/src/sdf_xarray/dataarray_accessor.py +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/src/sdf_xarray/dataset_accessor.py +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/src/sdf_xarray/plotting.py +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/src/sdf_xarray/sdf_interface.pyx +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/tests/test_cython.py +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/tests/test_dataset.py +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/tests/test_datatree.py +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/tests/test_epoch_dataarray_accessor.py +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/tests/test_epoch_dataset_accessor.py +0 -0
- {sdf_xarray-0.7.2 → sdf_xarray-0.7.3}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sdf-xarray
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
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
|
|
@@ -65,7 +65,12 @@ templates_path = ["_templates"]
|
|
|
65
65
|
# List of patterns, relative to source directory, that match files and
|
|
66
66
|
# directories to ignore when looking for source files.
|
|
67
67
|
# This pattern also affects html_static_path and html_extra_path.
|
|
68
|
-
exclude_patterns = [
|
|
68
|
+
exclude_patterns = [
|
|
69
|
+
"_build",
|
|
70
|
+
"Thumbs.db",
|
|
71
|
+
".DS_Store",
|
|
72
|
+
"epoch_workshop_2026/live_demo.ipynb",
|
|
73
|
+
]
|
|
69
74
|
|
|
70
75
|
# Numpy-doc config
|
|
71
76
|
napoleon_google_docstring = False
|
|
@@ -153,3 +158,23 @@ for dataset in datasets:
|
|
|
153
158
|
continue
|
|
154
159
|
else:
|
|
155
160
|
fetch_dataset(dataset, save_path=cwd)
|
|
161
|
+
|
|
162
|
+
epoch_workshop_datasets = [
|
|
163
|
+
"1_1_drifting_bunch",
|
|
164
|
+
"2_1_two_stream_instability",
|
|
165
|
+
"3_3_Gaussian_1d_laser",
|
|
166
|
+
"3_5_Gaussian_beam",
|
|
167
|
+
"4_2_self_heating",
|
|
168
|
+
"4_3_basic_target",
|
|
169
|
+
"4_4_momentum_distribution",
|
|
170
|
+
"5_1_probe",
|
|
171
|
+
"5_2_subsets",
|
|
172
|
+
]
|
|
173
|
+
|
|
174
|
+
epoch_workshop_dataset_folder = cwd / "epoch_workshop_2026" / "datasets"
|
|
175
|
+
for dataset in epoch_workshop_datasets:
|
|
176
|
+
# If the dataset already exists then don't download it again
|
|
177
|
+
if (epoch_workshop_dataset_folder / dataset).exists():
|
|
178
|
+
continue
|
|
179
|
+
else:
|
|
180
|
+
fetch_dataset(dataset, save_path=epoch_workshop_dataset_folder)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import sdf_xarray as sdfxr
|
|
4
|
+
|
|
5
|
+
input_dir = Path("datasets/1_1_drifting_bunch")
|
|
6
|
+
ds = sdfxr.open_mfdataset(input_dir)
|
|
7
|
+
|
|
8
|
+
# Convert the time to femtoseconds
|
|
9
|
+
ds = ds.epoch.rescale_coords(1e15, "fs", "time")
|
|
10
|
+
# Convert the x and y coords to microns
|
|
11
|
+
ds = ds.epoch.rescale_coords(1e6, "µm", ["X_Grid_mid"])
|
|
12
|
+
|
|
13
|
+
anim = ds["Derived_Number_Density"].epoch.animate()
|
|
14
|
+
|
|
15
|
+
# Visualise it in a Jupyter notebook
|
|
16
|
+
anim.show()
|
|
17
|
+
|
|
18
|
+
# Or save the animation
|
|
19
|
+
# anim.save(input_dir / "number_density.gif", fps=5)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
import sdf_xarray as sdfxr
|
|
6
|
+
|
|
7
|
+
input_dir = Path("datasets/3_3_Gaussian_1d_laser")
|
|
8
|
+
ds = sdfxr.open_mfdataset(input_dir)
|
|
9
|
+
|
|
10
|
+
# Convert the time to femtoseconds
|
|
11
|
+
ds = ds.epoch.rescale_coords(1e15, "fs", "time")
|
|
12
|
+
# Convert the x and y coords to microns
|
|
13
|
+
ds = ds.epoch.rescale_coords(1e6, "µm", ["X_Grid_mid"])
|
|
14
|
+
|
|
15
|
+
# Calculate Poynting flux magnitude
|
|
16
|
+
flux_magnitude = np.sqrt(
|
|
17
|
+
ds["Derived_Poynting_Flux_x"] ** 2
|
|
18
|
+
+ ds["Derived_Poynting_Flux_y"] ** 2
|
|
19
|
+
+ ds["Derived_Poynting_Flux_z"] ** 2
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# convert to W/cm^2
|
|
23
|
+
I_Wcm2 = flux_magnitude * 1e-4
|
|
24
|
+
I_Wcm2.attrs["long_name"] = "Poynting Flux Magnitude"
|
|
25
|
+
I_Wcm2.attrs["units"] = "W/cm$^2$"
|
|
26
|
+
|
|
27
|
+
anim = I_Wcm2.epoch.animate()
|
|
28
|
+
|
|
29
|
+
# Visualise it in a Jupyter notebook
|
|
30
|
+
anim.show()
|
|
31
|
+
|
|
32
|
+
# Or save the animation
|
|
33
|
+
# anim.save(input_dir / "laser.gif", fps=10)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import sdf_xarray as sdfxr
|
|
4
|
+
|
|
5
|
+
input_dir = Path("datasets/2_1_two_stream_instability")
|
|
6
|
+
ds = sdfxr.open_mfdataset(
|
|
7
|
+
input_dir, data_vars=["dist_fn_x_px_Left", "dist_fn_x_px_Right"]
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
# Rescale coords to account for kilometers
|
|
11
|
+
ds = ds.epoch.rescale_coords(1e-3, "km", ["X_x_px_Left"])
|
|
12
|
+
|
|
13
|
+
# Sum phase-space of species "Left" and "Right" in "x_px" distribution function
|
|
14
|
+
# NOTE: We only use the values from the right distribution function as if we inherit
|
|
15
|
+
# the coords we from the right we end up with 4 coords instead of 2
|
|
16
|
+
total_phase_space = ds["dist_fn_x_px_Left"] + ds["dist_fn_x_px_Right"].values
|
|
17
|
+
total_phase_space.attrs["long_name"] = "Phase Space Distribution"
|
|
18
|
+
total_phase_space.attrs["units"] = "kg.m/s"
|
|
19
|
+
|
|
20
|
+
anim = total_phase_space.epoch.animate()
|
|
21
|
+
# Visualise it in a Jupyter notebook
|
|
22
|
+
anim.show()
|
|
23
|
+
|
|
24
|
+
# Or save the animation
|
|
25
|
+
# anim.save(input_dir / "phase_space.gif")
|
sdf_xarray-0.7.3/docs/epoch_workshop_2026/animating/animate_2D_dist_fn_multispecies_alternative.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
from matplotlib.animation import FuncAnimation
|
|
5
|
+
|
|
6
|
+
import sdf_xarray as sdfxr
|
|
7
|
+
|
|
8
|
+
input_dir = Path("datasets/2_1_two_stream_instability")
|
|
9
|
+
ds = sdfxr.open_mfdataset(
|
|
10
|
+
input_dir, data_vars=["dist_fn_x_px_Left", "dist_fn_x_px_Right"]
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
# Rescale coords to account for kilometers
|
|
14
|
+
ds = ds.epoch.rescale_coords(1e-3, "km", ["X_x_px_Left"])
|
|
15
|
+
|
|
16
|
+
# Sum phase-space of species "Left" and "Right" in "x_px" distribution function
|
|
17
|
+
# NOTE: We only use the values from the right distribution function as if we inherit
|
|
18
|
+
# the coords we from the right we end up with 4 coords instead of 2
|
|
19
|
+
total_phase_space = ds["dist_fn_x_px_Left"] + ds["dist_fn_x_px_Right"].values
|
|
20
|
+
total_phase_space.attrs["long_name"] = "Phase Space Distribution"
|
|
21
|
+
total_phase_space.attrs["units"] = "kg.m/s"
|
|
22
|
+
|
|
23
|
+
fig, ax = plt.subplots()
|
|
24
|
+
|
|
25
|
+
# construct first frame
|
|
26
|
+
# Data needs to be transposed so that axes match
|
|
27
|
+
total_phase_space = total_phase_space.T
|
|
28
|
+
col_min = total_phase_space.values.min()
|
|
29
|
+
col_max = total_phase_space.values.max()
|
|
30
|
+
gif_frame = ax.pcolormesh(
|
|
31
|
+
total_phase_space["X_x_px_Left"],
|
|
32
|
+
total_phase_space["Px_x_px_Left"],
|
|
33
|
+
total_phase_space.isel(time=0),
|
|
34
|
+
vmin=col_min,
|
|
35
|
+
vmax=col_max,
|
|
36
|
+
)
|
|
37
|
+
ax.set_xlabel(
|
|
38
|
+
f"{total_phase_space['X_x_px_Left'].attrs['long_name']} [{total_phase_space['X_x_px_Left'].attrs['units']}]"
|
|
39
|
+
)
|
|
40
|
+
ax.set_ylabel(
|
|
41
|
+
f"{total_phase_space.attrs['long_name']} [{total_phase_space.attrs['units']}]"
|
|
42
|
+
)
|
|
43
|
+
ax.set_title(f"t = {ds['time'].values[0]:.3f} [{ds['time'].attrs['units']}]")
|
|
44
|
+
cbar = fig.colorbar(gif_frame, ax=ax)
|
|
45
|
+
cbar.set_label("Summed particle weight per bin")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# Make GIF
|
|
49
|
+
def update(i):
|
|
50
|
+
gif_frame.set_array(total_phase_space.isel(time=i))
|
|
51
|
+
ax.set_title(f"t = {ds['time'].values[i]:.3f} [{ds['time'].attrs['units']}]")
|
|
52
|
+
return (gif_frame,)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
anim = FuncAnimation(fig, update, frames=ds.sizes["time"])
|
|
56
|
+
anim.save(input_dir / "phase_space.gif")
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
import sdf_xarray as sdfxr
|
|
6
|
+
|
|
7
|
+
input_dir = Path("datasets/3_5_Gaussian_beam")
|
|
8
|
+
ds = sdfxr.open_mfdataset(input_dir)
|
|
9
|
+
|
|
10
|
+
# Convert the time to femtoseconds
|
|
11
|
+
ds = ds.epoch.rescale_coords(1e15, "fs", "time")
|
|
12
|
+
# Convert the x and y coords to microns
|
|
13
|
+
ds = ds.epoch.rescale_coords(1e6, "µm", ["X_Grid_mid", "Y_Grid_mid"])
|
|
14
|
+
|
|
15
|
+
# Calculate Poynting flux magnitude
|
|
16
|
+
flux_magnitude = np.sqrt(
|
|
17
|
+
ds["Derived_Poynting_Flux_x"] ** 2
|
|
18
|
+
+ ds["Derived_Poynting_Flux_y"] ** 2
|
|
19
|
+
+ ds["Derived_Poynting_Flux_z"] ** 2
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# convert to W/cm^2
|
|
23
|
+
I_Wcm2 = flux_magnitude * 1e-4
|
|
24
|
+
I_Wcm2.attrs["long_name"] = "Poynting Flux Magnitude"
|
|
25
|
+
I_Wcm2.attrs["units"] = "W/cm$^2$"
|
|
26
|
+
|
|
27
|
+
anim = I_Wcm2.epoch.animate()
|
|
28
|
+
|
|
29
|
+
# Visualise it in a Jupyter notebook
|
|
30
|
+
anim.show()
|
|
31
|
+
|
|
32
|
+
# Or save the animation
|
|
33
|
+
# anim.save(input_dir / "laser.gif", fps=10)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
file_format: mystnb
|
|
3
|
+
kernelspec:
|
|
4
|
+
name: python3
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Animations
|
|
8
|
+
|
|
9
|
+
```{note}
|
|
10
|
+
Unfortunately, these animations are not interactive like the rest of the documentation as building them on readthedocs takes too long so we display the GIFs from the datasets instead.
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Animate Density 1D
|
|
14
|
+
|
|
15
|
+
- **input deck:** <path:datasets/1_1_drifting_bunch/input.deck>
|
|
16
|
+
- **Python File:** <path:animating/animate_1D_density.py>
|
|
17
|
+
|
|
18
|
+
```{literalinclude} ./animating/animate_1D_density.py
|
|
19
|
+
```
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
## Animate Poynting Flux 1D
|
|
23
|
+
|
|
24
|
+
- **input deck:** <path:datasets/3_3_Gaussian_1d_laser/input.deck>
|
|
25
|
+
- **Python File:** <path:animating/animate_1D_poynting_flux.py>
|
|
26
|
+
|
|
27
|
+
```{literalinclude} ./animating/animate_1D_poynting_flux.py
|
|
28
|
+
```
|
|
29
|
+

|
|
30
|
+
|
|
31
|
+
## Animate Distribution Function Multi-Species 2D
|
|
32
|
+
|
|
33
|
+
- **input deck:** <path:datasets/2_1_two_stream_instability/input.deck>
|
|
34
|
+
- **Python File:** <path:animating/animate_2D_dist_fn_multispecies.py>
|
|
35
|
+
- **Python File (alternative):** <path:animating/animate_2D_dist_fn_multispecies_alternative.py>
|
|
36
|
+
|
|
37
|
+
```{literalinclude} ./animating/animate_2D_dist_fn_multispecies.py
|
|
38
|
+
```
|
|
39
|
+

|
|
40
|
+
|
|
41
|
+
## Animate Poynting Flux 2D
|
|
42
|
+
|
|
43
|
+
- **input deck:** <path:datasets/3_5_Gaussian_beam/input.deck>
|
|
44
|
+
- **Python File:** <path:animating/animate_2D_poynting_flux.py>
|
|
45
|
+
|
|
46
|
+
```{literalinclude} ./animating/animate_2D_poynting_flux.py
|
|
47
|
+
```
|
|
48
|
+

|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
import sdf_xarray as sdfxr
|
|
7
|
+
|
|
8
|
+
# Constants
|
|
9
|
+
mass = 9.1093837e-31
|
|
10
|
+
c = 299792458
|
|
11
|
+
q0 = 1.60217663e-19
|
|
12
|
+
|
|
13
|
+
input_dir = Path("datasets/4_3_basic_target")
|
|
14
|
+
ds = sdfxr.open_dataset(input_dir / "0000.sdf", keep_particles=True)
|
|
15
|
+
particles_magnitude = (
|
|
16
|
+
ds["Particles_Px_Electron"] ** 2
|
|
17
|
+
+ ds["Particles_Py_Electron"] ** 2
|
|
18
|
+
+ ds["Particles_Pz_Electron"] ** 2
|
|
19
|
+
)
|
|
20
|
+
ke_MeV = (np.sqrt(particles_magnitude * c**2 + mass**2 * c**4) - mass * c**2) / (
|
|
21
|
+
1.0e6 * q0
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
bin_edges = np.linspace(ke_MeV.min().values, ke_MeV.max().values, 101)
|
|
25
|
+
bin_N, _ = np.histogram(
|
|
26
|
+
ke_MeV.values, bins=bin_edges, weights=ds["Particles_Weight_Electron"]
|
|
27
|
+
)
|
|
28
|
+
dKE = np.diff(bin_edges)
|
|
29
|
+
dN_dKE = bin_N / dKE
|
|
30
|
+
bin_centres = 0.5 * (bin_edges[:-1] + bin_edges[1:])
|
|
31
|
+
|
|
32
|
+
plt.plot(bin_centres, dN_dKE)
|
|
33
|
+
plt.xlabel("Kinetic energy [MeV]")
|
|
34
|
+
plt.ylabel("dN/dKE [1/MeV]")
|
|
35
|
+
|
|
36
|
+
plt.savefig(input_dir / "ke_spectrum.png", dpi=300)
|
|
37
|
+
np.savetxt(input_dir / "ke_spectrum_vals.txt", ke_MeV.values)
|
|
38
|
+
np.savetxt(input_dir / "ke_spectrum_ke.txt", bin_centres)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
import sdf_xarray as sdfxr
|
|
7
|
+
|
|
8
|
+
# Constants
|
|
9
|
+
mass = 9.1093837e-31
|
|
10
|
+
c = 299792458
|
|
11
|
+
q0 = 1.60217663e-19
|
|
12
|
+
|
|
13
|
+
input_dir = Path("datasets/5_1_probe")
|
|
14
|
+
# Since we're loading particle and probes we need to specify their name
|
|
15
|
+
# from the input.deck
|
|
16
|
+
ds = sdfxr.open_mfdataset(
|
|
17
|
+
input_dir, keep_particles=True, probe_names=["Electron_probe"]
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
px = ds["Electron_probe_Px"].values.flatten()
|
|
21
|
+
py = ds["Electron_probe_Py"].values.flatten()
|
|
22
|
+
pz = ds["Electron_probe_Pz"].values.flatten()
|
|
23
|
+
probe_weights_raw = ds["Electron_probe_weight"].values.flatten()
|
|
24
|
+
|
|
25
|
+
# Create a mask to remove NaNs
|
|
26
|
+
mask = ~np.isnan(probe_weights_raw)
|
|
27
|
+
probe_weights = probe_weights_raw[mask]
|
|
28
|
+
probe_px = px[mask]
|
|
29
|
+
probe_py = py[mask]
|
|
30
|
+
probe_pz = pz[mask]
|
|
31
|
+
|
|
32
|
+
probe_magnitude = probe_px**2 + probe_py**2 + probe_pz**2
|
|
33
|
+
ke_MeV = (np.sqrt(probe_magnitude * c**2 + mass**2 * c**4) - mass * c**2) / (1.0e6 * q0)
|
|
34
|
+
|
|
35
|
+
bin_edges = np.linspace(ke_MeV.min(), ke_MeV.max(), 101)
|
|
36
|
+
bin_N, _ = np.histogram(ke_MeV, bins=bin_edges, weights=probe_weights)
|
|
37
|
+
dKE = np.diff(bin_edges)
|
|
38
|
+
dN_dKE = bin_N / dKE
|
|
39
|
+
bin_centres = 0.5 * (bin_edges[:-1] + bin_edges[1:])
|
|
40
|
+
|
|
41
|
+
plt.plot(bin_centres, dN_dKE)
|
|
42
|
+
plt.xlabel("Kinetic energy [MeV]")
|
|
43
|
+
plt.ylabel("dN/dKE [1/MeV]")
|
|
44
|
+
|
|
45
|
+
plt.savefig(input_dir / "ke_spectrum.png", dpi=300)
|
|
46
|
+
np.savetxt(input_dir / "ke_spectrum_vals.txt", ke_MeV)
|
|
47
|
+
np.savetxt(input_dir / "ke_spectrum_ke.txt", bin_centres)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import matplotlib.pyplot as plt
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
import sdf_xarray as sdfxr
|
|
7
|
+
|
|
8
|
+
input_dir = Path("datasets/4_4_momentum_distribution")
|
|
9
|
+
ds = sdfxr.open_dataset(input_dir / "0000.sdf", keep_particles=True)
|
|
10
|
+
px = ds["Particles_Px_Electron_user"].values
|
|
11
|
+
|
|
12
|
+
bin_edges = np.linspace(px.min(), px.max(), 101)
|
|
13
|
+
bin_N, _ = np.histogram(
|
|
14
|
+
px, bins=bin_edges, weights=ds["Particles_Weight_Electron_user"]
|
|
15
|
+
)
|
|
16
|
+
dpx = np.diff(bin_edges)
|
|
17
|
+
dN_dpx = bin_N / dpx
|
|
18
|
+
bin_centres = 0.5 * (bin_edges[:-1] + bin_edges[1:])
|
|
19
|
+
|
|
20
|
+
plt.plot(bin_centres, dN_dpx)
|
|
21
|
+
plt.xlabel("Px [kg.m/s]")
|
|
22
|
+
plt.ylabel("dN/dp$_x$ [s/(kg.m)]")
|
|
23
|
+
|
|
24
|
+
plt.savefig(input_dir / "px_spectrum.png", dpi=300)
|
|
25
|
+
np.savetxt(input_dir / "px_spectrum_vals.txt", dN_dpx)
|
|
26
|
+
np.savetxt(input_dir / "ke_spectrum_px.txt", bin_centres)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
file_format: mystnb
|
|
3
|
+
kernelspec:
|
|
4
|
+
name: python3
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Histograms
|
|
8
|
+
|
|
9
|
+
## Plot Histogram Kinetic Energy Probes
|
|
10
|
+
|
|
11
|
+
- **input deck:** <path:datasets/5_1_probe/input.deck>
|
|
12
|
+
- **Python File:** <path:histograms/plot_hist_ke_probe.py>
|
|
13
|
+
|
|
14
|
+
```{code-cell} ipython3
|
|
15
|
+
:load: ./histograms/plot_hist_ke_probe.py
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Plot Histogram Kinetic Energy
|
|
19
|
+
|
|
20
|
+
- **input deck:** <path:datasets/4_3_basic_target/input.deck>
|
|
21
|
+
- **Python File:** <path:histograms/plot_hist_ke.py>
|
|
22
|
+
|
|
23
|
+
```{code-cell} ipython3
|
|
24
|
+
:load: ./histograms/plot_hist_ke.py
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Plot Histogram Electron Momentum
|
|
28
|
+
|
|
29
|
+
- **input deck:** <path:datasets/4_4_momentum_distribution/input.deck>
|
|
30
|
+
- **Python File:** <path:histograms/plot_hist_px.py>
|
|
31
|
+
|
|
32
|
+
```{code-cell} ipython3
|
|
33
|
+
:load: ./histograms/plot_hist_px.py
|
|
34
|
+
```
|