thyra 3.0.0__tar.gz → 3.0.2__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.
- {thyra-3.0.0 → thyra-3.0.2}/PKG-INFO +4 -4
- {thyra-3.0.0 → thyra-3.0.2}/README.md +1 -1
- {thyra-3.0.0 → thyra-3.0.2}/pyproject.toml +5 -3
- {thyra-3.0.0 → thyra-3.0.2}/thyra/__init__.py +1 -1
- {thyra-3.0.0 → thyra-3.0.2}/thyra/converters/spatialdata/spatialdata_3d_converter.py +8 -3
- {thyra-3.0.0 → thyra-3.0.2}/thyra/converters/spatialdata/streaming_converter.py +29 -4
- {thyra-3.0.0 → thyra-3.0.2}/LICENSE +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/__main__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/alignment/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/alignment/affine.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/alignment/teaching_points.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/config.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/convert.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/converters/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/converters/spatialdata/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/converters/spatialdata/_chunking.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/converters/spatialdata/base_spatialdata_converter.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/converters/spatialdata/converter.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/converters/spatialdata/spatialdata_2d_converter.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/core/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/core/base_converter.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/core/base_extractor.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/core/base_reader.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/core/registry.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/extractors/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/extractors/bruker_extractor.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/extractors/imzml_extractor.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/extractors/waters_extractor.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/ontology/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/ontology/_ims.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/ontology/_ms.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/ontology/_uo.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/ontology/cache.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/types.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/metadata/validator.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/preview.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/base_bruker_reader.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/folder_structure.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/mis_parser.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/rapiflex/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/rapiflex/rapiflex_reader.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/sdk/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/sdk/dll/LICENCE-BRUKER.txt +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/sdk/dll/README.md +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/sdk/dll/timsdata.dll +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/sdk/dll/timsdata.so +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/sdk/dll_manager.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/sdk/platform_detector.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/sdk/sdk_functions.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/timstof_reader.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/utils/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/utils/batch_processor.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/utils/coordinate_cache.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/utils/mass_axis_builder.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/bruker/timstof/utils/memory_manager.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/imzml/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/imzml/imzml_reader.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/waters/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/waters/imaging_grid.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/waters/lib/MLReader.dll +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/waters/lib/MassLynxRaw.dll +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/waters/lib/libMLReader.so +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/waters/lib/libMassLynxRaw.so +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/waters/masslynx_lib.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/readers/waters/waters_reader.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/common_axis.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/constants.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/data_characteristics.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/decision_tree.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/gaps.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/instrument_detectors.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/mass_axis/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/mass_axis/base_generator.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/mass_axis/fticr_generator.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/mass_axis/linear_generator.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/mass_axis/linear_tof_generator.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/mass_axis/orbitrap_generator.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/mass_axis/reflector_tof_generator.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/strategies/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/strategies/base.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/strategies/nearest_neighbor.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/strategies/tic_preserving.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/tic.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/resampling/types.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/tools/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/tools/check_ontology.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/tools/make_example_data.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/utils/__init__.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/utils/bruker_exceptions.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/utils/logging_config.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/utils/windows_paths.py +0 -0
- {thyra-3.0.0 → thyra-3.0.2}/thyra/utils/zarr_atomic_write.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thyra
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
4
4
|
Summary: A modern Python library for converting Mass Spectrometry Imaging (MSI) data into SpatialData/Zarr format - your portal to spatial omics
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -42,8 +42,8 @@ Requires-Dist: tqdm (>=4.50.0)
|
|
|
42
42
|
Requires-Dist: zarr (>=3.1.4,<3.2)
|
|
43
43
|
Project-URL: Bug Tracker, https://github.com/M4i-Imaging-Mass-Spectrometry/thyra/issues
|
|
44
44
|
Project-URL: Changelog, https://github.com/M4i-Imaging-Mass-Spectrometry/thyra/blob/main/CHANGELOG.md
|
|
45
|
-
Project-URL: Contributing, https://
|
|
46
|
-
Project-URL: Documentation, https://
|
|
45
|
+
Project-URL: Contributing, https://M4i-Imaging-Mass-Spectrometry.github.io/thyra/contributing/
|
|
46
|
+
Project-URL: Documentation, https://M4i-Imaging-Mass-Spectrometry.github.io/thyra/
|
|
47
47
|
Project-URL: Discussions, https://github.com/M4i-Imaging-Mass-Spectrometry/thyra/discussions
|
|
48
48
|
Project-URL: Homepage, https://github.com/M4i-Imaging-Mass-Spectrometry/thyra
|
|
49
49
|
Project-URL: Repository, https://github.com/M4i-Imaging-Mass-Spectrometry/thyra
|
|
@@ -83,7 +83,7 @@ for a full walkthrough, including the published example dataset
|
|
|
83
83
|
- **Memory Efficient**: Handles large datasets (100+ GB) through streaming processing
|
|
84
84
|
- **Optical Alignment**: Automatic MSI-to-optical image registration for Bruker data
|
|
85
85
|
- **Multi-Region Support**: Handles slides with multiple tissue sections
|
|
86
|
-
- **Resampling**: Physics-aware mass axis resampling (
|
|
86
|
+
- **Resampling**: Physics-aware mass axis resampling (on by default in the CLI; opt-in from the Python API)
|
|
87
87
|
- **3D Support**: Process volume data or treat as 2D slices
|
|
88
88
|
- **Cross-Platform**: Windows, macOS, and Linux
|
|
89
89
|
|
|
@@ -32,7 +32,7 @@ for a full walkthrough, including the published example dataset
|
|
|
32
32
|
- **Memory Efficient**: Handles large datasets (100+ GB) through streaming processing
|
|
33
33
|
- **Optical Alignment**: Automatic MSI-to-optical image registration for Bruker data
|
|
34
34
|
- **Multi-Region Support**: Handles slides with multiple tissue sections
|
|
35
|
-
- **Resampling**: Physics-aware mass axis resampling (
|
|
35
|
+
- **Resampling**: Physics-aware mass axis resampling (on by default in the CLI; opt-in from the Python API)
|
|
36
36
|
- **3D Support**: Process volume data or treat as 2D slices
|
|
37
37
|
- **Cross-Platform**: Windows, macOS, and Linux
|
|
38
38
|
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "thyra"
|
|
7
|
-
version = "3.0.
|
|
7
|
+
version = "3.0.2"
|
|
8
8
|
description = "A modern Python library for converting Mass Spectrometry Imaging (MSI) data into SpatialData/Zarr format - your portal to spatial omics"
|
|
9
9
|
authors = ["Theodoros Visvikis <t.visvikis@maastrichtuniversity.nl>"]
|
|
10
10
|
maintainers = ["Theodoros Visvikis <t.visvikis@maastrichtuniversity.nl>"]
|
|
@@ -12,7 +12,7 @@ license = "MIT"
|
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
homepage = "https://github.com/M4i-Imaging-Mass-Spectrometry/thyra"
|
|
14
14
|
repository = "https://github.com/M4i-Imaging-Mass-Spectrometry/thyra"
|
|
15
|
-
documentation = "https://
|
|
15
|
+
documentation = "https://M4i-Imaging-Mass-Spectrometry.github.io/thyra/"
|
|
16
16
|
keywords = [
|
|
17
17
|
"mass-spectrometry",
|
|
18
18
|
"imaging",
|
|
@@ -50,7 +50,9 @@ packages = [{include = "thyra"}]
|
|
|
50
50
|
"Bug Tracker" = "https://github.com/M4i-Imaging-Mass-Spectrometry/thyra/issues"
|
|
51
51
|
"Discussions" = "https://github.com/M4i-Imaging-Mass-Spectrometry/thyra/discussions"
|
|
52
52
|
"Changelog" = "https://github.com/M4i-Imaging-Mass-Spectrometry/thyra/blob/main/CHANGELOG.md"
|
|
53
|
-
|
|
53
|
+
# There is no CONTRIBUTING.md at the repository root; the guide lives at
|
|
54
|
+
# docs/contributing.md and is published as this page.
|
|
55
|
+
"Contributing" = "https://M4i-Imaging-Mass-Spectrometry.github.io/thyra/contributing/"
|
|
54
56
|
|
|
55
57
|
[tool.poetry.dependencies]
|
|
56
58
|
python = ">=3.12, <3.14"
|
|
@@ -272,12 +272,17 @@ class SpatialData3DConverter(BaseSpatialDataConverter):
|
|
|
272
272
|
n_x, n_y, n_z = self._dimensions
|
|
273
273
|
|
|
274
274
|
if n_z > 1:
|
|
275
|
-
# True 3D TIC image
|
|
275
|
+
# True 3D TIC image. The accumulator is indexed [y, x, z] (see
|
|
276
|
+
# _create_data_structures), while Image3DModel declares
|
|
277
|
+
# (c, z, y, x) -- so the axes have to be *moved*. This used to
|
|
278
|
+
# relabel the shape instead, which reshapes nothing and left
|
|
279
|
+
# every volume whose extents were not all equal permuted: a
|
|
280
|
+
# 5(x) x 3(y) x 2(z) acquisition was stored as (1, 3, 5, 2).
|
|
276
281
|
tic_values = data_structures["tic_values"]
|
|
277
|
-
|
|
282
|
+
tic_values_zyx = np.transpose(tic_values, (2, 0, 1))
|
|
278
283
|
|
|
279
284
|
# Add channel dimension for 3D image
|
|
280
|
-
tic_values_with_channel =
|
|
285
|
+
tic_values_with_channel = tic_values_zyx[np.newaxis, ...]
|
|
281
286
|
|
|
282
287
|
# The image is intrinsically in raster pixel indices.
|
|
283
288
|
# Scale into physical micrometers so "global" agrees with
|
|
@@ -461,6 +461,7 @@ class StreamingSpatialDataConverter(BaseSpatialDataConverter):
|
|
|
461
461
|
nnz_per_row = np.zeros(n_rows, dtype=np.int64)
|
|
462
462
|
total_nnz = 0
|
|
463
463
|
pixel_count = 0
|
|
464
|
+
n_out_of_bounds = 0
|
|
464
465
|
|
|
465
466
|
region_map, region_total, region_count = self._init_region_accumulators(n_cols)
|
|
466
467
|
|
|
@@ -476,11 +477,22 @@ class StreamingSpatialDataConverter(BaseSpatialDataConverter):
|
|
|
476
477
|
mz_indices, resampled_ints = self._process_spectrum(mzs, intensities)
|
|
477
478
|
nnz = len(mz_indices)
|
|
478
479
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
480
|
+
# The row count and the TIC are both indexed by grid
|
|
481
|
+
# position, so both need the bounds check: a coordinate
|
|
482
|
+
# outside the declared dimensions would otherwise wrap
|
|
483
|
+
# round and land on an unrelated pixel. Unlike the PCS
|
|
484
|
+
# pre-scan the guard sits outside the `nnz > 0` test,
|
|
485
|
+
# because this assignment is unconditional -- a wrapped
|
|
486
|
+
# empty spectrum would overwrite a real row's count with
|
|
487
|
+
# zero. total_nnz travels with nnz_per_row so that
|
|
488
|
+
# indptr[-1] keeps matching the array size derived from
|
|
489
|
+
# it; pass 2 skips the same spectra.
|
|
482
490
|
if 0 <= y < n_y and 0 <= x < n_x:
|
|
491
|
+
nnz_per_row[pixel_idx] = nnz
|
|
492
|
+
total_nnz += nnz
|
|
483
493
|
tic_values[y, x] = float(np.sum(resampled_ints))
|
|
494
|
+
else:
|
|
495
|
+
n_out_of_bounds += 1
|
|
484
496
|
|
|
485
497
|
if nnz > 0:
|
|
486
498
|
np.add.at(total_intensity, mz_indices, resampled_ints)
|
|
@@ -500,6 +512,15 @@ class StreamingSpatialDataConverter(BaseSpatialDataConverter):
|
|
|
500
512
|
pbar.update(1)
|
|
501
513
|
|
|
502
514
|
logger.info(f"Pass 1 complete: {total_nnz:,} total non-zeros")
|
|
515
|
+
if n_out_of_bounds:
|
|
516
|
+
logger.warning(
|
|
517
|
+
"%d spectra sat outside the declared %dx%d grid and were "
|
|
518
|
+
"skipped. Previously they were written to a wrapped-round "
|
|
519
|
+
"row index, silently overwriting an unrelated pixel.",
|
|
520
|
+
n_out_of_bounds,
|
|
521
|
+
n_x,
|
|
522
|
+
n_y,
|
|
523
|
+
)
|
|
503
524
|
|
|
504
525
|
# Build indptr from nnz counts
|
|
505
526
|
indptr = np.zeros(n_rows + 1, dtype=np.int64)
|
|
@@ -628,7 +649,11 @@ class StreamingSpatialDataConverter(BaseSpatialDataConverter):
|
|
|
628
649
|
mz_indices, resampled_ints = self._process_spectrum(mzs, intensities)
|
|
629
650
|
nnz = len(mz_indices)
|
|
630
651
|
|
|
631
|
-
|
|
652
|
+
# Same bounds check as pass 1, and it has to be the same
|
|
653
|
+
# one: that pass reserved no room for a spectrum outside
|
|
654
|
+
# the grid, so writing it here would overrun the row it
|
|
655
|
+
# wrapped onto and displace that row's own entries.
|
|
656
|
+
if nnz > 0 and 0 <= y < n_y and 0 <= x < n_x:
|
|
632
657
|
pos = write_pos[pixel_idx]
|
|
633
658
|
positions = np.arange(pos, pos + nnz)
|
|
634
659
|
buf_positions.append(positions)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|