sdf-xarray 0.7.4__tar.gz → 0.8.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.7.4 → sdf_xarray-0.8.0}/PKG-INFO +1 -1
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/animation.md +2 -2
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/animating/animate_1D_density.py +2 -2
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/animating/animate_1D_poynting_flux.py +2 -2
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/animating/animate_2D_dist_fn_multispecies.py +1 -1
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/animating/animate_2D_dist_fn_multispecies_alternative.py +1 -1
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/animating/animate_2D_poynting_flux.py +2 -2
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/live_demo.ipynb +2 -2
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_1D_density.py +1 -1
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_1D_poynting_flux.py +1 -1
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_2D_density.py +1 -1
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_2D_dist_fn_multispecies.py +1 -1
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_2D_poynting_flux.py +1 -1
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_time_temperature.py +1 -1
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_x_px_scatter.py +1 -1
- sdf_xarray-0.8.0/docs/epoch_workshop_2026/workshop_details.md +7 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/unit_conversion.md +4 -4
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/pyproject.toml +2 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/src/sdf_xarray/_version.py +3 -3
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/src/sdf_xarray/dataset_accessor.py +30 -18
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/tests/test_epoch_dataset_accessor.py +43 -1
- sdf_xarray-0.7.4/docs/epoch_workshop_2026/workshop_details.md +0 -7
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/.github/workflows/build_publish.yml +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/.github/workflows/lint.yml +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/.github/workflows/tests.yml +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/.gitignore +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/.gitmodules +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/.readthedocs.yaml +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/CITATION.cff +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/CMakeLists.txt +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/CONTRIBUTING.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/LICENCE +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/README.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/.gitignore +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/_static/BEAM.png +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/_static/PlasmaFAIR.svg +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/_static/force_render_dark_xarray_objects.css +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/_static/sdf-xarray-logo-dark.svg +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/_static/sdf-xarray-logo-light.svg +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/_templates/custom-class-template.rst +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/_templates/custom-module-template.rst +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/api.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/conf.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/contributing.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/animations.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/histograms/plot_hist_ke.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/histograms/plot_hist_ke_probe.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/histograms/plot_hist_px.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/histograms.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plots.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/index.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/installation.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/known_issues.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/loading_data.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/make.bat +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/understanding_datasets.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/why_sdf_xarray.md +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/src/sdf_xarray/__init__.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/src/sdf_xarray/csdf.pxd +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/src/sdf_xarray/dataarray_accessor.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/src/sdf_xarray/download.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/src/sdf_xarray/plotting.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/src/sdf_xarray/sdf_interface.pyx +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/tests/test_cython.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/tests/test_dataset.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/tests/test_datatree.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/tests/test_epoch_dataarray_accessor.py +0 -0
- {sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sdf-xarray
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.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
|
|
@@ -170,8 +170,8 @@ Some functionality such as `aspect` and `size` are not fully implemented yet.
|
|
|
170
170
|
ds = sdfxr.open_mfdataset("tutorial_dataset_2d/*.sdf")
|
|
171
171
|
|
|
172
172
|
# Change the units of the coordinates
|
|
173
|
-
ds = ds.epoch.rescale_coords(
|
|
174
|
-
ds = ds.epoch.rescale_coords(
|
|
173
|
+
ds = ds.epoch.rescale_coords("µm", ["X_Grid_mid", "Y_Grid_mid"])
|
|
174
|
+
ds = ds.epoch.rescale_coords("fs", ["time"])
|
|
175
175
|
ds["time"].attrs["long_name"] = "t"
|
|
176
176
|
|
|
177
177
|
# Change units and name of the variable
|
{sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/animating/animate_1D_density.py
RENAMED
|
@@ -6,9 +6,9 @@ input_dir = Path("datasets/1_1_drifting_bunch")
|
|
|
6
6
|
ds = sdfxr.open_mfdataset(input_dir)
|
|
7
7
|
|
|
8
8
|
# Convert the time to femtoseconds
|
|
9
|
-
ds = ds.epoch.rescale_coords(
|
|
9
|
+
ds = ds.epoch.rescale_coords("fs", "time", 1e15)
|
|
10
10
|
# Convert the x and y coords to microns
|
|
11
|
-
ds = ds.epoch.rescale_coords(
|
|
11
|
+
ds = ds.epoch.rescale_coords("µm", ["X_Grid_mid"], 1e6)
|
|
12
12
|
|
|
13
13
|
anim = ds["Derived_Number_Density"].epoch.animate()
|
|
14
14
|
|
{sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/animating/animate_1D_poynting_flux.py
RENAMED
|
@@ -8,9 +8,9 @@ input_dir = Path("datasets/3_3_Gaussian_1d_laser")
|
|
|
8
8
|
ds = sdfxr.open_mfdataset(input_dir)
|
|
9
9
|
|
|
10
10
|
# Convert the time to femtoseconds
|
|
11
|
-
ds = ds.epoch.rescale_coords(
|
|
11
|
+
ds = ds.epoch.rescale_coords("fs", "time", 1e15)
|
|
12
12
|
# Convert the x and y coords to microns
|
|
13
|
-
ds = ds.epoch.rescale_coords(
|
|
13
|
+
ds = ds.epoch.rescale_coords("µm", ["X_Grid_mid"], 1e6)
|
|
14
14
|
|
|
15
15
|
# Calculate Poynting flux magnitude
|
|
16
16
|
flux_magnitude = np.sqrt(
|
|
@@ -8,7 +8,7 @@ ds = sdfxr.open_mfdataset(
|
|
|
8
8
|
)
|
|
9
9
|
|
|
10
10
|
# Rescale coords to account for kilometers
|
|
11
|
-
ds = ds.epoch.rescale_coords(
|
|
11
|
+
ds = ds.epoch.rescale_coords("km", ["X_x_px_Left"], 1e-3)
|
|
12
12
|
|
|
13
13
|
# Sum phase-space of species "Left" and "Right" in "x_px" distribution function
|
|
14
14
|
# NOTE: We only use the values from the right distribution function as if we inherit
|
|
@@ -11,7 +11,7 @@ ds = sdfxr.open_mfdataset(
|
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
# Rescale coords to account for kilometers
|
|
14
|
-
ds = ds.epoch.rescale_coords(
|
|
14
|
+
ds = ds.epoch.rescale_coords("km", ["X_x_px_Left"], 1e-3)
|
|
15
15
|
|
|
16
16
|
# Sum phase-space of species "Left" and "Right" in "x_px" distribution function
|
|
17
17
|
# NOTE: We only use the values from the right distribution function as if we inherit
|
{sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/animating/animate_2D_poynting_flux.py
RENAMED
|
@@ -8,9 +8,9 @@ input_dir = Path("datasets/3_5_Gaussian_beam")
|
|
|
8
8
|
ds = sdfxr.open_mfdataset(input_dir)
|
|
9
9
|
|
|
10
10
|
# Convert the time to femtoseconds
|
|
11
|
-
ds = ds.epoch.rescale_coords(
|
|
11
|
+
ds = ds.epoch.rescale_coords("fs", "time", 1e15)
|
|
12
12
|
# Convert the x and y coords to microns
|
|
13
|
-
ds = ds.epoch.rescale_coords(
|
|
13
|
+
ds = ds.epoch.rescale_coords("µm", ["X_Grid_mid", "Y_Grid_mid"], 1e6)
|
|
14
14
|
|
|
15
15
|
# Calculate Poynting flux magnitude
|
|
16
16
|
flux_magnitude = np.sqrt(
|
|
@@ -3800,7 +3800,7 @@
|
|
|
3800
3800
|
},
|
|
3801
3801
|
{
|
|
3802
3802
|
"cell_type": "code",
|
|
3803
|
-
"execution_count":
|
|
3803
|
+
"execution_count": null,
|
|
3804
3804
|
"id": "2ef27498",
|
|
3805
3805
|
"metadata": {
|
|
3806
3806
|
"colab": {
|
|
@@ -3833,7 +3833,7 @@
|
|
|
3833
3833
|
}
|
|
3834
3834
|
],
|
|
3835
3835
|
"source": [
|
|
3836
|
-
"ds = ds.epoch.rescale_coords(
|
|
3836
|
+
"ds = ds.epoch.rescale_coords(\"µm\", [\"X_Grid_mid\", \"Y_Grid_mid\"], 1e6)\n",
|
|
3837
3837
|
"ds[\"Derived_Number_Density_Electron\"].isel(time=0).epoch.plot()"
|
|
3838
3838
|
]
|
|
3839
3839
|
},
|
|
@@ -8,7 +8,7 @@ import sdf_xarray as sdfxr
|
|
|
8
8
|
input_dir = Path("datasets/1_1_drifting_bunch")
|
|
9
9
|
|
|
10
10
|
ds = sdfxr.open_dataset(input_dir / "0000.sdf")
|
|
11
|
-
ds = ds.epoch.rescale_coords(
|
|
11
|
+
ds = ds.epoch.rescale_coords("µm", ["X_Grid_mid"], 1e6)
|
|
12
12
|
|
|
13
13
|
ds["Derived_Number_Density"].epoch.plot()
|
|
14
14
|
plt.tight_layout()
|
{sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_1D_poynting_flux.py
RENAMED
|
@@ -10,7 +10,7 @@ input_dir = Path("datasets/3_3_Gaussian_1d_laser")
|
|
|
10
10
|
ds = sdfxr.open_dataset(input_dir / "0020.sdf")
|
|
11
11
|
|
|
12
12
|
# Convert the x and y coords to microns
|
|
13
|
-
ds = ds.epoch.rescale_coords(
|
|
13
|
+
ds = ds.epoch.rescale_coords("µm", ["X_Grid_mid"], 1e6)
|
|
14
14
|
|
|
15
15
|
# Calculate Poynting flux magnitude
|
|
16
16
|
flux_magnitude = np.sqrt(
|
|
@@ -8,7 +8,7 @@ import sdf_xarray as sdfxr
|
|
|
8
8
|
input_dir = Path("datasets/4_3_basic_target")
|
|
9
9
|
|
|
10
10
|
ds = sdfxr.open_dataset(input_dir / "0000.sdf")
|
|
11
|
-
ds = ds.epoch.rescale_coords(
|
|
11
|
+
ds = ds.epoch.rescale_coords("µm", ["X_Grid_mid", "Y_Grid_mid"], 1e6)
|
|
12
12
|
|
|
13
13
|
ds["Derived_Number_Density"].epoch.plot()
|
|
14
14
|
plt.tight_layout()
|
|
@@ -8,7 +8,7 @@ import sdf_xarray as sdfxr
|
|
|
8
8
|
input_dir = Path("datasets/2_1_two_stream_instability")
|
|
9
9
|
ds = sdfxr.open_dataset(input_dir / "0000.sdf")
|
|
10
10
|
|
|
11
|
-
ds = ds.epoch.rescale_coords(
|
|
11
|
+
ds = ds.epoch.rescale_coords("km", ["X_x_px_Left"], 1e-3)
|
|
12
12
|
|
|
13
13
|
# Sum phase-space of species "Left" and "Right" in "x_px" distribution function
|
|
14
14
|
# NOTE: We only use the values from the right distribution function as if we inherit
|
{sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_2D_poynting_flux.py
RENAMED
|
@@ -10,7 +10,7 @@ input_dir = Path("datasets/3_5_Gaussian_beam")
|
|
|
10
10
|
ds = sdfxr.open_dataset(input_dir / "0001.sdf")
|
|
11
11
|
|
|
12
12
|
# Convert the x and y coords to microns
|
|
13
|
-
ds = ds.epoch.rescale_coords(
|
|
13
|
+
ds = ds.epoch.rescale_coords("µm", ["X_Grid_mid", "Y_Grid_mid"], 1e6)
|
|
14
14
|
|
|
15
15
|
# Calculate Poynting flux magnitude
|
|
16
16
|
flux_magnitude = np.sqrt(
|
{sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_time_temperature.py
RENAMED
|
@@ -13,7 +13,7 @@ input_dir = Path("datasets/4_2_self_heating")
|
|
|
13
13
|
ds = sdfxr.open_mfdataset(input_dir)
|
|
14
14
|
|
|
15
15
|
# Convert the time to femtoseconds
|
|
16
|
-
ds = ds.epoch.rescale_coords(
|
|
16
|
+
ds = ds.epoch.rescale_coords("fs", "time", 1e15)
|
|
17
17
|
|
|
18
18
|
# Averate temperature over all spatial cells at each time-step
|
|
19
19
|
kB = 1.380649e-23
|
{sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/plotting/plot_x_px_scatter.py
RENAMED
|
@@ -9,7 +9,7 @@ input_dir = Path("datasets/5_2_subsets")
|
|
|
9
9
|
ds = sdfxr.open_dataset(input_dir / "0000.sdf", keep_particles=True)
|
|
10
10
|
|
|
11
11
|
ds = ds.epoch.rescale_coords(
|
|
12
|
-
|
|
12
|
+
"µm", ["X_Particles_subset_Refluxers_Electron", "Y_Target_mid"], 1e6
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
x = ds["X_Particles_subset_Refluxers_Electron"]
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Workshop Details
|
|
2
|
+
|
|
3
|
+
The workshop consisted of a series of talks and practical sessions delivered at the University of York over the course of 2 days (23-24 April). It covered setting up both `EPOCH` and `sdf-xarray` along with delving into the details of how PIC codes work. The timetable is located [here](https://epochpic.github.io/quickstart/epoch_workshop_2026.html) and recordings of the presentations can be found on [YouTube](https://youtube.com/playlist?list=PLXfw-OhAIheRtwRqrGZvMqFuQ2GrIBLVl).
|
|
4
|
+
|
|
5
|
+
## Live Demo
|
|
6
|
+
|
|
7
|
+
As part of the start of the workshop a live demo covering the key features of `sdf-xarray` was performed. You can download this jupyter notebook in order to follow along <path:live_demo.ipynb>. Alternatively, if you have a Google account you can use the online [Google Colab notebook](https://colab.research.google.com/drive/1FTKj6gUizKjcL1ZSK4sNKlWKs5mzrD2g?usp=sharing).
|
|
@@ -30,7 +30,7 @@ plt.rcParams.update({
|
|
|
30
30
|
For simple scaling and unit relabelling of coordinates (e.g., converting meters to microns),
|
|
31
31
|
the most straightforward approach is to use the [`xarray.Dataset.epoch.rescale_coords`](project:#sdf_xarray.dataset_accessor.EpochAccessor.rescale_coords) dataset accessor.
|
|
32
32
|
This function scales the coordinate values by a given multiplier and updates the
|
|
33
|
-
`"units"` attribute in one step.
|
|
33
|
+
`"units"` attribute in one step. If the multiplier is not specified then the conversion parameter is inferred from the units and converted automatically using `pint` (see [](#unit-conversion-with-pint-xarray) for details).
|
|
34
34
|
|
|
35
35
|
### Rescaling grid coordinates
|
|
36
36
|
|
|
@@ -41,7 +41,7 @@ We can use the [`xarray.Dataset.epoch.rescale_coords`](project:#sdf_xarray.datas
|
|
|
41
41
|
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))
|
|
42
42
|
|
|
43
43
|
ds = sdfxr.open_mfdataset("tutorial_dataset_2d/*.sdf")
|
|
44
|
-
ds_in_microns = ds.epoch.rescale_coords(
|
|
44
|
+
ds_in_microns = ds.epoch.rescale_coords("µm", ["X_Grid_mid", "Y_Grid_mid"], 1e6)
|
|
45
45
|
|
|
46
46
|
ds["Derived_Number_Density_Electron"].isel(time=0).epoch.plot(ax=ax1)
|
|
47
47
|
ax1.set_title("Original X Coordinate (m)")
|
|
@@ -55,7 +55,7 @@ fig.tight_layout()
|
|
|
55
55
|
### Rescaling time coordinate
|
|
56
56
|
|
|
57
57
|
We can also use the [`xarray.Dataset.epoch.rescale_coords`](project:#sdf_xarray.dataset_accessor.EpochAccessor.rescale_coords) method to convert the time coordinate from
|
|
58
|
-
seconds (`s`) to femto-seconds (`fs`)
|
|
58
|
+
seconds (`s`) to femto-seconds (`fs`).
|
|
59
59
|
|
|
60
60
|
```{code-cell} ipython3
|
|
61
61
|
ds = sdfxr.open_mfdataset("tutorial_dataset_2d/*.sdf")
|
|
@@ -63,7 +63,7 @@ ds["time"]
|
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
```{code-cell} ipython3
|
|
66
|
-
ds = ds.epoch.rescale_coords(
|
|
66
|
+
ds = ds.epoch.rescale_coords("fs", "time")
|
|
67
67
|
ds["time"]
|
|
68
68
|
```
|
|
69
69
|
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.
|
|
22
|
-
__version_tuple__ = version_tuple = (0,
|
|
21
|
+
__version__ = version = '0.8.0'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 8, 0)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'gbd2a24a3a'
|
|
@@ -19,37 +19,39 @@ class EpochAccessor:
|
|
|
19
19
|
|
|
20
20
|
def rescale_coords(
|
|
21
21
|
self,
|
|
22
|
-
multiplier: float,
|
|
23
22
|
unit_label: str,
|
|
24
23
|
coord_names: str | list[str],
|
|
24
|
+
multiplier: float | None = None,
|
|
25
25
|
) -> xr.Dataset:
|
|
26
26
|
"""
|
|
27
|
-
Rescales specified
|
|
28
|
-
|
|
27
|
+
Rescales specified coordinates in a Dataset by a given unit. If the
|
|
28
|
+
multiplier is not specified then the coordinates are automatically
|
|
29
|
+
scaled using `pint <https://pint.readthedocs.io/en/stable>`_, if the multiplier is specified then it will be
|
|
30
|
+
used to rescale the coordinate.
|
|
29
31
|
|
|
30
32
|
Parameters
|
|
31
33
|
----------
|
|
32
|
-
multiplier : float
|
|
33
|
-
The factor by which to multiply the coordinate values (e.g., 1e6 for meters to microns).
|
|
34
34
|
unit_label : str
|
|
35
35
|
The new unit label for the coordinates (e.g., "µm").
|
|
36
36
|
coord_names : str or list of str
|
|
37
37
|
The name(s) of the coordinate variable(s) to rescale.
|
|
38
38
|
If a string, only that coordinate is rescaled.
|
|
39
39
|
If a list, all listed coordinates are rescaled.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
A new Dataset with the updated and rescaled coordinates.
|
|
40
|
+
multiplier : float or None
|
|
41
|
+
The factor by which to multiply the coordinate values (e.g., 1e6
|
|
42
|
+
for meters to microns). If not specified then ``pint`` is used to
|
|
43
|
+
rescale the units automatically.
|
|
45
44
|
|
|
46
45
|
Examples
|
|
47
46
|
--------
|
|
48
|
-
# Convert X, Y, and Z from meters to microns
|
|
49
|
-
>>> ds_in_microns = ds.epoch.rescale_coords(
|
|
50
|
-
|
|
51
|
-
# Convert
|
|
52
|
-
>>>
|
|
47
|
+
>>> # Convert X, Y, and Z from meters to microns using pint
|
|
48
|
+
>>> ds_in_microns = ds.epoch.rescale_coords("µm", coord_names=["X_Grid", "Y_Grid", "Z_Grid"])
|
|
49
|
+
>>>
|
|
50
|
+
>>> # Convert X, Y, and Z from meters to microns
|
|
51
|
+
>>> ds_in_microns = ds.epoch.rescale_coords("µm", coord_names=["X_Grid", "Y_Grid", "Z_Grid"], 1e6)
|
|
52
|
+
>>>
|
|
53
|
+
>>> # Convert time to femtoseconds
|
|
54
|
+
>>> ds_in_mm = ds.epoch.rescale_coords("fs", coord_names="time")
|
|
53
55
|
"""
|
|
54
56
|
|
|
55
57
|
ds = self._ds
|
|
@@ -72,9 +74,19 @@ class EpochAccessor:
|
|
|
72
74
|
|
|
73
75
|
coord_original = ds[coord_name]
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
if multiplier is not None:
|
|
78
|
+
coord_rescaled = coord_original * multiplier
|
|
79
|
+
coord_rescaled.attrs = coord_original.attrs.copy()
|
|
80
|
+
coord_rescaled.attrs["units"] = unit_label
|
|
81
|
+
else:
|
|
82
|
+
coord_rescaled: xr.DataArray = (
|
|
83
|
+
coord_original.pint.quantify(coord_original.attrs["units"])
|
|
84
|
+
.pint.to(unit_label)
|
|
85
|
+
.pint.dequantify()
|
|
86
|
+
)
|
|
87
|
+
# Ensure the unit label follows the same naming convension the
|
|
88
|
+
# user has specified and not the one given by pint
|
|
89
|
+
coord_rescaled.attrs["units"] = unit_label
|
|
78
90
|
|
|
79
91
|
new_coords[coord_name] = coord_rescaled
|
|
80
92
|
|
|
@@ -50,6 +50,32 @@ def test_rescale_coords_X():
|
|
|
50
50
|
assert ds_rescaled["Z_Grid_mid"].attrs["full_name"] == "Grid/Grid_mid"
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
def test_rescale_coords_X_auto():
|
|
54
|
+
unit_label = "mm"
|
|
55
|
+
|
|
56
|
+
with xr.open_dataset(TEST_FILES_DIR_3D / "0000.sdf") as ds:
|
|
57
|
+
ds_rescaled = ds.epoch.rescale_coords(
|
|
58
|
+
unit_label=unit_label,
|
|
59
|
+
coord_names="X_Grid_mid",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
expected_x = ds["X_Grid_mid"].values * 1e3
|
|
63
|
+
assert np.allclose(ds_rescaled["X_Grid_mid"].values, expected_x)
|
|
64
|
+
assert ds_rescaled["X_Grid_mid"].attrs["units"] == unit_label
|
|
65
|
+
assert ds_rescaled["X_Grid_mid"].attrs["long_name"] == "X"
|
|
66
|
+
assert ds_rescaled["X_Grid_mid"].attrs["full_name"] == "Grid/Grid_mid"
|
|
67
|
+
|
|
68
|
+
assert np.allclose(ds_rescaled["Y_Grid_mid"].values, ds["Y_Grid_mid"].values)
|
|
69
|
+
assert ds_rescaled["Y_Grid_mid"].attrs["units"] == "m"
|
|
70
|
+
assert ds_rescaled["Y_Grid_mid"].attrs["long_name"] == "Y"
|
|
71
|
+
assert ds_rescaled["Y_Grid_mid"].attrs["full_name"] == "Grid/Grid_mid"
|
|
72
|
+
|
|
73
|
+
assert np.allclose(ds_rescaled["Z_Grid_mid"].values, ds["Z_Grid_mid"].values)
|
|
74
|
+
assert ds_rescaled["Z_Grid_mid"].attrs["units"] == "m"
|
|
75
|
+
assert ds_rescaled["Z_Grid_mid"].attrs["long_name"] == "Z"
|
|
76
|
+
assert ds_rescaled["Z_Grid_mid"].attrs["full_name"] == "Grid/Grid_mid"
|
|
77
|
+
|
|
78
|
+
|
|
53
79
|
def test_rescale_coords_X_Y():
|
|
54
80
|
multiplier = 1e2
|
|
55
81
|
unit_label = "cm"
|
|
@@ -142,7 +168,7 @@ def test_rescale_coords_non_existent_coord():
|
|
|
142
168
|
|
|
143
169
|
|
|
144
170
|
def test_rescale_coords_time():
|
|
145
|
-
multiplier =
|
|
171
|
+
multiplier = 1e15
|
|
146
172
|
unit_label = "fs"
|
|
147
173
|
|
|
148
174
|
with open_mfdataset(TEST_FILES_DIR_3D.glob("*.sdf")) as ds:
|
|
@@ -159,6 +185,22 @@ def test_rescale_coords_time():
|
|
|
159
185
|
assert ds_rescaled["time"].attrs["full_name"] == "time"
|
|
160
186
|
|
|
161
187
|
|
|
188
|
+
def test_rescale_coords_time_auto():
|
|
189
|
+
unit_label = "fs"
|
|
190
|
+
|
|
191
|
+
with open_mfdataset(TEST_FILES_DIR_3D.glob("*.sdf")) as ds:
|
|
192
|
+
ds_rescaled = ds.epoch.rescale_coords(
|
|
193
|
+
unit_label=unit_label,
|
|
194
|
+
coord_names="time",
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
expected_time = ds["time"].values * 1e15
|
|
198
|
+
assert np.allclose(ds_rescaled["time"].values, expected_time)
|
|
199
|
+
assert ds_rescaled["time"].attrs["units"] == unit_label
|
|
200
|
+
assert ds_rescaled["time"].attrs["long_name"] == "Time"
|
|
201
|
+
assert ds_rescaled["time"].attrs["full_name"] == "time"
|
|
202
|
+
|
|
203
|
+
|
|
162
204
|
def test_animate_multiple_accessor():
|
|
163
205
|
with open_mfdataset(TEST_FILES_DIR_1D.glob("*.sdf")) as ds:
|
|
164
206
|
assert hasattr(ds, "epoch")
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# Workshop Details
|
|
2
|
-
|
|
3
|
-
The workshop consists of a series of talks and practical sessions delivered at the University of York over the course of 2 days (23-24 April). It covers setting up both EPOCH and sdf-xarray along with delving into the details of how PIC codes work. The timetable can be found here <https://epochpic.github.io/quickstart/epoch_workshop_2026.html>.
|
|
4
|
-
|
|
5
|
-
## Live Demo
|
|
6
|
-
|
|
7
|
-
As part of the start of the workshop we will have a live demo covering the key features of sdf-xarray. Please download this jupyter notebook in order to follow along <path:live_demo.ipynb>. Alternatively, if you have a Google account you can use the online [Google Colab notebook](https://colab.research.google.com/drive/1FTKj6gUizKjcL1ZSK4sNKlWKs5mzrD2g?usp=sharing).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{sdf_xarray-0.7.4 → sdf_xarray-0.8.0}/docs/epoch_workshop_2026/histograms/plot_hist_ke_probe.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|