spectrum-reader-certic 0.1.0__py3-none-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.
@@ -0,0 +1,113 @@
1
+ """Read spectra from contiguous hyperspectral HDF5 files."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import operator
6
+ import os
7
+ import threading
8
+ from typing import TypeVar
9
+
10
+ from ._native import ffi, lib
11
+
12
+ __all__ = ["FormatError", "SpectrumError", "SpectrumFile"]
13
+
14
+ _SpectrumFileT = TypeVar("_SpectrumFileT", bound="SpectrumFile")
15
+
16
+ if lib.sr_abi_version() != 1:
17
+ raise ImportError("spectrum-reader native library has an incompatible ABI")
18
+
19
+
20
+ class SpectrumError(RuntimeError):
21
+ """An internal error in the native spectrum reader."""
22
+
23
+
24
+ class FormatError(ValueError):
25
+ """An unsupported or corrupt hyperspectral HDF5 file."""
26
+
27
+
28
+ def _check(status: int) -> None:
29
+ if status == 0:
30
+ return
31
+ message = ffi.string(lib.sr_last_error_message()).decode("utf-8", errors="replace")
32
+ error = {
33
+ 2: ValueError,
34
+ 3: OSError,
35
+ 4: FormatError,
36
+ 5: IndexError,
37
+ }.get(status, SpectrumError)
38
+ raise error(message)
39
+
40
+
41
+ class SpectrumFile:
42
+ """An open spectrum file. Use as a context manager or call close().
43
+
44
+ Operations on the same instance are serialized, including close(). The
45
+ native handle is also released automatically when the instance is collected.
46
+ """
47
+
48
+ def __init__(self, path: str | bytes | os.PathLike) -> None:
49
+ path = os.fspath(path)
50
+ encoded = os.fsdecode(path).encode("utf-8") if os.name == "nt" else os.fsencode(path)
51
+ if b"\0" in encoded:
52
+ raise ValueError("path must not contain a NUL byte")
53
+ self._lock = threading.Lock()
54
+ out = ffi.new("SrFile **")
55
+ _check(lib.sr_open(encoded, out))
56
+ self._handle = ffi.gc(out[0], lib.sr_close)
57
+ shape = ffi.new("uint64_t[3]")
58
+ _check(lib.sr_shape(self._handle, shape))
59
+ self._shape = (int(shape[0]), int(shape[1]), int(shape[2]))
60
+
61
+ def _require_open(self) -> None:
62
+ if self._handle == ffi.NULL:
63
+ raise ValueError("spectrum file is closed")
64
+
65
+ @property
66
+ def closed(self) -> bool:
67
+ """Whether the file has been closed."""
68
+ with self._lock:
69
+ return self._handle == ffi.NULL
70
+
71
+ @property
72
+ def shape(self) -> tuple[int, int, int]:
73
+ """The dataset dimensions: (rows, columns, bands)."""
74
+ with self._lock:
75
+ self._require_open()
76
+ return self._shape
77
+
78
+ @property
79
+ def wavelengths(self) -> list[float]:
80
+ """The wavelength of each spectral band, as Python floats."""
81
+ with self._lock:
82
+ self._require_open()
83
+ bands = self._shape[2]
84
+ out = ffi.new("double[]", bands)
85
+ _check(lib.sr_wavelengths(self._handle, out, bands))
86
+ return list(out)
87
+
88
+ def read_pixel(self, row: int, col: int) -> list[float]:
89
+ """Return all bands at a zero-based (row, column) position."""
90
+ row, col = operator.index(row), operator.index(col)
91
+ with self._lock:
92
+ self._require_open()
93
+ rows, cols, bands = self._shape
94
+ if not (0 <= row < rows and 0 <= col < cols):
95
+ raise IndexError(f"pixel ({row}, {col}) is outside ({rows}, {cols})")
96
+ out = ffi.new("float[]", bands)
97
+ _check(lib.sr_read_pixel(self._handle, row, col, out, bands))
98
+ return list(out)
99
+
100
+ def close(self) -> None:
101
+ """Release the native file handle. Repeated calls are harmless."""
102
+ with self._lock:
103
+ if self._handle != ffi.NULL:
104
+ ffi.release(self._handle)
105
+ self._handle = ffi.NULL
106
+
107
+ def __enter__(self: _SpectrumFileT) -> _SpectrumFileT:
108
+ with self._lock:
109
+ self._require_open()
110
+ return self
111
+
112
+ def __exit__(self, exc_type, exc_value, traceback) -> None:
113
+ self.close()
@@ -0,0 +1,7 @@
1
+ __all__ = ["lib", "ffi"]
2
+
3
+ import os
4
+ from .ffi import ffi
5
+
6
+ lib = ffi.dlopen(os.path.join(os.path.dirname(__file__), '_native.dll'))
7
+ del os
Binary file
@@ -0,0 +1,10 @@
1
+ # auto-generated file
2
+ import _cffi_backend
3
+
4
+ ffi = _cffi_backend.FFI('ffi',
5
+ _version = 0x2601,
6
+ _types = b'\x00\x00\x13\x0D\x00\x00\x00\x0F\x00\x00\x1F\x0D\x00\x00\x1B\x03\x00\x00\x1D\x03\x00\x00\x1C\x01\x00\x00\x00\x0F\x00\x00\x1F\x0D\x00\x00\x03\x11\x00\x00\x0D\x03\x00\x00\x00\x0F\x00\x00\x1F\x0D\x00\x00\x03\x11\x00\x00\x18\x01\x00\x00\x18\x01\x00\x00\x1E\x03\x00\x00\x1C\x01\x00\x00\x00\x0F\x00\x00\x1F\x0D\x00\x00\x1C\x03\x00\x00\x19\x03\x00\x00\x00\x0F\x00\x00\x20\x0D\x00\x00\x00\x0F\x00\x00\x21\x0D\x00\x00\x1B\x03\x00\x00\x00\x0F\x00\x00\x00\x09\x00\x00\x02\x01\x00\x00\x0E\x01\x00\x00\x0D\x01\x00\x00\x15\x01\x00\x00\x16\x01\x00\x00\x00\x01',
7
+ _globals = (b'\xFF\xFF\xFF\x1FSR_ERR_FORMAT',4,b'\xFF\xFF\xFF\x1FSR_ERR_INTERNAL',1,b'\xFF\xFF\xFF\x1FSR_ERR_INVALID_ARGUMENT',2,b'\xFF\xFF\xFF\x1FSR_ERR_IO',3,b'\xFF\xFF\xFF\x1FSR_ERR_OUT_OF_RANGE',5,b'\xFF\xFF\xFF\x1FSR_OK',0,b'\x00\x00\x16\x23sr_abi_version',0,b'\x00\x00\x18\x23sr_close',0,b'\x00\x00\x00\x23sr_last_error_message',0,b'\x00\x00\x12\x23sr_open',0,b'\x00\x00\x0B\x23sr_read_pixel',0,b'\x00\x00\x07\x23sr_shape',0,b'\x00\x00\x02\x23sr_wavelengths',0),
8
+ _struct_unions = ((b'\x00\x00\x00\x1B\x00\x00\x00\x10SrFile',),),
9
+ _typenames = (b'\x00\x00\x00\x1BSrFile',),
10
+ )
File without changes
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: spectrum-reader-CERTIC
3
+ Version: 0.1.0
4
+ Requires-Dist: cffi>=1.17
5
+ License-File: LICENSE.txt
6
+ Summary: Read single-pixel spectra from hyperspectral HDF5 files without libhdf5
7
+ License-Expression: CECILL-B
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
10
+
11
+ # spectrum-reader
12
+
13
+ Small Rust library that reads single-pixel spectra from hyperspectral HDF5 files without libhdf5. Designed for use in the SIDS.
14
+
15
+ ## Targets
16
+
17
+ - Linux x86_64 (Debian trixie): the production build. It is built on Debian trixie and its binary is the one shipped to the SIDS.
18
+ - macOS arm64: native library for local development and Python wheels (macOS 11+).
19
+ - Windows x86_64: native library and Python wheels, built with the MSVC target.
20
+
21
+ The Python Linux wheels target x86_64 with glibc 2.34 or newer, including Debian trixie.
22
+
23
+ ## C API
24
+
25
+ The declarations below are those of `include/spectrum_reader.h`.
26
+
27
+ ```c
28
+ uint32_t sr_abi_version(void);
29
+ const char *sr_last_error_message(void);
30
+ int32_t sr_open(const char *path, SrFile **out);
31
+ void sr_close(SrFile *file);
32
+ int32_t sr_shape(const SrFile *file, uint64_t *out);
33
+ int32_t sr_wavelengths(const SrFile *file, double *out, size_t len);
34
+ int32_t sr_read_pixel(const SrFile *file, uint64_t row, uint64_t col, float *out, size_t len);
35
+ ```
36
+
37
+ - Functions returning `int32_t` return `0` on success, otherwise one of: `1` internal error (including a caught panic), `2` invalid argument (null pointer, wrong buffer length), `3` I/O error, `4` unsupported or corrupt file, `5` pixel out of range.
38
+ - After a failed call, `sr_last_error_message()` returns a description. The message is kept per thread, is replaced by the next call on the same thread, and the pointer is only valid until then: copy it right away.
39
+ - `path` is a NUL-terminated byte string: filesystem bytes on Unix, UTF-8 on Windows. `sr_open` sets `*out` to NULL on failure.
40
+ - `sr_shape` writes three values: `rows`, `cols`, `bands`. `row` and `col` are the first two indices of the `spectra` dataset.
41
+ - The caller owns every output buffer. `len` must equal the number of bands exactly, otherwise the call fails and the buffer is left untouched.
42
+ - A handle can be shared between threads for `sr_shape`, `sr_wavelengths` and `sr_read_pixel`. `sr_close` must not run while another call uses the handle, and a closed handle must not be used again. `sr_close(NULL)` does nothing.
43
+ - Only little-endian float32 `spectra` (3 dimensions) and float64 `Wavelength` (1 dimension) with contiguous storage are supported. Anything else is rejected at `sr_open`.
44
+
45
+ ## Development
46
+
47
+ [rustup](https://rustup.rs) is required. The toolchain is pinned in `rust-toolchain.toml` and rustup installs it automatically the first time cargo runs.
48
+
49
+ ```
50
+ make test
51
+ make build
52
+ make smoke
53
+ make lint
54
+ ```
55
+
56
+ `make smoke` compiles `tests/smoke.c` against the built library and `include/spectrum_reader.h`, then runs it.
57
+
58
+ The C header is generated and committed. After changing the exported functions, run `make header`; `make check-header` fails if the committed header is out of date. This needs cbindgen 0.29.4:
59
+
60
+ ```
61
+ cargo install cbindgen --version 0.29.4 --locked
62
+ ```
63
+
64
+ The release library is `target/release/libspectrum_reader.so` (`.dylib` on macOS).
65
+
66
+ ### Building on macOS (arm64)
67
+
68
+ Install the Xcode command-line tools (`xcode-select --install`) and [rustup](https://rustup.rs), then from the repository root:
69
+
70
+ ```
71
+ make build
72
+ ```
73
+
74
+ The library is `target/release/libspectrum_reader.dylib`. Point the SIDS wrapper at it for local development, together with `include/spectrum_reader.h`.
75
+
76
+ ### Building the Linux library from macOS
77
+
78
+ An alternative to building on Debian trixie. [zig](https://ziglang.org) is used as the linker, and the glibc version the library requires is pinned in the target name (`.2.34`; trixie ships 2.41, so anything up to that works).
79
+
80
+ ```
81
+ rustup target add x86_64-unknown-linux-gnu
82
+ brew install zig
83
+ cargo install cargo-zigbuild --version 0.24.0 --locked
84
+ make build-linux
85
+ ```
86
+
87
+ The library is `target/x86_64-unknown-linux-gnu/release/libspectrum_reader.so`. It cannot run on the Mac, so `make smoke` does not test it: `make check` tests the macOS build of the same code.
88
+
89
+ ## Python bindings and wheels
90
+
91
+ The `spectrum-reader` Python package bundles the native library and uses CFFI to
92
+ call the C API. It supports Python 3.10+ and needs neither Rust nor libhdf5 on
93
+ the machine where a wheel is installed. Its only Python runtime dependency is
94
+ `cffi`, which pip installs automatically.
95
+
96
+ ```python
97
+ from spectrum_reader import SpectrumFile
98
+
99
+ with SpectrumFile("image.h5") as spectrum:
100
+ rows, cols, bands = spectrum.shape
101
+ wavelengths = spectrum.wavelengths
102
+ values = spectrum.read_pixel(row=0, col=0)
103
+ ```
104
+
105
+ Wavelengths and pixel values are returned as lists of Python floats. Coordinates
106
+ are zero-based. Paths can be strings, bytes, or `pathlib.Path` objects. Use the
107
+ context manager or call `close()` explicitly; repeated closes are harmless.
108
+ Calls on the same object, including `close()`, are synchronized.
109
+
110
+ Missing or unreadable files raise `OSError`; unsupported or corrupt files raise
111
+ `spectrum_reader.FormatError` (a `ValueError`); out-of-range pixels raise
112
+ `IndexError`. Using a closed file raises `ValueError`. Internal native errors
113
+ raise `spectrum_reader.SpectrumError` (a `RuntimeError`).
114
+
115
+ ### Build all three wheels from macOS
116
+
117
+ Install [uv](https://docs.astral.sh/uv/) and the Rust toolchain, then prepare the
118
+ cross-compilation tools:
119
+
120
+ ```sh
121
+ rustup target add aarch64-apple-darwin x86_64-unknown-linux-gnu x86_64-pc-windows-msvc
122
+ brew install zig llvm lld
123
+ export PATH="$(brew --prefix llvm)/bin:$(brew --prefix lld)/bin:$PATH"
124
+ make build-wheels
125
+ ```
126
+
127
+ The build targets run Maturin 1.15.0 and CFFI through uv. Linux builds use Zig;
128
+ Windows builds use Maturin's integrated xwin support, which downloads the
129
+ Microsoft CRT and Windows SDK on the first build (under the
130
+ [xwin license terms](https://github.com/rust-cross/cargo-xwin#cargo-xwin)).
131
+ Building the Darwin wheel requires a macOS host and the Xcode command-line tools.
132
+
133
+ The wheels are written to `dist/` (override with `WHEEL_OUT=path`):
134
+
135
+ | Make target | Wheel platform tag |
136
+ | --- | --- |
137
+ | `build-wheel-darwin-arm64` | `macosx_11_0_arm64` |
138
+ | `build-wheel-linux-amd64` | `manylinux_2_34_x86_64` |
139
+ | `build-wheel-windows-amd64` | `win_amd64` |
140
+
141
+ Each wheel has the `py3-none` Python/ABI tags, so a separate build for each
142
+ Python version is unnecessary. Run an individual target to build just that
143
+ platform, or `make build-wheel` for the current host. On Windows, run Make from
144
+ a shell with the MSVC build tools available; native builds do not use xwin.
145
+
146
+ Install the wheel matching your platform, for example on an Apple Silicon Mac:
147
+
148
+ ```sh
149
+ python -m pip install dist/spectrum_reader-0.1.0-py3-none-macosx_11_0_arm64.whl
150
+ ```
151
+
152
+ ### Test the Python package
153
+
154
+ ```sh
155
+ make test-python
156
+ ```
157
+
158
+ This builds and installs the package into an isolated uv environment and runs
159
+ the Python integration tests against the HDF5 fixtures. To test a particular
160
+ built wheel on its target platform:
161
+
162
+ ```sh
163
+ uv run --no-project --with /path/to/spectrum_reader.whl python -m unittest discover -s tests/python -v
164
+ ```
165
+
166
+ Use the wheel's actual filename. Cross-compiled wheels must be tested on their
167
+ respective operating systems; the local tests exercise only the host platform.
168
+
169
+ ## Updating the library in the SIDS
170
+
171
+ Build from a clean working tree at the commit being shipped, either on Debian trixie or from macOS (see above).
172
+
173
+ 1. Run all the checks; they must pass:
174
+
175
+ ```
176
+ make check
177
+ ```
178
+
179
+ It runs clippy (warnings are errors), the tests, the header staleness check and the C smoke test.
180
+
181
+ 2. If built on Debian trixie, check the glibc requirement of the library; the highest version printed must not exceed trixie's (2.41). A library from `make build-linux` is pinned to 2.34 already:
182
+
183
+ ```
184
+ objdump -T target/release/libspectrum_reader.so | grep -o 'GLIBC_[0-9.]*' | sort -uV | tail -1
185
+ ```
186
+
187
+ 3. Copy these two files into the SIDS repository:
188
+ - `target/release/libspectrum_reader.so` (`target/x86_64-unknown-linux-gnu/release/libspectrum_reader.so` if built with `make build-linux`)
189
+ - `include/spectrum_reader.h`
190
+
191
+ 4. If the exported functions or their behavior changed incompatibly, bump `ABI_VERSION` in `src/lib.rs` first, run `make header`, and update the version the SIDS wrapper expects from `sr_abi_version()`.
192
+
193
+ ## License
194
+
195
+ CeCILL-B. See `LICENSE.txt`.
196
+
@@ -0,0 +1,10 @@
1
+ spectrum_reader/__init__.py,sha256=ATZgMZ0uh8K22WkOdf85KgA97yVAGjBNr5HsPaO-tNc,3744
2
+ spectrum_reader/_native/__init__.py,sha256=6rC8Q16GkZtTIOrjfJTUvSGifaw5q6hgy4R3fFnk9wM,138
3
+ spectrum_reader/_native/_native.dll,sha256=ZGoJbE6IfMVqYCszw5fsK25Uioosv25wikCB382AudM,145920
4
+ spectrum_reader/_native/ffi.py,sha256=vf11rFTn6XEIr4BcKjr6aOEKjn33aLg_drAEfPc4qbc,1252
5
+ spectrum_reader/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ spectrum_reader_certic-0.1.0.dist-info/METADATA,sha256=mNsr8KdOLESvxKbfspj_52BraGmBQCyTts02TGtA-ZM,8448
7
+ spectrum_reader_certic-0.1.0.dist-info/WHEEL,sha256=8Aej0W0a6Cz6apA3IzJrTnxLRVLAt-w0Oh8SA3Con_c,94
8
+ spectrum_reader_certic-0.1.0.dist-info/licenses/LICENSE.txt,sha256=J-xqEfyVAesI6lUagCL93NuigDfeFE1qX-4dA-xZhl0,3421
9
+ spectrum_reader_certic-0.1.0.dist-info/sboms/spectrum_reader.cyclonedx.json,sha256=7-DW2iko48Oeyk7O_cBzd6ogwAi6Blu7ig3E2qQtJZk,1321
10
+ spectrum_reader_certic-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.15.0)
3
+ Root-Is-Purelib: false
4
+ Tag: py3-none-win_amd64
@@ -0,0 +1,73 @@
1
+ Copyright 2026 Université de Caen Normandie
2
+ Esplanade de la paix
3
+ CS 14032
4
+ 14032 Caen CEDEX 5
5
+
6
+ Auteur : CERTIC Université de Caen Normandie
7
+
8
+ Contributeurs :
9
+ - thomas.hennebert@unicaen.fr
10
+
11
+ Ce logiciel est régi par la licence CeCILL-B soumise au droit français et
12
+ respectant les principes de diffusion des logiciels libres. Vous pouvez
13
+ utiliser, modifier et/ou redistribuer ce programme sous les conditions
14
+ de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA
15
+ sur le site "http://www.cecill.info".
16
+
17
+ En contrepartie de l'accessibilité au code source et des droits de copie,
18
+ de modification et de redistribution accordés par cette licence, il n'est
19
+ offert aux utilisateurs qu'une garantie limitée. Pour les mêmes raisons,
20
+ seule une responsabilité restreinte pèse sur l'auteur du programme, le
21
+ titulaire des droits patrimoniaux et les concédants successifs.
22
+
23
+ A cet égard l'attention de l'utilisateur est attirée sur les risques
24
+ associés au chargement, à l'utilisation, à la modification et/ou au
25
+ développement et à la reproduction du logiciel par l'utilisateur étant
26
+ donné sa spécificité de logiciel libre, qui peut le rendre complexe à
27
+ manipuler et qui le réserve donc à des développeurs et des professionnels
28
+ avertis possédant des connaissances informatiques approfondies. Les
29
+ utilisateurs sont donc invités à charger et tester l'adéquation du
30
+ logiciel à leurs besoins dans des conditions permettant d'assurer la
31
+ sécurité de leurs systèmes et ou de leurs données et, plus généralement,
32
+ à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
33
+
34
+ Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
35
+ pris connaissance de la licence CeCILL-B, et que vous en avez accepté les
36
+ termes.
37
+
38
+ =========================================================================
39
+ Copyright 2026 Université de Caen Normandie
40
+ Esplanade de la paix
41
+ CS 14032
42
+ 14032 Caen CEDEX 5
43
+
44
+ Author: CERTIC Université de Caen Normandie
45
+
46
+ Contributors:
47
+ - thomas.hennebert@unicaen.fr
48
+
49
+ This software is governed by the CeCILL-B license under French law and
50
+ abiding by the rules of distribution of free software. You can use,
51
+ modify and/ or redistribute the software under the terms of the CeCILL-B
52
+ license as circulated by CEA, CNRS and INRIA at the following URL
53
+ "http://www.cecill.info".
54
+
55
+ As a counterpart to the access to the source code and rights to copy,
56
+ modify and redistribute granted by the license, users are provided only
57
+ with a limited warranty and the software's author, the holder of the
58
+ economic rights, and the successive licensors have only limited
59
+ liability.
60
+
61
+ In this respect, the user's attention is drawn to the risks associated
62
+ with loading, using, modifying and/or developing or reproducing the
63
+ software by the user in light of its specific status of free software,
64
+ that may mean that it is complicated to manipulate, and that also
65
+ therefore means that it is reserved for developers and experienced
66
+ professionals having in-depth computer knowledge. Users are therefore
67
+ encouraged to load and test the software's suitability as regards their
68
+ requirements in conditions enabling the security of their systems and/or
69
+ data to be ensured and, more generally, to use and operate it in the
70
+ same conditions as regards security.
71
+
72
+ The fact that you are presently reading this means that you have had
73
+ knowledge of the CeCILL-B license and that you accept its terms.
@@ -0,0 +1,50 @@
1
+ {
2
+ "bomFormat": "CycloneDX",
3
+ "specVersion": "1.5",
4
+ "version": 1,
5
+ "serialNumber": "urn:uuid:43cca485-4ff4-40b6-9be0-8d216455323c",
6
+ "metadata": {
7
+ "timestamp": "2026-11-12T13:05:11.115192000Z",
8
+ "tools": [
9
+ {
10
+ "vendor": "CycloneDX",
11
+ "name": "cargo-cyclonedx",
12
+ "version": "0.5.9"
13
+ }
14
+ ],
15
+ "component": {
16
+ "type": "library",
17
+ "bom-ref": "path+file:///Users/mickael/code/spectrum-reader#spectrum_reader@0.1.0",
18
+ "name": "spectrum_reader",
19
+ "version": "0.1.0",
20
+ "scope": "required",
21
+ "licenses": [
22
+ {
23
+ "expression": "CECILL-B"
24
+ }
25
+ ],
26
+ "purl": "pkg:cargo/spectrum_reader@0.1.0?download_url=file://.",
27
+ "components": [
28
+ {
29
+ "type": "library",
30
+ "bom-ref": "path+file:///Users/mickael/code/spectrum-reader#spectrum_reader@0.1.0 bin-target-0",
31
+ "name": "spectrum_reader",
32
+ "version": "0.1.0",
33
+ "purl": "pkg:cargo/spectrum_reader@0.1.0?download_url=file://.#src/lib.rs"
34
+ }
35
+ ]
36
+ },
37
+ "properties": [
38
+ {
39
+ "name": "cdx:rustc:sbom:target:all_targets",
40
+ "value": "true"
41
+ }
42
+ ]
43
+ },
44
+ "components": [],
45
+ "dependencies": [
46
+ {
47
+ "ref": "path+file:///Users/mickael/code/spectrum-reader#spectrum_reader@0.1.0"
48
+ }
49
+ ]
50
+ }