sdf-xarray 0.2.5__cp313-cp313-win_amd64.whl → 0.3.0__cp313-cp313-win_amd64.whl

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.

lib/SDFC_14.4.7/sdfc.lib CHANGED
Binary file
sdf_xarray/__init__.py CHANGED
@@ -2,12 +2,15 @@ import os
2
2
  import re
3
3
  from collections import Counter, defaultdict
4
4
  from collections.abc import Callable, Iterable
5
+ from importlib.metadata import version
5
6
  from itertools import product
7
+ from os import PathLike as os_PathLike
6
8
  from pathlib import Path
7
9
  from typing import ClassVar
8
10
 
9
11
  import numpy as np
10
12
  import xarray as xr
13
+ from packaging.version import Version
11
14
  from xarray.backends import AbstractDataStore, BackendArray, BackendEntrypoint
12
15
  from xarray.backends.file_manager import CachingFileManager
13
16
  from xarray.backends.locks import ensure_lock
@@ -21,6 +24,12 @@ import sdf_xarray.plotting # noqa: F401
21
24
 
22
25
  from .sdf_interface import Constant, SDFFile # type: ignore # noqa: PGH003
23
26
 
27
+ # TODO Remove this once the new kwarg options are fully implemented
28
+ if Version(version("xarray")) >= Version("2025.8.0"):
29
+ xr.set_options(use_new_combine_kwarg_defaults=True)
30
+
31
+ PathLike = str | os_PathLike
32
+
24
33
 
25
34
  def _rename_with_underscore(name: str) -> str:
26
35
  """A lot of the variable names have spaces, forward slashes and dashes in them, which
@@ -51,14 +60,32 @@ def _process_latex_name(variable_name: str) -> str:
51
60
  return variable_name
52
61
 
53
62
 
63
+ def _resolve_glob(path_glob: PathLike | Iterable[PathLike]):
64
+ """
65
+ Normalise input path_glob into a sorted list of absolute, resolved Path objects.
66
+ """
67
+
68
+ try:
69
+ p = Path(path_glob)
70
+ paths = list(p.parent.glob(p.name)) if p.name == "*.sdf" else list(p)
71
+ except TypeError:
72
+ paths = list({Path(p) for p in path_glob})
73
+
74
+ paths = sorted(p.resolve() for p in paths)
75
+ if not paths:
76
+ raise FileNotFoundError(f"No files matched pattern or input: {path_glob!r}")
77
+ return paths
78
+
79
+
54
80
  def combine_datasets(path_glob: Iterable | str, **kwargs) -> xr.Dataset:
55
81
  """Combine all datasets using a single time dimension"""
56
82
 
57
83
  return xr.open_mfdataset(
58
84
  path_glob,
59
- data_vars="minimal",
60
- coords="minimal",
61
- compat="override",
85
+ data_vars="all",
86
+ coords="different",
87
+ compat="no_conflicts",
88
+ join="outer",
62
89
  preprocess=SDFPreprocess(),
63
90
  **kwargs,
64
91
  )
@@ -69,6 +96,7 @@ def open_mfdataset(
69
96
  *,
70
97
  separate_times: bool = False,
71
98
  keep_particles: bool = False,
99
+ probe_names: list[str] | None = None,
72
100
  ) -> xr.Dataset:
73
101
  """Open a set of EPOCH SDF files as one `xarray.Dataset`
74
102
 
@@ -98,20 +126,21 @@ def open_mfdataset(
98
126
  different output frequencies
99
127
  keep_particles :
100
128
  If ``True``, also load particle data (this may use a lot of memory!)
129
+ probe_names :
130
+ List of EPOCH probe names
101
131
  """
102
132
 
103
- # TODO: This is not very robust, look at how xarray.open_mfdataset does it
104
- if isinstance(path_glob, str):
105
- path_glob = Path().glob(path_glob)
106
-
107
- # Coerce to list because we might need to use the sequence multiple times
108
- path_glob = sorted(list(path_glob)) # noqa: C414
109
-
133
+ path_glob = _resolve_glob(path_glob)
110
134
  if not separate_times:
111
- return combine_datasets(path_glob, keep_particles=keep_particles)
135
+ return combine_datasets(
136
+ path_glob, keep_particles=keep_particles, probe_names=probe_names
137
+ )
112
138
 
113
- 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]
139
+ _, var_times_map = make_time_dims(path_glob)
140
+ all_dfs = [
141
+ xr.open_dataset(f, keep_particles=keep_particles, probe_names=probe_names)
142
+ for f in path_glob
143
+ ]
115
144
 
116
145
  for df in all_dfs:
117
146
  for da in df:
@@ -128,7 +157,12 @@ def open_mfdataset(
128
157
  )
129
158
 
130
159
  return xr.combine_by_coords(
131
- all_dfs, data_vars="minimal", combine_attrs="drop_conflicts"
160
+ all_dfs,
161
+ data_vars="all",
162
+ coords="different",
163
+ combine_attrs="drop_conflicts",
164
+ join="outer",
165
+ compat="no_conflicts",
132
166
  )
133
167
 
134
168
 
@@ -211,14 +245,23 @@ class SDFDataStore(AbstractDataStore):
211
245
  "drop_variables",
212
246
  "keep_particles",
213
247
  "lock",
248
+ "probe_names",
214
249
  )
215
250
 
216
- def __init__(self, manager, drop_variables=None, keep_particles=False, lock=None):
251
+ def __init__(
252
+ self,
253
+ manager,
254
+ drop_variables=None,
255
+ keep_particles=False,
256
+ lock=None,
257
+ probe_names=None,
258
+ ):
217
259
  self._manager = manager
218
260
  self._filename = self.ds.filename
219
261
  self.drop_variables = drop_variables
220
262
  self.keep_particles = keep_particles
221
263
  self.lock = ensure_lock(lock)
264
+ self.probe_names = probe_names
222
265
 
223
266
  @classmethod
224
267
  def open(
@@ -227,6 +270,7 @@ class SDFDataStore(AbstractDataStore):
227
270
  lock=None,
228
271
  drop_variables=None,
229
272
  keep_particles=False,
273
+ probe_names=None,
230
274
  ):
231
275
  if isinstance(filename, os.PathLike):
232
276
  filename = os.fspath(filename)
@@ -237,6 +281,7 @@ class SDFDataStore(AbstractDataStore):
237
281
  lock=lock,
238
282
  drop_variables=drop_variables,
239
283
  keep_particles=keep_particles,
284
+ probe_names=probe_names,
240
285
  )
241
286
 
242
287
  def _acquire(self, needs_lock=True):
@@ -347,7 +392,28 @@ class SDFDataStore(AbstractDataStore):
347
392
 
348
393
  if value.is_point_data:
349
394
  # Point (particle) variables are 1D
350
- var_coords = (f"ID_{_process_grid_name(key, _grid_species_name)}",)
395
+
396
+ # Particle data does not maintain a fixed dimension size
397
+ # throughout the simulation. An example of a particle name comes
398
+ # in the form of `Particles/Px/Ion_H` which is then modified
399
+ # using `_process_grid_name()` into `Ion_H`. This is fine as the
400
+ # other components of the momentum (`Py`, `Pz`) will have the same
401
+ # size as they represent the same bunch of particles.
402
+
403
+ # Probes however have names in the form of `Electron_Front_Probe/Px`
404
+ # which are changed to just `Px`; this is fine when there is only one
405
+ # probe in the system but when there are multiple they will have
406
+ # conflicting sizes so we can't keep the names as simply `Px` so we
407
+ # instead set their dimension as the full name `Electron_Front_Probe_Px`.
408
+ is_probe_name_match = self.probe_names is not None and any(
409
+ name in key for name in self.probe_names
410
+ )
411
+ name_processor = (
412
+ _rename_with_underscore
413
+ if is_probe_name_match
414
+ else _grid_species_name
415
+ )
416
+ var_coords = (f"ID_{_process_grid_name(key, name_processor)}",)
351
417
  else:
352
418
  # These are DataArrays
353
419
 
@@ -414,6 +480,7 @@ class SDFEntrypoint(BackendEntrypoint):
414
480
  *,
415
481
  drop_variables=None,
416
482
  keep_particles=False,
483
+ probe_names=None,
417
484
  ):
418
485
  if isinstance(filename_or_obj, Path):
419
486
  # sdf library takes a filename only
@@ -424,6 +491,7 @@ class SDFEntrypoint(BackendEntrypoint):
424
491
  filename_or_obj,
425
492
  drop_variables=drop_variables,
426
493
  keep_particles=keep_particles,
494
+ probe_names=probe_names,
427
495
  )
428
496
  with close_on_error(store):
429
497
  return store.load()
@@ -432,6 +500,7 @@ class SDFEntrypoint(BackendEntrypoint):
432
500
  "filename_or_obj",
433
501
  "drop_variables",
434
502
  "keep_particles",
503
+ "probe_names",
435
504
  ]
436
505
 
437
506
  def guess_can_open(self, filename_or_obj):
sdf_xarray/_version.py CHANGED
@@ -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.3.0'
32
+ __version_tuple__ = version_tuple = (0, 3, 0)
33
+
34
+ __commit_id__ = commit_id = 'gcca942b3f'
sdf_xarray/plotting.py CHANGED
@@ -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
 
@@ -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.3.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>
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
@@ -88,6 +61,9 @@ sdf-xarray provides a backend for [xarray](https://xarray.dev) to read SDF files
88
61
  [EPOCH](https://epochpic.github.io) using the [SDF-C](https://github.com/epochpic/SDF_C) library.
89
62
  Part of [BEAM](#broad-epoch-analysis-modules-beam) (Broad EPOCH Analysis Modules).
90
63
 
64
+ > [!IMPORTANT]
65
+ > To install this package make sure you are using one of the Python versions listed above.
66
+
91
67
  ## Installation
92
68
 
93
69
  Install from PyPI with:
@@ -6,19 +6,19 @@ include/SDFC_14.4.7/sdf_list_type.h,sha256=Quu8v0-SEsQuJpGtEZnm09tAyXqWNitx0sXl5
6
6
  include/SDFC_14.4.7/sdf_vector_type.h,sha256=dbKjhzRRsvhzrnTwVjtVlvnuisEnRMKY-vvdm94ok_Q,1595
7
7
  include/SDFC_14.4.7/stack_allocator.h,sha256=L7U9vmGiVSw3VQLIv9EzTaVq7JbFxs9aNonKStTkUSg,1335
8
8
  include/SDFC_14.4.7/uthash.h,sha256=rIyy_-ylY6S_7WaZCCC3VtvXaC9q37rFyA0f1U9xc4w,63030
9
- lib/SDFC_14.4.7/sdfc.lib,sha256=D-ZfTK-UI85tD9nBu2i4Bb8mfo48Lc8TDDF6hDBJK4k,350410
9
+ lib/SDFC_14.4.7/sdfc.lib,sha256=a6io2pN2IuTiSejxXjJkOEqPsluzQiksXQkZLnRdeCU,350158
10
10
  lib/SDFC_14.4.7/SDFCConfig.cmake,sha256=IOA1eusC-KvUK4LNTEiOAmEdaPH1ZvNvbYPgiG1oZio,802
11
11
  lib/SDFC_14.4.7/SDFCConfigVersion.cmake,sha256=pN7Qqyf04s3izw7PYQ0XK6imvmhaVegSdR_nEl3Ok_o,2830
12
12
  lib/SDFC_14.4.7/SDFCTargets-release.cmake,sha256=G4zdx5PyjePigeD_a6rmZAxbk7L8Nf0klUnV78Lm2fI,828
13
13
  lib/SDFC_14.4.7/SDFCTargets.cmake,sha256=OVt1Gm8n7Ew4fiTmA9yHoef3vIIGwsXUZfqeG9p9Bys,4152
14
- sdf_xarray/__init__.py,sha256=MgATg9E6Jyo1fW3_li3lIEm-yxTHgJbNfZf5qeAvuyY,18073
15
- sdf_xarray/_version.py,sha256=XjF4m8_cMkXrbRU7Rim3aBSkgXL9DCvwDPeFFTVyWd8,532
14
+ sdf_xarray/__init__.py,sha256=RGtaYtX9Iqc7TMB305py2qW2HhILYkIidsDpjO6N8dI,20548
15
+ sdf_xarray/_version.py,sha256=iQCqXuCEb7bAhie1qOwoyJuqOm0k4QDq4mp-_ILwsSk,746
16
16
  sdf_xarray/csdf.pxd,sha256=ADPjAuHsodAvdOz96Z_XlFF7VL3KmVaXcTifWDP3rK0,4205
17
- sdf_xarray/plotting.py,sha256=ze1paC1Uw42WOWspdqkyNsUviDt-Z7AwQlPyO7JB90o,7007
18
- sdf_xarray/sdf_interface.cp313-win_amd64.pyd,sha256=UNph8MYHwpjg33jAijyaWZibVVOK4TakPln62O7Fnn0,357888
17
+ sdf_xarray/plotting.py,sha256=PnbEspR4XkA5SHkpoFKA2G7BYj5J3mVgR1TEeGol6Vw,7041
18
+ sdf_xarray/sdf_interface.cp313-win_amd64.pyd,sha256=aRouLMNZbxA8Byqg3Fp9Q-ENzODSbzRv0FyaXsbenrk,359936
19
19
  sdf_xarray/sdf_interface.pyx,sha256=PFC6upg14OZBqiGInLgBoxztIIKBk-HOh3WC9Ro4YUw,11975
20
- sdf_xarray-0.2.5.dist-info/METADATA,sha256=ybk80dZjGpoDSonOcmjyIO5HdCP4zUJRbqWjuxBn68c,9129
21
- sdf_xarray-0.2.5.dist-info/WHEEL,sha256=sy0UFHejwb8HKZF4TZKxRLz0uqFoYZA7Xu3tB1pL5yA,106
22
- sdf_xarray-0.2.5.dist-info/entry_points.txt,sha256=gP7BIQpXNg6vIf7S7p-Rw_EJZTC1X50BsVTkK7dA7g0,57
23
- sdf_xarray-0.2.5.dist-info/licenses/LICENCE,sha256=aHWuyELjtzIL1jTXFHTbI3tr9vyVyhnw3I9_QYPdEX8,1515
24
- sdf_xarray-0.2.5.dist-info/RECORD,,
20
+ sdf_xarray-0.3.0.dist-info/METADATA,sha256=q9WJBhz2Su52p14Q6b1ZBJRjCeepN7yfao9PdVnVbtU,7582
21
+ sdf_xarray-0.3.0.dist-info/WHEEL,sha256=vkL3wTIkhjZa3RmEXX20hldNp6Q8qtwRjrXW6K5sw_Q,106
22
+ sdf_xarray-0.3.0.dist-info/entry_points.txt,sha256=gP7BIQpXNg6vIf7S7p-Rw_EJZTC1X50BsVTkK7dA7g0,57
23
+ sdf_xarray-0.3.0.dist-info/licenses/LICENCE,sha256=aHWuyELjtzIL1jTXFHTbI3tr9vyVyhnw3I9_QYPdEX8,1515
24
+ sdf_xarray-0.3.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: scikit-build-core 0.11.2
2
+ Generator: scikit-build-core 0.11.6
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp313-cp313-win_amd64
5
5