zarrcurator 1.0.0b1__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.
- zarrcurator-1.0.0b1/PKG-INFO +403 -0
- zarrcurator-1.0.0b1/README.md +354 -0
- zarrcurator-1.0.0b1/pyproject.toml +99 -0
- zarrcurator-1.0.0b1/src/zarrcurator/__init__.py +55 -0
- zarrcurator-1.0.0b1/src/zarrcurator/__init__.py_default +2 -0
- zarrcurator-1.0.0b1/src/zarrcurator/benchmark.py +179 -0
- zarrcurator-1.0.0b1/src/zarrcurator/chunkkeys.py +136 -0
- zarrcurator-1.0.0b1/src/zarrcurator/cli.py +68 -0
- zarrcurator-1.0.0b1/src/zarrcurator/config.py +782 -0
- zarrcurator-1.0.0b1/src/zarrcurator/diagnoser.py +649 -0
- zarrcurator-1.0.0b1/src/zarrcurator/dispatcher.py +633 -0
- zarrcurator-1.0.0b1/src/zarrcurator/displayer.py +414 -0
- zarrcurator-1.0.0b1/src/zarrcurator/distributor.py +623 -0
- zarrcurator-1.0.0b1/src/zarrcurator/oceanVarsYAML.py +70 -0
- zarrcurator-1.0.0b1/src/zarrcurator/py.typed +0 -0
- zarrcurator-1.0.0b1/src/zarrcurator/storetree.py +287 -0
- zarrcurator-1.0.0b1/src/zarrcurator/subgroup.py +215 -0
- zarrcurator-1.0.0b1/src/zarrcurator/synthetic_store.py +411 -0
- zarrcurator-1.0.0b1/src/zarrcurator/utils.py +1873 -0
- zarrcurator-1.0.0b1/src/zarrcurator/zarrcurator.code-workspace +7 -0
- zarrcurator-1.0.0b1/src/zarrcurator/zarrmetadata.py +236 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: zarrcurator
|
|
3
|
+
Version: 1.0.0b1
|
|
4
|
+
Summary: Analyze Zarr stores for completeness, sizing, and archival distribution workflows
|
|
5
|
+
Keywords: zarr,analysis,data-archiving,cloud-storage,scientific-data
|
|
6
|
+
Author: Kameswarrao Modali
|
|
7
|
+
Author-email: Kameswarrao Modali <modali@dkrz.de>
|
|
8
|
+
License-Expression: GPL-3.0-only
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering
|
|
15
|
+
Classifier: Topic :: System :: Archiving
|
|
16
|
+
Requires-Dist: cftime>=1.6.6
|
|
17
|
+
Requires-Dist: fastparquet>=2026.9.0
|
|
18
|
+
Requires-Dist: fsspec>=2026.2.0
|
|
19
|
+
Requires-Dist: kerchunk>=0.2.10
|
|
20
|
+
Requires-Dist: matplotlib>=3.10.8
|
|
21
|
+
Requires-Dist: plotly>=6.6.0
|
|
22
|
+
Requires-Dist: pyslk>=2.3.0
|
|
23
|
+
Requires-Dist: rich>=14.3.3
|
|
24
|
+
Requires-Dist: s3fs>=2026.9.0
|
|
25
|
+
Requires-Dist: tqdm>=4.70.1
|
|
26
|
+
Requires-Dist: ujson>=6.0.0
|
|
27
|
+
Requires-Dist: validators>=0.35.0
|
|
28
|
+
Requires-Dist: xarray>=2026.7.0
|
|
29
|
+
Requires-Dist: zarr>=3.4.1
|
|
30
|
+
Requires-Dist: build>=1.4.0 ; extra == 'dev'
|
|
31
|
+
Requires-Dist: codespell>=2.4.1 ; extra == 'dev'
|
|
32
|
+
Requires-Dist: mypy>=1.19.1 ; extra == 'dev'
|
|
33
|
+
Requires-Dist: pre-commit>=4.3.0 ; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest>=9.0.2 ; extra == 'dev'
|
|
35
|
+
Requires-Dist: ruff>=0.15.4 ; extra == 'dev'
|
|
36
|
+
Requires-Dist: twine>=6.2.0 ; extra == 'dev'
|
|
37
|
+
Requires-Dist: sphinx>=9.1.0 ; extra == 'docs'
|
|
38
|
+
Requires-Dist: sphinx-rtd-theme>=3.1.0 ; extra == 'docs'
|
|
39
|
+
Requires-Dist: myst-parser>=5.1.0 ; extra == 'docs'
|
|
40
|
+
Requires-Dist: rst2pdf>=0.105 ; extra == 'docs'
|
|
41
|
+
Requires-Python: >=3.12
|
|
42
|
+
Project-URL: Homepage, https://github.com/kmodali/zarrcurator
|
|
43
|
+
Project-URL: Issues, https://github.com/kmodali/zarrcurator/issues
|
|
44
|
+
Project-URL: Documentation, https://zarrcurator.readthedocs.io
|
|
45
|
+
Project-URL: Changelog, https://github.com/kmodali/zarrcurator/blob/main/CHANGELOG.md
|
|
46
|
+
Provides-Extra: dev
|
|
47
|
+
Provides-Extra: docs
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# zarrcurator
|
|
51
|
+
|
|
52
|
+
zarrcurator analyzes Zarr stores for completeness and sizing, supports visualization, and can package selected content into tar archives for downstream archival workflows.
|
|
53
|
+
|
|
54
|
+
## Repository Layout
|
|
55
|
+
|
|
56
|
+
- `src/zarrcurator`: package source code
|
|
57
|
+
- `tests`: repository-level test suite
|
|
58
|
+
|
|
59
|
+
## Contributing
|
|
60
|
+
|
|
61
|
+
Contribution workflow, coding rules, testing expectations, and PR guidelines are documented in `CONTRIBUTING.md`.
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
zarrcurator requires Python 3.12 or newer and zarr 3.4.1 or newer (the version in `uv.lock`).
|
|
66
|
+
Older zarr versions read a zero-size shard as not written, so the check did not report it as
|
|
67
|
+
corrupt.
|
|
68
|
+
|
|
69
|
+
Install from a local clone (recommended for development):
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
cd /path/to/zarrcurator
|
|
73
|
+
python -m pip install -e .
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Install as a regular package from a local clone:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
cd /path/to/zarrcurator
|
|
80
|
+
python -m pip install .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Build wheel/sdist and install the wheel:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
cd /path/to/zarrcurator
|
|
87
|
+
python -m pip install build
|
|
88
|
+
python -m build
|
|
89
|
+
python -m pip install dist/*.whl
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Optional: install development tooling used in this repository:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
cd /path/to/zarrcurator
|
|
96
|
+
python -m pip install -e .[dev]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Optional: install documentation tooling:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
cd /path/to/zarrcurator
|
|
103
|
+
python -m pip install -e .[docs]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Development Commands
|
|
107
|
+
|
|
108
|
+
Run unit test suite:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
python -m pytest
|
|
112
|
+
python -m tests.test_all_modules
|
|
113
|
+
python -m tests.regression_test
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`python -m pytest` ends with a summary table of the results per test class (tests and
|
|
117
|
+
subtests passed, failed and skipped, and what each class covers, from its docstring).
|
|
118
|
+
`--summary-table-file=summary.md` also writes it to a file, `--no-summary-table` turns it off.
|
|
119
|
+
|
|
120
|
+
Run the store layout tests (zarr v2 and v3, `.` and `/` separators, nested groups, sharding):
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
python -m pytest tests/test_all_modules.py -k TestChunkKeySeparators
|
|
124
|
+
python -m pytest tests/test_all_modules.py -k TestDataTreeStores
|
|
125
|
+
python -m pytest tests/test_all_modules.py -k TestZarrV3Metadata
|
|
126
|
+
python -m pytest tests/test_all_modules.py -k TestSyntheticStoreVariants
|
|
127
|
+
python -m pytest tests/regression_test.py -k synthetic_store_layouts
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Run focused config/object-store tests:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
python -m unittest tests.test_all_modules.TestConfigAndSubgroup
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Generate API documentation from source docstrings:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
python scripts/generate_api_docstrings.py
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Build Read the Docs style documentation (HTML and PDF):
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
python -m sphinx -b html docs docs/_build/html
|
|
146
|
+
python -m sphinx -b pdf docs docs/_build/pdf
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Releases
|
|
150
|
+
|
|
151
|
+
Repository release process and checklist are documented in `RELEASE.md`.
|
|
152
|
+
|
|
153
|
+
Bump package version (single-source in `pyproject.toml`):
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
python scripts/release.py --bump patch
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Automated publishing is configured via GitHub Actions Trusted Publishing:
|
|
160
|
+
|
|
161
|
+
- `.github/workflows/publish-pypi.yml`
|
|
162
|
+
- tag push `v*` publishes to PyPI
|
|
163
|
+
- manual `workflow_dispatch` supports TestPyPI and PyPI targets
|
|
164
|
+
|
|
165
|
+
Version consistency CI is configured via:
|
|
166
|
+
|
|
167
|
+
- `.github/workflows/version-consistency.yml`
|
|
168
|
+
|
|
169
|
+
Run pre-commit quality checks (lint, type checks, spell checks, and hygiene checks):
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
python -m pip install pre-commit
|
|
173
|
+
pre-commit install
|
|
174
|
+
pre-commit run --all-files
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Run benchmark harness:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
python -m zarrcurator.benchmark --help
|
|
181
|
+
python -m zarrcurator.benchmark --synthetic --phase diagnose
|
|
182
|
+
python -m zarrcurator.benchmark --synthetic --phase both
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Create a synthetic Zarr experiment to test diagnose/distribute/dispatch flows:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
cd src
|
|
189
|
+
python -m zarrcurator.synthetic_store --output-dir ../tests/data/synthetic_experiment --clean --zarr-formats 2,3 --run-smoke
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
By default each format uses its own chunk key separator (v2 `0.1`, v3 `c/0/1`), no
|
|
193
|
+
sharding and a flat layout (all arrays in the root group). These options add variants:
|
|
194
|
+
|
|
195
|
+
- `--separators .,/`: both chunk key separators for each format.
|
|
196
|
+
- `--shards 4,4,8`: the zarr v3 stores also with sharded data variables (shard shape of
|
|
197
|
+
`time,lat,lon`, a multiple of the chunk shape `2,4,4`).
|
|
198
|
+
- `--layouts flat,tree`: also stores with nested groups, as written from an xarray DataTree:
|
|
199
|
+
`time` in the root group, `lat`, `lon`, `temp` and `humidity` in `/atmos`, and `salinity`
|
|
200
|
+
in `/atmos/ocean`, which uses the coordinates of the groups above it.
|
|
201
|
+
|
|
202
|
+
All variants, as in the committed fixture:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
python -m zarrcurator.synthetic_store --output-dir tests/data/synthetic_experiment --clean \
|
|
206
|
+
--zarr-formats 2,3 --separators .,/ --shards 4,4,8 --layouts flat,tree --stores-per-frequency 1
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
The variant is tagged in the store name, only where it differs from the default:
|
|
210
|
+
|
|
211
|
+
| Format | Separator | Chunk key | Sharded | Layout | Store name |
|
|
212
|
+
| ------ | --------- | --------- | ------- | ------ | ---------- |
|
|
213
|
+
| v2 | `.` | `0.0.0` | no | flat | `syntheticexp_P1D_000_z2.zarr` |
|
|
214
|
+
| v2 | `/` | `0/0/0` | no | flat | `syntheticexp_P1D_000_z2slash.zarr` |
|
|
215
|
+
| v3 | `/` | `c/0/0/0` | no | flat | `syntheticexp_P1D_000_z3.zarr` |
|
|
216
|
+
| v3 | `.` | `c.0.0.0` | no | flat | `syntheticexp_P1D_000_z3dot.zarr` |
|
|
217
|
+
| v3 | `/` | `c/0/0/0` (shard) | yes | flat | `syntheticexp_P1D_000_z3shard.zarr` |
|
|
218
|
+
| v2 | `.` | `0.0.0` | no | tree | `syntheticexp_P1D_000_z2tree.zarr` |
|
|
219
|
+
| v3 | `.` | `c.0.0.0` (shard) | yes | tree | `syntheticexp_P1D_000_z3dotshardtree.zarr` |
|
|
220
|
+
|
|
221
|
+
All arrays carry dimension names, so the stores open with xarray. The generated
|
|
222
|
+
`manifest.json` records each store's `zarr_format`, `separator`, `shards`, `layout`, the
|
|
223
|
+
array the anomalies are injected into (`anomaly_array`: `temp`, or `atmos/ocean/salinity`
|
|
224
|
+
in a tree) and the anomalies (`zero_size`, `missing`, `corrupt`, `unexpected`). All paths in
|
|
225
|
+
it are relative to the manifest's directory, so the fixture works from any checkout.
|
|
226
|
+
|
|
227
|
+
## Store Layouts
|
|
228
|
+
|
|
229
|
+
zarr v2 and v3 stores with `.` or `/` chunk key separators, nested groups (e.g. written with
|
|
230
|
+
`xarray.DataTree.to_zarr`) and sharded arrays are supported, from diagnosis to the Kerchunk
|
|
231
|
+
references of the tarballs. A store must open with xarray (all arrays need dimension names);
|
|
232
|
+
`dispatchStoreToTarStores` checks this first and raises a `ValueError` otherwise. The Kerchunk
|
|
233
|
+
references of all tarballs of a store are merged into one parquet reference of the store, in
|
|
234
|
+
the zarr v2 layout; stores with nested groups are opened from it with `consolidated=True`.
|
|
235
|
+
Details and examples: [docs/store_layouts.md](docs/store_layouts.md).
|
|
236
|
+
|
|
237
|
+
## Large Stores and Several Sessions
|
|
238
|
+
|
|
239
|
+
The steps that read a whole store can be interrupted and continued in a later session, by
|
|
240
|
+
calling them again in the same working directory:
|
|
241
|
+
|
|
242
|
+
| Step | Kept in the working directory | Continued by |
|
|
243
|
+
|---|---|---|
|
|
244
|
+
| `diagnoseStore` | `<store>.diag.checkpoint`: the entries diagnosed so far (every 30 s) | diagnosing only the remaining entries; the `.diag` equals that of a single session, and the checkpoint is removed when the `.diag` is written |
|
|
245
|
+
| `findMissingChunksInStore` | `<store>.check`: rewritten after each array; with `checkpointSignal`, `<store>.check.partial`: the chunks checked so far in unfinished arrays, written when that signal arrives | skipping the arrays it lists (with unchanged shape, chunks and shards) and the chunks checked in partly checked arrays; the partial file is removed when all arrays are checked |
|
|
246
|
+
| `dispatchStoreToTarStores` | the tarballs; each is written as `<name>.tar.part` and renamed when complete | skipping the tarballs that exist completely (per bin for arrays split into chunk tarballs) |
|
|
247
|
+
|
|
248
|
+
To start a step from the beginning, delete its checkpoint, report or tarballs, or set
|
|
249
|
+
`Dispatcher.skipExistingTars = False`. Details, and recommended settings for running a large
|
|
250
|
+
check as a SLURM job on one whole node: [docs/overview.md](docs/overview.md).
|
|
251
|
+
|
|
252
|
+
## Known Issues and Limitations
|
|
253
|
+
|
|
254
|
+
See [docs/known_issues.md](docs/known_issues.md). In short:
|
|
255
|
+
|
|
256
|
+
- Target sizes below 1 GiB fail for arrays larger than the target size.
|
|
257
|
+
- A metadata file larger than the target size (e.g. the consolidated metadata of a large
|
|
258
|
+
store with many groups) fails.
|
|
259
|
+
- Kerchunk references are zarr v2: zarr v3 codecs without a zarr v2 equivalent are rejected,
|
|
260
|
+
and a single shard larger than the target size makes an oversized tarball.
|
|
261
|
+
|
|
262
|
+
## Object Store Access
|
|
263
|
+
|
|
264
|
+
For supported S3 endpoints, zarrcurator now uses this access order:
|
|
265
|
+
|
|
266
|
+
1. Try anonymous access first.
|
|
267
|
+
2. If anonymous access fails, try configured credentials.
|
|
268
|
+
3. If credentials are missing and anonymous access fails, exit with a clear error message.
|
|
269
|
+
|
|
270
|
+
You can provide credentials in three supported ways:
|
|
271
|
+
|
|
272
|
+
1. Use the new utility helper (recommended for notebooks/scripts).
|
|
273
|
+
2. Use config setters with environment-variable names.
|
|
274
|
+
3. Export environment variables directly.
|
|
275
|
+
|
|
276
|
+
Using the utility helper:
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
import zarrcurator
|
|
280
|
+
|
|
281
|
+
# Accepts raw values OR env-var names containing the values.
|
|
282
|
+
zarrcurator.setObjectStoreCredentials(
|
|
283
|
+
accessKey="AWS_ACCESS_KEY_ID",
|
|
284
|
+
secretKey="AWS_SECRET_ACCESS_KEY",
|
|
285
|
+
)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
You can also pass credentials directly on store-facing utility calls:
|
|
289
|
+
|
|
290
|
+
```python
|
|
291
|
+
from zarrcurator.utils import diagnoseStore, findMissingChunksInStore
|
|
292
|
+
|
|
293
|
+
diagnoseStore(
|
|
294
|
+
"https://s3.eu-dkrz-3.dkrz.cloud/mybucket/my-store.zarr",
|
|
295
|
+
accessKey="AWS_ACCESS_KEY_ID",
|
|
296
|
+
secretKey="AWS_SECRET_ACCESS_KEY",
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
findMissingChunksInStore(
|
|
300
|
+
"https://s3.eu-dkrz-3.dkrz.cloud/mybucket/my-store.zarr",
|
|
301
|
+
accessKey="AKIA...",
|
|
302
|
+
secretKey="...",
|
|
303
|
+
)
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Using config setters:
|
|
307
|
+
|
|
308
|
+
```python
|
|
309
|
+
from zarrcurator.config import configObj
|
|
310
|
+
|
|
311
|
+
# Pass environment variable names.
|
|
312
|
+
configObj.setaccessKey("AWS_ACCESS_KEY_ID")
|
|
313
|
+
configObj.setsecretKey("AWS_SECRET_ACCESS_KEY")
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
Using environment variables:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
export AWS_ACCESS_KEY_ID="<ACCESS_KEY>"
|
|
320
|
+
export AWS_SECRET_ACCESS_KEY="<SECRET_KEY>"
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Alternative variable names are also recognized:
|
|
324
|
+
|
|
325
|
+
- `S3_ACCESS_KEY_ID`
|
|
326
|
+
- `S3_SECRET_ACCESS_KEY`
|
|
327
|
+
|
|
328
|
+
## Multithreading
|
|
329
|
+
|
|
330
|
+
Store diagnosis and missing-chunk detection run single-threaded by default. To enable multithreading, set:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
export ZARRCURATOR_MULTITHREAD=1
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
When enabled, diagnosis (`diagnose`, `diagnoseStore`):
|
|
337
|
+
|
|
338
|
+
- diagnoses the Zarr stores of an experiment in parallel (up to 10 threads)
|
|
339
|
+
- diagnoses the variables within each store in parallel (up to 10 threads)
|
|
340
|
+
- lists all files of each variable, including chunks in sub directories (`/` separator), and
|
|
341
|
+
gathers their sizes in parallel on local stores, with the thread count scaled by the number of
|
|
342
|
+
files (1, 10, 40, or 100 threads for fewer than 200, 200–499, 500–999, or 1000 and more); on
|
|
343
|
+
object stores the listing already holds the sizes
|
|
344
|
+
|
|
345
|
+
When enabled, missing-chunk detection (`findMissingChunksInStore`):
|
|
346
|
+
|
|
347
|
+
- checks several arrays at once (8 by default, at most the number of available CPUs; set
|
|
348
|
+
`ZARRCURATOR_ARRAY_WORKERS` to change it), so that small arrays, e.g. of low zoom levels, do not
|
|
349
|
+
run one after the other
|
|
350
|
+
- queries chunk sizes (zero-size detection) in parallel
|
|
351
|
+
- checks chunk readability (corruption detection) in parallel
|
|
352
|
+
|
|
353
|
+
The size queries and readability checks of all arrays share two thread pools; each array keeps
|
|
354
|
+
at most as many chunks in progress as the number of its chunks gives (1, 10, 40, or 100, see
|
|
355
|
+
`numThreadsForChunks`). The report is written after each array, in the order of the store.
|
|
356
|
+
The log has a `check_array start` and a `check_array end` line per array; the end line gives
|
|
357
|
+
the seconds, the bytes read, the number of chunks and the rate in GB/s, so the speed of a check
|
|
358
|
+
can be measured per array.
|
|
359
|
+
|
|
360
|
+
The thread counts are capped by the CPUs available to the process (within a SLURM job, the CPUs
|
|
361
|
+
allocated to it): I/O-bound work (listing files, querying sizes) uses at most 4 threads per
|
|
362
|
+
CPU, CPU-bound work (reading and decompressing chunks for the corruption check) at most one
|
|
363
|
+
thread per CPU; for `findMissingChunksInStore` these are the sizes of the two shared pools. For
|
|
364
|
+
example, with 8 CPUs at most 32 threads query sizes and 8 check chunks. Set
|
|
365
|
+
`ZARRCURATOR_MAX_THREADS` to a positive integer to set the maximum for all work instead:
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
export ZARRCURATOR_MAX_THREADS=16
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Any value other than `1` (or leaving the variable unset) keeps single-threaded mode. The active mode is reported in the logs (`mode=single-thread` / `mode=multi-thread`).
|
|
372
|
+
|
|
373
|
+
From Python, set the variable before running a diagnosis:
|
|
374
|
+
|
|
375
|
+
```python
|
|
376
|
+
import os
|
|
377
|
+
|
|
378
|
+
os.environ["ZARRCURATOR_MULTITHREAD"] = "1"
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## Logging
|
|
382
|
+
|
|
383
|
+
CLI logging level can be set via:
|
|
384
|
+
|
|
385
|
+
- argument: `--log-level DEBUG`
|
|
386
|
+
- environment variable: `ZARRCURATOR_LOG_LEVEL=DEBUG`
|
|
387
|
+
|
|
388
|
+
During CLI usage, logs are also written to a timestamped file:
|
|
389
|
+
|
|
390
|
+
- default directory: `logs/`
|
|
391
|
+
- filename pattern: `zarrcurator_YYYYMMDD_HHMMSS.log`
|
|
392
|
+
|
|
393
|
+
You can override the log directory with:
|
|
394
|
+
|
|
395
|
+
- environment variable: `ZARRCURATOR_LOG_DIR=/path/to/logs`
|
|
396
|
+
|
|
397
|
+
For notebook/library usage (non-CLI), enable the same logging with:
|
|
398
|
+
|
|
399
|
+
```python
|
|
400
|
+
import zarrcurator
|
|
401
|
+
|
|
402
|
+
zarrcurator.enable_logging("INFO")
|
|
403
|
+
```
|