Create instrument.detector.data from TIFF files#

If your acquisition was saved as .tiff files you can reuse them for the instrument/detector/data dataset.

Create an NXtomo#

See the “Create an NXtomo (from scratch)” tutorial for the initial steps.

Here we bootstrap an NXtomo with one dark frame and one flat frame at the beginning, followed by ten projections.

[1]:
import pint
import numpy
from nxtomo import NXtomo
from nxtomo.nxobject.nxdetector import ImageKey

ureg = pint.get_application_registry()

image_key_control = numpy.concatenate(
    [
        [ImageKey.DARK_FIELD] * 1,
        [ImageKey.FLAT_FIELD] * 1,
        [ImageKey.PROJECTION] * 10,
    ]
)

my_nxtomo = NXtomo()
my_nxtomo.instrument.detector.image_key_control = numpy.concatenate(
    [
        [ImageKey.DARK_FIELD] * 1,
        [ImageKey.FLAT_FIELD] * 1,
        [ImageKey.PROJECTION] * 10,
    ]
)
my_nxtomo.sample.rotation_angle = (
    numpy.concatenate(
        [
            [0, 0],
            numpy.linspace(0, 360, 10),
        ]
    )
    * ureg.degree
)
# ...

Append the TIFF files#

To append a series of TIFF files we can use the helper function create_detector_dataset_from_tiff. This function creates one HDF5 virtual source per TIFF file.

Each virtual source requires an external dataset entry that defines how to access the raw data. The external dataset is then referenced by the HDF5 virtual dataset, giving access to your TIFF files.

To create the external datasets, create_detector_dataset_from_tiff needs an HDF5 group (the output group), which should be the file containing the NXtomo.

Note: the creation of the HDF5 virtual dataset is handled by the library when you save the NXtomo to disk.

[2]:
import h5py
import os
from nxtomo.utils.utils import create_detector_dataset_from_tiff

output_file = "my_nxtomo_with_tiff.nx"
with h5py.File(output_file, mode="w") as h5f:
    external_dataset_group = h5f.require_group("external_datasets")

    assert os.path.exists("resources/raw_tiff_files/")
    my_nxtomo.instrument.detector.data = create_detector_dataset_from_tiff(
        tiff_files=(
            "resources/raw_tiff_files/dark.tif",
            "resources/raw_tiff_files/flat_0000.tif",
            "resources/raw_tiff_files/projection_0000.tif",
            "resources/raw_tiff_files/projection_0001.tif",
            "resources/raw_tiff_files/projection_0002.tif",
            "resources/raw_tiff_files/projection_0003.tif",
            "resources/raw_tiff_files/projection_0004.tif",
            "resources/raw_tiff_files/projection_0005.tif",
            "resources/raw_tiff_files/projection_0006.tif",
            "resources/raw_tiff_files/projection_0007.tif",
            "resources/raw_tiff_files/projection_0008.tif",
            "resources/raw_tiff_files/projection_0009.tif",
        ),
        external_dataset_group=external_dataset_group,
        relative_link=False,
    )

Save the final NXtomo#

[3]:
my_nxtomo.save(output_file, "entry0000")

You can now use this NXtomo like any other NXtomo and process it with nabu or other tools.

Note on performance#

Creating one external link per frame has a noticeable performance cost.

When building a sinogram the pipeline must open each file and read a single line, which is expensive.

Remove the output file#

[4]:
os.remove(output_file)