Source code for pystog.fourier_filter

"""
==============
FourierFilter
==============

This module defines the FourierFilter class
that performs the Fourier filter for a
given range to exclude.
"""

import numpy as np

from pystog.converter import Converter
from pystog.transformer import Transformer


[docs]class FourierFilter: """ The FourierFilter class is used to exlude a given range in the current function by a back Fourier Transform of that section, followed by a difference from the non-excluded function, and then a forward transform of the difference function Can currently do: a real space function -> reciprocal space function -> real space function :examples: >>> import numpy >>> from pystog import FourierFilter >>> ff = FourierFilter() >>> r, gr = numpy.loadtxt("my_gofr_file.txt",unpack=True) >>> q = numpy.linspace(0., 25., 2500) >>> q, sq = transformer.G_to_S(r, gr, q) >>> q_ft, sq_ft, q, sq, r, gr = ff.G_using_F(r, gr, q, sq, 1.5) """ def __init__(self): self.converter = Converter() self.transformer = Transformer() # g(r)
[docs] def g_using_F(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): """ Fourier filters real space :math:`g(r)` using the reciprocal space :math:`Q[S(Q)-1]` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`g(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param fq: :math:`Q[S(Q)-1]` vector :type fq: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`Q[S(Q)-1]` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`Q[S(Q)-1]`, and the filtered :math:`r` and :math:`g(r)`. Thus, [ :math:`Q_{FF}`, :math:`Q[S(Q)-1]_{FF}`, :math:`Q`, :math:`Q[S(Q)-1]`, :math:`r_{FF}`, :math:`g(r)_{FF}` ] :rtype: tuple of numpy.array """ # setup qmin, qmax, and get low-r region to back transform qmin = min(q) qmax = max(q) r_tmp, gr_tmp_init, dgr_tmp_init = self.transformer.apply_cropping( r, gr, 0.0, cutoff, dy=dgr) # Shift low-r so it goes to 1 at "high-r" for this section. Reduces the # sinc function issue. gr_tmp = gr_tmp_init + 1 # Transform the shifted low-r region to F(Q) to get F(Q)_ft q_ft, fq_ft, dfq_ft = self.transformer.g_to_F( r_tmp, gr_tmp, q, dgr=dgr_tmp_init, **kwargs) q_ft, fq_ft, dfq_ft = self.transformer.apply_cropping( q_ft, fq_ft, qmin, qmax, dy=dfq_ft) # Subtract F(Q)_ft from original F(Q) = delta_F(Q) q, fq, dfq = self.transformer.apply_cropping( q, fq, qmin, qmax, dy=dfq) fq = (fq - fq_ft) dfq = np.sqrt(dfq**2 + dfq_ft**2) # Transform delta_F(Q) for g(r) with low-r removed r, gr, dgr = self.transformer.F_to_g(q, fq, r, dfq=dfq, **kwargs) return q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr
[docs] def g_using_S(self, r, gr, q, sq, cutoff, dgr=None, dsq=None, **kwargs): """ Fourier filters real space :math:`g(r)` using the reciprocal space :math:`S(Q)` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`g(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param sq: :math:`S(Q)` vector :type sq: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`S(Q)` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`S(Q)`, and the filtered :math:`r` and :math:`g(r)`. Thus, [:math:`Q_{FF}`, :math:`S(Q)_{FF}`, :math:`Q`, :math:`S(Q)`, :math:`r_{FF}`, :math:`g(r)_{FF}]` :rtype: tuple of numpy.array """ fq, dfq = self.converter.S_to_F(q, sq, dsq=dsq) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.g_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) sq_ft, dsq_ft = self.converter.F_to_S(q_ft, fq_ft, dfq=dfq_ft) sq, dsq = self.converter.F_to_S(q, fq, dfq=dfq) return q_ft, sq_ft, q, sq, r, gr, dsq_ft, dsq, dgr
[docs] def g_using_FK(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): """ Fourier filters real space :math:`g(r)` using the reciprocal space :math:`F(Q)` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`g(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param fq: :math:`F(Q)` vector :type fq: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`F(Q)` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`F(Q)`, and the filtered :math:`r` and :math:`g(r)`. Thus, [:math:`Q_{FF}`, :math:`F(Q)_{FF}`, :math:`Q`, :math:`F(Q)`, :math:`r_{FF}`, :math:`g(r)_{FF}]` :rtype: tuple of numpy.array """ fq, dfq = self.converter.FK_to_F(q, fq, dfq=dfq, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.g_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) fq_ft, dfq_ft = self.converter.F_to_FK( q_ft, fq_ft, dfq=dfq_ft, **kwargs) fq, dfq = self.converter.F_to_FK(q, fq, dfq=dfq, **kwargs) return q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr
[docs] def g_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): """ Fourier filters real space :math:`g(r)` using the reciprocal space :math:`\\frac{d \\sigma}{d \\Omega}(Q)` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`g(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param dcs: :math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector :type dcs: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`\\frac{d \\sigma}{d \\Omega}(Q)` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, and the filtered :math:`r` and :math:`g(r)`. Thus, [:math:`Q_{FF}`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)_{FF}`, :math:`Q`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, :math:`r_{FF}`, :math:`g(r)_{FF}]` :rtype: tuple of numpy.array """ fq, dfq = self.converter.DCS_to_F(q, dcs, ddcs=ddcs, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.g_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) dcs_ft, ddcs_ft = self.converter.F_to_DCS( q_ft, fq_ft, dfq=dfq_ft, **kwargs) dcs, ddcs = self.converter.F_to_DCS(q_ft, fq, dfq=dfq, **kwargs) return q_ft, dcs_ft, q, dcs, r, gr, ddcs_ft, ddcs, dgr
# G(R) = PDF
[docs] def G_using_F(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): """ Fourier filters real space :math:`G_{PDFFIT}(r)` using the reciprocal space :math:`Q[S(Q)-1]` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`G_{PDFFIT}(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param fq: :math:`Q[S(Q)-1]` vector :type fq: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`Q[S(Q)-1]` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`Q[S(Q)-1]`, and the filtered :math:`r` and :math:`G_{PDFFIT}(r)`. Thus, [ :math:`Q_{FF}`, :math:`Q[S(Q)-1]_{FF}`, :math:`Q`, :math:`Q[S(Q)-1]`, :math:`r_{FF}`, :math:`G_{PDFFIT}(r)_{FF}` ] :rtype: tuple of numpy.array """ gr, dgr = self.converter.G_to_g(r, gr, dgr=dgr, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.g_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) gr, dgr = self.converter.g_to_G(r, gr, dgr=dgr, **kwargs) return q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr
[docs] def G_using_S(self, r, gr, q, sq, cutoff, dgr=None, dsq=None, **kwargs): """ Fourier filters real space :math:`G_{PDFFIT}(r)` using the reciprocal space :math:`S(Q)` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`G_{PDFFIT}(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param fq: :math:`S(Q)` vector :type fq: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`S(Q)` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`S(Q)`, and the filtered :math:`r` and :math:`G_{PDFFIT}(r)`. Thus, [ :math:`Q_{FF}`, :math:`S(Q)_{FF}`, :math:`Q`, :math:`S(Q)`, :math:`r_{FF}`, :math:`G_{PDFFIT}(r)_{FF}` ] :rtype: tuple of numpy.array """ fq, dfq = self.converter.S_to_F(q, sq, dsq=dsq) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.G_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) sq_ft, dsq_ft = self.converter.F_to_S(q_ft, fq_ft, dfq_ft) sq, dsq = self.converter.F_to_S(q, fq, dfq) return q_ft, sq_ft, q, sq, r, gr, dsq_ft, dsq, dgr
[docs] def G_using_FK(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): """ Fourier filters real space :math:`G_{PDFFIT}(r)` using the reciprocal space :math:`F(Q)` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`G_{PDFFIT}(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param fq: :math:`F(Q)` vector :type fq: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`F(Q)` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`F(Q)`, and the filtered :math:`r` and :math:`G_{PDFFIT}(r)`. Thus, [ :math:`Q_{FF}`, :math:`F(Q)_{FF}`, :math:`Q`, :math:`F(Q)`, :math:`r_{FF}`, :math:`G_{PDFFIT}(r)_{FF}` ] :rtype: tuple of numpy.array """ fq, dfq = self.converter.FK_to_F(q, fq, dfq=dfq, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.G_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) fq_ft, dfq_ft = self.converter.F_to_FK( q_ft, fq_ft, dfq=dfq_ft, **kwargs) fq, dfq = self.converter.F_to_FK(q, fq, dfq=dfq, **kwargs) return q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr
[docs] def G_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): """ Fourier filters real space :math:`G_{PDFFIT}(r)` using the reciprocal space :math:`\\frac{d \\sigma}{d \\Omega}(Q)` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`G_{PDFFIT}(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param dcs: :math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector :type dcs: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`\\frac{d \\sigma}{d \\Omega}(Q)` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, and the filtered :math:`r` and :math:`G_{PDFFIT}(r)`. Thus, [:math:`Q_{FF}`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)_{FF}`, :math:`Q`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, :math:`r_{FF}`, :math:`G_{PDFFIT}(r)_{FF}]` :rtype: tuple of numpy.array """ fq, dfq = self.converter.DCS_to_F(q, dcs, ddcs=ddcs, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.G_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) dcs_ft, ddcs_ft = self.converter.F_to_DCS( q_ft, fq_ft, dfq=dfq_ft, **kwargs) dcs, ddcs = self.converter.F_to_DCS(q, fq, dfq=dfq, **kwargs) return q_ft, dcs_ft, q, dcs, r, gr, ddcs_ft, ddcs, dgr
# Keen's G(r)
[docs] def GK_using_F(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): """ Fourier filters real space :math:`G_{Keen Version}(r)` using the reciprocal space :math:`Q[S(Q)-1]` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`G_{Keen Version}(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param fq: :math:`Q[S(Q)-1]` vector :type fq: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`Q[S(Q)-1]` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`Q[S(Q)-1]`, and the filtered :math:`r` and :math:`G_{Keen Version}(r)`. Thus, [ :math:`Q_{FF}`, :math:`Q[S(Q)-1]_{FF}`, :math:`Q`, :math:`Q[S(Q)-1]`, :math:`r_{FF}`, :math:`G_{Keen Version}(r)_{FF}` ] :rtype: tuple of numpy.array """ gr, dgr = self.converter.GK_to_g(r, gr, dgr=dgr, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.g_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) gr, dgr = self.converter.g_to_GK(r, gr, dgr=dgr, **kwargs) return q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr
[docs] def GK_using_S(self, r, gr, q, sq, cutoff, dgr=None, dsq=None, **kwargs): """ Fourier filters real space :math:`G_{Keen Version}(r)` using the reciprocal space :math:`S(Q)` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`G_{Keen Version}(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param fq: :math:`S(Q)` vector :type fq: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`S(Q)` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`S(Q)`, and the filtered :math:`r` and :math:`G_{Keen Version}(r)`. Thus, [ :math:`Q_{FF}`, :math:`S(Q)_{FF}`, :math:`Q`, :math:`S(Q)`, :math:`r_{FF}`, :math:`G_{Keen Version}(r)_{FF}` ] :rtype: tuple of numpy.array """ fq, dfq = self.converter.S_to_F(q, sq, dsq=dsq) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.GK_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) sq_ft, dsq_ft = self.converter.F_to_S(q_ft, fq_ft, dfq=dfq_ft) sq, dsq = self.converter.F_to_S(q, fq, dfq=dfq) return q_ft, sq_ft, q, sq, r, gr, dsq_ft, dsq, dgr
[docs] def GK_using_FK(self, r, gr, q, fq, cutoff, dgr=None, dfq=None, **kwargs): """ Fourier filters real space :math:`G_{Keen Version}(r)` using the reciprocal space :math:`F(Q)` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`G_{Keen Version}(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param fq: :math:`F(Q)` vector :type fq: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`F(Q)` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`F(Q)`, and the filtered :math:`r` and :math:`G_{Keen Version}(r)`. Thus, [ :math:`Q_{FF}`, :math:`F(Q)_{FF}`, :math:`Q`, :math:`F(Q)`, :math:`r_{FF}`, :math:`G_{Keen Version}(r)_{FF}` ] :rtype: tuple of numpy.array """ fq, dfq = self.converter.FK_to_F(q, fq, dfq=dfq, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.GK_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) fq_ft, dfq_ft = self.converter.F_to_FK( q_ft, fq_ft, dfq=dfq_ft, **kwargs) fq, dfq = self.converter.F_to_FK(q, fq, dfq=dfq, **kwargs) return q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr
[docs] def GK_using_DCS(self, r, gr, q, dcs, cutoff, dgr=None, ddcs=None, **kwargs): """ Fourier filters real space :math:`G_{Keen Version}(r)` using the reciprocal space :math:`\\frac{d \\sigma}{d \\Omega}(Q)` :param r: :math:`r`-space vector :type r: numpy.array or list :param gr: :math:`G_{Keen Version}(r)` vector :type gr: numpy.array or list :param q: :math:`Q`-space vector :type q: numpy.array or list :param dcs: :math:`\\frac{d \\sigma}{d \\Omega}(Q)` vector :type dcs: numpy.array or list :param cutoff: The :math:`r_{max}` value to filter from 0. to cutoff :type cutoff: float :return: A tuple of the :math:`Q` and :math:`\\frac{d \\sigma}{d \\Omega}(Q)` for the 0. to cutoff transform, the corrected :math:`Q` and :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, and the filtered :math:`r` and :math:`G_{Keen Version}(r)`. Thus, [:math:`Q_{FF}`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)_{FF}`, :math:`Q`, :math:`\\frac{d \\sigma}{d \\Omega}(Q)`, :math:`r_{FF}`, :math:`G_{Keen Version}(r)_{FF}]` :rtype: tuple of numpy.array """ fq, dfq = self.converter.DCS_to_F(q, dcs, ddcs=ddcs, **kwargs) q_ft, fq_ft, q, fq, r, gr, dfq_ft, dfq, dgr = self.GK_using_F( r, gr, q, fq, cutoff, dgr=dgr, dfq=dfq, **kwargs) dcs_ft, ddcs_ft = self.converter.F_to_DCS( q_ft, fq_ft, dfq=dfq_ft, **kwargs) dcs, ddcs = self.converter.F_to_DCS(q, fq, dfq=dfq, **kwargs) return q_ft, dcs_ft, q, dcs, r, gr, ddcs_ft, ddcs, dgr