Search for NXtomo(s), modify and resume processing#

H. Payno

Jan 09, 2024

15 min read

On this example we will see how to:

  • search for NXtomo(s)

  • modify the NXtomo

  • trigger downstream widgets

The script to search, modify and trigger downstream widget can be the first step of a workflow like

../../_images/start_workflow.png

Hint

to edit the script double click on the widget.

search for NXtomo(s)#

It can be the first step of a workflow.

Python comes with the glob module which allow to find pathnames matching.

You can use it for example to research all files ending by .nx which is the expected file extentions of NXtomos.

Hint

for convenience on this example we will look everywhere at a given location using the ‘**’ pattern. But you can also search at a specific level / depth instead

from glob import glob
import os

files = glob(
    os.path.join("/path/to/data/**", "*.nx"),  # search for all .nx file under /path/to/data/
    recursive=True,
)
print(files)                                   # print files found to make sure this part works

Now all those files can contain zero, one or several NXtomo that we want to use. There is several ways to do this. The simplest is probably to use the tomwer scan factory. It can browse a file and deduce if an entry is an NXtomo or not.

Then we can add the foolowing lines on the script

from glob import glob
from tomwer.core.scan.scanfactory import ScanFactory

# retrieve all scans
scans = []
for file_ in files:
    scans.extend(ScanFactory.create_scan_objects(file_))
# print found scans
print("found scans", [scan.get_identifier().short_description() for scan in scans])

Here is a concreate example of such a script and expected output

../../_images/find_nxtomo_example.png

Modify NXtomo(s)#

Nox that we have a set of scan we can modify them is we like (meadata only for now). For this the simplest is to use the NXtomo library

We cannot use directly the scans from tomwer because the API doesn’t allow ‘direct persistent’ modification of the data.

Here for example we want to modify for each NXtomo the energy. For this we need to:

  • load the NXtomo

  • modify it

  • overwrite the NXtomo

For this we can append to the script the following:

from nxtomo.application.nxtomo import NXtomo

for scan in scans:
    nx_tomo = NXtomo().load(scan.master_file, scan.entry)
    # then we can now modified the field we like
    nx_tomo.energy = new_value
    nx_tomo.save(
        file_path=scan.entry,
        data_path="entry",
        overwrite=True,
    )
    # scan.clear_caches()  # clear caches of the tomwer scan object. See caution at the bottom

See also

A tutorial explaining how to edit NXtomo can be found here: https://tomotools.gitlab-pages.esrf.fr/nxtomo/tutorials/nx_tomo_tutorial.html#edit-an-NXtomo

Resume processing / trigger downstream widgets#

Now that the NXtomo are modified we can provide this to the next widgets. For this we can define an output variable at the end of the script. In this example we want to provide a list of scan so we must define out_tomo_objs.

out_tomo_objs = scans

As much of the widgets expect a single scan object we will also need to add an instance of ‘tomo objs hub’ to the workflow to ‘split’ the list to a serie of ‘data’/’scan’ object and ensure a smooth processing.

../../_images/adding_hub.png

Warning

out_tomo_obj vs out_tomo_objs

You cannot set several time out_tomo_obj in a for loop. As output variable resolution is done only at the end. In this case it will trigger downstream widgets only once with the last value set.

Caution

Tomwer scan object caches

In this example we are not loading parameters from the scan object. But for example if we add a call to scan.energy before modifying the value it will be kept in the object cache. So when you modify a scan and reuse an existing scan object the safer usually is to clear caches. using the clear_caches() function.

Example with a workflow after#

Here it can be an example of processing after NXtomo search and edition that could be trigger. In this case it will build a volume for each scan.

../../_images/final_workflow.png

Warning

GUI freeze

The python script will be executed in the main Qt thread. As a consequence during it execution the GUI will not be responsive. So if your processing is heavy you might experience some gui freezing.