Beispiel #1
0
    def setUp(self):
        unittest.TestCase.setUp(self)
        self.transformer = Transformer()

        # Parameters for fourier transform testing
        self._ft_first = 28
        self._ft_last = 35
        fs = 100  # sample rate
        f = 10  # the frequency of the signal
        self._ft_xin = numpy.linspace(0.0, 100., 1000)
        self._ft_yin = numpy.asarray(
            [numpy.sin(2 * numpy.pi * f * (i / fs)) for i in self._ft_xin])
        self._ft_xout = numpy.linspace(0.0, 2.0, 100)
Beispiel #2
0
def create_reciprocal_space_functions(gr_filename,
                                      dq=0.02,
                                      qmin=0.00,
                                      qmax=35.0,
                                      **kwargs):
    r, gr = load_lammps_rdf(gr_filename)
    q = np.arange(qmin, qmax + dq, dq)
    t = Transformer()
    q, sq = t.g_to_S(r, gr, q, **kwargs)
    q, fq = t.g_to_F(r, gr, q, **kwargs)
    q, fq_keen = t.g_to_FK(r, gr, q, **kwargs)
    q, dcs = t.g_to_DCS(r, gr, q, **kwargs)
    data = [q, sq, fq, fq_keen, dcs]
    assert len(ReciprocalSpaceHeaders) == len(data)
    data = np.transpose(data)  # puts the data where each column is a function
    return ReciprocalSpaceHeaders, data
Beispiel #3
0
 def __init__(self):
     self.converter = Converter()
     self.transformer = Transformer()
Beispiel #4
0
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)
    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 this 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_initial, dgr_tmp_initial = 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_initial + 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_initial,
                                                      **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

    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 this 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

    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 this 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

    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 this 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
    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 this 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

    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 this 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

    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 this 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

    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 this 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)
    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 this 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

    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 this 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

    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 this 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

    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 this 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
Beispiel #5
0
class TestTransformerBase(unittest.TestCase):
    rtol = 1e-2
    atol = 1e-2

    def initialize_material(self):
        # setup input data
        self.kwargs = self.material.kwargs

        # setup the first, last indices
        self.real_space_first = self.material.real_space_first
        self.real_space_last = self.material.real_space_last

        data = load_data(self.material.real_space_filename)
        self.r = data[:, get_index_of_function("r", RealSpaceHeaders)]
        self.gofr = data[:, get_index_of_function("g(r)", RealSpaceHeaders)]
        self.GofR = data[:, get_index_of_function("G(r)", RealSpaceHeaders)]
        self.GKofR = data[:, get_index_of_function("GK(r)", RealSpaceHeaders)]

        # targets for 1st peaks
        self.gofr_target = self.material.gofr_target
        self.GofR_target = self.material.GofR_target
        self.GKofR_target = self.material.GKofR_target

        # setup the tolerance
        self.reciprocal_space_first = self.material.reciprocal_space_first
        self.reciprocal_space_last = self.material.reciprocal_space_last

        data = load_data(self.material.reciprocal_space_filename)
        self.q = data[:, get_index_of_function("Q", ReciprocalSpaceHeaders)]
        self.sq = data[:,
                       get_index_of_function("S(Q)", ReciprocalSpaceHeaders)]
        self.fq = data[:,
                       get_index_of_function("Q[S(Q)-1]",
                                             ReciprocalSpaceHeaders)]
        self.fq_keen = data[:,
                            get_index_of_function("FK(Q)",
                                                  ReciprocalSpaceHeaders)]
        self.dcs = data[:,
                        get_index_of_function("DCS(Q)", ReciprocalSpaceHeaders
                                              )]

        # targets for 1st peaks
        self.sq_target = self.material.sq_target
        self.fq_target = self.material.fq_target
        self.fq_keen_target = self.material.fq_keen_target
        self.dcs_target = self.material.dcs_target

    def setUp(self):
        unittest.TestCase.setUp(self)
        self.transformer = Transformer()

        # Parameters for fourier transform testing
        self._ft_first = 28
        self._ft_last = 35
        fs = 100  # sample rate
        f = 10  # the frequency of the signal
        self._ft_xin = numpy.linspace(0.0, 100., 1000)
        self._ft_yin = numpy.asarray(
            [numpy.sin(2 * numpy.pi * f * (i / fs)) for i in self._ft_xin])
        self._ft_xout = numpy.linspace(0.0, 2.0, 100)

    def tearDown(self):
        unittest.TestCase.tearDown(self)

    # Utilities

    def test_apply_cropping(self):
        xin = numpy.linspace(0.5, 1.0, 11)
        yin = numpy.linspace(4.5, 5.0, 11)
        x, y, _ = self.transformer.apply_cropping(xin, yin, 0.6, 0.7)
        assert_array_equal(x, [0.6, 0.65, 0.7])
        assert_array_equal(y, [4.6, 4.65, 4.7])

    def test_fourier_transform(self):
        xout, yout, _ = self.transformer.fourier_transform(
            self._ft_xin, self._ft_yin, self._ft_xout)
        yout_target = [
            -0.14265772, -10.8854444, 18.13582784, 49.72976782, 26.3590524,
            -8.08540764, -3.38810001
        ]
        assert_allclose(yout[self._ft_first:self._ft_last],
                        yout_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def test_fourier_transform_with_lorch(self):
        kwargs = {"lorch": True}
        xout, yout, _ = self.transformer.fourier_transform(
            self._ft_xin, self._ft_yin, self._ft_xout, **kwargs)
        yout_target = [
            -1.406162, 3.695632, 18.788041, 29.370677, 21.980533, 6.184271,
            -1.234159
        ]
        assert_allclose(yout[self._ft_first:self._ft_last],
                        yout_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def test_fourier_transform_with_low_x(self):
        kwargs = {"OmittedXrangeCorrection": True}
        xout, yout, _ = self.transformer.fourier_transform(
            self._ft_xin, self._ft_yin, self._ft_xout, **kwargs)
        yout_target = [
            -0.142658, -10.885444, 18.135828, 49.729768, 26.359052, -8.085408,
            -3.388100
        ]
        assert_allclose(yout[self._ft_first:self._ft_last],
                        yout_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def test_low_x_correction(self):
        kwargs = {"lorch": False}
        xout, yout, _ = self.transformer.fourier_transform(
            self._ft_xin, self._ft_yin, self._ft_xout, **kwargs)
        yout = self.transformer._low_x_correction(self._ft_xin, self._ft_yin,
                                                  xout, yout, **kwargs)
        yout_target = [
            -0.142658, -10.885444, 18.135828, 49.729768, 26.359052, -8.085408,
            -3.388100
        ]
        assert_allclose(yout[self._ft_first:self._ft_last],
                        yout_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def test_low_x_correction_with_lorch(self):
        kwargs = {"lorch": True}
        xout, yout, _ = self.transformer.fourier_transform(
            self._ft_xin, self._ft_yin, self._ft_xout, **kwargs)
        yout = self.transformer._low_x_correction(self._ft_xin, self._ft_yin,
                                                  xout, yout, **kwargs)
        yout_target = [
            -1.406162, 3.695632, 18.788041, 29.370677, 21.980533, 6.184271,
            -1.234159
        ]
        assert_allclose(yout[self._ft_first:self._ft_last],
                        yout_target,
                        rtol=self.rtol,
                        atol=self.atol)

    # Real space

    # g(r) tests

    def g_to_S(self):
        q, sq, _ = self.transformer.g_to_S(self.r, self.gofr, self.q,
                                           **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(sq[first:last],
                        self.sq_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def g_to_F(self):
        q, fq, _ = self.transformer.g_to_F(self.r, self.gofr, self.q,
                                           **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(fq[first:last],
                        self.fq_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def g_to_FK(self):
        q, fq_keen, _ = self.transformer.g_to_FK(self.r, self.gofr, self.q,
                                                 **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(fq_keen[first:last],
                        self.fq_keen_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def g_to_DCS(self):
        q, dcs, _ = self.transformer.g_to_DCS(self.r, self.gofr, self.q,
                                              **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(dcs[first:last],
                        self.dcs_target,
                        rtol=self.rtol,
                        atol=self.atol)

    # G(r) tests

    def G_to_S(self):
        q, sq, _ = self.transformer.G_to_S(self.r, self.GofR, self.q,
                                           **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(sq[first:last],
                        self.sq_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def G_to_F(self):
        q, fq, _ = self.transformer.G_to_F(self.r, self.GofR, self.q,
                                           **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(fq[first:last],
                        self.fq_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def G_to_FK(self):
        q, fq_keen, _ = self.transformer.G_to_FK(self.r, self.GofR, self.q,
                                                 **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(fq_keen[first:last],
                        self.fq_keen_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def G_to_DCS(self):
        q, dcs, _ = self.transformer.G_to_DCS(self.r, self.GofR, self.q,
                                              **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(dcs[first:last],
                        self.dcs_target,
                        rtol=self.rtol,
                        atol=self.atol)

    # GK(r) tests

    def GK_to_S(self):
        q, sq, _ = self.transformer.GK_to_S(self.r, self.GKofR, self.q,
                                            **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(sq[first:last],
                        self.sq_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def GK_to_F(self):
        q, fq, _ = self.transformer.GK_to_F(self.r, self.GKofR, self.q,
                                            **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(fq[first:last],
                        self.fq_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def GK_to_FK(self):
        q, fq_keen, _ = self.transformer.GK_to_FK(self.r, self.GKofR, self.q,
                                                  **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(fq_keen[first:last],
                        self.fq_keen_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def GK_to_DCS(self):
        q, dcs, _ = self.transformer.GK_to_DCS(self.r, self.GKofR, self.q,
                                               **self.kwargs)
        first, last = self.reciprocal_space_first, self.reciprocal_space_last
        assert_allclose(dcs[first:last],
                        self.dcs_target,
                        rtol=self.rtol,
                        atol=self.atol)

    # Reciprocal space

    # S(Q) tests
    def S_to_g(self):
        r, gofr, _ = self.transformer.S_to_g(self.q, self.sq, self.r,
                                             **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(gofr[first:last],
                        self.gofr_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def S_to_G(self):
        r, GofR, _ = self.transformer.S_to_G(self.q, self.sq, self.r,
                                             **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(GofR[first:last],
                        self.GofR_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def S_to_GK(self):
        r, GKofR, _ = self.transformer.S_to_GK(self.q, self.sq, self.r,
                                               **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(GKofR[first:last],
                        self.GKofR_target,
                        rtol=self.rtol,
                        atol=self.atol)

    # Q[S(Q)-1] tests

    def F_to_g(self):
        r, gofr, _ = self.transformer.F_to_g(self.q, self.fq, self.r,
                                             **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(gofr[first:last],
                        self.gofr_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def F_to_G(self):
        r, GofR, _ = self.transformer.F_to_G(self.q, self.fq, self.r,
                                             **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(GofR[first:last],
                        self.GofR_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def F_to_GK(self):
        r, GKofR, _ = self.transformer.F_to_GK(self.q, self.fq, self.r,
                                               **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(GKofR[first:last],
                        self.GKofR_target,
                        rtol=self.rtol,
                        atol=self.atol)

    # FK(Q) tests

    def FK_to_g(self):
        r, gofr, _ = self.transformer.FK_to_g(self.q, self.fq_keen, self.r,
                                              **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(gofr[first:last],
                        self.gofr_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def FK_to_G(self):
        r, GofR, _ = self.transformer.FK_to_G(self.q, self.fq_keen, self.r,
                                              **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(GofR[first:last],
                        self.GofR_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def FK_to_GK(self):
        r, GKofR, _ = self.transformer.FK_to_GK(self.q, self.fq_keen, self.r,
                                                **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(GKofR[first:last],
                        self.GKofR_target,
                        rtol=self.rtol,
                        atol=self.atol)

    # DCS(Q) tests

    def DCS_to_g(self):
        r, gofr, _ = self.transformer.DCS_to_g(self.q, self.dcs, self.r,
                                               **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(gofr[first:last],
                        self.gofr_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def DCS_to_G(self):
        r, GofR, _ = self.transformer.DCS_to_G(self.q, self.dcs, self.r,
                                               **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(GofR[first:last],
                        self.GofR_target,
                        rtol=self.rtol,
                        atol=self.atol)

    def DCS_to_GK(self):
        r, GKofR, _ = self.transformer.DCS_to_GK(self.q, self.dcs, self.r,
                                                 **self.kwargs)
        first, last = self.real_space_first, self.real_space_last
        assert_allclose(GKofR[first:last],
                        self.GKofR_target,
                        rtol=self.rtol,
                        atol=self.atol)