httomolibgpu 5.7__tar.gz → 5.8.1__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.
- {httomolibgpu-5.7/httomolibgpu.egg-info → httomolibgpu-5.8.1}/PKG-INFO +2 -1
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/misc/morph.py +63 -0
- httomolibgpu-5.8.1/httomolibgpu/misc/sorting.py +56 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/prep/stripe.py +20 -34
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/recon/algorithm.py +7 -5
- {httomolibgpu-5.7 → httomolibgpu-5.8.1/httomolibgpu.egg-info}/PKG-INFO +2 -1
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu.egg-info/SOURCES.txt +1 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu.egg-info/requires.txt +1 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/pyproject.toml +2 -1
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/LICENSE +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/MANIFEST.in +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/README.rst +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/__init__.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/cuda_kernels/__init__.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/cuda_kernels/calc_metrics.cu +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/cuda_kernels/center_360_shifts.cu +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/cuda_kernels/generate_mask.cu +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/cuda_kernels/median_kernel.cu +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/cuda_kernels/raven_filter.cu +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/cuda_kernels/remove_nan_inf.cu +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/cuda_kernels/remove_stripe_fw.cu +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/cupywrapper.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/misc/__init__.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/misc/corr.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/misc/denoise.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/misc/rescale.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/misc/utils.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/prep/__init__.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/prep/alignment.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/prep/normalize.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/prep/phase.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/recon/__init__.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/recon/_phase_cross_correlation.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu/recon/rotation.py +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu.egg-info/dependency_links.txt +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/httomolibgpu.egg-info/top_level.txt +0 -0
- {httomolibgpu-5.7 → httomolibgpu-5.8.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: httomolibgpu
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.8.1
|
|
4
4
|
Summary: Commonly used tomography data processing methods at DLS.
|
|
5
5
|
Author-email: Daniil Kazantsev <daniil.kazantsev@diamond.ac.uk>, Yousef Moazzam <yousef.moazzam@diamond.ac.uk>, Naman Gera <naman.gera@diamond.ac.uk>
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -33,6 +33,7 @@ Requires-Dist: imageio; extra == "dev"
|
|
|
33
33
|
Requires-Dist: h5py; extra == "dev"
|
|
34
34
|
Requires-Dist: pre-commit; extra == "dev"
|
|
35
35
|
Requires-Dist: pyfftw; extra == "dev"
|
|
36
|
+
Requires-Dist: tomophantom; extra == "dev"
|
|
36
37
|
Dynamic: license-file
|
|
37
38
|
|
|
38
39
|
HTTomolibGPU is a library of GPU accelerated methods for tomography
|
|
@@ -45,6 +45,7 @@ from httomolibgpu.misc.utils import (
|
|
|
45
45
|
__all__ = [
|
|
46
46
|
"sino_360_to_180",
|
|
47
47
|
"data_resampler",
|
|
48
|
+
"average_projection_frames",
|
|
48
49
|
]
|
|
49
50
|
|
|
50
51
|
|
|
@@ -305,3 +306,65 @@ def data_resampler(
|
|
|
305
306
|
if expanded:
|
|
306
307
|
scaled_data = cp.squeeze(scaled_data, axis=axis)
|
|
307
308
|
return scaled_data
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def average_projection_frames(
|
|
312
|
+
data: cp.ndarray,
|
|
313
|
+
projection_averaging_factor: int = 2,
|
|
314
|
+
) -> cp.ndarray:
|
|
315
|
+
"""
|
|
316
|
+
This method averages/downsamples by averaging data along the angular direction based on the provided projection_averaging_factor.
|
|
317
|
+
|
|
318
|
+
Parameters
|
|
319
|
+
----------
|
|
320
|
+
data : cp.ndarray
|
|
321
|
+
3d cupy array given as (angles, detY, detX).
|
|
322
|
+
projection_averaging_factor : int
|
|
323
|
+
to average every (defined by the provided factor) consecutive projections into one effective projection.
|
|
324
|
+
|
|
325
|
+
Raises
|
|
326
|
+
----------
|
|
327
|
+
ValueError: When data is not 3D
|
|
328
|
+
|
|
329
|
+
Returns
|
|
330
|
+
-------
|
|
331
|
+
cp.ndarray: 3D cupy array with averaged projection data
|
|
332
|
+
"""
|
|
333
|
+
|
|
334
|
+
### Data and parameters checks ###
|
|
335
|
+
methods_name = "average_projection_frames"
|
|
336
|
+
__check_if_data_3D_array(data, methods_name)
|
|
337
|
+
__check_if_data_correct_type(
|
|
338
|
+
data, accepted_type=["float32", "uint16"], methods_name=methods_name
|
|
339
|
+
)
|
|
340
|
+
__check_if_positive_nonzero(
|
|
341
|
+
projection_averaging_factor,
|
|
342
|
+
"projection_averaging_factor",
|
|
343
|
+
True,
|
|
344
|
+
True,
|
|
345
|
+
methods_name,
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
###################################
|
|
349
|
+
if projection_averaging_factor > 1:
|
|
350
|
+
k = projection_averaging_factor
|
|
351
|
+
n_proj = data.shape[0]
|
|
352
|
+
|
|
353
|
+
n_full = n_proj // k
|
|
354
|
+
remainder = n_proj % k
|
|
355
|
+
|
|
356
|
+
n_out = n_full + (remainder > 0)
|
|
357
|
+
|
|
358
|
+
averaged = cp.empty((n_out, *data.shape[1:]), dtype=data.dtype)
|
|
359
|
+
|
|
360
|
+
if n_full:
|
|
361
|
+
averaged[:n_full] = (
|
|
362
|
+
data[: n_full * k].reshape(n_full, k, *data.shape[1:]).mean(axis=1)
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
if remainder:
|
|
366
|
+
averaged[-1] = data[n_full * k :].mean(axis=0)
|
|
367
|
+
|
|
368
|
+
return averaged
|
|
369
|
+
else:
|
|
370
|
+
return data
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# ---------------------------------------------------------------------------
|
|
4
|
+
# Copyright 2026 Diamond Light Source Ltd.
|
|
5
|
+
#
|
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
# you may not use this file except in compliance with the License.
|
|
8
|
+
# You may obtain a copy of the License at
|
|
9
|
+
#
|
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
#
|
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either ecpress or implied.
|
|
15
|
+
# See the License for the specific language governing permissions and
|
|
16
|
+
# limitations under the License.
|
|
17
|
+
# ---------------------------------------------------------------------------
|
|
18
|
+
# Created By : Tomography Team at DLS <scientificsoftware@diamond.ac.uk>
|
|
19
|
+
# Created Date: 22 April 2026
|
|
20
|
+
# ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
from typing import Tuple
|
|
23
|
+
from httomolibgpu import cupywrapper
|
|
24
|
+
|
|
25
|
+
cp = cupywrapper.cp
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def argsort_with_reverse(
|
|
29
|
+
data: cp.ndarray, axis: int = -1
|
|
30
|
+
) -> Tuple[cp.ndarray, cp.ndarray]:
|
|
31
|
+
"""
|
|
32
|
+
Compute sorting indices for an 1D or 2D array, and efficiently compute the indices to revert the sort.
|
|
33
|
+
"""
|
|
34
|
+
dim = len(data.shape)
|
|
35
|
+
if 1 <= dim <= 2:
|
|
36
|
+
pass
|
|
37
|
+
else:
|
|
38
|
+
raise ValueError("only 1D and 2D arrays are supported")
|
|
39
|
+
if axis < 0:
|
|
40
|
+
axis = dim + axis
|
|
41
|
+
if axis >= dim:
|
|
42
|
+
raise ValueError("invalid axis")
|
|
43
|
+
sort_indices = cp.argsort(data, axis=axis)
|
|
44
|
+
reverse_sort_indices = cp.empty_like(sort_indices)
|
|
45
|
+
if dim == 1:
|
|
46
|
+
reverse_sort_indices[sort_indices] = cp.arange(0, data.size)
|
|
47
|
+
elif axis == 0: # sort rows
|
|
48
|
+
nrows, ncols = data.shape
|
|
49
|
+
cols = cp.arange(ncols)[None, :]
|
|
50
|
+
reverse_sort_indices[sort_indices, cols] = cp.arange(nrows)[:, None]
|
|
51
|
+
else: # sort columns
|
|
52
|
+
nrows, ncols = data.shape
|
|
53
|
+
rows = cp.arange(nrows)[:, None]
|
|
54
|
+
reverse_sort_indices[rows, sort_indices] = cp.arange(ncols)
|
|
55
|
+
|
|
56
|
+
return sort_indices, reverse_sort_indices
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
import numpy as np
|
|
24
24
|
import pywt
|
|
25
25
|
from httomolibgpu import cupywrapper
|
|
26
|
+
from httomolibgpu.misc.sorting import argsort_with_reverse
|
|
26
27
|
|
|
27
28
|
cp = cupywrapper.cp
|
|
28
29
|
cupy_run = cupywrapper.cupy_run
|
|
@@ -116,21 +117,18 @@ def _rs_sort(sinogram, size, dim):
|
|
|
116
117
|
"""
|
|
117
118
|
Remove stripes using the sorting technique.
|
|
118
119
|
"""
|
|
119
|
-
sinogram
|
|
120
|
+
#: Sort each row of the sinogram by its grayscale values
|
|
121
|
+
sortvals, sortvals_reverse = argsort_with_reverse(sinogram, axis=0)
|
|
120
122
|
|
|
121
|
-
|
|
122
|
-
#: Keep track of the sorting indices so we can reverse it below
|
|
123
|
-
sortvals = cp.argsort(sinogram, axis=1)
|
|
124
|
-
sortvals_reverse = cp.argsort(sortvals, axis=1)
|
|
125
|
-
sino_sort = cp.take_along_axis(sinogram, sortvals, axis=1)
|
|
123
|
+
sino_sort = cp.take_along_axis(sinogram, sortvals, axis=0)
|
|
126
124
|
|
|
127
125
|
#: Now apply the median filter on the sorted image along each row
|
|
128
|
-
sino_sort = median_filter(sino_sort, (
|
|
126
|
+
sino_sort = median_filter(sino_sort, (1, size) if dim == 1 else (size, size))
|
|
129
127
|
|
|
130
128
|
#: step 3: re-sort the smoothed image columns to the original rows
|
|
131
|
-
sino_corrected = cp.take_along_axis(sino_sort, sortvals_reverse, axis=
|
|
129
|
+
sino_corrected = cp.take_along_axis(sino_sort, sortvals_reverse, axis=0)
|
|
132
130
|
|
|
133
|
-
return
|
|
131
|
+
return sino_corrected
|
|
134
132
|
|
|
135
133
|
|
|
136
134
|
def remove_stripe_ti(
|
|
@@ -821,6 +819,7 @@ def remove_all_stripe(
|
|
|
821
819
|
la_size: int = 61,
|
|
822
820
|
sm_size: int = 21,
|
|
823
821
|
dim: Literal[1, 2] = 1,
|
|
822
|
+
normalize: bool = False,
|
|
824
823
|
) -> cp.ndarray:
|
|
825
824
|
"""
|
|
826
825
|
Remove all types of stripe artifacts from sinogram using Nghia Vo's
|
|
@@ -839,6 +838,8 @@ def remove_all_stripe(
|
|
|
839
838
|
Window size of the median filter to remove small-to-medium stripes.
|
|
840
839
|
dim : {1, 2},
|
|
841
840
|
Dimension of the window.
|
|
841
|
+
normalize : bool,
|
|
842
|
+
Controls whether to normalize while removing large stripes
|
|
842
843
|
|
|
843
844
|
Returns
|
|
844
845
|
-------
|
|
@@ -859,10 +860,10 @@ def remove_all_stripe(
|
|
|
859
860
|
__check_variable_type(dim, [int], "dim", [1, 2], methods_name)
|
|
860
861
|
###################################
|
|
861
862
|
|
|
862
|
-
matindex = _create_matindex(data.shape[2], data.shape[0])
|
|
863
863
|
for m in range(data.shape[1]):
|
|
864
864
|
sino = data[:, m, :]
|
|
865
|
-
sino = _rs_dead(sino, snr, la_size
|
|
865
|
+
sino = _rs_dead(sino, snr, la_size)
|
|
866
|
+
sino = _rs_large(sino, snr, la_size, normalize)
|
|
866
867
|
sino = _rs_sort(sino, sm_size, dim)
|
|
867
868
|
sino = cp.nan_to_num(sino)
|
|
868
869
|
data[:, m, :] = sino
|
|
@@ -910,15 +911,17 @@ def _detect_stripe(listdata, snr):
|
|
|
910
911
|
return listmask
|
|
911
912
|
|
|
912
913
|
|
|
913
|
-
def _rs_large(sinogram, snr, size,
|
|
914
|
+
def _rs_large(sinogram, snr, size, normalize, drop_ratio=0.1):
|
|
914
915
|
"""
|
|
915
916
|
Remove large stripes.
|
|
916
917
|
"""
|
|
917
918
|
drop_ratio = max(min(drop_ratio, 0.8), 0) # = cp.clip(drop_ratio, 0.0, 0.8)
|
|
918
919
|
nrow, ncol = sinogram.shape
|
|
919
920
|
ndrop = int(0.5 * drop_ratio * nrow)
|
|
920
|
-
|
|
921
|
+
sort_indices, sort_indices_reverse = argsort_with_reverse(sinogram, axis=0)
|
|
922
|
+
sinosort = cp.take_along_axis(sinogram, sort_indices, axis=0)
|
|
921
923
|
sinosmooth = median_filter(sinosort, (1, size))
|
|
924
|
+
|
|
922
925
|
list1 = cp.mean(sinosort[ndrop : nrow - ndrop], axis=0)
|
|
923
926
|
list2 = cp.mean(sinosmooth[ndrop : nrow - ndrop], axis=0)
|
|
924
927
|
listfact = list1 / list2
|
|
@@ -927,30 +930,16 @@ def _rs_large(sinogram, snr, size, matindex, drop_ratio=0.1, norm=True):
|
|
|
927
930
|
listmask = _detect_stripe(listfact, snr)
|
|
928
931
|
listmask = binary_dilation(listmask, iterations=1).astype(listmask.dtype)
|
|
929
932
|
matfact = cp.tile(listfact, (nrow, 1))
|
|
930
|
-
|
|
931
|
-
if norm is True:
|
|
933
|
+
if normalize:
|
|
932
934
|
sinogram = sinogram / matfact
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
ids = cp.argsort(matcombine[:, :, 1], axis=1)
|
|
937
|
-
matsort = matcombine.copy()
|
|
938
|
-
matsort[:, :, 0] = cp.take_along_axis(matsort[:, :, 0], ids, axis=1)
|
|
939
|
-
matsort[:, :, 1] = cp.take_along_axis(matsort[:, :, 1], ids, axis=1)
|
|
940
|
-
|
|
941
|
-
matsort[:, :, 1] = cp.transpose(sinosmooth)
|
|
942
|
-
ids = cp.argsort(matsort[:, :, 0], axis=1)
|
|
943
|
-
matsortback = matsort.copy()
|
|
944
|
-
matsortback[:, :, 0] = cp.take_along_axis(matsortback[:, :, 0], ids, axis=1)
|
|
945
|
-
matsortback[:, :, 1] = cp.take_along_axis(matsortback[:, :, 1], ids, axis=1)
|
|
946
|
-
|
|
947
|
-
sino_corrected = cp.transpose(matsortback[:, :, 1])
|
|
935
|
+
sort_indices, sort_indices_reverse = argsort_with_reverse(sinogram, axis=0)
|
|
936
|
+
sino_corrected = cp.take_along_axis(sinosmooth, sort_indices_reverse, axis=0)
|
|
948
937
|
listxmiss = cp.where(listmask > 0.0)[0]
|
|
949
938
|
sinogram[:, listxmiss] = sino_corrected[:, listxmiss]
|
|
950
939
|
return sinogram
|
|
951
940
|
|
|
952
941
|
|
|
953
|
-
def _rs_dead(sinogram, snr, size
|
|
942
|
+
def _rs_dead(sinogram, snr, size):
|
|
954
943
|
"""remove unresponsive and fluctuating stripes"""
|
|
955
944
|
sinogram = cp.copy(sinogram) # Make it mutable
|
|
956
945
|
nrow, _ = sinogram.shape
|
|
@@ -979,9 +968,6 @@ def _rs_dead(sinogram, snr, size, matindex, norm=True):
|
|
|
979
968
|
sinogram[:, listx[ids]] - sinogram[:, listx[ids - 1]]
|
|
980
969
|
)
|
|
981
970
|
|
|
982
|
-
# Remove residual stripes
|
|
983
|
-
if norm is True:
|
|
984
|
-
sinogram = _rs_large(sinogram, snr, size, matindex)
|
|
985
971
|
return sinogram
|
|
986
972
|
|
|
987
973
|
|
|
@@ -566,13 +566,13 @@ def FISTA3d_tomobar(
|
|
|
566
566
|
data_fidelity: str
|
|
567
567
|
Data fidelity given as 'LS' (Least Squares)
|
|
568
568
|
regularisation_type: str
|
|
569
|
-
A method to use for regularisation. Currently PD_TV and ROF_TV are available.
|
|
569
|
+
A method to use for regularisation. Currently PD_TV and ROF_TV penalties are available.
|
|
570
570
|
regularisation_parameter: float
|
|
571
571
|
The main regularisation parameter to control the amount of smoothing/noise removal. Larger values lead to stronger smoothing.
|
|
572
572
|
regularisation_iterations: int
|
|
573
573
|
The number of iterations for regularisers (aka INNER iterations).
|
|
574
574
|
regularisation_half_precision: bool
|
|
575
|
-
Perform faster regularisation computation in half-precision with
|
|
575
|
+
Perform faster regularisation computation in half-precision with some sacrifice in quality (can be used to find the best settings).
|
|
576
576
|
nonnegativity : bool
|
|
577
577
|
Impose nonnegativity constraint on the reconstructed image.
|
|
578
578
|
gpu_id : int
|
|
@@ -698,14 +698,16 @@ def ADMM3d_tomobar(
|
|
|
698
698
|
ADMM_rho_const: float
|
|
699
699
|
Convergence related parameter for ADMM, higher values lead to slower convergence, but too small values can destabilise the iterations.
|
|
700
700
|
Recommended range is between 0.9 and 2.0.
|
|
701
|
-
ADMM_relax_par:
|
|
702
|
-
|
|
701
|
+
ADMM_relax_par: float
|
|
702
|
+
Relaxation parameter which can lead to acceleration of the algorithm, keep it in the range between 1.5 and 1.8 to avoid divergence.
|
|
703
|
+
regularisation_type: str
|
|
704
|
+
A method to use for regularisation. Currently PD_TV and ROF_TV penalties are available.
|
|
703
705
|
regularisation_parameter: float
|
|
704
706
|
The main regularisation parameter to control the amount of smoothing/noise removal. Larger values lead to stronger smoothing.
|
|
705
707
|
regularisation_iterations: int
|
|
706
708
|
The number of iterations for regularisers (aka INNER iterations).
|
|
707
709
|
regularisation_half_precision: bool
|
|
708
|
-
Perform faster regularisation computation in half-precision with
|
|
710
|
+
Perform faster regularisation computation in half-precision with some sacrifice in quality (can be used to find the best settings).
|
|
709
711
|
nonnegativity : bool
|
|
710
712
|
Impose nonnegativity constraint (set to True) on the reconstructed image. Default False.
|
|
711
713
|
gpu_id : int
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: httomolibgpu
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.8.1
|
|
4
4
|
Summary: Commonly used tomography data processing methods at DLS.
|
|
5
5
|
Author-email: Daniil Kazantsev <daniil.kazantsev@diamond.ac.uk>, Yousef Moazzam <yousef.moazzam@diamond.ac.uk>, Naman Gera <naman.gera@diamond.ac.uk>
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -33,6 +33,7 @@ Requires-Dist: imageio; extra == "dev"
|
|
|
33
33
|
Requires-Dist: h5py; extra == "dev"
|
|
34
34
|
Requires-Dist: pre-commit; extra == "dev"
|
|
35
35
|
Requires-Dist: pyfftw; extra == "dev"
|
|
36
|
+
Requires-Dist: tomophantom; extra == "dev"
|
|
36
37
|
Dynamic: license-file
|
|
37
38
|
|
|
38
39
|
HTTomolibGPU is a library of GPU accelerated methods for tomography
|
|
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
|