sdf-xarray 0.2.5__tar.gz → 0.2.6__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.

Potentially problematic release.


This version of sdf-xarray might be problematic. Click here for more details.

Files changed (117) hide show
  1. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/.github/workflows/build_publish.yml +1 -1
  2. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/CONTRIBUTING.md +6 -0
  3. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/PKG-INFO +8 -35
  4. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/index.rst +1 -0
  5. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/key_functionality.rst +6 -0
  6. sdf_xarray-0.2.6/docs/known_issues.rst +9 -0
  7. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/pyproject.toml +7 -10
  8. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/src/sdf_xarray/__init__.py +47 -4
  9. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/src/sdf_xarray/_version.py +16 -3
  10. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/src/sdf_xarray/plotting.py +2 -2
  11. sdf_xarray-0.2.6/tests/example_two_probes_2D/0000.sdf +0 -0
  12. sdf_xarray-0.2.6/tests/example_two_probes_2D/0001.sdf +0 -0
  13. sdf_xarray-0.2.6/tests/example_two_probes_2D/0002.sdf +0 -0
  14. sdf_xarray-0.2.6/tests/example_two_probes_2D/input.deck +188 -0
  15. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/test_basic.py +30 -0
  16. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/uv.lock +999 -1041
  17. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/.github/workflows/black.yml +0 -0
  18. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/.github/workflows/lint.yml +0 -0
  19. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/.github/workflows/tests.yml +0 -0
  20. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/.gitignore +0 -0
  21. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/.gitmodules +0 -0
  22. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/.readthedocs.yaml +0 -0
  23. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/BEAM.png +0 -0
  24. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/CITATION.cff +0 -0
  25. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/CMakeLists.txt +0 -0
  26. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/LICENCE +0 -0
  27. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/PlasmaFAIR.svg +0 -0
  28. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/README.md +0 -0
  29. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/.gitignore +0 -0
  30. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/_templates/custom-class-template.rst +0 -0
  31. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/_templates/custom-module-template.rst +0 -0
  32. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/api.rst +0 -0
  33. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/conf.py +0 -0
  34. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/contributing.rst +0 -0
  35. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/getting_started.rst +0 -0
  36. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/make.bat +0 -0
  37. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0000.sdf +0 -0
  38. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0001.sdf +0 -0
  39. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0002.sdf +0 -0
  40. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0003.sdf +0 -0
  41. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0004.sdf +0 -0
  42. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0005.sdf +0 -0
  43. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0006.sdf +0 -0
  44. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0007.sdf +0 -0
  45. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0008.sdf +0 -0
  46. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0009.sdf +0 -0
  47. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0010.sdf +0 -0
  48. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0011.sdf +0 -0
  49. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0012.sdf +0 -0
  50. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0013.sdf +0 -0
  51. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0014.sdf +0 -0
  52. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0015.sdf +0 -0
  53. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0016.sdf +0 -0
  54. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0017.sdf +0 -0
  55. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0018.sdf +0 -0
  56. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0019.sdf +0 -0
  57. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0020.sdf +0 -0
  58. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0021.sdf +0 -0
  59. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0022.sdf +0 -0
  60. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0023.sdf +0 -0
  61. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0024.sdf +0 -0
  62. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0025.sdf +0 -0
  63. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0026.sdf +0 -0
  64. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0027.sdf +0 -0
  65. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0028.sdf +0 -0
  66. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0029.sdf +0 -0
  67. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0030.sdf +0 -0
  68. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0031.sdf +0 -0
  69. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0032.sdf +0 -0
  70. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0033.sdf +0 -0
  71. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0034.sdf +0 -0
  72. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0035.sdf +0 -0
  73. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0036.sdf +0 -0
  74. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0037.sdf +0 -0
  75. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0038.sdf +0 -0
  76. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0039.sdf +0 -0
  77. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/0040.sdf +0 -0
  78. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/deck.status +0 -0
  79. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/epoch1d.dat +0 -0
  80. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/input.deck +0 -0
  81. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/normal.visit +0 -0
  82. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/tutorial_dataset_1d/restart.visit +0 -0
  83. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/docs/unit_conversion.rst +0 -0
  84. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/src/sdf_xarray/csdf.pxd +0 -0
  85. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/src/sdf_xarray/sdf_interface.pyx +0 -0
  86. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_array_no_grids/0000.sdf +0 -0
  87. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_array_no_grids/0001.sdf +0 -0
  88. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_array_no_grids/README.md +0 -0
  89. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_array_no_grids/input.deck +0 -0
  90. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_dist_fn/0000.sdf +0 -0
  91. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_dist_fn/0001.sdf +0 -0
  92. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_dist_fn/0002.sdf +0 -0
  93. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_dist_fn/input.deck +0 -0
  94. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0000.sdf +0 -0
  95. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0001.sdf +0 -0
  96. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0002.sdf +0 -0
  97. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0003.sdf +0 -0
  98. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0004.sdf +0 -0
  99. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0005.sdf +0 -0
  100. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0006.sdf +0 -0
  101. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0007.sdf +0 -0
  102. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0008.sdf +0 -0
  103. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0009.sdf +0 -0
  104. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/0010.sdf +0 -0
  105. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/README.md +0 -0
  106. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_1D/input.deck +0 -0
  107. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_2D_moving_window/0000.sdf +0 -0
  108. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_2D_moving_window/0001.sdf +0 -0
  109. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_2D_moving_window/0002.sdf +0 -0
  110. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_2D_moving_window/0003.sdf +0 -0
  111. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_2D_moving_window/0004.sdf +0 -0
  112. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_files_2D_moving_window/input.deck +0 -0
  113. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_mismatched_files/0000.sdf +0 -0
  114. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_mismatched_files/0001.sdf +0 -0
  115. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/example_mismatched_files/0002.sdf +0 -0
  116. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/test_cython.py +0 -0
  117. {sdf_xarray-0.2.5 → sdf_xarray-0.2.6}/tests/test_epoch_accessor.py +0 -0
@@ -32,7 +32,7 @@ jobs:
32
32
  uv sync --python 3.12 --extra test --extra build --frozen
33
33
 
34
34
  - name: Build
35
- uses: pypa/cibuildwheel@v2.21.3
35
+ uses: pypa/cibuildwheel@v3.1.3
36
36
  env:
37
37
  CIBW_ARCHS_LINUX: auto
38
38
  CIBW_ARCHS_MACOS: x86_64 arm64
@@ -68,6 +68,12 @@ pip install "sdf-xarray[docs]"
68
68
  cd docs
69
69
  make html
70
70
  ```
71
+
72
+ The documentation can be updated by changing any of the `*.rst` files located
73
+ in the main `docs` directory. The existing documentation hopefully includes most
74
+ of the snippets you'd need to write or update it, however if you are stuck
75
+ please don't hesitate to reach out.
76
+
71
77
  Every time you make changes to the documentation or add a new page, you must
72
78
  re-run the `make html` command to regenerate the HTML files.
73
79
 
@@ -1,47 +1,20 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: sdf-xarray
3
- Version: 0.2.5
3
+ Version: 0.2.6
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>
6
- License: Copyright 2024, Peter Hill, Joel Adams, epochpic team
7
-
8
- Redistribution and use in source and binary forms, with or without
9
- modification, are permitted provided that the following conditions are
10
- met:
11
-
12
- 1. Redistributions of source code must retain the above copyright
13
- notice, this list of conditions and the following disclaimer.
14
-
15
- 2. Redistributions in binary form must reproduce the above copyright
16
- notice, this list of conditions and the following disclaimer in the
17
- documentation and/or other materials provided with the distribution.
18
-
19
- 3. Neither the name of the copyright holder nor the names of its
20
- contributors may be used to endorse or promote products derived from
21
- this software without specific prior written permission.
22
-
23
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
- “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
-
6
+ License-Expression: BSD-3-Clause
7
+ Classifier: Development Status :: 5 - Production/Stable
8
+ Classifier: Intended Audience :: Science/Research
9
+ Classifier: Topic :: Scientific/Engineering
10
+ Classifier: Operating System :: OS Independent
35
11
  Classifier: Programming Language :: Python
36
12
  Classifier: Programming Language :: Python :: 3
37
13
  Classifier: Programming Language :: Python :: 3.10
38
14
  Classifier: Programming Language :: Python :: 3.11
39
15
  Classifier: Programming Language :: Python :: 3.12
40
16
  Classifier: Programming Language :: Python :: 3.13
41
- Classifier: Intended Audience :: Science/Research
42
- Classifier: Topic :: Scientific/Engineering
43
- Classifier: Operating System :: OS Independent
44
- Requires-Python: >=3.10
17
+ Requires-Python: <3.14,>=3.10
45
18
  Requires-Dist: numpy>=2.0.0
46
19
  Requires-Dist: xarray>=2024.1.0
47
20
  Requires-Dist: dask>=2024.7.1
@@ -15,6 +15,7 @@ plasma PIC code.
15
15
  Getting Started <getting_started>
16
16
  Key Functionality <key_functionality>
17
17
  Unit Conversion <unit_conversion>
18
+ Known Issues <known_issues>
18
19
  Contributing <contributing>
19
20
 
20
21
  .. toctree::
@@ -51,6 +51,12 @@ done via the ``preprocess`` parameter.
51
51
  Reading particle data
52
52
  ~~~~~~~~~~~~~~~~~~~~~
53
53
 
54
+ .. warning::
55
+ It is **not recommended** to use :func:`xarray.open_mfdataset` or :func:`open_mfdataset` to load particle data from multiple SDF outputs. The number of particles often varies between outputs, which can lead to inconsistent array shapes that these functions cannot handle. Instead, consider loading each file individually and then concatenating them manually.
56
+
57
+ .. note::
58
+ When loading multiple probes from a single SDF file, you **must** use the `probe_names` parameter to assign a unique name to each. For example, use `probe_names=["Front_Electron_Probe", "Back_Electron_Probe"]`. Failing to do so will result in dimension name conflicts.
59
+
54
60
  By default, particle data isn't kept as it takes up a lot of space.
55
61
  Pass ``keep_particles=True`` as a keyword argument to
56
62
  :func:`xarray.open_dataset` (for single files) or :func:`xarray.open_mfdataset` (for
@@ -0,0 +1,9 @@
1
+ .. _sec-known-issues:
2
+
3
+ ============
4
+ Known Issues
5
+ ============
6
+
7
+ There are a couple of known 'quirks' in sdf-xarray:
8
+
9
+ - `Issue #57 <https://github.com/epochpic/sdf-xarray/issues/57>`_ Loading multiple SDF files with `open_mfdataset` can lead to out-of-memory errors. The issue is believed to stem from how the underlying `xarray` library handles coordinates, causing it to infer an excessively large array shape that requests far more memory than is needed. Due to the significant architectural changes required for a fix, the maintainers do not plan to resolve this. The recommended solution is to load the files individually or in smaller batches.
@@ -10,30 +10,27 @@ build-backend = "scikit_build_core.build"
10
10
  [project]
11
11
  name = "sdf-xarray"
12
12
  dynamic = ["version"]
13
- license = { file = "LICENCE" }
13
+ license = "BSD-3-Clause"
14
14
  readme = "README.md"
15
15
  authors = [
16
16
  { name = "Peter Hill", email = "peter.hill@york.ac.uk" },
17
17
  { name = "Joel Adams", email = "joel.adams@york.ac.uk" },
18
18
  { name = "Shaun Doherty", email = "shaun.doherty@york.ac.uk" },
19
19
  ]
20
- requires-python = ">=3.10"
21
- dependencies = [
22
- "numpy>=2.0.0",
23
- "xarray>=2024.1.0",
24
- "dask>=2024.7.1",
25
- ]
20
+ requires-python = ">=3.10,<3.14"
21
+ dependencies = ["numpy>=2.0.0", "xarray>=2024.1.0", "dask>=2024.7.1"]
26
22
  description = "Provides a backend for xarray to read SDF files as created by the EPOCH plasma PIC code."
27
23
  classifiers = [
24
+ "Development Status :: 5 - Production/Stable",
25
+ "Intended Audience :: Science/Research",
26
+ "Topic :: Scientific/Engineering",
27
+ "Operating System :: OS Independent",
28
28
  "Programming Language :: Python",
29
29
  "Programming Language :: Python :: 3",
30
30
  "Programming Language :: Python :: 3.10",
31
31
  "Programming Language :: Python :: 3.11",
32
32
  "Programming Language :: Python :: 3.12",
33
33
  "Programming Language :: Python :: 3.13",
34
- "Intended Audience :: Science/Research",
35
- "Topic :: Scientific/Engineering",
36
- "Operating System :: OS Independent",
37
34
  ]
38
35
 
39
36
  [project.optional-dependencies]
@@ -69,6 +69,7 @@ def open_mfdataset(
69
69
  *,
70
70
  separate_times: bool = False,
71
71
  keep_particles: bool = False,
72
+ probe_names: list[str] | None = None,
72
73
  ) -> xr.Dataset:
73
74
  """Open a set of EPOCH SDF files as one `xarray.Dataset`
74
75
 
@@ -98,6 +99,8 @@ def open_mfdataset(
98
99
  different output frequencies
99
100
  keep_particles :
100
101
  If ``True``, also load particle data (this may use a lot of memory!)
102
+ probe_names :
103
+ List of EPOCH probe names
101
104
  """
102
105
 
103
106
  # TODO: This is not very robust, look at how xarray.open_mfdataset does it
@@ -108,10 +111,15 @@ def open_mfdataset(
108
111
  path_glob = sorted(list(path_glob)) # noqa: C414
109
112
 
110
113
  if not separate_times:
111
- return combine_datasets(path_glob, keep_particles=keep_particles)
114
+ return combine_datasets(
115
+ path_glob, keep_particles=keep_particles, probe_names=probe_names
116
+ )
112
117
 
113
118
  time_dims, var_times_map = make_time_dims(path_glob)
114
- all_dfs = [xr.open_dataset(f, keep_particles=keep_particles) for f in path_glob]
119
+ all_dfs = [
120
+ xr.open_dataset(f, keep_particles=keep_particles, probe_names=probe_names)
121
+ for f in path_glob
122
+ ]
115
123
 
116
124
  for df in all_dfs:
117
125
  for da in df:
@@ -211,14 +219,23 @@ class SDFDataStore(AbstractDataStore):
211
219
  "drop_variables",
212
220
  "keep_particles",
213
221
  "lock",
222
+ "probe_names",
214
223
  )
215
224
 
216
- def __init__(self, manager, drop_variables=None, keep_particles=False, lock=None):
225
+ def __init__(
226
+ self,
227
+ manager,
228
+ drop_variables=None,
229
+ keep_particles=False,
230
+ lock=None,
231
+ probe_names=None,
232
+ ):
217
233
  self._manager = manager
218
234
  self._filename = self.ds.filename
219
235
  self.drop_variables = drop_variables
220
236
  self.keep_particles = keep_particles
221
237
  self.lock = ensure_lock(lock)
238
+ self.probe_names = probe_names
222
239
 
223
240
  @classmethod
224
241
  def open(
@@ -227,6 +244,7 @@ class SDFDataStore(AbstractDataStore):
227
244
  lock=None,
228
245
  drop_variables=None,
229
246
  keep_particles=False,
247
+ probe_names=None,
230
248
  ):
231
249
  if isinstance(filename, os.PathLike):
232
250
  filename = os.fspath(filename)
@@ -237,6 +255,7 @@ class SDFDataStore(AbstractDataStore):
237
255
  lock=lock,
238
256
  drop_variables=drop_variables,
239
257
  keep_particles=keep_particles,
258
+ probe_names=probe_names,
240
259
  )
241
260
 
242
261
  def _acquire(self, needs_lock=True):
@@ -347,7 +366,28 @@ class SDFDataStore(AbstractDataStore):
347
366
 
348
367
  if value.is_point_data:
349
368
  # Point (particle) variables are 1D
350
- var_coords = (f"ID_{_process_grid_name(key, _grid_species_name)}",)
369
+
370
+ # Particle data does not maintain a fixed dimension size
371
+ # throughout the simulation. An example of a particle name comes
372
+ # in the form of `Particles/Px/Ion_H` which is then modified
373
+ # using `_process_grid_name()` into `Ion_H`. This is fine as the
374
+ # other components of the momentum (`Py`, `Pz`) will have the same
375
+ # size as they represent the same bunch of particles.
376
+
377
+ # Probes however have names in the form of `Electron_Front_Probe/Px`
378
+ # which are changed to just `Px`; this is fine when there is only one
379
+ # probe in the system but when there are multiple they will have
380
+ # conflicting sizes so we can't keep the names as simply `Px` so we
381
+ # instead set their dimension as the full name `Electron_Front_Probe_Px`.
382
+ is_probe_name_match = self.probe_names is not None and any(
383
+ name in key for name in self.probe_names
384
+ )
385
+ name_processor = (
386
+ _rename_with_underscore
387
+ if is_probe_name_match
388
+ else _grid_species_name
389
+ )
390
+ var_coords = (f"ID_{_process_grid_name(key, name_processor)}",)
351
391
  else:
352
392
  # These are DataArrays
353
393
 
@@ -414,6 +454,7 @@ class SDFEntrypoint(BackendEntrypoint):
414
454
  *,
415
455
  drop_variables=None,
416
456
  keep_particles=False,
457
+ probe_names=None,
417
458
  ):
418
459
  if isinstance(filename_or_obj, Path):
419
460
  # sdf library takes a filename only
@@ -424,6 +465,7 @@ class SDFEntrypoint(BackendEntrypoint):
424
465
  filename_or_obj,
425
466
  drop_variables=drop_variables,
426
467
  keep_particles=keep_particles,
468
+ probe_names=probe_names,
427
469
  )
428
470
  with close_on_error(store):
429
471
  return store.load()
@@ -432,6 +474,7 @@ class SDFEntrypoint(BackendEntrypoint):
432
474
  "filename_or_obj",
433
475
  "drop_variables",
434
476
  "keep_particles",
477
+ "probe_names",
435
478
  ]
436
479
 
437
480
  def guess_can_open(self, filename_or_obj):
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '0.2.5'
21
- __version_tuple__ = version_tuple = (0, 2, 5)
31
+ __version__ = version = '0.2.6'
32
+ __version_tuple__ = version_tuple = (0, 2, 6)
33
+
34
+ __commit_id__ = commit_id = 'g67411803b'
@@ -114,8 +114,8 @@ def animate(
114
114
  --------
115
115
  >>> dataset["Derived_Number_Density_Electron"].epoch.animate()
116
116
  """
117
- import matplotlib.pyplot as plt
118
- from matplotlib.animation import FuncAnimation
117
+ import matplotlib.pyplot as plt # noqa: PLC0415
118
+ from matplotlib.animation import FuncAnimation # noqa: PLC0415
119
119
 
120
120
  kwargs_original = kwargs.copy()
121
121
 
@@ -0,0 +1,188 @@
1
+
2
+ ### USER DEFINED CONSTANTS ###
3
+ begin:constant
4
+ # User input constants
5
+ n_elec = 6e+29 #average electron number density
6
+ I_peak = 1e+28 #peak intensity of the laser
7
+
8
+ scale_length = 0.5e-6 #scale length of the target
9
+ L_target_x = 1.5e-6 #length of the target
10
+ L_target_y = 10e-6 #width of the target
11
+
12
+ lambda_L = 800e-9 #wavelength of the laser
13
+ y_fwhm_L = 2e-6 #intensity fwhm in y
14
+ tau_fwhm_L = 16e-15 #intensity fwhm in t
15
+
16
+ mppc = 100 #macro particles per cell
17
+ end:constant
18
+
19
+ begin:control
20
+ nx = 150
21
+ ny = 200
22
+ nsteps = -1
23
+ t_end = 200e-15
24
+ x_min = -10e-06
25
+ x_max = 5e-06
26
+ y_min = -10e-06
27
+ y_max = -y_min
28
+ nparticles = nint(((L_target_x * L_target_y) / ((x_max - x_min) * (y_max - y_min))) * nx * ny * mppc)
29
+ dt_multiplier = 0.8
30
+ smooth_currents = T
31
+ dlb_threshold = 0.8
32
+ stdout_frequency = 100 # Print ETA
33
+ particle_tstart = 30e-15 # Time before the laser hits the target
34
+ end:control
35
+
36
+ ### CALCULATD CONSTANTS ###
37
+ begin:constant
38
+ w_t = tau_fwhm_L / (2*sqrt(loge(2))) # Beam waist in t
39
+ w_y = y_fwhm_L / (2*sqrt(loge(2))) # Beam waist in y
40
+ t_hw01m = 0.5 * tau_fwhm_L * sqrt(loge(10)/loge(2))
41
+
42
+ x_foc = -x_min # Boundary to focal point distance
43
+ k_L = 2.0 * pi / lambda_L # Laser wave number
44
+ x_Rr = pi * w_y^2 / lambda_L # Rayleigh range
45
+ omega_L = 2 * pi * c / lambda_L # Angular frequency of the laser
46
+
47
+ w_boundary = w_y * sqrt(1 + (x_foc/x_Rr)^2) # Waist on boundary
48
+ I_boundary = I_peak * (w_y / w_boundary)^2 # Intens. on boundary
49
+ r_curve = x_foc * (1 + (x_Rr/x_foc)^2) # Boundary curv. rad.
50
+ phase_Gouy = atan(-x_foc/r_curve) # Boundary Gouy shift
51
+ end:constant
52
+
53
+ begin:laser
54
+ boundary = x_min
55
+ intensity = I_boundary
56
+ omega = omega_L
57
+ phase = k_L * y^2 / (2 * r_curve) - phase_Gouy
58
+ profile = gauss(y, 0, w_boundary)
59
+ t_profile = gauss(time, t_hw01m, w_t)
60
+ t_start = 0.0
61
+ t_end = end
62
+ end:laser
63
+
64
+ begin:qed
65
+ use_qed = F
66
+ qed_start_time = 0
67
+ produce_photons = T
68
+ photon_energy_min = 1 * kev
69
+ produce_pairs = T
70
+ photon_dynamics = T
71
+ end:qed
72
+
73
+ begin:collisions
74
+ use_collisions = T
75
+ coulomb_log = auto
76
+ collide = all
77
+ end:collisions
78
+
79
+ begin:boundaries
80
+ bc_x_min_particle = simple_outflow
81
+ bc_x_max_particle = simple_outflow
82
+ bc_y_min_particle = reflect
83
+ bc_y_max_particle = reflect
84
+ bc_x_min_field = simple_laser
85
+ bc_x_max_field = conduct
86
+ bc_y_min_field = conduct
87
+ bc_y_max_field = conduct
88
+ end:boundaries
89
+
90
+ begin:species
91
+ name = Electron
92
+ frac = 0.5
93
+ dump = T
94
+ temperature = 300
95
+ number_density = if((abs(y) lt L_target_y/2), if((x lt 0) or (x gt L_target_x), 0, if((x gt 0) and (x lt scale_length), n_elec * (1-exp(x/scale_length))/(1-exp(1)), n_elec)), 0)
96
+ number_density_min = 1
97
+ identify:electron
98
+ end:species
99
+
100
+ begin:species
101
+ name = Ion_C
102
+ charge = 6
103
+ atomic_number = 12
104
+ mass = 1836.2 * 12
105
+ frac = 0.25
106
+ dump = T
107
+ number_density = number_density(Electron) * (6/7)
108
+ temperature = temperature_x(Electron)
109
+ number_density_min = 1
110
+ end:species
111
+
112
+ begin:species
113
+ name = Ion_H
114
+ charge = 1
115
+ atomic_number = 1
116
+ mass = 1836.2
117
+ fraction = 0.25
118
+ dump = T
119
+ number_density = number_density(Electron) / 7
120
+ temperature = temperature_x(Electron)
121
+ number_density_min = 1
122
+ identify:proton
123
+ end:species
124
+
125
+ begin:species
126
+ name = Photon
127
+ nparticles = 0
128
+ dump = T
129
+ identify:photon
130
+ end:species
131
+
132
+ begin:species
133
+ name = Positron
134
+ nparticles = 0
135
+ dump = T
136
+ identify:positron
137
+ end:species
138
+
139
+ ### THE MANY PARTICLE PROBES ###
140
+
141
+ #Electron#
142
+ begin:probe
143
+ name = Electron_Front_Probe
144
+ point = (x_min, 0)
145
+ normal = (-1.0, 0.0)
146
+ ek_min = 0.0
147
+ ek_max = -1.0
148
+ include_species : Electron
149
+ dumpmask = always
150
+ end:probe
151
+ begin:probe
152
+ name = Electron_Back_Probe
153
+ point = (x_max, 0)
154
+ normal = (1.0, 0.0)
155
+ ek_min = 0.0
156
+ ek_max = -1.0
157
+ include_species : Electron
158
+ dumpmask = always
159
+ end:probe
160
+
161
+ ################################
162
+
163
+ begin:output_global
164
+ force_final_to_be_restartable = F
165
+ end:output_global
166
+
167
+ begin:output
168
+ name = normal
169
+ grid = always
170
+ particle_probes = always
171
+ dt_snapshot = 15e-14
172
+ ex = always + single
173
+ ey = always + single
174
+ ez = always + single
175
+ bx = always + single
176
+ by = always + single
177
+ bz = always + single
178
+ particles = always
179
+ particle_weight = always
180
+ px = always + single
181
+ py = always + single
182
+ pz = always + single
183
+ average_particle_energy = always + species + no_sum + single
184
+ number_density = always + species + no_sum + single
185
+ absorption = always
186
+ total_energy_sum = always + species
187
+ end:output
188
+
@@ -11,6 +11,7 @@ EXAMPLE_MISMATCHED_FILES_DIR = (
11
11
  )
12
12
  EXAMPLE_ARRAYS_DIR = pathlib.Path(__file__).parent / "example_array_no_grids"
13
13
  EXAMPLE_3D_DIST_FN = pathlib.Path(__file__).parent / "example_dist_fn"
14
+ EXAMPLE_2D_PARTICLE_DATA = pathlib.Path(__file__).parent / "example_two_probes_2D"
14
15
 
15
16
 
16
17
  def test_basic():
@@ -226,3 +227,32 @@ def test_erroring_drop_variables():
226
227
  xr.open_dataset(
227
228
  EXAMPLE_FILES_DIR / "0000.sdf", drop_variables=["Electric_Field/E"]
228
229
  )
230
+
231
+
232
+ def test_loading_multiple_probes():
233
+ with xr.open_dataset(
234
+ EXAMPLE_2D_PARTICLE_DATA / "0002.sdf",
235
+ keep_particles=True,
236
+ probe_names=["Electron_Front_Probe", "Electron_Back_Probe"],
237
+ ) as df:
238
+ assert "X_Probe_Electron_Front_Probe" in df.coords
239
+ assert "X_Probe_Electron_Back_Probe" in df.coords
240
+ assert "ID_Electron_Front_Probe_Px" in df.dims
241
+ assert "ID_Electron_Back_Probe_Px" in df.dims
242
+
243
+
244
+ def test_loading_one_probe_drop_second_probe():
245
+ with xr.open_dataset(
246
+ EXAMPLE_2D_PARTICLE_DATA / "0002.sdf",
247
+ keep_particles=True,
248
+ drop_variables=[
249
+ "Electron_Back_Probe_Px",
250
+ "Electron_Back_Probe_Py",
251
+ "Electron_Back_Probe_Pz",
252
+ "Electron_Back_Probe_weight",
253
+ ],
254
+ probe_names=["Electron_Front_Probe"],
255
+ ) as df:
256
+ assert "X_Probe_Electron_Front_Probe" in df.coords
257
+ assert "ID_Electron_Front_Probe_Px" in df.dims
258
+ assert "ID_Electron_Back_Probe_Px" not in df.dims