nabu 2024.2.4__py3-none-any.whl → 2025.1.0.dev4__py3-none-any.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.
Files changed (164) hide show
  1. doc/doc_config.py +32 -0
  2. nabu/__init__.py +1 -1
  3. nabu/app/bootstrap_stitching.py +4 -2
  4. nabu/app/cast_volume.py +7 -13
  5. nabu/app/cli_configs.py +0 -5
  6. nabu/app/compare_volumes.py +1 -1
  7. nabu/app/composite_cor.py +2 -4
  8. nabu/app/correct_rot.py +0 -8
  9. nabu/app/diag_to_pix.py +5 -6
  10. nabu/app/diag_to_rot.py +10 -11
  11. nabu/app/multicor.py +1 -1
  12. nabu/app/parse_reconstruction_log.py +1 -0
  13. nabu/app/prepare_weights_double.py +1 -2
  14. nabu/app/reconstruct_helical.py +1 -5
  15. nabu/app/reduce_dark_flat.py +0 -2
  16. nabu/app/rotate.py +3 -1
  17. nabu/app/tests/test_reduce_dark_flat.py +2 -2
  18. nabu/app/validator.py +1 -4
  19. nabu/cuda/convolution.py +1 -1
  20. nabu/cuda/fft.py +1 -1
  21. nabu/cuda/medfilt.py +1 -1
  22. nabu/cuda/padding.py +1 -1
  23. nabu/cuda/src/cone.cu +19 -9
  24. nabu/cuda/src/hierarchical_backproj.cu +16 -0
  25. nabu/cuda/utils.py +2 -2
  26. nabu/estimation/alignment.py +17 -31
  27. nabu/estimation/cor.py +23 -29
  28. nabu/estimation/cor_sino.py +2 -8
  29. nabu/estimation/focus.py +4 -8
  30. nabu/estimation/tests/test_alignment.py +2 -0
  31. nabu/estimation/tests/test_tilt.py +1 -1
  32. nabu/estimation/tilt.py +5 -4
  33. nabu/io/cast_volume.py +5 -5
  34. nabu/io/detector_distortion.py +5 -6
  35. nabu/io/reader.py +3 -3
  36. nabu/io/reader_helical.py +5 -4
  37. nabu/io/tests/test_cast_volume.py +2 -2
  38. nabu/io/tests/test_readers.py +4 -4
  39. nabu/io/tests/test_writers.py +2 -2
  40. nabu/io/utils.py +8 -4
  41. nabu/io/writer.py +1 -2
  42. nabu/misc/fftshift.py +1 -1
  43. nabu/misc/fourier_filters.py +1 -1
  44. nabu/misc/histogram.py +1 -1
  45. nabu/misc/histogram_cuda.py +1 -1
  46. nabu/misc/padding_base.py +1 -1
  47. nabu/misc/rotation.py +1 -1
  48. nabu/misc/rotation_cuda.py +1 -1
  49. nabu/misc/tests/test_binning.py +1 -1
  50. nabu/misc/transpose.py +1 -1
  51. nabu/misc/unsharp.py +1 -1
  52. nabu/misc/unsharp_cuda.py +1 -1
  53. nabu/misc/unsharp_opencl.py +1 -1
  54. nabu/misc/utils.py +1 -1
  55. nabu/opencl/fft.py +1 -1
  56. nabu/opencl/padding.py +1 -1
  57. nabu/opencl/utils.py +8 -8
  58. nabu/pipeline/config.py +2 -2
  59. nabu/pipeline/config_validators.py +4 -3
  60. nabu/pipeline/datadump.py +3 -3
  61. nabu/pipeline/estimators.py +6 -6
  62. nabu/pipeline/fullfield/chunked.py +4 -5
  63. nabu/pipeline/fullfield/dataset_validator.py +0 -1
  64. nabu/pipeline/fullfield/nabu_config.py +2 -1
  65. nabu/pipeline/fullfield/reconstruction.py +9 -8
  66. nabu/pipeline/helical/dataset_validator.py +3 -4
  67. nabu/pipeline/helical/fbp.py +4 -4
  68. nabu/pipeline/helical/filtering.py +5 -4
  69. nabu/pipeline/helical/gridded_accumulator.py +9 -10
  70. nabu/pipeline/helical/helical_chunked_regridded.py +1 -0
  71. nabu/pipeline/helical/helical_reconstruction.py +10 -7
  72. nabu/pipeline/helical/helical_utils.py +1 -2
  73. nabu/pipeline/helical/nabu_config.py +1 -0
  74. nabu/pipeline/helical/span_strategy.py +1 -0
  75. nabu/pipeline/helical/weight_balancer.py +1 -2
  76. nabu/pipeline/tests/__init__.py +0 -0
  77. nabu/pipeline/utils.py +1 -1
  78. nabu/pipeline/writer.py +1 -1
  79. nabu/preproc/alignment.py +0 -10
  80. nabu/preproc/ctf.py +8 -8
  81. nabu/preproc/ctf_cuda.py +1 -1
  82. nabu/preproc/double_flatfield_cuda.py +2 -2
  83. nabu/preproc/double_flatfield_variable_region.py +0 -1
  84. nabu/preproc/flatfield.py +1 -1
  85. nabu/preproc/flatfield_cuda.py +1 -2
  86. nabu/preproc/flatfield_variable_region.py +3 -3
  87. nabu/preproc/phase.py +2 -4
  88. nabu/preproc/phase_cuda.py +2 -2
  89. nabu/preproc/shift_cuda.py +0 -1
  90. nabu/preproc/tests/test_ctf.py +3 -3
  91. nabu/preproc/tests/test_double_flatfield.py +1 -1
  92. nabu/preproc/tests/test_flatfield.py +1 -1
  93. nabu/preproc/tests/test_vshift.py +4 -1
  94. nabu/processing/azim.py +2 -2
  95. nabu/processing/convolution_cuda.py +6 -4
  96. nabu/processing/fft_base.py +1 -1
  97. nabu/processing/fft_cuda.py +19 -8
  98. nabu/processing/fft_opencl.py +9 -4
  99. nabu/processing/fftshift.py +1 -1
  100. nabu/processing/histogram.py +1 -1
  101. nabu/processing/muladd.py +0 -1
  102. nabu/processing/padding_base.py +1 -1
  103. nabu/processing/padding_cuda.py +0 -1
  104. nabu/processing/processing_base.py +1 -1
  105. nabu/processing/tests/test_fft.py +1 -1
  106. nabu/processing/tests/test_fftshift.py +1 -1
  107. nabu/processing/tests/test_medfilt.py +1 -3
  108. nabu/processing/tests/test_padding.py +1 -1
  109. nabu/processing/tests/test_roll.py +1 -1
  110. nabu/processing/unsharp_opencl.py +1 -1
  111. nabu/reconstruction/astra.py +245 -0
  112. nabu/reconstruction/cone.py +9 -4
  113. nabu/reconstruction/fbp_base.py +2 -2
  114. nabu/reconstruction/filtering_cuda.py +1 -1
  115. nabu/reconstruction/hbp.py +16 -3
  116. nabu/reconstruction/mlem.py +0 -1
  117. nabu/reconstruction/projection.py +3 -5
  118. nabu/reconstruction/sinogram.py +1 -1
  119. nabu/reconstruction/sinogram_cuda.py +0 -1
  120. nabu/reconstruction/tests/test_cone.py +76 -3
  121. nabu/reconstruction/tests/test_deringer.py +2 -2
  122. nabu/reconstruction/tests/test_fbp.py +1 -1
  123. nabu/reconstruction/tests/test_halftomo.py +27 -1
  124. nabu/reconstruction/tests/test_mlem.py +3 -2
  125. nabu/reconstruction/tests/test_projector.py +7 -2
  126. nabu/reconstruction/tests/test_sino_normalization.py +0 -1
  127. nabu/resources/dataset_analyzer.py +4 -4
  128. nabu/resources/gpu.py +4 -4
  129. nabu/resources/logger.py +4 -4
  130. nabu/resources/nxflatfield.py +2 -2
  131. nabu/resources/tests/test_nxflatfield.py +4 -4
  132. nabu/stitching/alignment.py +1 -4
  133. nabu/stitching/config.py +19 -16
  134. nabu/stitching/frame_composition.py +8 -10
  135. nabu/stitching/overlap.py +2 -2
  136. nabu/stitching/slurm_utils.py +2 -2
  137. nabu/stitching/stitcher/base.py +2 -0
  138. nabu/stitching/stitcher/dumper/base.py +0 -1
  139. nabu/stitching/stitcher/dumper/postprocessing.py +1 -1
  140. nabu/stitching/stitcher/post_processing.py +6 -6
  141. nabu/stitching/stitcher/pre_processing.py +13 -11
  142. nabu/stitching/stitcher/single_axis.py +3 -4
  143. nabu/stitching/stitcher_2D.py +2 -1
  144. nabu/stitching/tests/test_config.py +7 -8
  145. nabu/stitching/tests/test_sample_normalization.py +1 -1
  146. nabu/stitching/tests/test_slurm_utils.py +1 -2
  147. nabu/stitching/tests/test_z_postprocessing_stitching.py +1 -1
  148. nabu/stitching/tests/test_z_preprocessing_stitching.py +4 -4
  149. nabu/stitching/utils/tests/__init__.py +0 -0
  150. nabu/stitching/utils/tests/test_post-processing.py +1 -0
  151. nabu/stitching/utils/utils.py +10 -12
  152. nabu/tests.py +0 -3
  153. nabu/testutils.py +30 -8
  154. nabu/utils.py +28 -18
  155. {nabu-2024.2.4.dist-info → nabu-2025.1.0.dev4.dist-info}/METADATA +25 -25
  156. nabu-2025.1.0.dev4.dist-info/RECORD +320 -0
  157. {nabu-2024.2.4.dist-info → nabu-2025.1.0.dev4.dist-info}/WHEEL +1 -1
  158. nabu/io/tests/test_detector_distortion.py +0 -178
  159. nabu/resources/tests/test_extract.py +0 -9
  160. nabu-2024.2.4.dist-info/RECORD +0 -318
  161. /nabu/{stitching → app}/tests/__init__.py +0 -0
  162. {nabu-2024.2.4.dist-info → nabu-2025.1.0.dev4.dist-info}/LICENSE +0 -0
  163. {nabu-2024.2.4.dist-info → nabu-2025.1.0.dev4.dist-info}/entry_points.txt +0 -0
  164. {nabu-2024.2.4.dist-info → nabu-2025.1.0.dev4.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- from distutils.version import StrictVersion
1
+ from distutils.version import StrictVersion # pylint: disable=E0401
2
2
  from typing import Optional, Union
3
3
  import logging
4
4
  import functools
@@ -9,7 +9,6 @@ from nxtomo.utils.transformation import build_matrix, DetYFlipTransformation
9
9
  from silx.utils.enum import Enum as _Enum
10
10
  from scipy.fft import rfftn as local_fftn
11
11
  from scipy.fft import irfftn as local_ifftn
12
- from ..overlap import OverlapStitchingStrategy, ImageStichOverlapKernel
13
12
  from ..alignment import AlignmentAxis1, AlignmentAxis2, PaddedRawData
14
13
  from ...misc import fourier_filters
15
14
  from ...estimation.alignment import AlignmentBase
@@ -75,7 +74,7 @@ def find_frame_relative_shifts(
75
74
  """
76
75
  :param overlap_axis: axis in [0, 1] on which the overlap exists. In image space. So 0 is aka y and 1 as x
77
76
  """
78
- if not overlap_axis in (0, 1):
77
+ if overlap_axis not in (0, 1):
79
78
  raise ValueError(f"overlap_axis should be in (0, 1). Get {overlap_axis}")
80
79
  from nabu.stitching.config import (
81
80
  KEY_LOW_PASS_FILTER,
@@ -146,7 +145,7 @@ def find_frame_relative_shifts(
146
145
  }
147
146
 
148
147
  res_algo = {}
149
- for shift_alg in set((x_cross_correlation_function, y_cross_correlation_function)):
148
+ for shift_alg in set((x_cross_correlation_function, y_cross_correlation_function)): # noqa: C405
150
149
  if shift_alg not in shift_methods:
151
150
  raise ValueError(f"requested image alignment function not handled ({shift_alg})")
152
151
  try:
@@ -249,7 +248,7 @@ def find_volumes_relative_shifts(
249
248
 
250
249
  w_window_size = int(y_shifts_params.get(KEY_WINDOW_SIZE, 400))
251
250
  start_overlap = max(estimated_shifts[0] // 2 - w_window_size // 2, 0)
252
- end_overlap = min(estimated_shifts[0] // 2 + w_window_size // 2, min(upper_frame.shape[0], lower_frame.shape[0]))
251
+ end_overlap = min(estimated_shifts[0] // 2 + w_window_size // 2, upper_frame.shape[0], lower_frame.shape[0])
253
252
 
254
253
  if start_overlap == 0:
255
254
  overlap_upper_frame = upper_frame[-end_overlap:]
@@ -385,12 +384,10 @@ def find_projections_relative_shifts(
385
384
  cor_options=cor_options,
386
385
  )
387
386
 
388
- estimated_shifts = tuple(
389
- [
390
- estimated_shifts[0],
391
- (lower_scan_pos - upper_scan_pos),
392
- ]
393
- )
387
+ estimated_shifts = [
388
+ estimated_shifts[0],
389
+ (lower_scan_pos - upper_scan_pos),
390
+ ]
394
391
  x_cross_correlation_function = ShiftAlgorithm.NONE
395
392
 
396
393
  # } else we will compute shift from the flat projections
@@ -464,7 +461,8 @@ def find_projections_relative_shifts(
464
461
  start_overlap = max(estimated_shifts[axis_proj_space] // 2 - w_window_size // 2, 0)
465
462
  end_overlap = min(
466
463
  estimated_shifts[axis_proj_space] // 2 + w_window_size // 2,
467
- min(upper_proj.shape[axis_proj_space], lower_proj.shape[axis_proj_space]),
464
+ upper_proj.shape[axis_proj_space],
465
+ lower_proj.shape[axis_proj_space],
468
466
  )
469
467
  o_upper_sel = numpy.array(range(-end_overlap, -start_overlap))
470
468
  overlap_upper_frame = numpy.take_along_axis(
nabu/tests.py CHANGED
@@ -1,6 +1,3 @@
1
- #!/usr/bin/env python
2
- # -*- coding: utf-8 -*-
3
-
4
1
  import sys
5
2
  import os
6
3
  import pytest
nabu/testutils.py CHANGED
@@ -41,7 +41,10 @@ def generate_tests_scenarios(configurations):
41
41
  - the key is the name of a parameter
42
42
  - the value is one value of this parameter
43
43
  """
44
- scenarios = [{key: val for key, val in zip(configurations.keys(), p_)} for p_ in product(*configurations.values())]
44
+ scenarios = [
45
+ {key: val for key, val in zip(configurations.keys(), p_)} # noqa: C416
46
+ for p_ in product(*configurations.values())
47
+ ]
45
48
  return scenarios
46
49
 
47
50
 
@@ -81,12 +84,34 @@ def get_big_data(filename):
81
84
 
82
85
 
83
86
  def uncompress_file(compressed_file_path, target_directory):
84
- with tarfile.open(compressed_file_path) as f:
85
- f.extractall(path=target_directory)
87
+ if not tarfile.is_tarfile(compressed_file_path):
88
+ raise ValueError(f"Invalid tar file: {compressed_file_path}")
89
+
90
+ def is_safe_member(member, target_directory):
91
+ """Ensure the member does not extract outside the target directory."""
92
+ if not isinstance(member, tarfile.TarInfo):
93
+ return False # Reject any unexpected type
94
+
95
+ abs_target = os.path.abspath(target_directory)
96
+ member_path = os.path.abspath(os.path.join(target_directory, member.name))
97
+ return member_path.startswith(abs_target)
98
+
99
+ def get_valid_members(tar):
100
+ members = [m for m in tar.getmembers() if is_safe_member(m, target_directory)]
101
+ if not members:
102
+ raise ValueError("No valid files to extract or archive contains unsafe paths.")
103
+ for member in members:
104
+ if not is_safe_member(member, target_directory):
105
+ raise ValueError(f"Unsafe path detected: {member.name}")
106
+
107
+ with tarfile.open(compressed_file_path, "r") as tar:
108
+ tar.extractall( # noqa: S202 - what can be done in addition of the above checks ?
109
+ path=target_directory, members=get_valid_members(tar)
110
+ )
86
111
 
87
112
 
88
113
  def get_file(fname):
89
- downloaded_file = dataset_downloaded_path = utilstest.getfile(fname)
114
+ downloaded_file = utilstest.getfile(fname)
90
115
  if ".tar" in fname:
91
116
  uncompress_file(downloaded_file, os.path.dirname(downloaded_file))
92
117
  downloaded_file = downloaded_file.split(".tar")[0]
@@ -204,10 +229,7 @@ def generate_nx_dataset(out_fname, image_key, data_volume=None, rotation_angle=N
204
229
  nx_entry = nx_dict["entry"]
205
230
 
206
231
  def _get_field(dict_, path):
207
- if path.startswith("/"):
208
- path = path[1:]
209
- if path.endswith("/"):
210
- path = path[:-1]
232
+ path = path.strip("/")
211
233
  split_path = path.split("/")
212
234
  if len(split_path) == 1:
213
235
  return dict_[split_path[0]]
nabu/utils.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from fnmatch import fnmatch
2
2
  from functools import partial
3
3
  import os
4
- from functools import partial, lru_cache
4
+ from functools import lru_cache
5
5
  from itertools import product
6
6
  import warnings
7
7
  from time import time
@@ -94,7 +94,7 @@ def indices_to_slices(indices):
94
94
  jumps = np.hstack([-1, jumps, len(indices) - 1])
95
95
  slices = []
96
96
  for i in range(len(jumps) - 1):
97
- slices.append(slice(indices[jumps[i] + 1], indices[jumps[i + 1]] + 1))
97
+ slices.append(slice(indices[jumps[i] + 1], indices[jumps[i + 1]] + 1)) # noqa: PERF401
98
98
  return slices
99
99
 
100
100
 
@@ -183,7 +183,7 @@ def list_match_queries(available, queries):
183
183
  for a in available:
184
184
  for q in queries:
185
185
  if fnmatch(a, q):
186
- matches.append(a)
186
+ matches.append(a) # noqa: PERF401
187
187
  return matches
188
188
 
189
189
 
@@ -211,7 +211,7 @@ def _sizeof(Type):
211
211
  return np.dtype(Type).itemsize
212
212
 
213
213
 
214
- class _Default_format(dict):
214
+ class _DefaultFormat(dict):
215
215
  """
216
216
  https://docs.python.org/3/library/stdtypes.html
217
217
  """
@@ -224,7 +224,7 @@ def safe_format(str_, **kwargs):
224
224
  """
225
225
  Alternative to str.format(), but does not throw a KeyError when fields are missing.
226
226
  """
227
- return str_.format_map(_Default_format(**kwargs))
227
+ return str_.format_map(_DefaultFormat(**kwargs))
228
228
 
229
229
 
230
230
  def get_ftype(url):
@@ -296,7 +296,7 @@ def view_as_images_stack(img):
296
296
 
297
297
 
298
298
  def rescale_integers(items, new_tot):
299
- """ "
299
+ """
300
300
  From a given sequence of integers, create a new sequence
301
301
  where the sum of all items must be equal to "new_tot".
302
302
  The relative contribution of each item to the new total is approximately kept.
@@ -329,6 +329,8 @@ def merged_shape(shapes, axis=0):
329
329
  return (shapes[0][0], n_img, shapes[0][2])
330
330
  elif axis == 2:
331
331
  return shapes[0][:2] + (n_img,)
332
+ else:
333
+ raise ValueError
332
334
 
333
335
 
334
336
  def is_device_backend(backend):
@@ -371,7 +373,7 @@ def generate_powers():
371
373
  powers = product(*valuations)
372
374
  res = []
373
375
  for pw in powers:
374
- res.append(np.prod(list(map(lambda x: x[0] ** x[1], zip(primes, pw)))))
376
+ res.append(np.prod(list(map(lambda x: x[0] ** x[1], zip(primes, pw))))) # noqa: PERF401
375
377
  return np.unique(res)
376
378
 
377
379
 
@@ -422,10 +424,14 @@ def partition_dict(dict_, n_partitions):
422
424
 
423
425
 
424
426
  def first_dict_item(dict_):
425
- keys = sorted(list(dict_.keys()))
427
+ keys = sorted(dict_.keys())
426
428
  return dict_[keys[0]]
427
429
 
428
430
 
431
+ def first_generator_item(gen):
432
+ return next(iter(gen)) # instead of list(gen)[0]
433
+
434
+
429
435
  def subsample_dict(dic, subsampling_factor):
430
436
  """
431
437
  Subsample a dict where keys are integers.
@@ -437,7 +443,7 @@ def subsample_dict(dic, subsampling_factor):
437
443
  return res
438
444
 
439
445
 
440
- def compare_dicts(dic1, dic2):
446
+ def compare_dicts(dic1, dic2): # noqa: PLR0911
441
447
  """
442
448
  Compare two dictionaries. Return None if and only iff the dictionaries are the same.
443
449
 
@@ -629,7 +635,7 @@ def get_num_threads(n=None):
629
635
  return min(n_avail, n)
630
636
 
631
637
 
632
- class DictToObj(object):
638
+ class DictToObj:
633
639
  """utility class to transform a dictionary into an object with dictionary items as members.
634
640
  Example:
635
641
 
@@ -646,14 +652,17 @@ def remove_parenthesis_or_brackets(input_str):
646
652
  """
647
653
  clear string from left and or roght parenthesis / braquets
648
654
  """
649
- if input_str.startswith("(") and input_str.endswith(")") or input_str.startswith("[") and input_str.endswith("]"):
655
+ if (input_str.startswith("(") and input_str.endswith(")")) or (
656
+ input_str.startswith("[") and input_str.endswith("]")
657
+ ):
650
658
  input_str = input_str[1:-1]
651
659
  return input_str
652
660
 
653
661
 
654
662
  def filter_str_def(elmt):
655
663
  """clean elemt if is a string defined from a text file.
656
- Remove some character that could have be put on left or right and some empty spaces"""
664
+ Remove some character that could have be put on left or right and some empty spaces
665
+ """
657
666
  if elmt is None:
658
667
  return None
659
668
  assert isinstance(elmt, str)
@@ -676,7 +685,7 @@ def convert_str_to_tuple(input_str: str, none_if_empty: bool = False):
676
685
  if isinstance(input_str, tuple):
677
686
  return input_str
678
687
  if not isinstance(input_str, str):
679
- raise TypeError("input_str should be a string not {}, {}".format(type(input_str), input_str))
688
+ raise TypeError(f"input_str should be a string not {type(input_str)}, {input_str}")
680
689
  input_str = input_str.lstrip(" ").lstrip("(").lstrip("[").lstrip(" ").rstrip(" ")
681
690
  input_str = remove_parenthesis_or_brackets(input_str)
682
691
  input_str = input_str.replace("\n", ",")
@@ -767,7 +776,7 @@ def median2(img):
767
776
  Roughly same speed as scipy median filter, but more memory demanding.
768
777
  """
769
778
  img2 = extend_image_onepixel(img)
770
- I = np.array(
779
+ img3 = np.array(
771
780
  [
772
781
  img2[0:-2, 0:-2],
773
782
  img2[0:-2, 1:-1],
@@ -780,7 +789,7 @@ def median2(img):
780
789
  img2[2:, 2:],
781
790
  ]
782
791
  )
783
- return np.median(I, axis=0)
792
+ return np.median(img3, axis=0)
784
793
 
785
794
 
786
795
  # ------------------------------------------------------------------------------
@@ -820,6 +829,7 @@ def warning(msg):
820
829
  print(msg)
821
830
  res = func(*args, **kwargs)
822
831
  return res
832
+ return None
823
833
 
824
834
  return wrapper
825
835
 
@@ -840,7 +850,7 @@ def deprecated(msg, do_print=False):
840
850
 
841
851
  def deprecated_class(msg, do_print=False):
842
852
  def decorator(cls):
843
- class wrapper:
853
+ class Wrapper:
844
854
  def __init__(self, *args, **kwargs):
845
855
  deprecation_warning(msg, do_print=do_print, func_name=cls.__name__)
846
856
  self.wrapped = cls(*args, **kwargs)
@@ -849,7 +859,7 @@ def deprecated_class(msg, do_print=False):
849
859
  def __getattr__(self, name):
850
860
  return getattr(self.wrapped, name)
851
861
 
852
- return wrapper
862
+ return Wrapper
853
863
 
854
864
  return decorator
855
865
 
@@ -905,7 +915,7 @@ from warnings import catch_warnings
905
915
  # catch_warnings() does not have "action=XX" kwarg for python < 3.11
906
916
  from sys import version_info
907
917
 
908
- if version_info.major == 3 and version_info.minor < 11:
918
+ if version_info.major == 3 and version_info.minor < 11: # noqa: YTT204 - not sure about this
909
919
 
910
920
  def dummy(*args, **kwargs):
911
921
  pass
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: nabu
3
- Version: 2024.2.4
3
+ Version: 2025.1.0.dev4
4
4
  Summary: Nabu - Tomography software
5
5
  Author-email: Pierre Paleo <pierre.paleo@esrf.fr>, Henri Payno <henri.payno@esrf.fr>, Alessandro Mirone <mirone@esrf.fr>, Jérôme Lesaint <jerome.lesaint@esrf.fr>
6
6
  Maintainer-email: Pierre Paleo <pierre.paleo@esrf.fr>
@@ -49,35 +49,35 @@ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
49
49
  Requires-Python: >=3.7
50
50
  Description-Content-Type: text/markdown
51
51
  License-File: LICENSE
52
- Requires-Dist: numpy <2,>1.9.0
52
+ Requires-Dist: numpy>1.9.0
53
53
  Requires-Dist: scipy
54
- Requires-Dist: h5py >=3.0
55
- Requires-Dist: silx >=0.15.0
56
- Requires-Dist: tomoscan >=2.1.0
54
+ Requires-Dist: h5py>=3.0
55
+ Requires-Dist: silx>=0.15.0
56
+ Requires-Dist: tomoscan>=2.1.0
57
57
  Requires-Dist: psutil
58
58
  Requires-Dist: pytest
59
59
  Requires-Dist: tifffile
60
60
  Requires-Dist: tqdm
61
- Provides-Extra: doc
62
- Requires-Dist: sphinx ; extra == 'doc'
63
- Requires-Dist: cloud-sptheme ; extra == 'doc'
64
- Requires-Dist: myst-parser ; extra == 'doc'
65
- Requires-Dist: nbsphinx ; extra == 'doc'
66
61
  Provides-Extra: full
67
- Requires-Dist: scikit-image ; extra == 'full'
68
- Requires-Dist: PyWavelets ; extra == 'full'
69
- Requires-Dist: glymur ; extra == 'full'
70
- Requires-Dist: pycuda !=2024.1.1 ; extra == 'full'
71
- Requires-Dist: scikit-cuda ; extra == 'full'
72
- Requires-Dist: pycudwt ; extra == 'full'
73
- Requires-Dist: sluurp >=0.3 ; extra == 'full'
74
- Requires-Dist: pyvkfft ; extra == 'full'
75
- Provides-Extra: full_nocuda
76
- Requires-Dist: scikit-image ; extra == 'full_nocuda'
77
- Requires-Dist: PyWavelets ; extra == 'full_nocuda'
78
- Requires-Dist: glymur ; extra == 'full_nocuda'
79
- Requires-Dist: sluurp >=0.3 ; extra == 'full_nocuda'
80
- Requires-Dist: pyvkfft ; extra == 'full_nocuda'
62
+ Requires-Dist: scikit-image; extra == "full"
63
+ Requires-Dist: PyWavelets; extra == "full"
64
+ Requires-Dist: glymur; extra == "full"
65
+ Requires-Dist: pycuda!=2024.1.1; extra == "full"
66
+ Requires-Dist: scikit-cuda; extra == "full"
67
+ Requires-Dist: pycudwt; extra == "full"
68
+ Requires-Dist: sluurp>=0.3; extra == "full"
69
+ Requires-Dist: pyvkfft; extra == "full"
70
+ Provides-Extra: full-nocuda
71
+ Requires-Dist: scikit-image; extra == "full-nocuda"
72
+ Requires-Dist: PyWavelets; extra == "full-nocuda"
73
+ Requires-Dist: glymur; extra == "full-nocuda"
74
+ Requires-Dist: sluurp>=0.3; extra == "full-nocuda"
75
+ Requires-Dist: pyvkfft; extra == "full-nocuda"
76
+ Provides-Extra: doc
77
+ Requires-Dist: sphinx; extra == "doc"
78
+ Requires-Dist: cloud_sptheme; extra == "doc"
79
+ Requires-Dist: myst-parser; extra == "doc"
80
+ Requires-Dist: nbsphinx; extra == "doc"
81
81
 
82
82
  # Nabu
83
83