Source code for nabu.thirdparty.tomwer_load_flats_darks

"""
script embedding all function needed to read flats and darks.

For information calculation method is stored in the results/configuration
dictionary
"""


"""
IMPORTANT: this script is used as long as flat-fielding with "raw" flats/daks
is not implemented in nabu.
For now we load results from tomwer.
"""

import typing
import h5py
from silx.io.url import DataUrl
from tomoscan.io import HDF5File
from silx.io.utils import h5py_read_dataset
import logging

MAX_DEPTH = 2

logger = logging.getLogger(__name__)

[docs] def get_process_entries(root_node: h5py.Group, depth: int) -> tuple: """ return the list of 'Nxtomo' entries at the root level :param str file_path: :return: list of valid Nxtomo node (ordered alphabetically) :rtype: tuple ..note: entries are sorted to insure consistency """ def _get_entries(node, depth_): if isinstance(node, h5py.Dataset): return {} res_buf = {} if is_process_node(node) is True: res_buf[node.name] = int(node['sequence_index'][()]) assert isinstance(node, h5py.Group) if depth_ >= 1: for sub_node in node.values(): res_buf[node.name] = _get_entries(node=sub_node, depth_=depth_-1) return res_buf res = {} for node in root_node.values(): res.update(_get_entries(node=node, depth_=depth-1)) return res
[docs] def is_process_node(node): return (node.name.split('/')[-1].startswith('tomwer_process_') and 'NX_class' in node.attrs and node.attrs['NX_class'] == "NXprocess" and 'program' in node and h5py_read_dataset(node['program']) == 'tomwer_dark_refs' and 'version' in node and 'sequence_index' in node)
[docs] def get_darks_frm_process_file(process_file, entry) -> typing.Union[None, dict]: """ :param process_file: :return: """ if entry is None: with HDF5File(process_file, 'r', swmr=True) as h5f: entries = get_process_entries(root_node=h5f, depth=MAX_DEPTH) if len(entries) == 0: logger.info( 'unable to find a DarkRef process in %s' % process_file) return None elif len(entries) > 0: raise ValueError('several entry found, entry should be ' 'specify') else: entry = list(entries.keys())[0] logger.info('take %s as default entry' % entry) with HDF5File(process_file, 'r', swmr=True) as h5f: dark_nodes = get_process_entries(root_node=h5f[entry], depth=MAX_DEPTH-1) index_to_path = {} for key, value in dark_nodes.items(): index_to_path[key] = key if len(dark_nodes) == 0: return {} # take the last processed dark ref last_process_index = sorted(dark_nodes.keys())[-1] last_process_dark = index_to_path[last_process_index] if(len(index_to_path)) > 1: logger.warning('several processing found for dark-ref,' 'take the last one: %s' % last_process_dark) res = {} if 'results' in h5f[last_process_dark].keys(): results_node = h5f[last_process_dark]['results'] if 'darks' in results_node.keys(): darks = results_node['darks'] for index in darks: res[int(index)] = DataUrl( file_path=process_file, data_path=darks[index].name, scheme="silx" ) return res
[docs] def get_flats_frm_process_file(process_file, entry) -> typing.Union[None, dict]: """ :param process_file: :return: """ if entry is None: with HDF5File(process_file, 'r', swmr=True) as h5f: entries = get_process_entries(root_node=h5f, depth=MAX_DEPTH) if len(entries) == 0: logger.info( 'unable to find a DarkRef process in %s' % process_file) return None elif len(entries) > 0: raise ValueError('several entry found, entry should be ' 'specify') else: entry = list(entries.keys())[0] logger.info('take %s as default entry' % entry) with HDF5File(process_file, 'r', swmr=True) as h5f: dkref_nodes = get_process_entries(root_node=h5f[entry], depth=MAX_DEPTH-1) if len(dkref_nodes) == 0: return {} index_to_path = {} for key, value in dkref_nodes.items(): index_to_path[key] = key # take the last processed dark ref last_process_index = sorted(dkref_nodes.keys())[-1] last_process_dkrf = index_to_path[last_process_index] if(len(index_to_path)) > 1: logger.warning('several processing found for dark-ref,' 'take the last one: %s' % last_process_dkrf) res = {} if 'results' in h5f[last_process_dkrf].keys(): results_node = h5f[last_process_dkrf]['results'] if 'flats' in results_node.keys(): flats = results_node['flats'] for index in flats: res[int(index)] = DataUrl( file_path=process_file, data_path=flats[index].name, scheme="silx" ) return res