thyra 2.2.0__tar.gz → 2.2.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-2.2.0 → thyra-2.2.2}/PKG-INFO +1 -1
- {thyra-2.2.0 → thyra-2.2.2}/pyproject.toml +1 -1
- {thyra-2.2.0 → thyra-2.2.2}/thyra/__init__.py +1 -1
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/imzml/imzml_reader.py +18 -1
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/data_characteristics.py +14 -1
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/instrument_detectors.py +102 -11
- {thyra-2.2.0 → thyra-2.2.2}/LICENSE +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/README.md +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/__main__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/alignment/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/alignment/affine.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/alignment/teaching_points.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/config.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/convert.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/converters/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/converters/spatialdata/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/converters/spatialdata/_chunking.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/converters/spatialdata/base_spatialdata_converter.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/converters/spatialdata/converter.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/converters/spatialdata/spatialdata_2d_converter.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/converters/spatialdata/spatialdata_3d_converter.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/converters/spatialdata/streaming_converter.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/core/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/core/base_converter.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/core/base_extractor.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/core/base_reader.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/core/registry.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/extractors/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/extractors/bruker_extractor.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/extractors/imzml_extractor.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/extractors/waters_extractor.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/ontology/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/ontology/_ims.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/ontology/_ms.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/ontology/_uo.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/ontology/cache.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/types.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/metadata/validator.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/preview.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/base_bruker_reader.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/folder_structure.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/mis_parser.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/rapiflex/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/rapiflex/rapiflex_reader.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/sdk/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/sdk/dll/LICENCE-BRUKER.txt +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/sdk/dll/README.md +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/sdk/dll/timsdata.dll +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/sdk/dll/timsdata.so +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/sdk/dll_manager.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/sdk/platform_detector.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/sdk/sdk_functions.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/timstof_reader.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/utils/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/utils/batch_processor.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/utils/coordinate_cache.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/utils/mass_axis_builder.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/bruker/timstof/utils/memory_manager.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/imzml/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/waters/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/waters/imaging_grid.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/waters/lib/MLReader.dll +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/waters/lib/MassLynxRaw.dll +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/waters/lib/libMLReader.so +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/waters/lib/libMassLynxRaw.so +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/waters/masslynx_lib.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/readers/waters/waters_reader.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/common_axis.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/constants.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/decision_tree.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/gaps.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/mass_axis/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/mass_axis/base_generator.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/mass_axis/fticr_generator.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/mass_axis/linear_generator.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/mass_axis/linear_tof_generator.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/mass_axis/orbitrap_generator.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/mass_axis/reflector_tof_generator.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/strategies/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/strategies/base.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/strategies/nearest_neighbor.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/strategies/tic_preserving.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/tic.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/resampling/types.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/tools/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/tools/check_ontology.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/tools/make_example_data.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/utils/__init__.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/utils/bruker_exceptions.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/utils/logging_config.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/utils/windows_paths.py +0 -0
- {thyra-2.2.0 → thyra-2.2.2}/thyra/utils/zarr_atomic_write.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "thyra"
|
|
7
|
-
version = "2.2.
|
|
7
|
+
version = "2.2.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>"]
|
|
@@ -415,9 +415,26 @@ class ImzMLReader(BaseMSIReader):
|
|
|
415
415
|
# Initialize the parser
|
|
416
416
|
logger.info(f"Initializing ImzML parser for {imzml_path}")
|
|
417
417
|
try:
|
|
418
|
+
# ElementTree, NOT lxml. pyimzml prunes each <spectrum> out of the
|
|
419
|
+
# tree (`slist.remove(elem)`) while iterparse is still streaming the
|
|
420
|
+
# document, which invalidates libxml2's text-node coalescing
|
|
421
|
+
# accelerator: ctxt->nodelen/nodemem go on describing a text node
|
|
422
|
+
# inside the subtree that was just removed, so later character data
|
|
423
|
+
# is appended at a stale offset and the buffer is doubled on every
|
|
424
|
+
# miss until xmlRealloc fails. lxml surfaces libxml2's
|
|
425
|
+
# XML_ERR_NO_MEMORY as a *syntax* error, so it reads as a corrupt
|
|
426
|
+
# file when nothing is wrong with it:
|
|
427
|
+
# XMLSyntaxError: xmlSAX2Characters, line 212575, column 1
|
|
428
|
+
# It only bites when the text between </spectrum> and <spectrum> is
|
|
429
|
+
# exactly "\r\n" -- CRLF with no indentation, how IONTOF SurfaceLab
|
|
430
|
+
# writes imzML. Indented or LF-only files coalesce differently and
|
|
431
|
+
# survive, which is why most files never hit it. ElementTree builds
|
|
432
|
+
# the tree in Python, so there is no C parser state to invalidate;
|
|
433
|
+
# it is also pyimzml's own default, parses byte-identically, and is
|
|
434
|
+
# faster here -- 67s vs 118s on a 2.1 GB imzML at the same peak RSS.
|
|
418
435
|
self.parser = ImzMLParser(
|
|
419
436
|
filename=str(imzml_path),
|
|
420
|
-
parse_lib="
|
|
437
|
+
parse_lib="ElementTree",
|
|
421
438
|
ibd_file=self.ibd_file,
|
|
422
439
|
)
|
|
423
440
|
except Exception as e:
|
|
@@ -66,6 +66,14 @@ class DataCharacteristics:
|
|
|
66
66
|
|
|
67
67
|
Profile data typically has >5000 points per spectrum,
|
|
68
68
|
indicating continuous signal rather than centroid peaks.
|
|
69
|
+
|
|
70
|
+
This says how densely the spectra are sampled. It says nothing about
|
|
71
|
+
which instrument produced them, so it **must not be used to pick a
|
|
72
|
+
resampling strategy or an axis type**: those encode assumptions about
|
|
73
|
+
the acquisition's physics. ``RapiflexDetector`` used to match on this
|
|
74
|
+
alone, which handed MALDI-TOF treatment to any dense profile data --
|
|
75
|
+
TOF-SIMS, Orbitrap, anything -- with no check that the data was
|
|
76
|
+
MALDI-TOF at all.
|
|
69
77
|
"""
|
|
70
78
|
avg = self.avg_peaks_per_spectrum
|
|
71
79
|
return (
|
|
@@ -76,7 +84,12 @@ class DataCharacteristics:
|
|
|
76
84
|
|
|
77
85
|
@property
|
|
78
86
|
def is_maldi_tof(self) -> bool:
|
|
79
|
-
"""Check if this is MALDI-TOF data.
|
|
87
|
+
"""Check if this is MALDI-TOF data.
|
|
88
|
+
|
|
89
|
+
Carries the same caveat as :attr:`is_high_density_profile`, which its
|
|
90
|
+
last clause consults: density plus a vendor name is not a modality.
|
|
91
|
+
No detector calls this.
|
|
92
|
+
"""
|
|
80
93
|
return (
|
|
81
94
|
self.is_rapiflex_format
|
|
82
95
|
or self.instrument_type == "MALDI-TOF"
|
|
@@ -52,6 +52,30 @@ class InstrumentDetector(ABC):
|
|
|
52
52
|
"""Get the recommended mass axis type for this instrument."""
|
|
53
53
|
pass
|
|
54
54
|
|
|
55
|
+
@property
|
|
56
|
+
def source_grid_law(self) -> Optional[AxisType]:
|
|
57
|
+
"""Spacing law of the *source* m/z grid, when it is known.
|
|
58
|
+
|
|
59
|
+
``tic_preserving`` interpolates onto the target axis and then applies
|
|
60
|
+
one global scaling factor. That composite operator is exact only when
|
|
61
|
+
the source grid follows the same spacing law as the target axis; off
|
|
62
|
+
the diagonal it distorts the ratio between two peaks by exactly
|
|
63
|
+
``(m_hi / m_lo) ** (p_target - p_source)``, with ``p`` = 0, 0.5, 1,
|
|
64
|
+
1.5, 2 for constant / linear_tof / reflector_tof / orbitrap / fticr.
|
|
65
|
+
|
|
66
|
+
SCiLS Lab gates its own TIC-preserving resampling on the same
|
|
67
|
+
condition -- "If all axis types are identical, a TIC preserving
|
|
68
|
+
resampling is applied, otherwise a linear interpolation is performed"
|
|
69
|
+
(SCiLS Lab 2026b User Guide, p.80).
|
|
70
|
+
|
|
71
|
+
``None`` -- the default -- means Thyra does not know the source law.
|
|
72
|
+
That is the honest answer for every detector that matches on
|
|
73
|
+
something other than a vendor format whose grid Thyra itself lays
|
|
74
|
+
out, and :class:`InstrumentDetectorChain` refuses ``TIC_PRESERVING``
|
|
75
|
+
for such a detector.
|
|
76
|
+
"""
|
|
77
|
+
return None
|
|
78
|
+
|
|
55
79
|
|
|
56
80
|
class CentroidImzMLDetector(InstrumentDetector):
|
|
57
81
|
"""Detector for centroid ImzML data.
|
|
@@ -91,23 +115,33 @@ class RapiflexDetector(InstrumentDetector):
|
|
|
91
115
|
return "Rapiflex MALDI-TOF"
|
|
92
116
|
|
|
93
117
|
def matches(self, characteristics: DataCharacteristics) -> bool:
|
|
94
|
-
"""Check if data
|
|
118
|
+
"""Check if data came from Bruker flexImaging/Rapiflex.
|
|
119
|
+
|
|
120
|
+
Both branches below are written by one producer, the Rapiflex
|
|
121
|
+
metadata extractor, so a match here means the spectra arrive on the
|
|
122
|
+
uniform-in-m/z grid ``RapiflexReader`` builds.
|
|
123
|
+
|
|
124
|
+
Peak density is deliberately *not* consulted. It used to be: any
|
|
125
|
+
profile data averaging more than
|
|
126
|
+
``Thresholds.PROFILE_PEAK_DENSITY`` points per spectrum was handed
|
|
127
|
+
MALDI-TOF treatment regardless of what instrument produced it. That
|
|
128
|
+
made the detector modality-blind -- a dense TOF-SIMS or Orbitrap
|
|
129
|
+
profile acquisition would have been resampled by MALDI-TOF logic
|
|
130
|
+
onto a MALDI-shaped axis, silently. SCiLS Lab does not guess
|
|
131
|
+
modality either; its importer takes ``--project TIMSTOF|TOF|FT`` as
|
|
132
|
+
an argument (2026b User Guide, p.81). Unknown-provenance profile
|
|
133
|
+
data now falls through to :class:`DefaultDetector`, which bins
|
|
134
|
+
counts rather than interpolating and so is safe for any modality.
|
|
135
|
+
"""
|
|
95
136
|
# Direct Rapiflex format detection
|
|
96
137
|
if characteristics.is_rapiflex_format:
|
|
97
138
|
return True
|
|
98
139
|
|
|
99
140
|
# Bruker MALDI-TOF detection
|
|
100
|
-
|
|
141
|
+
return (
|
|
101
142
|
characteristics.instrument_type == "MALDI-TOF"
|
|
102
143
|
and characteristics.manufacturer == "Bruker"
|
|
103
|
-
)
|
|
104
|
-
return True
|
|
105
|
-
|
|
106
|
-
# Profile data with high peak density (likely MALDI-TOF)
|
|
107
|
-
if characteristics.is_high_density_profile:
|
|
108
|
-
return True
|
|
109
|
-
|
|
110
|
-
return False
|
|
144
|
+
)
|
|
111
145
|
|
|
112
146
|
def get_resampling_method(self) -> ResamplingMethod:
|
|
113
147
|
"""Return TIC-preserving for profile MALDI-TOF data."""
|
|
@@ -117,6 +151,19 @@ class RapiflexDetector(InstrumentDetector):
|
|
|
117
151
|
"""Return constant axis matching SCiLS Lab convention."""
|
|
118
152
|
return AxisType.CONSTANT
|
|
119
153
|
|
|
154
|
+
@property
|
|
155
|
+
def source_grid_law(self) -> Optional[AxisType]:
|
|
156
|
+
"""Report the constant law of the flexImaging source grid.
|
|
157
|
+
|
|
158
|
+
``RapiflexReader.get_common_mass_axis`` lays every spectrum out with
|
|
159
|
+
``np.linspace(mass_start, mass_end, n_points)``, so the source
|
|
160
|
+
spacing is constant in m/z -- the same law as the ``constant`` target
|
|
161
|
+
axis :meth:`get_axis_type` asks for. Source law equal to target law
|
|
162
|
+
is what makes ``tic_preserving`` exact here, and it is the reason
|
|
163
|
+
this is the only route on which the chain permits it.
|
|
164
|
+
"""
|
|
165
|
+
return AxisType.CONSTANT
|
|
166
|
+
|
|
120
167
|
|
|
121
168
|
class TimsTOFDetector(InstrumentDetector):
|
|
122
169
|
"""Detector for Bruker timsTOF data.
|
|
@@ -273,6 +320,9 @@ class InstrumentDetectorChain:
|
|
|
273
320
|
) -> ResamplingMethod:
|
|
274
321
|
"""Get resampling method for the detected instrument.
|
|
275
322
|
|
|
323
|
+
``TIC_PRESERVING`` additionally has to clear the matching-axis-law
|
|
324
|
+
gate; see :meth:`_gate_tic_preserving`.
|
|
325
|
+
|
|
276
326
|
Args:
|
|
277
327
|
characteristics: Data characteristics to match
|
|
278
328
|
|
|
@@ -280,10 +330,51 @@ class InstrumentDetectorChain:
|
|
|
280
330
|
Recommended resampling method for the instrument
|
|
281
331
|
"""
|
|
282
332
|
detector = self.detect(characteristics)
|
|
283
|
-
method =
|
|
333
|
+
method = self._gate_tic_preserving(detector)
|
|
284
334
|
logger.info(f"Selected resampling method: {method.name}")
|
|
285
335
|
return method
|
|
286
336
|
|
|
337
|
+
@staticmethod
|
|
338
|
+
def _gate_tic_preserving(detector: InstrumentDetector) -> ResamplingMethod:
|
|
339
|
+
"""Allow ``TIC_PRESERVING`` only when source and target laws agree.
|
|
340
|
+
|
|
341
|
+
SCiLS Lab applies TIC-preserving resampling to profile data only
|
|
342
|
+
when all the mass axes being combined are of the same type, and
|
|
343
|
+
linear interpolation otherwise (2026b User Guide, p.80). That is
|
|
344
|
+
also precisely the condition under which Thyra's operator --
|
|
345
|
+
interpolate, then rescale by one global factor -- is exact. See
|
|
346
|
+
:attr:`InstrumentDetector.source_grid_law` for the error off the
|
|
347
|
+
diagonal.
|
|
348
|
+
|
|
349
|
+
A detector that has not declared its source grid law does not clear
|
|
350
|
+
the gate. Auto-selection therefore cannot reach the interpolating
|
|
351
|
+
path on data whose acquisition Thyra has not actually identified.
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
detector: The detector that matched.
|
|
355
|
+
|
|
356
|
+
Returns:
|
|
357
|
+
The detector's method, or ``NEAREST_NEIGHBOR`` in its place.
|
|
358
|
+
"""
|
|
359
|
+
method = detector.get_resampling_method()
|
|
360
|
+
if method is not ResamplingMethod.TIC_PRESERVING:
|
|
361
|
+
return method
|
|
362
|
+
|
|
363
|
+
axis_type = detector.get_axis_type()
|
|
364
|
+
source_law = detector.source_grid_law
|
|
365
|
+
if source_law is axis_type:
|
|
366
|
+
return method
|
|
367
|
+
|
|
368
|
+
logger.info(
|
|
369
|
+
"%s asks for TIC_PRESERVING onto a %s axis, but the source grid "
|
|
370
|
+
"law is %s. TIC-preserving resampling is exact only when the two "
|
|
371
|
+
"match, so NEAREST_NEIGHBOR is used instead.",
|
|
372
|
+
detector.name,
|
|
373
|
+
axis_type.name,
|
|
374
|
+
"unknown" if source_law is None else source_law.name,
|
|
375
|
+
)
|
|
376
|
+
return ResamplingMethod.NEAREST_NEIGHBOR
|
|
377
|
+
|
|
287
378
|
def get_axis_type(self, characteristics: DataCharacteristics) -> AxisType:
|
|
288
379
|
"""Get axis type for the detected instrument.
|
|
289
380
|
|
|
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
|