Tutorial for the CompositeCreatorApp#

Motivation#

The CompositeCreatorApp is designed to combine multiple images into a composite image. Only basic operations of binning and cropping are applied to the raw images. Global offsets in the image data can be handled with a mask and background file.

Note

While the use of different Parameters is handled in different sections of this manual, they must all be combined to use all capabilities of the CompositeCreatorApp.

Globally controlled settings#

Some settings used by the CompositeCreatorApp are controlled globally by pydidas. These are:

  • The width of the border between images in pixels (user/mosaic_border_width)

  • The value of the border pixels (user/mosaic_border_value)

  • The maximum image size in megapixels (global/max_image_size)

  • The path for the detector mask file (user/det_mask)

  • The pixel value for masked pixels (user/det_mask_val)

and for parallel processing additionally:

  • The number of parallel worker processes (global/mp_n_workers)

Because these settings will typically be reused quite often, they have been implemented as global pydidas QSettings. The default is a border width of 0 pixels and a border pixel value of 0. The default maximum size is 100 Mpx. To modify these values, the user needs to create a QSettings instance and adjust these values, if required:

>>> import pydidas
>>> config = pydidas.core.PydidasQsettings()
>>> config.set_value('user/mosaic_border_width', 5)
>>> config.set_value('user/mosaic_border_value', 1)
>>> config.set_value('global/max_image_size', 250)

Setup of the CompositeCreatorApp#

This section describes the different input Parameters that can be used and gives an overview of the Complete list of CompositeCreatorApp Parameters at the end of the section.

Selection of input data#

First of all, the user needs to define whether the app will be run in live_processing mode or not. This flag defines whether checks for file existance and size will be performed before the start of the processing. The default setting is False which will enforce file system checks. This value is stored in the live_processing Parameter (see Complete list of CompositeCreatorApp Parameters for details).

The input data is defined through the files to use by defining the first and last file (or only one file if a file with multiple frames per file is used, e.g. hdf5). The file(s) must be selected by the first_file and last_file Parameters. If not every file single but only every n-th file should be processed, this can be defined by the file_stepping Parameter. pydidas will check the filenames for running numbers and determine the names automatically. Incrementing numbers do not need to be given by wildcards but must be separated by a delimiter of “.” or “_” or “-” or “ “.

Note that the first file must exist at the time the app is run because the file size will be used as reference for the future files.

For hdf5 files, the hdf5 dataset needs to be specified as well. The dataset can be given with the hdf5_key Parameter. The default is entry/data/data and if this is correct, the Parameter does not need to be specified. A subset of images from hdf5 files can be selected by using the hdf5_first_image_num and hdf5_last_image_num Parameters with a frame stepping of hdf5_stepping.

See Complete list of CompositeCreatorApp Parameters for the detailed list of all Parameters.

Example 1: Loading a number of tiff files#

For the first example, we want to load every 3rd file from a running scan which produces tiff files named /scratch/scan_42/test_image_0000_suffix.tiff to /scratch/scan_42/test_image_1200_suffix.tiff:

>>> import pydidas
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.set_param_value('first_file', '/scratch/scan_42/test_image_0000_suffix.tiff')
>>> app.set_param_value('last_file', '/scratch/scan_42/test_image_1200_suffix.tiff')
>>> app.set_param_value('file_stepping', 3)
>>> app.set_param_value('live_processing', True)

Once started, this app will run until the file /scratch/scan_42/test_image_1200_suffix.tiff has been created and processed.

Example 2: Loading a subset of frames from a single hdf5 file#

For this example, we want to load every 2nd frame for the frames 10 to 30 from a single hdf5 file named /scratch/test_scan/some_file.h5.

>>> import pydidas
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.set_param_value('first_file', '/scratch/test_scan/some_file.h5')
>>> app.set_param_value('hdf5_first_image_num', 10)
>>> app.set_param_value('hdf5_last_image_num', 30)
>>> app.set_param_value('hdf5_stepping', 2)

Using a mask file#

A mask file can be used by activating the use_global_det_mask Parameter. This will instruct the app to apply the global mask to the data frame. For more information on the global settings, please refer to pydidas QSettings. The filename for the mask file must be given with the user/det_mask value and the value for the masked pixels by the user/det_mask_val.

The example below shows the code to instruct the app to use the /scratch/det_mask.npy file and substitute masked pixels with a value of zero.

>>> import pydidas
>>> config = pydidas.core.PydidasQsettings()
>>> config.set_value('user/det_mask', '/scratch/det_mask.npy')
>>> config.set_value('user/det_mask_val', 0)
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.set_param_value('use_global_det_mask', True)

Using a background file#

Usage of a background file (which will be subtracted from all frames) can be activated by setting the use_bg_file Parameter to True.

The background file itself can be selected by specifying the bg_file Parameter. If a hdf5 file is selected, the dataset and frame can be given by the bg_hdf5_key and bg_hdf5_frame. These values default to entry/data/data and 0, respectively.

As example, let us use the 0th frame from the /scratch/scan_42/test.h5df5 file and the entry/detector/data dataset:

>>> import pydidas
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.set_param_value('use_bg_file', True)
>>> app.set_param_value('bg_file', '/scratch/scan_42/test.h5df5')
>>> app.set_param_value('bg_hdf5_key', 'entry/detector/data')
# Because the bg_hdf5_frame defaults to 0, this Parameter does not need to
# be modified:
>>> app.get_param_value('bg_hdf5_frame')
0

Using a region of interest#

A region of interest (ROI) can be selected by defining the four values for lower and upper pixels in x and y. Usage of the ROI must be activated by setting the Parameter use_roi to True. The four boundaries can be defined by the roi_xlow, roi_xhigh, roi_ylow, roi_yhigh values. To use the full range, use None as value for the high boundaries and 0 for the low boundaries. These values are modulated by the image width and height, respectively. A value of roi_yhigh = -5 thus corresponds to cropping the five rightmost pixel rows.

The defaults are roi_xlow = 0, roi_xhigh = None, roi_ylow = 0, and roi_yhigh = None. Note that if the ROI is activated, all four values are used and need to be set correctly.

As example, let the input image be of size 1000 x 1000 and let us select a ROI of pixel rows 5 to 1000 in height and the pixel columns 120 to 900 in width.

>>> import pydidas
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.set_param_value('use_roi', True)

# Set up the ROI in x:
>>> app.set_param_value('roi_xlow', 120)
>>> app.set_param_value('roi_xhigh', 900)
# Because we know the image size is 1000, a value of -100 for roi_xhigh
# has the same effect as 900.

# Set up the ROI in y:
>>> app.set_param_value('roi_ylow', 5)
# We do not need to specify a roi_yhigh value because the default of None
# corresponds to the full height as upper y boundary:
>>> app.get_param_value('roi_yhigh') is None
True

Use binning#

Images can be binned to reduce their size in the composite image. This operation is controlled by the binning Parameter. A value of 1 corresponds to the input size and is ignored. The binning must be an integer value.

Warning

If a combination of binning and ROI is used, the ROI pixel coordinates refer to the unbinned image.

As example, we set the binning factor to re-bin images by a factor of 4 in the composite image:

>>> import pydidas
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.set_param_value('binning', 4)

Image thresholds#

The range of the composite image can be restricted by using thresholds. Two thresholds for the upper and lower value must be given. To activate the use of thresholds, set the use_thresholds Parameter to True. The values for the lower and upper thresholds are given by the threshold_low and threshold_high Parameters, respectively. A value of None for a threshold will disable this specific threshold. The default value for threshold values is None.

As example, let us define an upper threshold of 42.0 and disable the lower threshold.

>>> import pydidas
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.set_param_value('use_thresholds', True)
>>> app.set_param_value('threshold_high', 42.0)

# The lower thresholds's default value is None, which will make the app
# ignore this threshold and it does not need to be changed:
>>> app.get_param_value('threshold_low') is None
True

Composite layout#

The arrangement of the images in the resulting mosaic image are controlled by the composite_nx and composite_ny Parameters. These control the number of individual images in the x and y directions, respectively. The numbers must be chosen in a manner that the total number \(N_{total}\) is less or equal to the product \(N_x * N_y\) but is not unnecessary large. Mathematically, the two following conditions need to be fulfilled:

\[\begin{split}N_x * (N_y - 1) &< N_{total} <= N_x * N_y \\ (N_x - 1) * N_y &< N_{total} <= N_x * N_y\end{split}\]

One dimension can be automatically adjusted in size by using the value -1. The default values are Nx = 1 and Ny = -1.

In addition, raw images can be flipped or rotated prior to inserting them into the composite. The composite_image_op Parameter allows to select the type of operation to be performed (if any).

The order in which the images are inserted in the composite can be controlled by the composite_xdir_orientation and composite_ydir_orientation Parameters which allow to select if images are added from the left or right and top or bottom border, respectively.

As example, we want to create a composite with a number of twenty images in y and we want to adjust x automatically.

>>> import pydidas
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.set_param_value('composite_nx', -1)
>>> app.set_param_value('composite_ny', 20)

As second example, we want to create a composite of 90 images with 10 images in y and starting at the left side in x.

>>> import pydidas
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.set_param_value('composite_nx', 9)
>>> app.set_param_value('composite_ny', 10)
>>> app.set_param_value('composite_xdir_orientation', 'right-to-left')

Tip

Mathematically, it is equivalent to change the orientation of the raw images or to change the order of the images in the composite. However, users might prefer to have the composite composed in the same orientation as their raw data scan.

Running the CompositeCreatorApp#

Once configured, the CompositeCreatorApp is run like any pydidas app, as described in detail in Running pydidas applications.

As a recap, to run the app serially, use the run <pydidas.apps.CompositeCreatorApp.run method:

>>> import pydidas
>>> app = pydidas.apps.CompositeCreatorApp()
>>> app.run()

To run it utilizing parallelization, set up an AppRunner and use its :py:meth`start <pydidas.multiprocessing.AppRunner.start>` method:

>>> app = pydidas.apps.CompositeCreatorApp()
>>> runner = pydidas.multiprocessing.AppRunner(app)
>>> runner.start()
>>> app = runner.get_app()

If any thresholding should be performed, this operation needs to be called on the app by the apply_thresholds method. Note that it is also possible to provide new threshold values. Please see the apply_thresholds documentation for this.

Simply call the method to update the composite image with the thresholds provided by the associated Parameters:

# To apply the thresholds
>>> app.apply_threshold()

# to apply new threshold values:
>>> app.apply_thresholds(low=0, high=42)

Warning

If the use_thresholds Parameter is value False, calling the apply_thresholds method will have no effect.

Accessing results#

After running the CompositeCreatorApp, results can be accessed either directly to store the object for further use in the Python console or script or they can be stored.

Accessing results within Python#

The results can be accessed through the composite property which will return the array with the image data:

>>> image = app.composite
>>> type(image)
numpy.ndarray

Exporting results#

Results can be exported by using the export_image method in any format known to pydidas. The format is determined automatically from the extension:

# To export in numpy format:
>>> app.export_image('/scratch/image.npy')

# or to export as tiff
>>> app.export_image('/scratch/image.tiff')

Complete list of CompositeCreatorApp Parameters#