Skip to content

Commit 2bff6b1

Browse files
committed
add nxtomo reader
- this PR can be used as an example on how to get your own raw dataa into the app
1 parent 6511f06 commit 2bff6b1

File tree

8 files changed

+597
-9
lines changed

8 files changed

+597
-9
lines changed

.readthedocs.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
version: 2
22

33
build:
4-
os: "ubuntu-20.04"
4+
os: 'ubuntu-20.04'
55
tools:
6-
python: "mambaforge-4.10"
6+
python: 'mambaforge-4.10'
77

88
# Build documentation in the docs/ directory with Sphinx
99
sphinx:
@@ -15,4 +15,4 @@ conda:
1515
python:
1616
install:
1717
- method: pip
18-
path: .
18+
path: .

environment-nocuda.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ dependencies:
2121
- astra-toolbox
2222
- bqplot
2323
- pip:
24-
- bqplot-image-gl
24+
- bqplot-image-gl
25+
- tomoscan

environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ dependencies:
2424
- bqplot
2525
- pip:
2626
- bqplot-image-gl
27+
- tomoscan
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import os
2+
import pathlib
3+
4+
import dxchange
5+
import numpy
6+
from nxtomo import NXtomo
7+
from nxtomo.nxobject.nxdetector import ImageKey
8+
from tomoscan.esrf.scan.nxtomoscan import NXtomoScan
9+
10+
THIS_PATH = pathlib.Path(os.path.dirname(os.path.abspath(__file__)))
11+
DATA_PATH = pathlib.Path(THIS_PATH / "tomo_00077.h5") # from tomobank
12+
13+
# I took most of this from the tomoscan tutorial, but I had to modify it.
14+
# I am not sure how you are storing your "projections" data. Basically, we want
15+
# projection images along x and y in a [Z, Y, X] array, like is output by dxchange.read_aps_32id.
16+
# You can modify your data import method in tomopyui.backend.io to get it into the right format.
17+
proj, flat, dark, theta = dxchange.read_aps_32id(fname=DATA_PATH, proj=(0, 477))
18+
19+
binning = 8
20+
proj_binned = proj[:, ::binning, ::binning]
21+
dark_binned = dark[:, ::binning, ::binning]
22+
flat_binned = flat[:, ::binning, ::binning]
23+
assert proj_binned.shape[2] == dark_binned.shape[2] == flat_binned.shape[2]
24+
assert proj_binned.shape[1] == dark_binned.shape[1] == flat_binned.shape[1]
25+
proj_rotation_angles = theta * 180 / numpy.pi
26+
assert len(proj_rotation_angles) == len(proj_binned)
27+
28+
my_nxtomo = NXtomo()
29+
30+
# create the array
31+
data = numpy.concatenate(
32+
[
33+
dark_binned,
34+
flat_binned,
35+
proj_binned,
36+
]
37+
)
38+
assert data.ndim == 3
39+
print(data.shape)
40+
# then register the data to the detector
41+
my_nxtomo.instrument.detector.data = data
42+
43+
image_key_control = numpy.concatenate(
44+
[
45+
[ImageKey.DARK_FIELD] * len(dark_binned),
46+
[ImageKey.FLAT_FIELD] * len(flat_binned),
47+
[ImageKey.PROJECTION] * len(proj_binned),
48+
]
49+
)
50+
51+
# insure with have the same number of frames and image key
52+
assert len(image_key_control) == len(data)
53+
# print position of flats in the sequence
54+
print("flats indexes are", numpy.where(image_key_control == ImageKey.FLAT_FIELD))
55+
# then register the image keys to the detector
56+
my_nxtomo.instrument.detector.image_key_control = image_key_control
57+
58+
rotation_angle = numpy.concatenate(
59+
[
60+
[0 for x in range(len(dark_binned))],
61+
[0 for x in range(len(flat_binned))],
62+
proj_rotation_angles,
63+
]
64+
)
65+
assert len(rotation_angle) == len(data)
66+
# register rotation angle to the sample
67+
my_nxtomo.sample.rotation_angle = rotation_angle
68+
69+
my_nxtomo.instrument.detector.field_of_view = "Full"
70+
71+
my_nxtomo.instrument.detector.x_pixel_size = (
72+
my_nxtomo.instrument.detector.y_pixel_size
73+
) = 1e-7 # pixel size must be provided in SI: meter
74+
my_nxtomo.instrument.detector.x_pixel_size = (
75+
my_nxtomo.instrument.detector.y_pixel_size
76+
) = 0.1
77+
my_nxtomo.instrument.detector.x_pixel_size.unit = (
78+
my_nxtomo.instrument.detector.y_pixel_size.unit
79+
) = "micrometer"
80+
81+
nx_tomo_file_path = pathlib.Path(THIS_PATH / "tomo_00077.nx")
82+
my_nxtomo.save(file_path=str(nx_tomo_file_path), data_path="entry", overwrite=True)
83+
84+
has_tomoscan = False
85+
try:
86+
import tomoscan
87+
except ImportError:
88+
has_tomoscan = False
89+
from tomoscan.esrf import NXtomoScan
90+
from tomoscan.validator import ReconstructionValidator
91+
92+
has_tomoscan = True
93+
94+
if has_tomoscan:
95+
scan = NXtomoScan(nx_tomo_file_path, entry="entry")
96+
validator = ReconstructionValidator(
97+
scan, check_phase_retrieval=False, check_values=True
98+
)
99+
assert validator.is_valid()

examples/data/nxtomo/tomo_00077.nx

19.5 MB
Binary file not shown.

0 commit comments

Comments
 (0)