Source code for savu.data.data_structures.data_add_ons

# Copyright 2014 Diamond Light Source Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
.. module:: data_additions
   :platform: Unix
   :synopsis: A module containing add_on classes, which have instances \
       encapsulated within the Data class.

.. moduleauthor:: Nicola Wadeson <scientificsoftware@diamond.ac.uk>

"""

import savu.data.data_structures.data_notes as notes
from savu.core.utils import docstring_parameter


[docs]class Padding(object): """ A class that organises padding of the data. An instance of Padding can be associated with a Data object in a plugin that inherits from BaseFilter, inside :meth:`savu.plugins.base_filter.BaseFilter.set_filter_padding` """ def __init__(self, pData): self._pData = pData self.mtp = pData._get_max_frames_process() self.padding_dirs = {} self.pad_dict = None self.dims = None self.pattern_name = list(pData.get_pattern().keys())[0] self.pattern = pData.get_pattern()[self.pattern_name] self.dims = self.__set_dims() self.mode = 'edge' def __set_dims(self): dims = [] core_dir = self.pattern['core_dims'] slice_dir = self.pattern['slice_dims'] for dim in range(len(core_dir + slice_dir)): self.padding_dirs[dim] = {'before': 0, 'after': 0} return dims
[docs] def pad_mode(self, mode): self.mode = mode
[docs] def pad_frame_edges(self, padding): """ Pad all the edges of a frame of data with the same pad amount (i.e pad in the core dimensions). :param int padding: The pad amount """ core_dirs = self.pattern['core_dims'] for core in core_dirs: self._pad_direction(str(core) + '.' + str(padding))
[docs] def pad_multi_frames(self, padding): """ Add extra frames before and after the current frame of data (i.e pad in the fastest changing slice dimension). :param int padding: The pad amount """ sdir = self.pattern['slice_dims'][0] self._pad_direction(str(sdir) + '.' + str(padding))
[docs] @docstring_parameter(notes._padding.__doc__) def pad_directions(self, pad_list): """ Pad multiple, individually specified, dimensions. :param list(dict) pad_list: A list of strings of the form 'dim.pad',\ 'dim.after.pad' or 'dim.before.pad' {0} """ for entry in pad_list: self._pad_direction(entry)
@docstring_parameter(notes._padding.__doc__) def _pad_direction(self, pad_str): """ Pad the data in a specified dimension. :param str pad_str: A string of the form 'dim.pad', 'dim.after.pad'\ or 'dim.before.pad' {0} """ pad_vals = pad_str.split('.') pplace = None pad_place = ['before', 'after'] if len(pad_vals) == 3: pdir, pplace, pval = pad_vals remove = list(set(pad_place).difference(set([pplace])))[0] pad_place.remove(remove) else: pdir, pval = pad_vals pdir = int(pdir) allowed_dims = \ self.pattern['core_dims'] + (self.pattern['slice_dims'][0],) if pdir not in allowed_dims: raise Exception('Only core and first slice dimensions, %s, can be ' 'padded. I cannot pad data dim %s in this plugin.' % (allowed_dims, str(pdir))) else: for p in pad_place: self.padding_dirs[pdir][p] += int(pval) def _get_padding_directions(self): """ Get padding directions. :returns: padding dictionary :rtype: dict """ for key in list(self.padding_dirs.keys()): if sum(self.padding_dirs[key].values()) == 0: del self.padding_dirs[key] return self.padding_dirs def _get_plugin_padding_directions(self): """ Get padding directions. :returns: padding dictionary :rtype: dict """ for key in list(self.padding_dirs.keys()): if sum(self.padding_dirs[key].values()) == 0: del self.padding_dirs[key] return self.padding_dirs
[docs]class DataMapping(object): """ A class providing helper functions to multi-modal loaders. """ def __init__(self): self._is_tomo = None self._is_map = None self._motors = None self._motor_type = None self._axes = None
[docs] def set_motors(self, motors): self.motors = motors
[docs] def get_motors(self): return self.motors
[docs] def set_motor_type(self, motor_type): self.motor_type = motor_type
[docs] def get_motor_type(self): return self.motor_type
[docs] def set_axes(self, axes): self.axes = axes
[docs] def get_axes(self): return self.axes
[docs] def check_is_map(self, proj_dir): pattern = [] if self._is_map: ovs = [] for i in self.get_shape(): if i != proj_dir[0]: if i != proj_dir[1]: ovs.append(i) pattern = \ {"PROJECTION", {'core_dims': proj_dir, 'slice_dims': ovs}} return pattern
[docs] def check_is_tomo(self, proj_dir, rotation): pattern = [] if self._is_tomo: ovs = [] for i in self.get_shape(): if i != rotation: if i != proj_dir[1]: ovs.append(i) pattern = {"SINOGRAM", {'core_dims': (rotation, proj_dir[-1]), 'slice_dims': ovs}} return pattern