|
1 | 1 | # SPDX-License-Identifier: BSD-3-Clause |
2 | | -# Copyright (c) 2024 Scipp contributors (https://github.com/scipp) |
3 | | -import pooch |
| 2 | +# Copyright (c) 2025 Scipp contributors (https://github.com/scipp) |
| 3 | +"""Data files bundled with ESSreduce.""" |
| 4 | + |
| 5 | +from functools import cache |
| 6 | +from pathlib import Path |
4 | 7 |
|
5 | 8 |
|
6 | 9 | class Registry: |
7 | | - def __init__(self, instrument: str, files: dict[str, str], version: str): |
| 10 | + """A registry for data files. |
| 11 | +
|
| 12 | + Note |
| 13 | + ---- |
| 14 | + This class requires [Pooch](https://www.fatiando.org/pooch/latest/) which |
| 15 | + is not a hard dependency of ESSreduce and needs to be installed separately. |
| 16 | + """ |
| 17 | + |
| 18 | + def __init__( |
| 19 | + self, |
| 20 | + instrument: str, |
| 21 | + files: dict[str, str], |
| 22 | + version: str, |
| 23 | + retry_if_failed: int = 3, |
| 24 | + ) -> None: |
| 25 | + import pooch |
| 26 | + |
8 | 27 | self._registry = pooch.create( |
9 | 28 | path=pooch.os_cache(f'ess/{instrument}'), |
10 | 29 | env=f'ESS_{instrument.upper()}_DATA_DIR', |
11 | 30 | base_url=f'https://public.esss.dk/groups/scipp/ess/{instrument}/' |
12 | 31 | + '{version}/', |
13 | 32 | version=version, |
14 | 33 | registry=files, |
15 | | - retry_if_failed=3, |
| 34 | + retry_if_failed=retry_if_failed, |
16 | 35 | ) |
| 36 | + self._unzip_processor = pooch.Unzip() |
17 | 37 |
|
18 | | - def __contains__(self, key): |
| 38 | + def __contains__(self, key: str) -> bool: |
| 39 | + """Return True if the key is in the registry.""" |
19 | 40 | return key in self._registry.registry |
20 | 41 |
|
21 | | - def get_path(self, name: str, unzip: bool = False) -> str: |
22 | | - """ |
23 | | - Get the path to a file in the registry. |
| 42 | + @cache # noqa: B019 |
| 43 | + def get_path(self, name: str, unzip: bool = False) -> Path: |
| 44 | + """Get the path to a file in the registry. |
| 45 | +
|
| 46 | + Downloads the file if necessary. |
| 47 | +
|
| 48 | + Note that return values of this method are cached to avoid recomputing |
| 49 | + potentially expensive checksums. |
| 50 | + This usually means that the ``Registry`` object itself gets stored until the |
| 51 | + Python interpreter shuts down. |
| 52 | + However, registries are small and do not own resources. |
| 53 | + It is anyway expected that the registry objects are stored at |
| 54 | + module scope and live until program exit. |
24 | 55 |
|
25 | 56 | Parameters |
26 | 57 | ---------- |
27 | 58 | name: |
28 | 59 | Name of the file to get the path for. |
29 | 60 | unzip: |
30 | 61 | If `True`, unzip the file before returning the path. |
| 62 | +
|
| 63 | + Returns |
| 64 | + ------- |
| 65 | + : |
| 66 | + The Path to the file. |
31 | 67 | """ |
32 | | - return self._registry.fetch(name, processor=pooch.Unzip() if unzip else None) |
| 68 | + return Path( |
| 69 | + self._registry.fetch( |
| 70 | + name, processor=self._unzip_processor if unzip else None |
| 71 | + ) |
| 72 | + ) |
33 | 73 |
|
34 | 74 |
|
35 | 75 | _bifrost_registry = Registry( |
@@ -76,37 +116,37 @@ def get_path(self, name: str, unzip: bool = False) -> str: |
76 | 116 | ) |
77 | 117 |
|
78 | 118 |
|
79 | | -def bifrost_simulated_elastic() -> str: |
| 119 | +def bifrost_simulated_elastic() -> Path: |
80 | 120 | """McStas simulation with elastic incoherent scattering + phonon.""" |
81 | 121 | return _bifrost_registry.get_path('BIFROST_20240914T053723.h5') |
82 | 122 |
|
83 | 123 |
|
84 | | -def loki_tutorial_sample_run_60250() -> str: |
| 124 | +def loki_tutorial_sample_run_60250() -> Path: |
85 | 125 | """Sample run with sample and sample holder/can, no transmission monitor in beam.""" |
86 | 126 | return _loki_registry.get_path('60250-2022-02-28_2215.nxs') |
87 | 127 |
|
88 | 128 |
|
89 | | -def loki_tutorial_sample_run_60339() -> str: |
| 129 | +def loki_tutorial_sample_run_60339() -> Path: |
90 | 130 | """Sample run with sample and sample holder/can, no transmission monitor in beam.""" |
91 | 131 | return _loki_registry.get_path('60339-2022-02-28_2215.nxs') |
92 | 132 |
|
93 | 133 |
|
94 | | -def loki_tutorial_background_run_60248() -> str: |
| 134 | +def loki_tutorial_background_run_60248() -> Path: |
95 | 135 | """Background run with sample holder/can only, no transmission monitor.""" |
96 | 136 | return _loki_registry.get_path('60248-2022-02-28_2215.nxs') |
97 | 137 |
|
98 | 138 |
|
99 | | -def loki_tutorial_background_run_60393() -> str: |
| 139 | +def loki_tutorial_background_run_60393() -> Path: |
100 | 140 | """Background run with sample holder/can only, no transmission monitor.""" |
101 | 141 | return _loki_registry.get_path('60393-2022-02-28_2215.nxs') |
102 | 142 |
|
103 | 143 |
|
104 | | -def loki_tutorial_sample_transmission_run() -> str: |
| 144 | +def loki_tutorial_sample_transmission_run() -> Path: |
105 | 145 | """Sample transmission run (sample + sample holder/can + transmission monitor).""" |
106 | 146 | return _loki_registry.get_path('60394-2022-02-28_2215.nxs') |
107 | 147 |
|
108 | 148 |
|
109 | | -def dream_coda_test_file() -> str: |
| 149 | +def dream_coda_test_file() -> Path: |
110 | 150 | """CODA file for DREAM where most pulses have been removed. |
111 | 151 |
|
112 | 152 | See ``tools/shrink_nexus.py``. |
|
0 commit comments