sdf-xarray 0.4.0__cp314-cp314t-macosx_11_0_arm64.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.
@@ -0,0 +1,342 @@
1
+ cimport csdf
2
+
3
+ import dataclasses
4
+ import re
5
+ import time
6
+
7
+ from libc.string cimport memcpy
8
+
9
+ import numpy as np
10
+
11
+ cimport numpy as cnp
12
+
13
+ cnp.import_array()
14
+
15
+ # Some systems don't have F128
16
+ _NUMPY_128 = getattr(np, "float128", None)
17
+
18
+ cdef list[cnp.dtype | None] _sdf_type_mapping = [
19
+ None,
20
+ cnp.dtype(np.int32),
21
+ cnp.dtype(np.int64),
22
+ cnp.dtype(np.float32),
23
+ cnp.dtype(np.float64),
24
+ _NUMPY_128,
25
+ cnp.dtype("S"),
26
+ cnp.dtype(np.bool_),
27
+ ]
28
+
29
+
30
+ @dataclasses.dataclass
31
+ cdef class Block:
32
+ _id: str
33
+ name: str
34
+ dtype: np.dtype
35
+ shape: tuple[int]
36
+ is_point_data: bool
37
+ sdffile: SDFFile | None
38
+
39
+
40
+ @dataclasses.dataclass
41
+ cdef class Variable(Block):
42
+ units: str | None
43
+ mult: float | None
44
+ grid: str | None
45
+ grid_mid: str | None
46
+
47
+ @property
48
+ def data(self) -> np.ndarray :
49
+ """Read a variable from the file, returning numpy array
50
+ """
51
+
52
+ return self.sdffile.read(self)
53
+
54
+ @staticmethod
55
+ cdef Variable from_block(str name, csdf.sdf_block_t* block, SDFFile sdffile):
56
+ return Variable(
57
+ _id=block.id.decode("UTF-8"),
58
+ name=name,
59
+ dtype=_sdf_type_mapping[block.datatype_out],
60
+ shape=tuple(block.dims[i] for i in range(block.ndims)),
61
+ units=block.units.decode("UTF-8") if block.units else None,
62
+ mult=block.mult if block.mult else None,
63
+ grid=block.mesh_id.decode("UTF-8") if block.mesh_id else None,
64
+ grid_mid=f"{block.mesh_id.decode('UTF-8')}_mid" if block.mesh_id else None,
65
+ is_point_data=block.blocktype == csdf.SDF_BLOCKTYPE_POINT_VARIABLE,
66
+ sdffile=sdffile,
67
+ )
68
+
69
+
70
+ @dataclasses.dataclass
71
+ cdef class Mesh(Block):
72
+ units: tuple[str]
73
+ labels: tuple[str]
74
+ mults: tuple[float] | None
75
+ parent: Mesh | None = None
76
+
77
+ @property
78
+ def data(self) -> tuple[np.ndarray]:
79
+ """Read a variable from the file, returning numpy array
80
+ """
81
+
82
+ return self.sdffile.read(self)
83
+
84
+ @staticmethod
85
+ cdef Mesh from_block(str name, csdf.sdf_block_t* block, SDFFile sdffile):
86
+ return Mesh(
87
+ _id=block.id.decode("UTF-8"),
88
+ name=name,
89
+ dtype=_sdf_type_mapping[block.datatype_out],
90
+ shape=tuple(block.dims[i] for i in range(block.ndims)),
91
+ units=tuple(
92
+ block.dim_units[i].decode("UTF-8") for i in range(block.ndims)
93
+ ),
94
+ labels=tuple(
95
+ block.dim_labels[i].decode("UTF-8") for i in range(block.ndims)
96
+ ),
97
+ mults=(
98
+ tuple(block.dim_mults[i] for i in range(block.ndims))
99
+ if block.dim_mults
100
+ else None
101
+ ),
102
+ is_point_data=block.blocktype == csdf.SDF_BLOCKTYPE_POINT_MESH,
103
+ sdffile=sdffile,
104
+ )
105
+
106
+
107
+ _CONSTANT_UNITS_RE = re.compile(r"(?P<name>.*) \((?P<units>.*)\)$")
108
+
109
+ @dataclasses.dataclass
110
+ cdef class Constant:
111
+ _id: str
112
+ name: str
113
+ data: int | str | float | bool
114
+ units: str | None
115
+
116
+ @staticmethod
117
+ cdef Constant from_block(str name, csdf.sdf_block_t* block):
118
+ data: int | str | float | double | bool
119
+
120
+ if block.datatype == csdf.SDF_DATATYPE_REAL4:
121
+ data = (<float*>block.const_value)[0]
122
+ elif block.datatype == csdf.SDF_DATATYPE_REAL8:
123
+ data = (<double*>block.const_value)[0]
124
+ if block.datatype == csdf.SDF_DATATYPE_INTEGER4:
125
+ data = (<csdf.int32_t*>block.const_value)[0]
126
+ if block.datatype == csdf.SDF_DATATYPE_INTEGER8:
127
+ data = (<csdf.int64_t*>block.const_value)[0]
128
+ if block.datatype == csdf.SDF_DATATYPE_LOGICAL:
129
+ data = (<bint*>block.const_value)[0]
130
+
131
+ # There's no metadata with e.g. units, but there's a
132
+ # convention to put one in brackets at the end of the name,
133
+ # if so, strip it off to give the name and units
134
+ units = None
135
+ if match := _CONSTANT_UNITS_RE.match(name):
136
+ name = match["name"]
137
+ units = match["units"]
138
+
139
+ return Constant(
140
+ _id=block.id.decode("UTF-8"), name=name, data=data, units=units
141
+ )
142
+
143
+ @property
144
+ def is_point_data(self) -> bool:
145
+ return False
146
+
147
+
148
+ cdef class SDFFile:
149
+ """Read an SDF file
150
+
151
+ Attributes
152
+ ----------
153
+ header: dict
154
+ File metadata
155
+ run_info: dict
156
+ More metadata
157
+ variables: dict[str, Variable]
158
+ Mapping of variable name to metadata
159
+ grids: dict[str, Mesh]
160
+ Mapping of grid ID to metadata
161
+
162
+ """
163
+ cdef csdf.sdf_file_t* _c_sdf_file
164
+ cdef public str filename
165
+ cdef public dict header, run_info
166
+ cdef public dict[str, Variable] variables
167
+ cdef public dict[str, Mesh] grids
168
+
169
+ def __cinit__(self, filename: str):
170
+ self._c_sdf_file = csdf.sdf_open(
171
+ filename.encode("UTF-8"), 0, csdf.SDF_READ, False
172
+ )
173
+ if self._c_sdf_file == NULL:
174
+ raise IOError(f"Failed to open SDF file '{filename}'")
175
+
176
+ csdf.sdf_stack_init(self._c_sdf_file)
177
+ csdf.sdf_read_blocklist_all(self._c_sdf_file)
178
+
179
+ self.header = {
180
+ "filename": filename,
181
+ "file_version": self._c_sdf_file.file_version,
182
+ "file_revision": self._c_sdf_file.file_revision,
183
+ "code_name": self._c_sdf_file.code_name.decode("UTF-8"),
184
+ "step": self._c_sdf_file.step,
185
+ "time": self._c_sdf_file.time,
186
+ "jobid1": self._c_sdf_file.jobid1,
187
+ "jobid2": self._c_sdf_file.jobid2,
188
+ "code_io_version": self._c_sdf_file.code_io_version,
189
+ "restart_flag": bool(self._c_sdf_file.restart_flag),
190
+ "other_domains": bool(self._c_sdf_file.other_domains),
191
+ "station_file": bool(self._c_sdf_file.station_file),
192
+ }
193
+ self._read_variable_metadata()
194
+
195
+ cdef _read_variable_metadata(self):
196
+ cdef csdf.sdf_block_t* block = self._c_sdf_file.blocklist
197
+ cdef csdf.run_info* run = NULL
198
+
199
+ self.variables = {}
200
+ self.grids = {}
201
+
202
+ for i in range(self._c_sdf_file.nblocks):
203
+ name = block.name.decode("UTF-8")
204
+
205
+ if block.blocktype == csdf.SDF_BLOCKTYPE_RUN_INFO:
206
+ run = <csdf.run_info*>block.data
207
+ self.run_info = {
208
+ "version": f"{run.version}.{run.revision}.{run.minor_rev}",
209
+ "commit_id": run.commit_id.decode("UTF-8"),
210
+ "sha1sum": run.sha1sum.decode("UTF-8"),
211
+ "compile_machine": run.compile_machine.decode("UTF-8"),
212
+ "compile_flags": run.compile_flags.decode("UTF-8"),
213
+ "defines": f"{run.defines}",
214
+ "compile_date": time.ctime(run.compile_date),
215
+ "run_date": time.ctime(run.run_date),
216
+ "io_date": time.ctime(run.io_date),
217
+ }
218
+
219
+ elif block.blocktype == csdf.SDF_BLOCKTYPE_CONSTANT:
220
+ # We modify the name to remove units, so convert it
221
+ # first so we can get the new name
222
+ constant = Constant.from_block(name, block)
223
+ self.variables[constant.name] = constant
224
+
225
+ elif block.blocktype in (
226
+ csdf.SDF_BLOCKTYPE_PLAIN_MESH,
227
+ csdf.SDF_BLOCKTYPE_POINT_MESH,
228
+ csdf.SDF_BLOCKTYPE_LAGRANGIAN_MESH
229
+ ):
230
+ grid_id = block.id.decode("UTF-8")
231
+ self.grids[grid_id] = Mesh.from_block(name, block, self)
232
+
233
+ if block.blocktype != csdf.SDF_BLOCKTYPE_POINT_MESH:
234
+ # Make the corresponding grid at mid-points, except for
235
+ # particle grids
236
+ mid_grid_block = Mesh.from_block(f"{name}_mid", block, self)
237
+ mid_grid_block.shape = tuple(
238
+ dim - 1 for dim in mid_grid_block.shape if dim > 1
239
+ )
240
+ mid_grid_block.parent = self.grids[grid_id]
241
+ self.grids[f"{grid_id}_mid"] = mid_grid_block
242
+
243
+ elif block.blocktype in (
244
+ csdf.SDF_BLOCKTYPE_PLAIN_VARIABLE,
245
+ csdf.SDF_BLOCKTYPE_PLAIN_DERIVED,
246
+ csdf.SDF_BLOCKTYPE_POINT_VARIABLE,
247
+ csdf.SDF_BLOCKTYPE_POINT_DERIVED,
248
+ csdf.SDF_BLOCKTYPE_ARRAY,
249
+ ):
250
+ # If the block doesn't have a datatype, that probably
251
+ # means its actually a grid dimension
252
+ if block.datatype_out != 0:
253
+ self.variables[name] = Variable.from_block(name, block, self)
254
+
255
+ block = block.next
256
+
257
+ cpdef read(self, var: Block):
258
+ """Read a variable from the file, returning numpy array
259
+ """
260
+
261
+ if self._c_sdf_file is NULL:
262
+ raise RuntimeError(
263
+ f"Can't read '{var.name}', file '{self.filename}' is closed"
264
+ )
265
+
266
+ is_mesh: bool = isinstance(var, Mesh)
267
+
268
+ # Has a parent block, so we need to average node data to midpoint
269
+ if is_mesh and var.parent:
270
+ return self._read_mid_grid(var)
271
+
272
+ cdef csdf.sdf_block_t* block = csdf.sdf_find_block_by_name(
273
+ self._c_sdf_file, var.name.encode("utf-8")
274
+ )
275
+
276
+ if block is NULL:
277
+ raise RuntimeError(f"Could not read variable '{var.name}'")
278
+
279
+ self._c_sdf_file.current_block = block
280
+ csdf.sdf_helper_read_data(self._c_sdf_file, block)
281
+
282
+ if is_mesh:
283
+ # Meshes store the data for separate dimensions in block.grids
284
+ if not (block.grids is not NULL and block.grids[0] is not NULL):
285
+ raise RuntimeError(f"Could not read variable '{var.name}'")
286
+
287
+ data = []
288
+ for i, dim in enumerate(var.shape):
289
+ data.append(
290
+ self._make_array((dim,), var.dtype, block.grids[i])
291
+ )
292
+ return tuple(data)
293
+
294
+ # Normal variables
295
+ return self._make_array(var.shape, var.dtype, block.data)
296
+
297
+ cdef _read_mid_grid(self, mesh: Mesh):
298
+ """Read a midpoint grid"""
299
+
300
+ data = []
301
+ for dim in mesh.parent.data:
302
+ if len(dim.shape) == 1:
303
+ mid_point = (dim[:-1] + dim[1:]) / 2
304
+ elif len(dim.shape) == 2:
305
+ mid_point = (
306
+ dim[:-1, :-1] + dim[1:, :-1] + dim[:-1, 1:] + dim[1:, 1:]
307
+ ) / 4
308
+ else:
309
+ raise ValueError(
310
+ f"Unexpected number of dimensions reading mesh '{mesh.name}' "
311
+ f"(expected 1 or 2, got {len(dim.shape)})"
312
+ )
313
+ data.append(mid_point)
314
+ return tuple(data)
315
+
316
+ cdef cnp.ndarray _make_array(
317
+ self, tuple[int, ...] dims, cnp.dtype dtype, void* data
318
+ ):
319
+ """Helper function for making Numpy arrays from data allocated elsewhere"""
320
+ # This is not as efficient as it could be -- we should be able to steal
321
+ # the block's data, but I've not worked out to do that properly
322
+ # yet. This is correct at least, and means we don't need to worry about
323
+ # freeing the memory. Can't just use PyArray_NewFromDescr because this
324
+ # isn't available from Cython. Might be able to use one of the other
325
+ # low-level creation routines?
326
+ var_array = np.empty(dims, dtype=dtype, order="F")
327
+ memcpy(cnp.PyArray_DATA(var_array), data, var_array.nbytes)
328
+
329
+ return var_array
330
+
331
+ def close(self):
332
+ if self._c_sdf_file is NULL:
333
+ return
334
+ csdf.sdf_stack_destroy(self._c_sdf_file)
335
+ csdf.sdf_close(self._c_sdf_file)
336
+ self._c_sdf_file = NULL
337
+
338
+ def __enter__(self):
339
+ return self
340
+
341
+ def __exit__(self, exc_type, exc_value, exc_tb):
342
+ self.close()
@@ -0,0 +1,151 @@
1
+ Metadata-Version: 2.4
2
+ Name: sdf-xarray
3
+ Version: 0.4.0
4
+ Summary: Provides a backend for xarray to read SDF files as created by the EPOCH plasma PIC code.
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>
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
11
+ Classifier: Programming Language :: Python
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Requires-Python: <3.15,>=3.10
19
+ Requires-Dist: numpy>=2.0.0
20
+ Requires-Dist: xarray>=2024.1.0
21
+ Requires-Dist: dask>=2024.7.1
22
+ Provides-Extra: jupyter
23
+ Requires-Dist: dask[diagnostics]; extra == "jupyter"
24
+ Requires-Dist: ipykernel>=6.29.5; extra == "jupyter"
25
+ Provides-Extra: pint
26
+ Requires-Dist: pint; extra == "pint"
27
+ Requires-Dist: pint-xarray; extra == "pint"
28
+ Description-Content-Type: text/markdown
29
+
30
+ # sdf-xarray
31
+
32
+ ![Dynamic TOML Badge](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fraw.githubusercontent.com%2Fepochpic%2Fsdf-xarray%2Frefs%2Fheads%2Fmain%2Fpyproject.toml&query=%24.project.requires-python&label=python&logo=python)
33
+ [![Available on PyPI](https://img.shields.io/pypi/v/sdf-xarray?color=blue&logo=pypi)](https://pypi.org/project/sdf-xarray/)
34
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.15351323.svg)](https://doi.org/10.5281/zenodo.15351323)
35
+ ![Build/Publish](https://github.com/epochpic/sdf-xarray/actions/workflows/build_publish.yml/badge.svg)
36
+ ![Tests](https://github.com/epochpic/sdf-xarray/actions/workflows/tests.yml/badge.svg)
37
+ [![Read the Docs](https://img.shields.io/readthedocs/sdf-xarray?logo=readthedocs&link=https%3A%2F%2Fsdf-xarray.readthedocs.io%2F)](https://sdf-xarray.readthedocs.io)
38
+ [![Formatted with black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/python/black)
39
+
40
+
41
+ sdf-xarray provides a backend for [xarray](https://xarray.dev) to read SDF files as created by
42
+ [EPOCH](https://epochpic.github.io) using the [SDF-C](https://github.com/epochpic/SDF_C) library.
43
+ Part of [BEAM](#broad-epoch-analysis-modules-beam) (Broad EPOCH Analysis Modules).
44
+
45
+ ## Installation
46
+
47
+ > [!IMPORTANT]
48
+ > To install this package make sure you are using one of the Python versions listed above.
49
+
50
+ Install from PyPI with:
51
+
52
+ ```bash
53
+ pip install sdf-xarray
54
+ ```
55
+
56
+ or download this code locally:
57
+
58
+ ```bash
59
+ git clone --recursive https://github.com/epochpic/sdf-xarray.git
60
+ cd sdf-xarray
61
+ pip install .
62
+ ```
63
+
64
+ We recommend switching to [uv](https://docs.astral.sh/uv/) to manage packages.
65
+
66
+ ## Usage
67
+
68
+ Below are some simple examples to get you started. Please read the full
69
+ documentation here <https://sdf-xarray.readthedocs.io>.
70
+
71
+ ### Single file loading
72
+
73
+ ```python
74
+ import xarray as xr
75
+
76
+ df = xr.open_dataset("0010.sdf")
77
+
78
+ print(df["Electric_Field_Ex"])
79
+
80
+ # <xarray.DataArray 'Electric_Field_Ex' (X_x_px_deltaf_electron_beam: 16)> Size: 128B
81
+ # [16 values with dtype=float64]
82
+ # Coordinates:
83
+ # * X_x_px_deltaf_electron_beam (X_x_px_deltaf_electron_beam) float64 128B 1...
84
+ # Attributes:
85
+ # units: V/m
86
+ # full_name: "Electric Field/Ex"
87
+ ```
88
+
89
+ ### Multi-file loading
90
+
91
+ You can open all the SDF files for a given simulation by calling the `open_mfdataset`
92
+ function from `sdf_xarray`. This will additionally add a time dimension using the `"time"`
93
+ value stored in each files attributes.
94
+
95
+ > [!IMPORTANT]
96
+ > If your simulation has multiple `output` blocks so that not all variables are
97
+ > output at every time step, then at the timesteps where those variables are not
98
+ > present they will have have a value of nan. To clean your dataset by removing
99
+ > these nan values we suggest using the `xarray.DataArray.dropna` function or
100
+ > loading sparse data along separate time dimensions using `separate_times=True`.
101
+
102
+ ```python
103
+ from sdf_xarray import open_mfdataset
104
+
105
+ ds = open_mfdataset("*.sdf")
106
+ print(ds)
107
+
108
+ # Dimensions:
109
+ # time: 301, X_Grid_mid: 128, ...
110
+ # Coordinates: (9) ...
111
+ # Data variables: (18) ...
112
+ # Indexes: (9) ...
113
+ # Attributes: (22) ...
114
+ ```
115
+
116
+ ## Citing
117
+
118
+ If sdf-xarray contributes to a project that leads to publication, please acknowledge this by citing sdf-xarray. This can be done by clicking the "cite this repository" button located near the top right of this page.
119
+
120
+ ## Contributing
121
+
122
+ We welcome contributions to the BEAM ecosystem! Whether it's reporting issues, suggesting features, or submitting pull requests, your input helps improve these tools for the community.
123
+
124
+ ### How to Contribute
125
+
126
+ There are many ways to get involved:
127
+ - **Report bugs**: Found something not working as expected? Open an issue with as much detail as possible.
128
+ - **Request a feature**: Got an idea for a new feature or enhancement? Open a feature request on [GitHub Issues](https://github.com/epochpic/sdf-xarray/issues)!
129
+ - **Improve the documentation**: We aim to keep our docs clear and helpful—if something's missing or unclear, feel free to suggest edits.
130
+ - **Submit code changes**: Bug fixes, refactoring, or new features are welcome.
131
+
132
+
133
+ All code is automatically linted, formatted, and tested via GitHub Actions.
134
+
135
+ To run checks locally before opening a pull request, see [CONTRIBUTING.md](CONTRIBUTING.md) or [readthedocs documentation](https://sdf-xarray.readthedocs.io/en/latest/contributing.html)
136
+
137
+ ## Broad EPOCH Analysis Modules (BEAM)
138
+
139
+ ![BEAM logo](./BEAM.png)
140
+
141
+ **BEAM** is a collection of independent yet complementary open-source tools for analysing EPOCH simulations, designed to be modular so researchers can adopt only the components they require without being constrained by a rigid framework. In line with the **FAIR principles — Findable**, **Accessible**, **Interoperable**, and **Reusable** — each package is openly published with clear documentation and versioning (Findable), distributed via public repositories (Accessible), designed to follow common standards for data structures and interfaces (Interoperable), and includes licensing and metadata to support long-term use and adaptation (Reusable). The packages are as follows:
142
+
143
+ - [sdf-xarray](https://github.com/epochpic/sdf-xarray): Reading and processing SDF files and converting them to [xarray](https://docs.xarray.dev/en/stable/).
144
+ - [epydeck](https://github.com/epochpic/epydeck): Input deck reader and writer.
145
+ - [epyscan](https://github.com/epochpic/epyscan): Create campaigns over a given parameter space using various sampling methods.
146
+
147
+ ## PlasmaFAIR
148
+
149
+ ![PlasmaFAIR logo](PlasmaFAIR.svg)
150
+
151
+ Originally developed by [PlasmaFAIR](https://plasmafair.github.io), EPSRC Grant EP/V051822/1
@@ -0,0 +1,26 @@
1
+ include/SDFC_14.4.7/sdf_derived.h,sha256=VqRsCmjmSRIOGqZSiPMsvmNaFBoNzXhrlKeyWGYIzm8,636
2
+ include/SDFC_14.4.7/sdf_helper.h,sha256=UD291Xf8ZUeh34iv-qLN-u8f5vPQz0joTFxIQWUIVYA,1020
3
+ include/SDFC_14.4.7/sdf_vector_type.h,sha256=5tcQcF7zDm7kTkLCzm12G5Z3ARVXvw7-XpKQ6WWej6U,1527
4
+ include/SDFC_14.4.7/stack_allocator.h,sha256=dwR5vISInhS-qtN2HF3_8CVlnHJgWKMZxEn9RiMGjuM,1286
5
+ include/SDFC_14.4.7/sdf_extension.h,sha256=my_ze10hSGfWEQEaUWh8TxFuVsiAl-g6aDn6qB2QQUY,1136
6
+ include/SDFC_14.4.7/uthash.h,sha256=BN_4JfPHloW0kI3VRhvCqP8D2VcvD0HpSLgo4MBz6Sk,62067
7
+ include/SDFC_14.4.7/sdf.h,sha256=8RWP2yH8xn_sCcbqZPT443LBaPy_3SHjOxA6IL4xLzE,24996
8
+ include/SDFC_14.4.7/sdf_list_type.h,sha256=WEq5Qmtv00-A7lmLadxC7RbFy46yLYRgg0LynCGk4PE,1350
9
+ lib/SDFC_14.4.7/libsdfc.a,sha256=B_y_GclgdE0xdSv7uUxlENCg1xoKQ_7O20UMdNwyi94,601592
10
+ lib/SDFC_14.4.7/SDFCTargets-release.cmake,sha256=Xq-QJnH563tMRWlM5o2wdMSm9EiSKXru4U4hlR-eXlo,811
11
+ lib/SDFC_14.4.7/SDFCTargets.cmake,sha256=clkZz74QIZf_Fi28OhBWw6bM4D2ljPzytSapo0xz2r0,4046
12
+ lib/SDFC_14.4.7/SDFCConfig.cmake,sha256=QQOXXHTYSEzXXckN8CCi9vuhMmirf2MrOA8b3tY4m2A,784
13
+ lib/SDFC_14.4.7/SDFCConfigVersion.cmake,sha256=2dR0eWIHiMKSdOwWBD9kI6EA-1mvVZsn61d50hSazkE,2765
14
+ sdf_xarray/_version.py,sha256=l7h0kVANk_zkMPjiVLsVjseleQV1Jro7H3JphPhrob0,712
15
+ sdf_xarray/plotting.py,sha256=HHLZISdFaiafTlRrTRshwT4FdRn5Z6VWIyU8vAwm_J0,9257
16
+ sdf_xarray/download.py,sha256=5rY5TPXxTZr4B_0OQHgur2Knerg4OwSD4E5dboFAycg,3036
17
+ sdf_xarray/dataset_accessor.py,sha256=ziVMAunCxSvIsJuETt8dSYAVXQkBSX8mOmipxvNFW0s,2379
18
+ sdf_xarray/sdf_interface.pyx,sha256=6wnODbj5Gi4IinwL-EXTPfcxJGtN6Nm9BQ7R88xwkrs,11754
19
+ sdf_xarray/__init__.py,sha256=vHfy048FKTbrgyyQJ1QN6hzgxfH42oUuwnlvX5JHON0,23584
20
+ sdf_xarray/sdf_interface.cpython-314t-darwin.so,sha256=yjURK6RR0bfktkuUlQE8c3EOOjdeTNhrClTdtFVaBlg,419384
21
+ sdf_xarray/csdf.pxd,sha256=6VCmPTbvKOQt3O-r1R1Gj-GvQJ2pOUeSRnkxgMLBvy0,4078
22
+ sdf_xarray-0.4.0.dist-info/RECORD,,
23
+ sdf_xarray-0.4.0.dist-info/WHEEL,sha256=FQvoGV7U_hR0JELuWQHk3LhwiQiBfE7EgRQx8v3hXSQ,142
24
+ sdf_xarray-0.4.0.dist-info/entry_points.txt,sha256=gP7BIQpXNg6vIf7S7p-Rw_EJZTC1X50BsVTkK7dA7g0,57
25
+ sdf_xarray-0.4.0.dist-info/METADATA,sha256=9EoUJ22i_txDaZAX6ZIgnaQdogVv88M-L2VFIZDHofQ,6921
26
+ sdf_xarray-0.4.0.dist-info/licenses/LICENCE,sha256=0FfLVWQRQERtj0vUKjJk7-UrDp-t70Et9izWejGe4Os,1487
@@ -0,0 +1,6 @@
1
+ Wheel-Version: 1.0
2
+ Generator: scikit-build-core 0.11.6
3
+ Root-Is-Purelib: false
4
+ Tag: cp314-cp314t-macosx_11_0_arm64
5
+ Generator: delocate 0.13.0
6
+
@@ -0,0 +1,3 @@
1
+ [xarray.backends]
2
+ sdf_engine = sdf_xarray:SDFEntrypoint
3
+
@@ -0,0 +1,28 @@
1
+ Copyright 2024, Peter Hill, Joel Adams, epochpic team
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions are
5
+ met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+
14
+ 3. Neither the name of the copyright holder nor the names of its
15
+ contributors may be used to endorse or promote products derived from
16
+ this software without specific prior written permission.
17
+
18
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
+ HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.