Source code for plugins.filters.paganin_filter

# 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:: paganin_filter
   :platform: Unix
   :synopsis: A plugin to apply the Paganin filter.

.. moduleauthor:: Nghia Vo <scientificsoftware@diamond.ac.uk>

"""
import math
import logging
import numpy as np
import pyfftw.interfaces.scipy_fftpack as fft

from savu.plugins.filters.base_filter import BaseFilter
from savu.plugins.driver.cpu_plugin import CpuPlugin
from savu.plugins.utils import register_plugin, dawn_compatible


[docs]@dawn_compatible @register_plugin class PaganinFilter(BaseFilter, CpuPlugin): def __init__(self): logging.debug("initialising Paganin Filter") logging.debug("Calling super to make sure that all superclases are " + " initialised") super(PaganinFilter, self).__init__("PaganinFilter") self.filtercomplex = None self.count = 0
[docs] def set_filter_padding(self, in_pData, out_pData): in_data = self.get_in_datasets()[0] det_x = in_data.get_data_dimension_by_axis_label('detector_x') det_y = in_data.get_data_dimension_by_axis_label('detector_y') pad_det_y = '%s.%s' % (det_y, self.parameters['Padtopbottom']) pad_det_x = '%s.%s' % (det_x, self.parameters['Padleftright']) mode = self.parameters['Padmethod'] pad_dict = {'pad_directions': [pad_det_x, pad_det_y], 'pad_mode': mode} in_pData[0].padding = pad_dict out_pData[0].padding = pad_dict
[docs] def pre_process(self): self._setup_paganin(*self.get_plugin_in_datasets()[0].get_shape())
def _setup_paganin(self, height, width): micron = 10 ** (-6) keV = 1000.0 distance = self.parameters['Distance'] energy = self.parameters['Energy'] * keV resolution = self.parameters['Resolution'] * micron wavelength = (1240.0 / energy) * 10.0 ** (-9) ratio = self.parameters['Ratio'] height1 = height + 2 * self.parameters['Padtopbottom'] width1 = width + 2 * self.parameters['Padleftright'] centery = np.ceil(height1 / 2.0) - 1.0 centerx = np.ceil(width1 / 2.0) - 1.0 # Define the paganin filter dpx = 1.0 / (width1 * resolution) dpy = 1.0 / (height1 * resolution) pxlist = (np.arange(width1) - centerx) * dpx pylist = (np.arange(height1) - centery) * dpy pxx = np.zeros((height1, width1), dtype=np.float32) pxx[:, 0:width1] = pxlist pyy = np.zeros((height1, width1), dtype=np.float32) pyy[0:height1, :] = np.reshape(pylist, (height1, 1)) pd = (pxx * pxx + pyy * pyy) * wavelength * distance * math.pi filter1 = 1.0 + ratio * pd self.filtercomplex = filter1 + filter1 * 1j def _paganin(self, data): pci1 = fft.fft2(np.float32(data)) pci2 = fft.fftshift(pci1) / self.filtercomplex fpci = np.abs(fft.ifft2(pci2)) result = -0.5 * self.parameters['Ratio'] * np.log( fpci + self.parameters['increment']) return result
[docs] def process_frames(self, data): proj = np.nan_to_num(data[0]) # Noted performance proj[proj == 0] = 1.0 return self._paganin(proj)
[docs] def get_max_frames(self): return 'single'