Creating an Observable from a Simulation

When running a refinement, MDMC makes quantitative comparisons between properties measured experimentally and calculated from MD simulations: within MDMC each of these properties is an Observable. Examples of these observables are the dynamic structure factor, \(S(Q,\omega)\), and the pair distribution function, \(G(r)\).

Within a refinement, each Observable is calculated from MD automatically. However it is also useful to be able to calculate an Observable from an MD simulation and plot it, which is demonstrated in this tutorial.

This tutorial requires matplotlib to be installed:

[1]:
try:
    %matplotlib notebook
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
except ImportError:
    %pip install matplotlib
    try:
        %matplotlib notebook
        import matplotlib.pyplot as plt
        from mpl_toolkits.mplot3d import Axes3D
    except ImportError:
        print('Please restart the kernel so that matplotlib can be imported.')

Running a simulation

Below we setup and run a simulation of liquid argon so that we have a CompactTrajectory from which to calculate an Observable.

As this is minimizing, equilibrating, and running a production run, this should take ~3 minutes to execute. Minimization lowers the potential energy of the simulated system by adjusting atomic positions. Running a simulation with equilibration set to True will not record a CompactTrajectory, and since we specified neither a thermostat or barastat for the simulation a Berendsen thermostat will be applied for the duration of the equilibration. It will not be present for the second run, when the CompactTrajectory is recorded.

[2]:
from MDMC.MD import *
import numpy as np

# Build universe
universe = Universe(dimensions=38.4441)
Ar = Atom('Ar', charge=0.)
# Fill box with 1000 atoms, and hence atoms per AA^-3 density = 0.0176
universe.fill(Ar, num_struc_units=1000)
print('Universe contains {} Ar atoms'.format(len(universe.atoms)))
Ar_dispersion = Dispersion(universe,
                           (Ar.atom_type, Ar.atom_type),
                           cutoff=8.,
                           vdw_tail_correction=True,
                           function=LennardJones(1.0243, 3.36))

# MD Engine setup
simulation = Simulation(universe,
                        engine="lammps",
                        time_step=10.0,
                        temperature=120.,
                        traj_step=25)

# Energy Minimization and equilibration
simulation.minimize(n_steps=50)
simulation.run(n_steps=20000, equilibration=True)
simulation.run(12025)
trajectory = simulation.trajectory
Supported DL_POLY version 5.0
Universe created with:
  Dimensions       [38.44, 38.44, 38.44]
  Force field                       None
  Number of atoms                      0

Universe contains 1000 Ar atoms
LAMMPS (29 Sep 2021 - Update 3)
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98)
  using 1 OpenMP thread(s) per MPI task
LAMMPS output is captured by PyLammps wrapper
LAMMPS (29 Sep 2021 - Update 3)
LAMMPS output is captured by PyLammps wrapper
OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98)
  using 1 OpenMP thread(s) per MPI task
Total wall time: 0:00:00
Simulation created with lammps engine and settings:
  temperature  120.0

3D surface plotting

Below we define a simple function for plotting 3D surfaces, which we will use for plotting the observables.

[3]:
def plot_surface(x, y, z):
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    X, Y = np.meshgrid(x, y)
    surf = ax.plot_surface(X, Y, z)
    plt.show()

Calculating \(S(Q,\omega)\)

To see which observables can be calculated, use the help function to look at the observables module documentation:

[4]:
from MDMC.trajectory_analysis import observables
help(observables)
Help on package MDMC.trajectory_analysis.observables in MDMC.trajectory_analysis:

NAME
    MDMC.trajectory_analysis.observables - Modules calculating observables from molecular dynamics trajectories

DESCRIPTION
    Observables (/ indicates alias)
    -----------
    DynamicStructureFactor / SQw
    CoherentDynamicStructureFactor / SQwCoherent / SQwCoh / SQw_coh
    IncoherentDynamicStructureFactor / SQwIncoherentSQwIncoh / SQw_incoh
    IntermediateScatteringFunction / FQt
    PDF / PairDistributionFunction
    CoherentIntermediateScatteringFunction / FQtCoherent / FQtCoh / FQt_coh
    IncoherentIntermediateScatteringFunction / FQtIncoherentFQtIncoh / FQt_incoh

    Examples
    --------
    Observables can be instantiated using the names above. For instance an SQw
    observable can be instantiated using either of the aliases:

    .. code-block:: python

        from MDMC.trajectory_analysis import observables
        sqw = observables.SQw()                     # This line...
        sqw = observables.DynamicStructureFactor()  # ...is equivalent to this line

PACKAGE CONTENTS
    fqt
    fqt_coh
    fqt_incoh
    obs
    obs_factory
    pdf
    sqw

CLASSES
    MDMC.trajectory_analysis.observables.fqt.AbstractFQt(MDMC.trajectory_analysis.observables.sqw.SQwMixins, MDMC.trajectory_analysis.observables.obs.Observable)
        MDMC.trajectory_analysis.observables.fqt.FQt
        MDMC.trajectory_analysis.observables.fqt_coh.FQtCoherent
        MDMC.trajectory_analysis.observables.fqt_incoh.FQtIncoherent
    MDMC.trajectory_analysis.observables.obs.Observable(abc.ABC)
        MDMC.trajectory_analysis.observables.pdf.PairDistributionFunction
    MDMC.trajectory_analysis.observables.sqw.AbstractSQw(MDMC.trajectory_analysis.observables.sqw.SQwMixins, MDMC.trajectory_analysis.observables.obs.Observable)
        MDMC.trajectory_analysis.observables.sqw.SQw
        MDMC.trajectory_analysis.observables.sqw.SQwCoherent
        MDMC.trajectory_analysis.observables.sqw.SQwIncoherent

    CoherentDynamicStructureFactor = class SQwCoherent(AbstractSQw)
     |  A class for the coherent dynamic structure factor
     |
     |  Method resolution order:
     |      SQwCoherent
     |      AbstractSQw
     |      SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'SQw_coh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractSQw:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_dt(self) -> float
     |      Calculates the time separation of frames required by the experimental
     |      dataset, assuming uniform spacing. Note that this may be different from
     |      the time separation that the user has given as an input, as it only
     |      depends on the current values for ``self.E``. The relationship between
     |      time and energy comes from the numpy implementation of the FFT for
     |      ``2 * nE`` points where:
     |
     |      .. math::
     |          \nu_{max} &=& \frac{n_E - 1}{2 n_E \Delta t} \\\\
     |          \therefore \Delta t &=& \frac{h (n_E - 1)}{2 n_E E_{max}}
     |
     |      Returns
     |      -------
     |      float
     |          The time separation required by the current values of ``self.E``
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the dynamic structure factor, S(Q, w) from a ``CompactTrajectory``.
     |
     |      If the ``CompactTrajectory`` has more frames than the ``self.maximum_frames()``
     |      that can be used to recreate the grid of energy points, it can slice the
     |      ``CompactTrajectory`` into sub-trajectories of length ``self.maximum_frames()``,
     |      with the slicing specified through the settings ``use_average`` and ``cont_slicing``.
     |
     |      The ``independent_variable`` ``Q`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          An MDMC ``CompactTrajectory`` from which to calculate ``SQw``
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |          ``energy_resolution` (`dict`)
     |              Optionally specify energy resolution and function in units of ueV (micro eV),
     |              in the format of the one-line dict {'function': value}, where `function`
     |              is the resolution function and `value` is the desired `FWHM`.
     |              e.g. to pass a Gaussian resolution of 80ueV we use {'gaussian': 80}.
     |              Currently accepted functions are 'gaussian' and 'lorentzian'
     |              Can also be 'lazily' given as `float`, in which case it is assumed to be Gaussian.
     |          ``Q_values`` (`array`)
     |              1D array of Q `float` (in ``Ang^-1``). (optional)
     |          ``use_average`` (`bool`)
     |              Optional parameter if a list of more than one ``Trajectory`` is used. If set to
     |              True (default) then the mean value for S(Q, w) is calculated. Also, the errors
     |              are set to the standard deviation calculated over the list of
     |              ``CompactTrajectory`` objects.
     |           ``cont_slicing`` (`bool`)
     |              Flag to decide between two possible behaviours when the number of ``MD_steps`` is
     |              larger than the minimum required to calculate the observables. If ``False``
     |              (default) then the ``CompactTrajectory`` is sliced into non-overlapping
     |              sub-``CompactTrajectory`` blocks for each of which the observable is calculated.
     |              If ``True``, then the ``CompactTrajectory`` is sliced into as many non-identical
     |              sub-``CompactTrajectory`` blocks as possible (with overlap allowed).
     |
     |  calculate_resolution_functions(self, dt: float) -> dict
     |      Generates a resolution function in momentum and time that can be used in the calculation of
     |      SQw. Note that this uses the ``SQw`` values of the ``Observable`` it is called from, and so
     |      should only be called for an observable which has been created from relevant resolution
     |      data, i.e. a vanadium sample.
     |
     |      Note that if this resolution function is used on data outside its original range, then it
     |      will use nearest neighbour extrapolation. Additionally, the input will be reflected in the
     |      time/energy domain as symmetry about 0 is assumed. If for whatever reason this is not
     |      appropriate for the data in question, this function should not be used.
     |
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          The time spacing to use when performing the inverse Fourier transform in units of `fs`.
     |          Ideally this should be the same as the frame separation expected when applying this
     |          function.
     |
     |      Returns
     |      -------
     |      dict
     |          A dictionary with the key 'SQw' corresponding to function which accepts arrays of time
     |          and momentum (respectively) and returns a 2D array of values for the instrument
     |          resolution.
     |
     |  validate_energy(self, dt: float) -> None
     |      Asserts that the user set frame separation ``dt`` leads to energy
     |      separation that matches that of the experiment. If not, it
     |      includes the time separation required in the error.
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          Frame separation in ``fs``
     |
     |      Returns
     |      -------
     |      None
     |
     |      Raises
     |      ------
     |      AssertionError
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from AbstractSQw:
     |
     |  calculate_E(nE: int, dt: float) -> numpy.ndarray
     |      Calculates an array of ``nE`` uniformly spaced energy values from the
     |      time separation of the ``CompactTrajectory`` frames, ``dt``. The
     |      frequencie are determined by the Fast Fourier Transform, as implemented
     |      by numpy, for ``2 * nE`` points in time which we then crop to only
     |      include ``nE`` positive frequencies. As we are dealing with frequency
     |      rather than angular frequency here, the relation to between energy
     |      is given by:
     |
     |      .. math::
     |
     |          E = h \nu
     |
     |      Parameters
     |      ----------
     |      nE : int
     |          The number of energy values to be calculated
     |      dt : float
     |          The step size between frames in ``fs``
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          An ``array`` of `float` specifying the energy in units of ``meV``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractSQw:
     |
     |  E
     |
     |  SQw
     |
     |  SQw_err
     |
     |  dependent_variables
     |      Get the dependent variables: this is SQw, the
     |      dynamic structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'SQw' dependent variable is indexed in terms of 'Q' and 'E'.
     |      Explicitly: we have that self.SQw[Q_index, E_index] is the data point for
     |      given indices of self.Q and self.E
     |      It also means that:
     |      np.shape(self.SQw)=(np.size(self.Q), np.size(self.E))
     |
     |      The purpose of this method is to ensure consistency
     |      between different readers/methods which create ``SQw`` objects.
     |
     |      Return
     |      ------
     |      Dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the energy 'E' and reciprocal
     |      lattice points 'Q' within the dynamic structure factor ``Observables``.
     |      If using FFT, then 'E' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      Dict[str, Dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'E' and 'Q'.
     |
     |  w
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractSQw:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the dynamic
     |      structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and energy E (in``meV``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    CoherentIntermediateScatteringFunction = class FQtCoherent(MDMC.trajectory_analysis.observables.fqt.AbstractFQt)
     |  A class for containing, calculating and reading the intermediate scattering
     |  function for the coherent dynamic structure factor
     |
     |  Method resolution order:
     |      FQtCoherent
     |      MDMC.trajectory_analysis.observables.fqt.AbstractFQt
     |      MDMC.trajectory_analysis.observables.sqw.SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'FQt_coh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  apply_resolution(self, resolution: MDMC.resolution.resolution.Resolution) -> 'FQt'
     |      Apply instrument resolution to an FQt object.
     |
     |      Parameters
     |      ----------
     |      resolution: Resolution
     |          The Resolution object to apply to FQt.
     |
     |      Returns
     |      -------
     |      The FQt object with resolution applied.
     |
     |  calculate_SQw(self, energy: 'list[float]', resolution: MDMC.resolution.resolution.Resolution = None) -> 'np.ndarray'
     |      Calculates S(Q, w) from F(Q, t), accounting for instrument resolution.
     |
     |      In order to obtain ``len(energy)`` values in energy, we reflect the
     |      intermediate scattering function in time to give it dimensions of
     |      ``(len(self.Q), 2 * (len(self.t)) - 2)``. This uses the fact it is even
     |      in time, and the number of time points is chosen to be 1 greater than
     |      the number of energy points [Rapaport, The Art of Molecular Dynamics
     |      Simulation (2nd Edition), 2004, page 142].
     |
     |      The numpy implementation of the FFT gives frequencies arranged so that
     |      the first ``len(energy)`` points in the energy dimension correspond to
     |      positive frequencies, and the remaining points have negative frequency.
     |
     |      Parameters
     |      ----------
     |      energy: list of floats
     |          the list of energy (E) points at which S(Q, w) will be calculated.
     |      resolution: Resolution (default None)
     |          The instrument resolution object which will be applied to FQt.
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          The S(Q, w) calculated from F(Q, t)
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict) -> None
     |      Calculates the intermediate scattering function from a trajectory.
     |
     |      ``independent_variables`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          a single ``CompactTrajectory`` object.
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  dependent_variables
     |      Get the dependent variables: this is
     |      FQt, the intermediate scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'FQt' dependent variable is indexed in terms of 'Q' and 't'.
     |      Explicitly: we have that self.FQt[Q_index, t_index] is the data point
     |      for given indices of self.Q and self.t
     |      It also means that:
     |      np.shape(self.FQt)=(np.size(self.Q), np.size(self.t))
     |
     |      The purpose of this method is to ensure consistency between
     |      different readers/methods which create ``FQt`` objects.
     |
     |      Return
     |      ------
     |      dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the time 't' and reciprocal
     |      lattice points 'Q' within the intermediate scattering function ``Observables``.
     |      If using FFT, then 't' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 't' and 'Q'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  FQt
     |
     |  errors
     |      Get or set the errors on the dependent variables, the intermediate
     |      scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and time t (in ``fs``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  t
     |      Get or set the times of the intermediate scattering function in units of
     |      ``fs``
     |
     |      Returns
     |      -------
     |      numpy.array
     |          1D array of times in ``fs``
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    DynamicStructureFactor = class SQw(AbstractSQw)
     |  A class for the total dynamic structure factor
     |
     |  Calculation is done in the respective FQt object, and this is
     |  just a reference to get the correct FQt object.
     |
     |  Method resolution order:
     |      SQw
     |      AbstractSQw
     |      SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'SQw'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractSQw:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_dt(self) -> float
     |      Calculates the time separation of frames required by the experimental
     |      dataset, assuming uniform spacing. Note that this may be different from
     |      the time separation that the user has given as an input, as it only
     |      depends on the current values for ``self.E``. The relationship between
     |      time and energy comes from the numpy implementation of the FFT for
     |      ``2 * nE`` points where:
     |
     |      .. math::
     |          \nu_{max} &=& \frac{n_E - 1}{2 n_E \Delta t} \\\\
     |          \therefore \Delta t &=& \frac{h (n_E - 1)}{2 n_E E_{max}}
     |
     |      Returns
     |      -------
     |      float
     |          The time separation required by the current values of ``self.E``
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the dynamic structure factor, S(Q, w) from a ``CompactTrajectory``.
     |
     |      If the ``CompactTrajectory`` has more frames than the ``self.maximum_frames()``
     |      that can be used to recreate the grid of energy points, it can slice the
     |      ``CompactTrajectory`` into sub-trajectories of length ``self.maximum_frames()``,
     |      with the slicing specified through the settings ``use_average`` and ``cont_slicing``.
     |
     |      The ``independent_variable`` ``Q`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          An MDMC ``CompactTrajectory`` from which to calculate ``SQw``
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |          ``energy_resolution` (`dict`)
     |              Optionally specify energy resolution and function in units of ueV (micro eV),
     |              in the format of the one-line dict {'function': value}, where `function`
     |              is the resolution function and `value` is the desired `FWHM`.
     |              e.g. to pass a Gaussian resolution of 80ueV we use {'gaussian': 80}.
     |              Currently accepted functions are 'gaussian' and 'lorentzian'
     |              Can also be 'lazily' given as `float`, in which case it is assumed to be Gaussian.
     |          ``Q_values`` (`array`)
     |              1D array of Q `float` (in ``Ang^-1``). (optional)
     |          ``use_average`` (`bool`)
     |              Optional parameter if a list of more than one ``Trajectory`` is used. If set to
     |              True (default) then the mean value for S(Q, w) is calculated. Also, the errors
     |              are set to the standard deviation calculated over the list of
     |              ``CompactTrajectory`` objects.
     |           ``cont_slicing`` (`bool`)
     |              Flag to decide between two possible behaviours when the number of ``MD_steps`` is
     |              larger than the minimum required to calculate the observables. If ``False``
     |              (default) then the ``CompactTrajectory`` is sliced into non-overlapping
     |              sub-``CompactTrajectory`` blocks for each of which the observable is calculated.
     |              If ``True``, then the ``CompactTrajectory`` is sliced into as many non-identical
     |              sub-``CompactTrajectory`` blocks as possible (with overlap allowed).
     |
     |  calculate_resolution_functions(self, dt: float) -> dict
     |      Generates a resolution function in momentum and time that can be used in the calculation of
     |      SQw. Note that this uses the ``SQw`` values of the ``Observable`` it is called from, and so
     |      should only be called for an observable which has been created from relevant resolution
     |      data, i.e. a vanadium sample.
     |
     |      Note that if this resolution function is used on data outside its original range, then it
     |      will use nearest neighbour extrapolation. Additionally, the input will be reflected in the
     |      time/energy domain as symmetry about 0 is assumed. If for whatever reason this is not
     |      appropriate for the data in question, this function should not be used.
     |
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          The time spacing to use when performing the inverse Fourier transform in units of `fs`.
     |          Ideally this should be the same as the frame separation expected when applying this
     |          function.
     |
     |      Returns
     |      -------
     |      dict
     |          A dictionary with the key 'SQw' corresponding to function which accepts arrays of time
     |          and momentum (respectively) and returns a 2D array of values for the instrument
     |          resolution.
     |
     |  validate_energy(self, dt: float) -> None
     |      Asserts that the user set frame separation ``dt`` leads to energy
     |      separation that matches that of the experiment. If not, it
     |      includes the time separation required in the error.
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          Frame separation in ``fs``
     |
     |      Returns
     |      -------
     |      None
     |
     |      Raises
     |      ------
     |      AssertionError
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from AbstractSQw:
     |
     |  calculate_E(nE: int, dt: float) -> numpy.ndarray
     |      Calculates an array of ``nE`` uniformly spaced energy values from the
     |      time separation of the ``CompactTrajectory`` frames, ``dt``. The
     |      frequencie are determined by the Fast Fourier Transform, as implemented
     |      by numpy, for ``2 * nE`` points in time which we then crop to only
     |      include ``nE`` positive frequencies. As we are dealing with frequency
     |      rather than angular frequency here, the relation to between energy
     |      is given by:
     |
     |      .. math::
     |
     |          E = h \nu
     |
     |      Parameters
     |      ----------
     |      nE : int
     |          The number of energy values to be calculated
     |      dt : float
     |          The step size between frames in ``fs``
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          An ``array`` of `float` specifying the energy in units of ``meV``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractSQw:
     |
     |  E
     |
     |  SQw
     |
     |  SQw_err
     |
     |  dependent_variables
     |      Get the dependent variables: this is SQw, the
     |      dynamic structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'SQw' dependent variable is indexed in terms of 'Q' and 'E'.
     |      Explicitly: we have that self.SQw[Q_index, E_index] is the data point for
     |      given indices of self.Q and self.E
     |      It also means that:
     |      np.shape(self.SQw)=(np.size(self.Q), np.size(self.E))
     |
     |      The purpose of this method is to ensure consistency
     |      between different readers/methods which create ``SQw`` objects.
     |
     |      Return
     |      ------
     |      Dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the energy 'E' and reciprocal
     |      lattice points 'Q' within the dynamic structure factor ``Observables``.
     |      If using FFT, then 'E' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      Dict[str, Dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'E' and 'Q'.
     |
     |  w
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractSQw:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the dynamic
     |      structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and energy E (in``meV``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    class FQt(AbstractFQt)
     |  A class for containing, calculating and reading the intermediate scattering
     |  function for the total dynamic structure factor
     |
     |  Method resolution order:
     |      FQt
     |      AbstractFQt
     |      MDMC.trajectory_analysis.observables.sqw.SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'IntermediateScatteringFunction'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractFQt:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  apply_resolution(self, resolution: MDMC.resolution.resolution.Resolution) -> 'FQt'
     |      Apply instrument resolution to an FQt object.
     |
     |      Parameters
     |      ----------
     |      resolution: Resolution
     |          The Resolution object to apply to FQt.
     |
     |      Returns
     |      -------
     |      The FQt object with resolution applied.
     |
     |  calculate_SQw(self, energy: 'list[float]', resolution: MDMC.resolution.resolution.Resolution = None) -> 'np.ndarray'
     |      Calculates S(Q, w) from F(Q, t), accounting for instrument resolution.
     |
     |      In order to obtain ``len(energy)`` values in energy, we reflect the
     |      intermediate scattering function in time to give it dimensions of
     |      ``(len(self.Q), 2 * (len(self.t)) - 2)``. This uses the fact it is even
     |      in time, and the number of time points is chosen to be 1 greater than
     |      the number of energy points [Rapaport, The Art of Molecular Dynamics
     |      Simulation (2nd Edition), 2004, page 142].
     |
     |      The numpy implementation of the FFT gives frequencies arranged so that
     |      the first ``len(energy)`` points in the energy dimension correspond to
     |      positive frequencies, and the remaining points have negative frequency.
     |
     |      Parameters
     |      ----------
     |      energy: list of floats
     |          the list of energy (E) points at which S(Q, w) will be calculated.
     |      resolution: Resolution (default None)
     |          The instrument resolution object which will be applied to FQt.
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          The S(Q, w) calculated from F(Q, t)
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict) -> None
     |      Calculates the intermediate scattering function from a trajectory.
     |
     |      ``independent_variables`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          a single ``CompactTrajectory`` object.
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractFQt:
     |
     |  dependent_variables
     |      Get the dependent variables: this is
     |      FQt, the intermediate scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'FQt' dependent variable is indexed in terms of 'Q' and 't'.
     |      Explicitly: we have that self.FQt[Q_index, t_index] is the data point
     |      for given indices of self.Q and self.t
     |      It also means that:
     |      np.shape(self.FQt)=(np.size(self.Q), np.size(self.t))
     |
     |      The purpose of this method is to ensure consistency between
     |      different readers/methods which create ``FQt`` objects.
     |
     |      Return
     |      ------
     |      dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the time 't' and reciprocal
     |      lattice points 'Q' within the intermediate scattering function ``Observables``.
     |      If using FFT, then 't' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 't' and 'Q'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractFQt:
     |
     |  FQt
     |
     |  errors
     |      Get or set the errors on the dependent variables, the intermediate
     |      scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and time t (in ``fs``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  t
     |      Get or set the times of the intermediate scattering function in units of
     |      ``fs``
     |
     |      Returns
     |      -------
     |      numpy.array
     |          1D array of times in ``fs``
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    FQtCoh = class FQtCoherent(MDMC.trajectory_analysis.observables.fqt.AbstractFQt)
     |  A class for containing, calculating and reading the intermediate scattering
     |  function for the coherent dynamic structure factor
     |
     |  Method resolution order:
     |      FQtCoherent
     |      MDMC.trajectory_analysis.observables.fqt.AbstractFQt
     |      MDMC.trajectory_analysis.observables.sqw.SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'FQt_coh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  apply_resolution(self, resolution: MDMC.resolution.resolution.Resolution) -> 'FQt'
     |      Apply instrument resolution to an FQt object.
     |
     |      Parameters
     |      ----------
     |      resolution: Resolution
     |          The Resolution object to apply to FQt.
     |
     |      Returns
     |      -------
     |      The FQt object with resolution applied.
     |
     |  calculate_SQw(self, energy: 'list[float]', resolution: MDMC.resolution.resolution.Resolution = None) -> 'np.ndarray'
     |      Calculates S(Q, w) from F(Q, t), accounting for instrument resolution.
     |
     |      In order to obtain ``len(energy)`` values in energy, we reflect the
     |      intermediate scattering function in time to give it dimensions of
     |      ``(len(self.Q), 2 * (len(self.t)) - 2)``. This uses the fact it is even
     |      in time, and the number of time points is chosen to be 1 greater than
     |      the number of energy points [Rapaport, The Art of Molecular Dynamics
     |      Simulation (2nd Edition), 2004, page 142].
     |
     |      The numpy implementation of the FFT gives frequencies arranged so that
     |      the first ``len(energy)`` points in the energy dimension correspond to
     |      positive frequencies, and the remaining points have negative frequency.
     |
     |      Parameters
     |      ----------
     |      energy: list of floats
     |          the list of energy (E) points at which S(Q, w) will be calculated.
     |      resolution: Resolution (default None)
     |          The instrument resolution object which will be applied to FQt.
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          The S(Q, w) calculated from F(Q, t)
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict) -> None
     |      Calculates the intermediate scattering function from a trajectory.
     |
     |      ``independent_variables`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          a single ``CompactTrajectory`` object.
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  dependent_variables
     |      Get the dependent variables: this is
     |      FQt, the intermediate scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'FQt' dependent variable is indexed in terms of 'Q' and 't'.
     |      Explicitly: we have that self.FQt[Q_index, t_index] is the data point
     |      for given indices of self.Q and self.t
     |      It also means that:
     |      np.shape(self.FQt)=(np.size(self.Q), np.size(self.t))
     |
     |      The purpose of this method is to ensure consistency between
     |      different readers/methods which create ``FQt`` objects.
     |
     |      Return
     |      ------
     |      dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the time 't' and reciprocal
     |      lattice points 'Q' within the intermediate scattering function ``Observables``.
     |      If using FFT, then 't' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 't' and 'Q'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  FQt
     |
     |  errors
     |      Get or set the errors on the dependent variables, the intermediate
     |      scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and time t (in ``fs``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  t
     |      Get or set the times of the intermediate scattering function in units of
     |      ``fs``
     |
     |      Returns
     |      -------
     |      numpy.array
     |          1D array of times in ``fs``
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    class FQtCoherent(MDMC.trajectory_analysis.observables.fqt.AbstractFQt)
     |  A class for containing, calculating and reading the intermediate scattering
     |  function for the coherent dynamic structure factor
     |
     |  Method resolution order:
     |      FQtCoherent
     |      MDMC.trajectory_analysis.observables.fqt.AbstractFQt
     |      MDMC.trajectory_analysis.observables.sqw.SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'FQt_coh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  apply_resolution(self, resolution: MDMC.resolution.resolution.Resolution) -> 'FQt'
     |      Apply instrument resolution to an FQt object.
     |
     |      Parameters
     |      ----------
     |      resolution: Resolution
     |          The Resolution object to apply to FQt.
     |
     |      Returns
     |      -------
     |      The FQt object with resolution applied.
     |
     |  calculate_SQw(self, energy: 'list[float]', resolution: MDMC.resolution.resolution.Resolution = None) -> 'np.ndarray'
     |      Calculates S(Q, w) from F(Q, t), accounting for instrument resolution.
     |
     |      In order to obtain ``len(energy)`` values in energy, we reflect the
     |      intermediate scattering function in time to give it dimensions of
     |      ``(len(self.Q), 2 * (len(self.t)) - 2)``. This uses the fact it is even
     |      in time, and the number of time points is chosen to be 1 greater than
     |      the number of energy points [Rapaport, The Art of Molecular Dynamics
     |      Simulation (2nd Edition), 2004, page 142].
     |
     |      The numpy implementation of the FFT gives frequencies arranged so that
     |      the first ``len(energy)`` points in the energy dimension correspond to
     |      positive frequencies, and the remaining points have negative frequency.
     |
     |      Parameters
     |      ----------
     |      energy: list of floats
     |          the list of energy (E) points at which S(Q, w) will be calculated.
     |      resolution: Resolution (default None)
     |          The instrument resolution object which will be applied to FQt.
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          The S(Q, w) calculated from F(Q, t)
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict) -> None
     |      Calculates the intermediate scattering function from a trajectory.
     |
     |      ``independent_variables`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          a single ``CompactTrajectory`` object.
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  dependent_variables
     |      Get the dependent variables: this is
     |      FQt, the intermediate scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'FQt' dependent variable is indexed in terms of 'Q' and 't'.
     |      Explicitly: we have that self.FQt[Q_index, t_index] is the data point
     |      for given indices of self.Q and self.t
     |      It also means that:
     |      np.shape(self.FQt)=(np.size(self.Q), np.size(self.t))
     |
     |      The purpose of this method is to ensure consistency between
     |      different readers/methods which create ``FQt`` objects.
     |
     |      Return
     |      ------
     |      dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the time 't' and reciprocal
     |      lattice points 'Q' within the intermediate scattering function ``Observables``.
     |      If using FFT, then 't' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 't' and 'Q'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  FQt
     |
     |  errors
     |      Get or set the errors on the dependent variables, the intermediate
     |      scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and time t (in ``fs``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  t
     |      Get or set the times of the intermediate scattering function in units of
     |      ``fs``
     |
     |      Returns
     |      -------
     |      numpy.array
     |          1D array of times in ``fs``
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    FQtIncoherentFQtIncoh = class FQtIncoherent(MDMC.trajectory_analysis.observables.fqt.AbstractFQt)
     |  A class for containing, calculating and reading the intermediate scattering
     |  function for the incoherent dynamic structure factor
     |
     |  Method resolution order:
     |      FQtIncoherent
     |      MDMC.trajectory_analysis.observables.fqt.AbstractFQt
     |      MDMC.trajectory_analysis.observables.sqw.SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'IncoherentIntermediateScatteringFunction'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  apply_resolution(self, resolution: MDMC.resolution.resolution.Resolution) -> 'FQt'
     |      Apply instrument resolution to an FQt object.
     |
     |      Parameters
     |      ----------
     |      resolution: Resolution
     |          The Resolution object to apply to FQt.
     |
     |      Returns
     |      -------
     |      The FQt object with resolution applied.
     |
     |  calculate_SQw(self, energy: 'list[float]', resolution: MDMC.resolution.resolution.Resolution = None) -> 'np.ndarray'
     |      Calculates S(Q, w) from F(Q, t), accounting for instrument resolution.
     |
     |      In order to obtain ``len(energy)`` values in energy, we reflect the
     |      intermediate scattering function in time to give it dimensions of
     |      ``(len(self.Q), 2 * (len(self.t)) - 2)``. This uses the fact it is even
     |      in time, and the number of time points is chosen to be 1 greater than
     |      the number of energy points [Rapaport, The Art of Molecular Dynamics
     |      Simulation (2nd Edition), 2004, page 142].
     |
     |      The numpy implementation of the FFT gives frequencies arranged so that
     |      the first ``len(energy)`` points in the energy dimension correspond to
     |      positive frequencies, and the remaining points have negative frequency.
     |
     |      Parameters
     |      ----------
     |      energy: list of floats
     |          the list of energy (E) points at which S(Q, w) will be calculated.
     |      resolution: Resolution (default None)
     |          The instrument resolution object which will be applied to FQt.
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          The S(Q, w) calculated from F(Q, t)
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict) -> None
     |      Calculates the intermediate scattering function from a trajectory.
     |
     |      ``independent_variables`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          a single ``CompactTrajectory`` object.
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  dependent_variables
     |      Get the dependent variables: this is
     |      FQt, the intermediate scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'FQt' dependent variable is indexed in terms of 'Q' and 't'.
     |      Explicitly: we have that self.FQt[Q_index, t_index] is the data point
     |      for given indices of self.Q and self.t
     |      It also means that:
     |      np.shape(self.FQt)=(np.size(self.Q), np.size(self.t))
     |
     |      The purpose of this method is to ensure consistency between
     |      different readers/methods which create ``FQt`` objects.
     |
     |      Return
     |      ------
     |      dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the time 't' and reciprocal
     |      lattice points 'Q' within the intermediate scattering function ``Observables``.
     |      If using FFT, then 't' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 't' and 'Q'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  FQt
     |
     |  errors
     |      Get or set the errors on the dependent variables, the intermediate
     |      scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and time t (in ``fs``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  t
     |      Get or set the times of the intermediate scattering function in units of
     |      ``fs``
     |
     |      Returns
     |      -------
     |      numpy.array
     |          1D array of times in ``fs``
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    FQt_coh = class FQtCoherent(MDMC.trajectory_analysis.observables.fqt.AbstractFQt)
     |  A class for containing, calculating and reading the intermediate scattering
     |  function for the coherent dynamic structure factor
     |
     |  Method resolution order:
     |      FQtCoherent
     |      MDMC.trajectory_analysis.observables.fqt.AbstractFQt
     |      MDMC.trajectory_analysis.observables.sqw.SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'FQt_coh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  apply_resolution(self, resolution: MDMC.resolution.resolution.Resolution) -> 'FQt'
     |      Apply instrument resolution to an FQt object.
     |
     |      Parameters
     |      ----------
     |      resolution: Resolution
     |          The Resolution object to apply to FQt.
     |
     |      Returns
     |      -------
     |      The FQt object with resolution applied.
     |
     |  calculate_SQw(self, energy: 'list[float]', resolution: MDMC.resolution.resolution.Resolution = None) -> 'np.ndarray'
     |      Calculates S(Q, w) from F(Q, t), accounting for instrument resolution.
     |
     |      In order to obtain ``len(energy)`` values in energy, we reflect the
     |      intermediate scattering function in time to give it dimensions of
     |      ``(len(self.Q), 2 * (len(self.t)) - 2)``. This uses the fact it is even
     |      in time, and the number of time points is chosen to be 1 greater than
     |      the number of energy points [Rapaport, The Art of Molecular Dynamics
     |      Simulation (2nd Edition), 2004, page 142].
     |
     |      The numpy implementation of the FFT gives frequencies arranged so that
     |      the first ``len(energy)`` points in the energy dimension correspond to
     |      positive frequencies, and the remaining points have negative frequency.
     |
     |      Parameters
     |      ----------
     |      energy: list of floats
     |          the list of energy (E) points at which S(Q, w) will be calculated.
     |      resolution: Resolution (default None)
     |          The instrument resolution object which will be applied to FQt.
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          The S(Q, w) calculated from F(Q, t)
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict) -> None
     |      Calculates the intermediate scattering function from a trajectory.
     |
     |      ``independent_variables`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          a single ``CompactTrajectory`` object.
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  dependent_variables
     |      Get the dependent variables: this is
     |      FQt, the intermediate scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'FQt' dependent variable is indexed in terms of 'Q' and 't'.
     |      Explicitly: we have that self.FQt[Q_index, t_index] is the data point
     |      for given indices of self.Q and self.t
     |      It also means that:
     |      np.shape(self.FQt)=(np.size(self.Q), np.size(self.t))
     |
     |      The purpose of this method is to ensure consistency between
     |      different readers/methods which create ``FQt`` objects.
     |
     |      Return
     |      ------
     |      dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the time 't' and reciprocal
     |      lattice points 'Q' within the intermediate scattering function ``Observables``.
     |      If using FFT, then 't' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 't' and 'Q'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  FQt
     |
     |  errors
     |      Get or set the errors on the dependent variables, the intermediate
     |      scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and time t (in ``fs``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  t
     |      Get or set the times of the intermediate scattering function in units of
     |      ``fs``
     |
     |      Returns
     |      -------
     |      numpy.array
     |          1D array of times in ``fs``
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    FQt_incoh = class FQtIncoherent(MDMC.trajectory_analysis.observables.fqt.AbstractFQt)
     |  A class for containing, calculating and reading the intermediate scattering
     |  function for the incoherent dynamic structure factor
     |
     |  Method resolution order:
     |      FQtIncoherent
     |      MDMC.trajectory_analysis.observables.fqt.AbstractFQt
     |      MDMC.trajectory_analysis.observables.sqw.SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'IncoherentIntermediateScatteringFunction'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  apply_resolution(self, resolution: MDMC.resolution.resolution.Resolution) -> 'FQt'
     |      Apply instrument resolution to an FQt object.
     |
     |      Parameters
     |      ----------
     |      resolution: Resolution
     |          The Resolution object to apply to FQt.
     |
     |      Returns
     |      -------
     |      The FQt object with resolution applied.
     |
     |  calculate_SQw(self, energy: 'list[float]', resolution: MDMC.resolution.resolution.Resolution = None) -> 'np.ndarray'
     |      Calculates S(Q, w) from F(Q, t), accounting for instrument resolution.
     |
     |      In order to obtain ``len(energy)`` values in energy, we reflect the
     |      intermediate scattering function in time to give it dimensions of
     |      ``(len(self.Q), 2 * (len(self.t)) - 2)``. This uses the fact it is even
     |      in time, and the number of time points is chosen to be 1 greater than
     |      the number of energy points [Rapaport, The Art of Molecular Dynamics
     |      Simulation (2nd Edition), 2004, page 142].
     |
     |      The numpy implementation of the FFT gives frequencies arranged so that
     |      the first ``len(energy)`` points in the energy dimension correspond to
     |      positive frequencies, and the remaining points have negative frequency.
     |
     |      Parameters
     |      ----------
     |      energy: list of floats
     |          the list of energy (E) points at which S(Q, w) will be calculated.
     |      resolution: Resolution (default None)
     |          The instrument resolution object which will be applied to FQt.
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          The S(Q, w) calculated from F(Q, t)
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict) -> None
     |      Calculates the intermediate scattering function from a trajectory.
     |
     |      ``independent_variables`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          a single ``CompactTrajectory`` object.
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  dependent_variables
     |      Get the dependent variables: this is
     |      FQt, the intermediate scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'FQt' dependent variable is indexed in terms of 'Q' and 't'.
     |      Explicitly: we have that self.FQt[Q_index, t_index] is the data point
     |      for given indices of self.Q and self.t
     |      It also means that:
     |      np.shape(self.FQt)=(np.size(self.Q), np.size(self.t))
     |
     |      The purpose of this method is to ensure consistency between
     |      different readers/methods which create ``FQt`` objects.
     |
     |      Return
     |      ------
     |      dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the time 't' and reciprocal
     |      lattice points 'Q' within the intermediate scattering function ``Observables``.
     |      If using FFT, then 't' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 't' and 'Q'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  FQt
     |
     |  errors
     |      Get or set the errors on the dependent variables, the intermediate
     |      scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and time t (in ``fs``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  t
     |      Get or set the times of the intermediate scattering function in units of
     |      ``fs``
     |
     |      Returns
     |      -------
     |      numpy.array
     |          1D array of times in ``fs``
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    IncoherentDynamicStructureFactor = class SQwIncoherent(AbstractSQw)
     |  A class for the incoherent dynamic structure factor
     |
     |  Method resolution order:
     |      SQwIncoherent
     |      AbstractSQw
     |      SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'SQw_incoh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractSQw:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_dt(self) -> float
     |      Calculates the time separation of frames required by the experimental
     |      dataset, assuming uniform spacing. Note that this may be different from
     |      the time separation that the user has given as an input, as it only
     |      depends on the current values for ``self.E``. The relationship between
     |      time and energy comes from the numpy implementation of the FFT for
     |      ``2 * nE`` points where:
     |
     |      .. math::
     |          \nu_{max} &=& \frac{n_E - 1}{2 n_E \Delta t} \\\\
     |          \therefore \Delta t &=& \frac{h (n_E - 1)}{2 n_E E_{max}}
     |
     |      Returns
     |      -------
     |      float
     |          The time separation required by the current values of ``self.E``
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the dynamic structure factor, S(Q, w) from a ``CompactTrajectory``.
     |
     |      If the ``CompactTrajectory`` has more frames than the ``self.maximum_frames()``
     |      that can be used to recreate the grid of energy points, it can slice the
     |      ``CompactTrajectory`` into sub-trajectories of length ``self.maximum_frames()``,
     |      with the slicing specified through the settings ``use_average`` and ``cont_slicing``.
     |
     |      The ``independent_variable`` ``Q`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          An MDMC ``CompactTrajectory`` from which to calculate ``SQw``
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |          ``energy_resolution` (`dict`)
     |              Optionally specify energy resolution and function in units of ueV (micro eV),
     |              in the format of the one-line dict {'function': value}, where `function`
     |              is the resolution function and `value` is the desired `FWHM`.
     |              e.g. to pass a Gaussian resolution of 80ueV we use {'gaussian': 80}.
     |              Currently accepted functions are 'gaussian' and 'lorentzian'
     |              Can also be 'lazily' given as `float`, in which case it is assumed to be Gaussian.
     |          ``Q_values`` (`array`)
     |              1D array of Q `float` (in ``Ang^-1``). (optional)
     |          ``use_average`` (`bool`)
     |              Optional parameter if a list of more than one ``Trajectory`` is used. If set to
     |              True (default) then the mean value for S(Q, w) is calculated. Also, the errors
     |              are set to the standard deviation calculated over the list of
     |              ``CompactTrajectory`` objects.
     |           ``cont_slicing`` (`bool`)
     |              Flag to decide between two possible behaviours when the number of ``MD_steps`` is
     |              larger than the minimum required to calculate the observables. If ``False``
     |              (default) then the ``CompactTrajectory`` is sliced into non-overlapping
     |              sub-``CompactTrajectory`` blocks for each of which the observable is calculated.
     |              If ``True``, then the ``CompactTrajectory`` is sliced into as many non-identical
     |              sub-``CompactTrajectory`` blocks as possible (with overlap allowed).
     |
     |  calculate_resolution_functions(self, dt: float) -> dict
     |      Generates a resolution function in momentum and time that can be used in the calculation of
     |      SQw. Note that this uses the ``SQw`` values of the ``Observable`` it is called from, and so
     |      should only be called for an observable which has been created from relevant resolution
     |      data, i.e. a vanadium sample.
     |
     |      Note that if this resolution function is used on data outside its original range, then it
     |      will use nearest neighbour extrapolation. Additionally, the input will be reflected in the
     |      time/energy domain as symmetry about 0 is assumed. If for whatever reason this is not
     |      appropriate for the data in question, this function should not be used.
     |
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          The time spacing to use when performing the inverse Fourier transform in units of `fs`.
     |          Ideally this should be the same as the frame separation expected when applying this
     |          function.
     |
     |      Returns
     |      -------
     |      dict
     |          A dictionary with the key 'SQw' corresponding to function which accepts arrays of time
     |          and momentum (respectively) and returns a 2D array of values for the instrument
     |          resolution.
     |
     |  validate_energy(self, dt: float) -> None
     |      Asserts that the user set frame separation ``dt`` leads to energy
     |      separation that matches that of the experiment. If not, it
     |      includes the time separation required in the error.
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          Frame separation in ``fs``
     |
     |      Returns
     |      -------
     |      None
     |
     |      Raises
     |      ------
     |      AssertionError
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from AbstractSQw:
     |
     |  calculate_E(nE: int, dt: float) -> numpy.ndarray
     |      Calculates an array of ``nE`` uniformly spaced energy values from the
     |      time separation of the ``CompactTrajectory`` frames, ``dt``. The
     |      frequencie are determined by the Fast Fourier Transform, as implemented
     |      by numpy, for ``2 * nE`` points in time which we then crop to only
     |      include ``nE`` positive frequencies. As we are dealing with frequency
     |      rather than angular frequency here, the relation to between energy
     |      is given by:
     |
     |      .. math::
     |
     |          E = h \nu
     |
     |      Parameters
     |      ----------
     |      nE : int
     |          The number of energy values to be calculated
     |      dt : float
     |          The step size between frames in ``fs``
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          An ``array`` of `float` specifying the energy in units of ``meV``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractSQw:
     |
     |  E
     |
     |  SQw
     |
     |  SQw_err
     |
     |  dependent_variables
     |      Get the dependent variables: this is SQw, the
     |      dynamic structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'SQw' dependent variable is indexed in terms of 'Q' and 'E'.
     |      Explicitly: we have that self.SQw[Q_index, E_index] is the data point for
     |      given indices of self.Q and self.E
     |      It also means that:
     |      np.shape(self.SQw)=(np.size(self.Q), np.size(self.E))
     |
     |      The purpose of this method is to ensure consistency
     |      between different readers/methods which create ``SQw`` objects.
     |
     |      Return
     |      ------
     |      Dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the energy 'E' and reciprocal
     |      lattice points 'Q' within the dynamic structure factor ``Observables``.
     |      If using FFT, then 'E' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      Dict[str, Dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'E' and 'Q'.
     |
     |  w
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractSQw:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the dynamic
     |      structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and energy E (in``meV``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    IncoherentIntermediateScatteringFunction = class FQtIncoherent(MDMC.trajectory_analysis.observables.fqt.AbstractFQt)
     |  A class for containing, calculating and reading the intermediate scattering
     |  function for the incoherent dynamic structure factor
     |
     |  Method resolution order:
     |      FQtIncoherent
     |      MDMC.trajectory_analysis.observables.fqt.AbstractFQt
     |      MDMC.trajectory_analysis.observables.sqw.SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'IncoherentIntermediateScatteringFunction'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  apply_resolution(self, resolution: MDMC.resolution.resolution.Resolution) -> 'FQt'
     |      Apply instrument resolution to an FQt object.
     |
     |      Parameters
     |      ----------
     |      resolution: Resolution
     |          The Resolution object to apply to FQt.
     |
     |      Returns
     |      -------
     |      The FQt object with resolution applied.
     |
     |  calculate_SQw(self, energy: 'list[float]', resolution: MDMC.resolution.resolution.Resolution = None) -> 'np.ndarray'
     |      Calculates S(Q, w) from F(Q, t), accounting for instrument resolution.
     |
     |      In order to obtain ``len(energy)`` values in energy, we reflect the
     |      intermediate scattering function in time to give it dimensions of
     |      ``(len(self.Q), 2 * (len(self.t)) - 2)``. This uses the fact it is even
     |      in time, and the number of time points is chosen to be 1 greater than
     |      the number of energy points [Rapaport, The Art of Molecular Dynamics
     |      Simulation (2nd Edition), 2004, page 142].
     |
     |      The numpy implementation of the FFT gives frequencies arranged so that
     |      the first ``len(energy)`` points in the energy dimension correspond to
     |      positive frequencies, and the remaining points have negative frequency.
     |
     |      Parameters
     |      ----------
     |      energy: list of floats
     |          the list of energy (E) points at which S(Q, w) will be calculated.
     |      resolution: Resolution (default None)
     |          The instrument resolution object which will be applied to FQt.
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          The S(Q, w) calculated from F(Q, t)
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict) -> None
     |      Calculates the intermediate scattering function from a trajectory.
     |
     |      ``independent_variables`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          a single ``CompactTrajectory`` object.
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  dependent_variables
     |      Get the dependent variables: this is
     |      FQt, the intermediate scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'FQt' dependent variable is indexed in terms of 'Q' and 't'.
     |      Explicitly: we have that self.FQt[Q_index, t_index] is the data point
     |      for given indices of self.Q and self.t
     |      It also means that:
     |      np.shape(self.FQt)=(np.size(self.Q), np.size(self.t))
     |
     |      The purpose of this method is to ensure consistency between
     |      different readers/methods which create ``FQt`` objects.
     |
     |      Return
     |      ------
     |      dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the time 't' and reciprocal
     |      lattice points 'Q' within the intermediate scattering function ``Observables``.
     |      If using FFT, then 't' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 't' and 'Q'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.fqt.AbstractFQt:
     |
     |  FQt
     |
     |  errors
     |      Get or set the errors on the dependent variables, the intermediate
     |      scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and time t (in ``fs``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  t
     |      Get or set the times of the intermediate scattering function in units of
     |      ``fs``
     |
     |      Returns
     |      -------
     |      numpy.array
     |          1D array of times in ``fs``
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    IntermediateScatteringFunction = class FQt(AbstractFQt)
     |  A class for containing, calculating and reading the intermediate scattering
     |  function for the total dynamic structure factor
     |
     |  Method resolution order:
     |      FQt
     |      AbstractFQt
     |      MDMC.trajectory_analysis.observables.sqw.SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'IntermediateScatteringFunction'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractFQt:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  apply_resolution(self, resolution: MDMC.resolution.resolution.Resolution) -> 'FQt'
     |      Apply instrument resolution to an FQt object.
     |
     |      Parameters
     |      ----------
     |      resolution: Resolution
     |          The Resolution object to apply to FQt.
     |
     |      Returns
     |      -------
     |      The FQt object with resolution applied.
     |
     |  calculate_SQw(self, energy: 'list[float]', resolution: MDMC.resolution.resolution.Resolution = None) -> 'np.ndarray'
     |      Calculates S(Q, w) from F(Q, t), accounting for instrument resolution.
     |
     |      In order to obtain ``len(energy)`` values in energy, we reflect the
     |      intermediate scattering function in time to give it dimensions of
     |      ``(len(self.Q), 2 * (len(self.t)) - 2)``. This uses the fact it is even
     |      in time, and the number of time points is chosen to be 1 greater than
     |      the number of energy points [Rapaport, The Art of Molecular Dynamics
     |      Simulation (2nd Edition), 2004, page 142].
     |
     |      The numpy implementation of the FFT gives frequencies arranged so that
     |      the first ``len(energy)`` points in the energy dimension correspond to
     |      positive frequencies, and the remaining points have negative frequency.
     |
     |      Parameters
     |      ----------
     |      energy: list of floats
     |          the list of energy (E) points at which S(Q, w) will be calculated.
     |      resolution: Resolution (default None)
     |          The instrument resolution object which will be applied to FQt.
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          The S(Q, w) calculated from F(Q, t)
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict) -> None
     |      Calculates the intermediate scattering function from a trajectory.
     |
     |      ``independent_variables`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          a single ``CompactTrajectory`` object.
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractFQt:
     |
     |  dependent_variables
     |      Get the dependent variables: this is
     |      FQt, the intermediate scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'FQt' dependent variable is indexed in terms of 'Q' and 't'.
     |      Explicitly: we have that self.FQt[Q_index, t_index] is the data point
     |      for given indices of self.Q and self.t
     |      It also means that:
     |      np.shape(self.FQt)=(np.size(self.Q), np.size(self.t))
     |
     |      The purpose of this method is to ensure consistency between
     |      different readers/methods which create ``FQt`` objects.
     |
     |      Return
     |      ------
     |      dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the time 't' and reciprocal
     |      lattice points 'Q' within the intermediate scattering function ``Observables``.
     |      If using FFT, then 't' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 't' and 'Q'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractFQt:
     |
     |  FQt
     |
     |  errors
     |      Get or set the errors on the dependent variables, the intermediate
     |      scattering function (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and time t (in ``fs``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  t
     |      Get or set the times of the intermediate scattering function in units of
     |      ``fs``
     |
     |      Returns
     |      -------
     |      numpy.array
     |          1D array of times in ``fs``
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    PDF = class PairDistributionFunction(MDMC.trajectory_analysis.observables.obs.Observable)
     |  A class for containing, calculating and reading a pair distribution function (PDF).
     |
     |  We derive our definitions for this from the following publication:
     |  "A comparison of various commonly used correlation functions for describing total scattering"
     |  Keen, D. A. (2001). J. Appl. Cryst. 34, 172-177.
     |  DOI: https://doi.org/10.1107/S0021889800019993
     |
     |  We employ the following mathematical form for the total pair distribution function (``PDF``):
     |
     |      .. math::
     |
     |          G(r) = \sum_{i,j}^{N_{elements}} c_ic_jb_ib_j(g_{ij}(r) - 1)
     |
     |
     |      where :math:`c_i` is the number concentration of element :math:`i`,
     |      :math:`b_i` is the (coherent) scattering length of element :math:`i`.
     |      (This corresponds to equation 8 in the above publication)
     |
     |
     |  The partial pair distribution, :math:`g_{ij}`, is:
     |
     |      .. math::
     |
     |          g_{ij}(r) = \frac{h_{ij}(r)}{4 \pi r^2 \rho_{j} \Delta{r}}
     |
     |      where :math:`h_{ij}`` is the histogram of distances of :math:`j` element
     |      atoms around atoms of element :math:`i`, with bins of size
     |      :math:`\Delta{r}`, and :math:`\rho_{j}` is the number density of
     |      atoms of element :math:`j`. As :math:`g_{ij}(0) = 0`, it is evident that
     |      :math:`G(0) = -\sum_{i,j}^{N_{elements}} c_ic_jb_ib_j`.
     |      (This corresponds to equation 10 in the above publication)
     |
     |  The total PDF is contained in ``PDF`` and the partial pair PDFs (if calculated or imported)
     |  are contained in ``partial_pdfs``.
     |
     |  Method resolution order:
     |      PairDistributionFunction
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the pair distribution function, :math:`G(r)`` from a
     |      ``CompactTrajectory``
     |
     |      The partial pair distribution for a pair i-j, :math:`g_{ij}`, is:
     |
     |      .. math::
     |
     |          g_{ij}(r) = \frac{h_{ij}(r)}{4 \pi r^2 \rho_{j} \Delta{r}}
     |
     |      where :math:`h_{ij}`` is the histogram of distances of :math:`j` element
     |      atoms around atoms of element :math:`i`, with bins of size
     |      :math:`\Delta{r}`, and :math:`\rho_{j}` is the number density of
     |      atoms of element :math:`j`. As :math:`g_{ij}(0) = 0`, it is evident that
     |      :math:`G(0) = -\sum_{i,j}^{N_{elements}} c_ic_jb_ib_j`.
     |
     |      This corresponds to the equation (8) in the following paper:
     |      "A comparison of various commonly used correlation functions for
     |       describing total scattering"
     |      Keen, D. A. (2001). J. Appl. Cryst. 34, 172-177.
     |      DOI: https://doi.org/10.1107/S0021889800019993
     |
     |      The total pair distribution function (``pdf.PDF``) has the form:
     |
     |      .. math::
     |
     |          G(r) = \sum_{i,j}^{N_{elements}} c_ic_jb_ib_j(g_{ij}(r) - 1)
     |
     |      where :math:`c_i` is the proportion of element :math:`i` in the material,
     |      :math:`b_i` is the (coherent) scattering length of element :math:`i`
     |
     |      This corresponds to the equation (10) in the above paper.
     |
     |      Independent variables can either be set previously or defined within
     |      settings.
     |
     |      A number of frames can be specified, from which the ``PDF`` and its
     |      error are calculated. If the number of frames is too large relative to
     |      the run length, the samples will be correlated, which will result in an
     |      underestimate of the error.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |           A single ``CompactTrajectory`` object.
     |      verbose: int
     |          Verbose print settings. Not currently implemented for PDF.
     |      **settings
     |          n_frames : int
     |              The number of frames from which the pdf and its error are
     |              calculated. These frames are selected uniformly, and the step is taken to be
     |              n_frames / total number of frames rounded to the nearest positive integer.
     |              If this is not passed, 1% of the total number of frames are used
     |              (rounded up to the nearest positive integer).
     |          use_average : bool
     |              Optional parameter. If set to True then the mean value for PDF is
     |              calculated across selected frames from the trajectory. Also, the errors
     |              are set to the standard deviation calculated over the multiple frames.
     |              If set to False (default), only the last frame of the trajectory is used and
     |              n_frames will be ignored.
     |          subset : list of tuples
     |              The subset of element pairs from which the PDF is calculated.
     |              This can be used to calculate the partial PDFs of a
     |              multicomponent system. If this is not passed, all combinations
     |              of elements are used i.e. the PDF is the total PDF.
     |          b_coh : dict
     |              A dictionary containing coherent scattering length values for one or more elements.
     |              This can be used to calculate the PDF of a system where one or more elements
     |              has a coherent scattering length different from the coherent scattering length in
     |              MDMC.common.atom_properties (i.e. if it has been isotopically substituted).
     |          r_min : float
     |              The minimum ``r`` (atomic separation) in Angstrom for which the PDF will be
     |              calculated. If this, ``r_max``, and ``r_step`` are passed then
     |              these will create a range for the independent variable ``r``,
     |              which will overwrite any ``r`` which has previously been
     |              defined. This cannot be passed if ``r`` is passed.
     |          r_max : float
     |              The maximum ``r`` (atomic separation) in Angstrom for which the PDF will be
     |              calculated. If this, ``r_min``, and ``r_step`` are passed then
     |              these will create a range for the independent variable ``r``,
     |              which will overwrite any ``r`` which has previously been
     |              defined. This cannot be passed if ``r`` is passed.
     |          r_step : float
     |              The step size of ``r`` (atomic separation) for which the PDF
     |              will be calculated. If this, ``r_min``, and ``r_max`` are passed
     |              then these will create a range for the independent variable
     |              ``r``, which will overwrite any ``r`` which has previously been
     |              defined. This cannot be passed if ``r`` is passed.
     |          r : numpy.ndarray
     |              The uniform ``r`` values in Angstrom for which the PDF will be calculated.
     |              This cannot be passed if ``r_min``, ``r_max``, and ``r_step``
     |              are passed.
     |          dimensions : array-like
     |              A 3 element `array-like` (`list`, `tuple`) with the dimensions
     |              of the ``Universe`` in Angstrom.
     |
     |
     |      Examples
     |      --------
     |      To calculate the O-O partial PDF from a simulation of water, use the
     |      subset keyword:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, subset=[(O, O)])
     |
     |      To calculate the sum of the H-O and O-O partial PDFs:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, subset=[(O, O), (H, O)])
     |
     |      To calculate the total PDF for sodium chloride with 37Cl:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, b_coh={'Cl':3.08})
     |
     |      To calculate the total PDF for r values of [1., 2., 3., 4.]:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, r=[1., 2., 3., 4.])
     |
     |      To calculate the total PDF over an average of 5 frames:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, use_average=True, n_frames=5)
     |
     |  maximum_frames(self) -> None
     |      There is no hard limit on the number of frames that can be used, so
     |      return None
     |
     |      Returns
     |      -------
     |      None
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to
     |      calculate the ``dependent_variables`` is 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`, not
     |          used
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  PDF
     |
     |  PDF_err
     |
     |  dependent_variables
     |      Get the dependent variables: these are PDF, the pair distribution function (in ``barn``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The shape of the 'PDF' dependent variable in terms of 'r'':
     |      np.shape(self.PDF)=(np.size(self.r))
     |
     |      Return
     |      ------
     |      dict
     |          The shape of the PDF dependent variable
     |
     |  uniformity_requirements
     |      Defines the current limitations on the atomic separation distance 'r'
     |      of the ``PairDistributionFunction`` ``Observable.
     |      The requirement is that 'r' must be uniform, but it does not have to start at zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'r'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the pair distribution function
     |      (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variable: this is
     |      the atomic separation distance r (in ``Ang``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  r
     |      Get or set the value of the atomic separation distance (in ``Ang``)
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'PairDistributionFunction'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    class PairDistributionFunction(MDMC.trajectory_analysis.observables.obs.Observable)
     |  A class for containing, calculating and reading a pair distribution function (PDF).
     |
     |  We derive our definitions for this from the following publication:
     |  "A comparison of various commonly used correlation functions for describing total scattering"
     |  Keen, D. A. (2001). J. Appl. Cryst. 34, 172-177.
     |  DOI: https://doi.org/10.1107/S0021889800019993
     |
     |  We employ the following mathematical form for the total pair distribution function (``PDF``):
     |
     |      .. math::
     |
     |          G(r) = \sum_{i,j}^{N_{elements}} c_ic_jb_ib_j(g_{ij}(r) - 1)
     |
     |
     |      where :math:`c_i` is the number concentration of element :math:`i`,
     |      :math:`b_i` is the (coherent) scattering length of element :math:`i`.
     |      (This corresponds to equation 8 in the above publication)
     |
     |
     |  The partial pair distribution, :math:`g_{ij}`, is:
     |
     |      .. math::
     |
     |          g_{ij}(r) = \frac{h_{ij}(r)}{4 \pi r^2 \rho_{j} \Delta{r}}
     |
     |      where :math:`h_{ij}`` is the histogram of distances of :math:`j` element
     |      atoms around atoms of element :math:`i`, with bins of size
     |      :math:`\Delta{r}`, and :math:`\rho_{j}` is the number density of
     |      atoms of element :math:`j`. As :math:`g_{ij}(0) = 0`, it is evident that
     |      :math:`G(0) = -\sum_{i,j}^{N_{elements}} c_ic_jb_ib_j`.
     |      (This corresponds to equation 10 in the above publication)
     |
     |  The total PDF is contained in ``PDF`` and the partial pair PDFs (if calculated or imported)
     |  are contained in ``partial_pdfs``.
     |
     |  Method resolution order:
     |      PairDistributionFunction
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Methods defined here:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the pair distribution function, :math:`G(r)`` from a
     |      ``CompactTrajectory``
     |
     |      The partial pair distribution for a pair i-j, :math:`g_{ij}`, is:
     |
     |      .. math::
     |
     |          g_{ij}(r) = \frac{h_{ij}(r)}{4 \pi r^2 \rho_{j} \Delta{r}}
     |
     |      where :math:`h_{ij}`` is the histogram of distances of :math:`j` element
     |      atoms around atoms of element :math:`i`, with bins of size
     |      :math:`\Delta{r}`, and :math:`\rho_{j}` is the number density of
     |      atoms of element :math:`j`. As :math:`g_{ij}(0) = 0`, it is evident that
     |      :math:`G(0) = -\sum_{i,j}^{N_{elements}} c_ic_jb_ib_j`.
     |
     |      This corresponds to the equation (8) in the following paper:
     |      "A comparison of various commonly used correlation functions for
     |       describing total scattering"
     |      Keen, D. A. (2001). J. Appl. Cryst. 34, 172-177.
     |      DOI: https://doi.org/10.1107/S0021889800019993
     |
     |      The total pair distribution function (``pdf.PDF``) has the form:
     |
     |      .. math::
     |
     |          G(r) = \sum_{i,j}^{N_{elements}} c_ic_jb_ib_j(g_{ij}(r) - 1)
     |
     |      where :math:`c_i` is the proportion of element :math:`i` in the material,
     |      :math:`b_i` is the (coherent) scattering length of element :math:`i`
     |
     |      This corresponds to the equation (10) in the above paper.
     |
     |      Independent variables can either be set previously or defined within
     |      settings.
     |
     |      A number of frames can be specified, from which the ``PDF`` and its
     |      error are calculated. If the number of frames is too large relative to
     |      the run length, the samples will be correlated, which will result in an
     |      underestimate of the error.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |           A single ``CompactTrajectory`` object.
     |      verbose: int
     |          Verbose print settings. Not currently implemented for PDF.
     |      **settings
     |          n_frames : int
     |              The number of frames from which the pdf and its error are
     |              calculated. These frames are selected uniformly, and the step is taken to be
     |              n_frames / total number of frames rounded to the nearest positive integer.
     |              If this is not passed, 1% of the total number of frames are used
     |              (rounded up to the nearest positive integer).
     |          use_average : bool
     |              Optional parameter. If set to True then the mean value for PDF is
     |              calculated across selected frames from the trajectory. Also, the errors
     |              are set to the standard deviation calculated over the multiple frames.
     |              If set to False (default), only the last frame of the trajectory is used and
     |              n_frames will be ignored.
     |          subset : list of tuples
     |              The subset of element pairs from which the PDF is calculated.
     |              This can be used to calculate the partial PDFs of a
     |              multicomponent system. If this is not passed, all combinations
     |              of elements are used i.e. the PDF is the total PDF.
     |          b_coh : dict
     |              A dictionary containing coherent scattering length values for one or more elements.
     |              This can be used to calculate the PDF of a system where one or more elements
     |              has a coherent scattering length different from the coherent scattering length in
     |              MDMC.common.atom_properties (i.e. if it has been isotopically substituted).
     |          r_min : float
     |              The minimum ``r`` (atomic separation) in Angstrom for which the PDF will be
     |              calculated. If this, ``r_max``, and ``r_step`` are passed then
     |              these will create a range for the independent variable ``r``,
     |              which will overwrite any ``r`` which has previously been
     |              defined. This cannot be passed if ``r`` is passed.
     |          r_max : float
     |              The maximum ``r`` (atomic separation) in Angstrom for which the PDF will be
     |              calculated. If this, ``r_min``, and ``r_step`` are passed then
     |              these will create a range for the independent variable ``r``,
     |              which will overwrite any ``r`` which has previously been
     |              defined. This cannot be passed if ``r`` is passed.
     |          r_step : float
     |              The step size of ``r`` (atomic separation) for which the PDF
     |              will be calculated. If this, ``r_min``, and ``r_max`` are passed
     |              then these will create a range for the independent variable
     |              ``r``, which will overwrite any ``r`` which has previously been
     |              defined. This cannot be passed if ``r`` is passed.
     |          r : numpy.ndarray
     |              The uniform ``r`` values in Angstrom for which the PDF will be calculated.
     |              This cannot be passed if ``r_min``, ``r_max``, and ``r_step``
     |              are passed.
     |          dimensions : array-like
     |              A 3 element `array-like` (`list`, `tuple`) with the dimensions
     |              of the ``Universe`` in Angstrom.
     |
     |
     |      Examples
     |      --------
     |      To calculate the O-O partial PDF from a simulation of water, use the
     |      subset keyword:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, subset=[(O, O)])
     |
     |      To calculate the sum of the H-O and O-O partial PDFs:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, subset=[(O, O), (H, O)])
     |
     |      To calculate the total PDF for sodium chloride with 37Cl:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, b_coh={'Cl':3.08})
     |
     |      To calculate the total PDF for r values of [1., 2., 3., 4.]:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, r=[1., 2., 3., 4.])
     |
     |      To calculate the total PDF over an average of 5 frames:
     |
     |          .. highlight:: python
     |          .. code-block:: python
     |
     |          pdf.calculate_from_MD(trajectory, use_average=True, n_frames=5)
     |
     |  maximum_frames(self) -> None
     |      There is no hard limit on the number of frames that can be used, so
     |      return None
     |
     |      Returns
     |      -------
     |      None
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to
     |      calculate the ``dependent_variables`` is 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`, not
     |          used
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties defined here:
     |
     |  PDF
     |
     |  PDF_err
     |
     |  dependent_variables
     |      Get the dependent variables: these are PDF, the pair distribution function (in ``barn``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The shape of the 'PDF' dependent variable in terms of 'r'':
     |      np.shape(self.PDF)=(np.size(self.r))
     |
     |      Return
     |      ------
     |      dict
     |          The shape of the PDF dependent variable
     |
     |  uniformity_requirements
     |      Defines the current limitations on the atomic separation distance 'r'
     |      of the ``PairDistributionFunction`` ``Observable.
     |      The requirement is that 'r' must be uniform, but it does not have to start at zero.
     |
     |      Return
     |      ------
     |      dict[str, dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'r'.
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors defined here:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the pair distribution function
     |      (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variable: this is
     |      the atomic separation distance r (in ``Ang``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  r
     |      Get or set the value of the atomic separation distance (in ``Ang``)
     |
     |  ----------------------------------------------------------------------
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'PairDistributionFunction'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    class SQw(AbstractSQw)
     |  A class for the total dynamic structure factor
     |
     |  Calculation is done in the respective FQt object, and this is
     |  just a reference to get the correct FQt object.
     |
     |  Method resolution order:
     |      SQw
     |      AbstractSQw
     |      SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'SQw'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractSQw:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_dt(self) -> float
     |      Calculates the time separation of frames required by the experimental
     |      dataset, assuming uniform spacing. Note that this may be different from
     |      the time separation that the user has given as an input, as it only
     |      depends on the current values for ``self.E``. The relationship between
     |      time and energy comes from the numpy implementation of the FFT for
     |      ``2 * nE`` points where:
     |
     |      .. math::
     |          \nu_{max} &=& \frac{n_E - 1}{2 n_E \Delta t} \\\\
     |          \therefore \Delta t &=& \frac{h (n_E - 1)}{2 n_E E_{max}}
     |
     |      Returns
     |      -------
     |      float
     |          The time separation required by the current values of ``self.E``
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the dynamic structure factor, S(Q, w) from a ``CompactTrajectory``.
     |
     |      If the ``CompactTrajectory`` has more frames than the ``self.maximum_frames()``
     |      that can be used to recreate the grid of energy points, it can slice the
     |      ``CompactTrajectory`` into sub-trajectories of length ``self.maximum_frames()``,
     |      with the slicing specified through the settings ``use_average`` and ``cont_slicing``.
     |
     |      The ``independent_variable`` ``Q`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          An MDMC ``CompactTrajectory`` from which to calculate ``SQw``
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |          ``energy_resolution` (`dict`)
     |              Optionally specify energy resolution and function in units of ueV (micro eV),
     |              in the format of the one-line dict {'function': value}, where `function`
     |              is the resolution function and `value` is the desired `FWHM`.
     |              e.g. to pass a Gaussian resolution of 80ueV we use {'gaussian': 80}.
     |              Currently accepted functions are 'gaussian' and 'lorentzian'
     |              Can also be 'lazily' given as `float`, in which case it is assumed to be Gaussian.
     |          ``Q_values`` (`array`)
     |              1D array of Q `float` (in ``Ang^-1``). (optional)
     |          ``use_average`` (`bool`)
     |              Optional parameter if a list of more than one ``Trajectory`` is used. If set to
     |              True (default) then the mean value for S(Q, w) is calculated. Also, the errors
     |              are set to the standard deviation calculated over the list of
     |              ``CompactTrajectory`` objects.
     |           ``cont_slicing`` (`bool`)
     |              Flag to decide between two possible behaviours when the number of ``MD_steps`` is
     |              larger than the minimum required to calculate the observables. If ``False``
     |              (default) then the ``CompactTrajectory`` is sliced into non-overlapping
     |              sub-``CompactTrajectory`` blocks for each of which the observable is calculated.
     |              If ``True``, then the ``CompactTrajectory`` is sliced into as many non-identical
     |              sub-``CompactTrajectory`` blocks as possible (with overlap allowed).
     |
     |  calculate_resolution_functions(self, dt: float) -> dict
     |      Generates a resolution function in momentum and time that can be used in the calculation of
     |      SQw. Note that this uses the ``SQw`` values of the ``Observable`` it is called from, and so
     |      should only be called for an observable which has been created from relevant resolution
     |      data, i.e. a vanadium sample.
     |
     |      Note that if this resolution function is used on data outside its original range, then it
     |      will use nearest neighbour extrapolation. Additionally, the input will be reflected in the
     |      time/energy domain as symmetry about 0 is assumed. If for whatever reason this is not
     |      appropriate for the data in question, this function should not be used.
     |
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          The time spacing to use when performing the inverse Fourier transform in units of `fs`.
     |          Ideally this should be the same as the frame separation expected when applying this
     |          function.
     |
     |      Returns
     |      -------
     |      dict
     |          A dictionary with the key 'SQw' corresponding to function which accepts arrays of time
     |          and momentum (respectively) and returns a 2D array of values for the instrument
     |          resolution.
     |
     |  validate_energy(self, dt: float) -> None
     |      Asserts that the user set frame separation ``dt`` leads to energy
     |      separation that matches that of the experiment. If not, it
     |      includes the time separation required in the error.
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          Frame separation in ``fs``
     |
     |      Returns
     |      -------
     |      None
     |
     |      Raises
     |      ------
     |      AssertionError
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from AbstractSQw:
     |
     |  calculate_E(nE: int, dt: float) -> numpy.ndarray
     |      Calculates an array of ``nE`` uniformly spaced energy values from the
     |      time separation of the ``CompactTrajectory`` frames, ``dt``. The
     |      frequencie are determined by the Fast Fourier Transform, as implemented
     |      by numpy, for ``2 * nE`` points in time which we then crop to only
     |      include ``nE`` positive frequencies. As we are dealing with frequency
     |      rather than angular frequency here, the relation to between energy
     |      is given by:
     |
     |      .. math::
     |
     |          E = h \nu
     |
     |      Parameters
     |      ----------
     |      nE : int
     |          The number of energy values to be calculated
     |      dt : float
     |          The step size between frames in ``fs``
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          An ``array`` of `float` specifying the energy in units of ``meV``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractSQw:
     |
     |  E
     |
     |  SQw
     |
     |  SQw_err
     |
     |  dependent_variables
     |      Get the dependent variables: this is SQw, the
     |      dynamic structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'SQw' dependent variable is indexed in terms of 'Q' and 'E'.
     |      Explicitly: we have that self.SQw[Q_index, E_index] is the data point for
     |      given indices of self.Q and self.E
     |      It also means that:
     |      np.shape(self.SQw)=(np.size(self.Q), np.size(self.E))
     |
     |      The purpose of this method is to ensure consistency
     |      between different readers/methods which create ``SQw`` objects.
     |
     |      Return
     |      ------
     |      Dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the energy 'E' and reciprocal
     |      lattice points 'Q' within the dynamic structure factor ``Observables``.
     |      If using FFT, then 'E' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      Dict[str, Dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'E' and 'Q'.
     |
     |  w
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractSQw:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the dynamic
     |      structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and energy E (in``meV``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    SQwCoh = class SQwCoherent(AbstractSQw)
     |  A class for the coherent dynamic structure factor
     |
     |  Method resolution order:
     |      SQwCoherent
     |      AbstractSQw
     |      SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'SQw_coh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractSQw:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_dt(self) -> float
     |      Calculates the time separation of frames required by the experimental
     |      dataset, assuming uniform spacing. Note that this may be different from
     |      the time separation that the user has given as an input, as it only
     |      depends on the current values for ``self.E``. The relationship between
     |      time and energy comes from the numpy implementation of the FFT for
     |      ``2 * nE`` points where:
     |
     |      .. math::
     |          \nu_{max} &=& \frac{n_E - 1}{2 n_E \Delta t} \\\\
     |          \therefore \Delta t &=& \frac{h (n_E - 1)}{2 n_E E_{max}}
     |
     |      Returns
     |      -------
     |      float
     |          The time separation required by the current values of ``self.E``
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the dynamic structure factor, S(Q, w) from a ``CompactTrajectory``.
     |
     |      If the ``CompactTrajectory`` has more frames than the ``self.maximum_frames()``
     |      that can be used to recreate the grid of energy points, it can slice the
     |      ``CompactTrajectory`` into sub-trajectories of length ``self.maximum_frames()``,
     |      with the slicing specified through the settings ``use_average`` and ``cont_slicing``.
     |
     |      The ``independent_variable`` ``Q`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          An MDMC ``CompactTrajectory`` from which to calculate ``SQw``
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |          ``energy_resolution` (`dict`)
     |              Optionally specify energy resolution and function in units of ueV (micro eV),
     |              in the format of the one-line dict {'function': value}, where `function`
     |              is the resolution function and `value` is the desired `FWHM`.
     |              e.g. to pass a Gaussian resolution of 80ueV we use {'gaussian': 80}.
     |              Currently accepted functions are 'gaussian' and 'lorentzian'
     |              Can also be 'lazily' given as `float`, in which case it is assumed to be Gaussian.
     |          ``Q_values`` (`array`)
     |              1D array of Q `float` (in ``Ang^-1``). (optional)
     |          ``use_average`` (`bool`)
     |              Optional parameter if a list of more than one ``Trajectory`` is used. If set to
     |              True (default) then the mean value for S(Q, w) is calculated. Also, the errors
     |              are set to the standard deviation calculated over the list of
     |              ``CompactTrajectory`` objects.
     |           ``cont_slicing`` (`bool`)
     |              Flag to decide between two possible behaviours when the number of ``MD_steps`` is
     |              larger than the minimum required to calculate the observables. If ``False``
     |              (default) then the ``CompactTrajectory`` is sliced into non-overlapping
     |              sub-``CompactTrajectory`` blocks for each of which the observable is calculated.
     |              If ``True``, then the ``CompactTrajectory`` is sliced into as many non-identical
     |              sub-``CompactTrajectory`` blocks as possible (with overlap allowed).
     |
     |  calculate_resolution_functions(self, dt: float) -> dict
     |      Generates a resolution function in momentum and time that can be used in the calculation of
     |      SQw. Note that this uses the ``SQw`` values of the ``Observable`` it is called from, and so
     |      should only be called for an observable which has been created from relevant resolution
     |      data, i.e. a vanadium sample.
     |
     |      Note that if this resolution function is used on data outside its original range, then it
     |      will use nearest neighbour extrapolation. Additionally, the input will be reflected in the
     |      time/energy domain as symmetry about 0 is assumed. If for whatever reason this is not
     |      appropriate for the data in question, this function should not be used.
     |
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          The time spacing to use when performing the inverse Fourier transform in units of `fs`.
     |          Ideally this should be the same as the frame separation expected when applying this
     |          function.
     |
     |      Returns
     |      -------
     |      dict
     |          A dictionary with the key 'SQw' corresponding to function which accepts arrays of time
     |          and momentum (respectively) and returns a 2D array of values for the instrument
     |          resolution.
     |
     |  validate_energy(self, dt: float) -> None
     |      Asserts that the user set frame separation ``dt`` leads to energy
     |      separation that matches that of the experiment. If not, it
     |      includes the time separation required in the error.
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          Frame separation in ``fs``
     |
     |      Returns
     |      -------
     |      None
     |
     |      Raises
     |      ------
     |      AssertionError
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from AbstractSQw:
     |
     |  calculate_E(nE: int, dt: float) -> numpy.ndarray
     |      Calculates an array of ``nE`` uniformly spaced energy values from the
     |      time separation of the ``CompactTrajectory`` frames, ``dt``. The
     |      frequencie are determined by the Fast Fourier Transform, as implemented
     |      by numpy, for ``2 * nE`` points in time which we then crop to only
     |      include ``nE`` positive frequencies. As we are dealing with frequency
     |      rather than angular frequency here, the relation to between energy
     |      is given by:
     |
     |      .. math::
     |
     |          E = h \nu
     |
     |      Parameters
     |      ----------
     |      nE : int
     |          The number of energy values to be calculated
     |      dt : float
     |          The step size between frames in ``fs``
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          An ``array`` of `float` specifying the energy in units of ``meV``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractSQw:
     |
     |  E
     |
     |  SQw
     |
     |  SQw_err
     |
     |  dependent_variables
     |      Get the dependent variables: this is SQw, the
     |      dynamic structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'SQw' dependent variable is indexed in terms of 'Q' and 'E'.
     |      Explicitly: we have that self.SQw[Q_index, E_index] is the data point for
     |      given indices of self.Q and self.E
     |      It also means that:
     |      np.shape(self.SQw)=(np.size(self.Q), np.size(self.E))
     |
     |      The purpose of this method is to ensure consistency
     |      between different readers/methods which create ``SQw`` objects.
     |
     |      Return
     |      ------
     |      Dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the energy 'E' and reciprocal
     |      lattice points 'Q' within the dynamic structure factor ``Observables``.
     |      If using FFT, then 'E' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      Dict[str, Dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'E' and 'Q'.
     |
     |  w
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractSQw:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the dynamic
     |      structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and energy E (in``meV``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    class SQwCoherent(AbstractSQw)
     |  A class for the coherent dynamic structure factor
     |
     |  Method resolution order:
     |      SQwCoherent
     |      AbstractSQw
     |      SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'SQw_coh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractSQw:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_dt(self) -> float
     |      Calculates the time separation of frames required by the experimental
     |      dataset, assuming uniform spacing. Note that this may be different from
     |      the time separation that the user has given as an input, as it only
     |      depends on the current values for ``self.E``. The relationship between
     |      time and energy comes from the numpy implementation of the FFT for
     |      ``2 * nE`` points where:
     |
     |      .. math::
     |          \nu_{max} &=& \frac{n_E - 1}{2 n_E \Delta t} \\\\
     |          \therefore \Delta t &=& \frac{h (n_E - 1)}{2 n_E E_{max}}
     |
     |      Returns
     |      -------
     |      float
     |          The time separation required by the current values of ``self.E``
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the dynamic structure factor, S(Q, w) from a ``CompactTrajectory``.
     |
     |      If the ``CompactTrajectory`` has more frames than the ``self.maximum_frames()``
     |      that can be used to recreate the grid of energy points, it can slice the
     |      ``CompactTrajectory`` into sub-trajectories of length ``self.maximum_frames()``,
     |      with the slicing specified through the settings ``use_average`` and ``cont_slicing``.
     |
     |      The ``independent_variable`` ``Q`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          An MDMC ``CompactTrajectory`` from which to calculate ``SQw``
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |          ``energy_resolution` (`dict`)
     |              Optionally specify energy resolution and function in units of ueV (micro eV),
     |              in the format of the one-line dict {'function': value}, where `function`
     |              is the resolution function and `value` is the desired `FWHM`.
     |              e.g. to pass a Gaussian resolution of 80ueV we use {'gaussian': 80}.
     |              Currently accepted functions are 'gaussian' and 'lorentzian'
     |              Can also be 'lazily' given as `float`, in which case it is assumed to be Gaussian.
     |          ``Q_values`` (`array`)
     |              1D array of Q `float` (in ``Ang^-1``). (optional)
     |          ``use_average`` (`bool`)
     |              Optional parameter if a list of more than one ``Trajectory`` is used. If set to
     |              True (default) then the mean value for S(Q, w) is calculated. Also, the errors
     |              are set to the standard deviation calculated over the list of
     |              ``CompactTrajectory`` objects.
     |           ``cont_slicing`` (`bool`)
     |              Flag to decide between two possible behaviours when the number of ``MD_steps`` is
     |              larger than the minimum required to calculate the observables. If ``False``
     |              (default) then the ``CompactTrajectory`` is sliced into non-overlapping
     |              sub-``CompactTrajectory`` blocks for each of which the observable is calculated.
     |              If ``True``, then the ``CompactTrajectory`` is sliced into as many non-identical
     |              sub-``CompactTrajectory`` blocks as possible (with overlap allowed).
     |
     |  calculate_resolution_functions(self, dt: float) -> dict
     |      Generates a resolution function in momentum and time that can be used in the calculation of
     |      SQw. Note that this uses the ``SQw`` values of the ``Observable`` it is called from, and so
     |      should only be called for an observable which has been created from relevant resolution
     |      data, i.e. a vanadium sample.
     |
     |      Note that if this resolution function is used on data outside its original range, then it
     |      will use nearest neighbour extrapolation. Additionally, the input will be reflected in the
     |      time/energy domain as symmetry about 0 is assumed. If for whatever reason this is not
     |      appropriate for the data in question, this function should not be used.
     |
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          The time spacing to use when performing the inverse Fourier transform in units of `fs`.
     |          Ideally this should be the same as the frame separation expected when applying this
     |          function.
     |
     |      Returns
     |      -------
     |      dict
     |          A dictionary with the key 'SQw' corresponding to function which accepts arrays of time
     |          and momentum (respectively) and returns a 2D array of values for the instrument
     |          resolution.
     |
     |  validate_energy(self, dt: float) -> None
     |      Asserts that the user set frame separation ``dt`` leads to energy
     |      separation that matches that of the experiment. If not, it
     |      includes the time separation required in the error.
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          Frame separation in ``fs``
     |
     |      Returns
     |      -------
     |      None
     |
     |      Raises
     |      ------
     |      AssertionError
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from AbstractSQw:
     |
     |  calculate_E(nE: int, dt: float) -> numpy.ndarray
     |      Calculates an array of ``nE`` uniformly spaced energy values from the
     |      time separation of the ``CompactTrajectory`` frames, ``dt``. The
     |      frequencie are determined by the Fast Fourier Transform, as implemented
     |      by numpy, for ``2 * nE`` points in time which we then crop to only
     |      include ``nE`` positive frequencies. As we are dealing with frequency
     |      rather than angular frequency here, the relation to between energy
     |      is given by:
     |
     |      .. math::
     |
     |          E = h \nu
     |
     |      Parameters
     |      ----------
     |      nE : int
     |          The number of energy values to be calculated
     |      dt : float
     |          The step size between frames in ``fs``
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          An ``array`` of `float` specifying the energy in units of ``meV``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractSQw:
     |
     |  E
     |
     |  SQw
     |
     |  SQw_err
     |
     |  dependent_variables
     |      Get the dependent variables: this is SQw, the
     |      dynamic structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'SQw' dependent variable is indexed in terms of 'Q' and 'E'.
     |      Explicitly: we have that self.SQw[Q_index, E_index] is the data point for
     |      given indices of self.Q and self.E
     |      It also means that:
     |      np.shape(self.SQw)=(np.size(self.Q), np.size(self.E))
     |
     |      The purpose of this method is to ensure consistency
     |      between different readers/methods which create ``SQw`` objects.
     |
     |      Return
     |      ------
     |      Dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the energy 'E' and reciprocal
     |      lattice points 'Q' within the dynamic structure factor ``Observables``.
     |      If using FFT, then 'E' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      Dict[str, Dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'E' and 'Q'.
     |
     |  w
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractSQw:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the dynamic
     |      structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and energy E (in``meV``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    SQwIncoherentSQwIncoh = class SQwIncoherent(AbstractSQw)
     |  A class for the incoherent dynamic structure factor
     |
     |  Method resolution order:
     |      SQwIncoherent
     |      AbstractSQw
     |      SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'SQw_incoh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractSQw:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_dt(self) -> float
     |      Calculates the time separation of frames required by the experimental
     |      dataset, assuming uniform spacing. Note that this may be different from
     |      the time separation that the user has given as an input, as it only
     |      depends on the current values for ``self.E``. The relationship between
     |      time and energy comes from the numpy implementation of the FFT for
     |      ``2 * nE`` points where:
     |
     |      .. math::
     |          \nu_{max} &=& \frac{n_E - 1}{2 n_E \Delta t} \\\\
     |          \therefore \Delta t &=& \frac{h (n_E - 1)}{2 n_E E_{max}}
     |
     |      Returns
     |      -------
     |      float
     |          The time separation required by the current values of ``self.E``
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the dynamic structure factor, S(Q, w) from a ``CompactTrajectory``.
     |
     |      If the ``CompactTrajectory`` has more frames than the ``self.maximum_frames()``
     |      that can be used to recreate the grid of energy points, it can slice the
     |      ``CompactTrajectory`` into sub-trajectories of length ``self.maximum_frames()``,
     |      with the slicing specified through the settings ``use_average`` and ``cont_slicing``.
     |
     |      The ``independent_variable`` ``Q`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          An MDMC ``CompactTrajectory`` from which to calculate ``SQw``
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |          ``energy_resolution` (`dict`)
     |              Optionally specify energy resolution and function in units of ueV (micro eV),
     |              in the format of the one-line dict {'function': value}, where `function`
     |              is the resolution function and `value` is the desired `FWHM`.
     |              e.g. to pass a Gaussian resolution of 80ueV we use {'gaussian': 80}.
     |              Currently accepted functions are 'gaussian' and 'lorentzian'
     |              Can also be 'lazily' given as `float`, in which case it is assumed to be Gaussian.
     |          ``Q_values`` (`array`)
     |              1D array of Q `float` (in ``Ang^-1``). (optional)
     |          ``use_average`` (`bool`)
     |              Optional parameter if a list of more than one ``Trajectory`` is used. If set to
     |              True (default) then the mean value for S(Q, w) is calculated. Also, the errors
     |              are set to the standard deviation calculated over the list of
     |              ``CompactTrajectory`` objects.
     |           ``cont_slicing`` (`bool`)
     |              Flag to decide between two possible behaviours when the number of ``MD_steps`` is
     |              larger than the minimum required to calculate the observables. If ``False``
     |              (default) then the ``CompactTrajectory`` is sliced into non-overlapping
     |              sub-``CompactTrajectory`` blocks for each of which the observable is calculated.
     |              If ``True``, then the ``CompactTrajectory`` is sliced into as many non-identical
     |              sub-``CompactTrajectory`` blocks as possible (with overlap allowed).
     |
     |  calculate_resolution_functions(self, dt: float) -> dict
     |      Generates a resolution function in momentum and time that can be used in the calculation of
     |      SQw. Note that this uses the ``SQw`` values of the ``Observable`` it is called from, and so
     |      should only be called for an observable which has been created from relevant resolution
     |      data, i.e. a vanadium sample.
     |
     |      Note that if this resolution function is used on data outside its original range, then it
     |      will use nearest neighbour extrapolation. Additionally, the input will be reflected in the
     |      time/energy domain as symmetry about 0 is assumed. If for whatever reason this is not
     |      appropriate for the data in question, this function should not be used.
     |
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          The time spacing to use when performing the inverse Fourier transform in units of `fs`.
     |          Ideally this should be the same as the frame separation expected when applying this
     |          function.
     |
     |      Returns
     |      -------
     |      dict
     |          A dictionary with the key 'SQw' corresponding to function which accepts arrays of time
     |          and momentum (respectively) and returns a 2D array of values for the instrument
     |          resolution.
     |
     |  validate_energy(self, dt: float) -> None
     |      Asserts that the user set frame separation ``dt`` leads to energy
     |      separation that matches that of the experiment. If not, it
     |      includes the time separation required in the error.
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          Frame separation in ``fs``
     |
     |      Returns
     |      -------
     |      None
     |
     |      Raises
     |      ------
     |      AssertionError
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from AbstractSQw:
     |
     |  calculate_E(nE: int, dt: float) -> numpy.ndarray
     |      Calculates an array of ``nE`` uniformly spaced energy values from the
     |      time separation of the ``CompactTrajectory`` frames, ``dt``. The
     |      frequencie are determined by the Fast Fourier Transform, as implemented
     |      by numpy, for ``2 * nE`` points in time which we then crop to only
     |      include ``nE`` positive frequencies. As we are dealing with frequency
     |      rather than angular frequency here, the relation to between energy
     |      is given by:
     |
     |      .. math::
     |
     |          E = h \nu
     |
     |      Parameters
     |      ----------
     |      nE : int
     |          The number of energy values to be calculated
     |      dt : float
     |          The step size between frames in ``fs``
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          An ``array`` of `float` specifying the energy in units of ``meV``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractSQw:
     |
     |  E
     |
     |  SQw
     |
     |  SQw_err
     |
     |  dependent_variables
     |      Get the dependent variables: this is SQw, the
     |      dynamic structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'SQw' dependent variable is indexed in terms of 'Q' and 'E'.
     |      Explicitly: we have that self.SQw[Q_index, E_index] is the data point for
     |      given indices of self.Q and self.E
     |      It also means that:
     |      np.shape(self.SQw)=(np.size(self.Q), np.size(self.E))
     |
     |      The purpose of this method is to ensure consistency
     |      between different readers/methods which create ``SQw`` objects.
     |
     |      Return
     |      ------
     |      Dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the energy 'E' and reciprocal
     |      lattice points 'Q' within the dynamic structure factor ``Observables``.
     |      If using FFT, then 'E' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      Dict[str, Dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'E' and 'Q'.
     |
     |  w
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractSQw:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the dynamic
     |      structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and energy E (in``meV``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    SQw_coh = class SQwCoherent(AbstractSQw)
     |  A class for the coherent dynamic structure factor
     |
     |  Method resolution order:
     |      SQwCoherent
     |      AbstractSQw
     |      SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'SQw_coh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractSQw:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_dt(self) -> float
     |      Calculates the time separation of frames required by the experimental
     |      dataset, assuming uniform spacing. Note that this may be different from
     |      the time separation that the user has given as an input, as it only
     |      depends on the current values for ``self.E``. The relationship between
     |      time and energy comes from the numpy implementation of the FFT for
     |      ``2 * nE`` points where:
     |
     |      .. math::
     |          \nu_{max} &=& \frac{n_E - 1}{2 n_E \Delta t} \\\\
     |          \therefore \Delta t &=& \frac{h (n_E - 1)}{2 n_E E_{max}}
     |
     |      Returns
     |      -------
     |      float
     |          The time separation required by the current values of ``self.E``
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the dynamic structure factor, S(Q, w) from a ``CompactTrajectory``.
     |
     |      If the ``CompactTrajectory`` has more frames than the ``self.maximum_frames()``
     |      that can be used to recreate the grid of energy points, it can slice the
     |      ``CompactTrajectory`` into sub-trajectories of length ``self.maximum_frames()``,
     |      with the slicing specified through the settings ``use_average`` and ``cont_slicing``.
     |
     |      The ``independent_variable`` ``Q`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          An MDMC ``CompactTrajectory`` from which to calculate ``SQw``
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |          ``energy_resolution` (`dict`)
     |              Optionally specify energy resolution and function in units of ueV (micro eV),
     |              in the format of the one-line dict {'function': value}, where `function`
     |              is the resolution function and `value` is the desired `FWHM`.
     |              e.g. to pass a Gaussian resolution of 80ueV we use {'gaussian': 80}.
     |              Currently accepted functions are 'gaussian' and 'lorentzian'
     |              Can also be 'lazily' given as `float`, in which case it is assumed to be Gaussian.
     |          ``Q_values`` (`array`)
     |              1D array of Q `float` (in ``Ang^-1``). (optional)
     |          ``use_average`` (`bool`)
     |              Optional parameter if a list of more than one ``Trajectory`` is used. If set to
     |              True (default) then the mean value for S(Q, w) is calculated. Also, the errors
     |              are set to the standard deviation calculated over the list of
     |              ``CompactTrajectory`` objects.
     |           ``cont_slicing`` (`bool`)
     |              Flag to decide between two possible behaviours when the number of ``MD_steps`` is
     |              larger than the minimum required to calculate the observables. If ``False``
     |              (default) then the ``CompactTrajectory`` is sliced into non-overlapping
     |              sub-``CompactTrajectory`` blocks for each of which the observable is calculated.
     |              If ``True``, then the ``CompactTrajectory`` is sliced into as many non-identical
     |              sub-``CompactTrajectory`` blocks as possible (with overlap allowed).
     |
     |  calculate_resolution_functions(self, dt: float) -> dict
     |      Generates a resolution function in momentum and time that can be used in the calculation of
     |      SQw. Note that this uses the ``SQw`` values of the ``Observable`` it is called from, and so
     |      should only be called for an observable which has been created from relevant resolution
     |      data, i.e. a vanadium sample.
     |
     |      Note that if this resolution function is used on data outside its original range, then it
     |      will use nearest neighbour extrapolation. Additionally, the input will be reflected in the
     |      time/energy domain as symmetry about 0 is assumed. If for whatever reason this is not
     |      appropriate for the data in question, this function should not be used.
     |
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          The time spacing to use when performing the inverse Fourier transform in units of `fs`.
     |          Ideally this should be the same as the frame separation expected when applying this
     |          function.
     |
     |      Returns
     |      -------
     |      dict
     |          A dictionary with the key 'SQw' corresponding to function which accepts arrays of time
     |          and momentum (respectively) and returns a 2D array of values for the instrument
     |          resolution.
     |
     |  validate_energy(self, dt: float) -> None
     |      Asserts that the user set frame separation ``dt`` leads to energy
     |      separation that matches that of the experiment. If not, it
     |      includes the time separation required in the error.
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          Frame separation in ``fs``
     |
     |      Returns
     |      -------
     |      None
     |
     |      Raises
     |      ------
     |      AssertionError
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from AbstractSQw:
     |
     |  calculate_E(nE: int, dt: float) -> numpy.ndarray
     |      Calculates an array of ``nE`` uniformly spaced energy values from the
     |      time separation of the ``CompactTrajectory`` frames, ``dt``. The
     |      frequencie are determined by the Fast Fourier Transform, as implemented
     |      by numpy, for ``2 * nE`` points in time which we then crop to only
     |      include ``nE`` positive frequencies. As we are dealing with frequency
     |      rather than angular frequency here, the relation to between energy
     |      is given by:
     |
     |      .. math::
     |
     |          E = h \nu
     |
     |      Parameters
     |      ----------
     |      nE : int
     |          The number of energy values to be calculated
     |      dt : float
     |          The step size between frames in ``fs``
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          An ``array`` of `float` specifying the energy in units of ``meV``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractSQw:
     |
     |  E
     |
     |  SQw
     |
     |  SQw_err
     |
     |  dependent_variables
     |      Get the dependent variables: this is SQw, the
     |      dynamic structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'SQw' dependent variable is indexed in terms of 'Q' and 'E'.
     |      Explicitly: we have that self.SQw[Q_index, E_index] is the data point for
     |      given indices of self.Q and self.E
     |      It also means that:
     |      np.shape(self.SQw)=(np.size(self.Q), np.size(self.E))
     |
     |      The purpose of this method is to ensure consistency
     |      between different readers/methods which create ``SQw`` objects.
     |
     |      Return
     |      ------
     |      Dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the energy 'E' and reciprocal
     |      lattice points 'Q' within the dynamic structure factor ``Observables``.
     |      If using FFT, then 'E' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      Dict[str, Dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'E' and 'Q'.
     |
     |  w
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractSQw:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the dynamic
     |      structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and energy E (in``meV``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

    SQw_incoh = class SQwIncoherent(AbstractSQw)
     |  A class for the incoherent dynamic structure factor
     |
     |  Method resolution order:
     |      SQwIncoherent
     |      AbstractSQw
     |      SQwMixins
     |      MDMC.trajectory_analysis.observables.obs.Observable
     |      abc.ABC
     |      builtins.object
     |
     |  Data and other attributes defined here:
     |
     |  __abstractmethods__ = frozenset()
     |
     |  name = 'SQw_incoh'
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from AbstractSQw:
     |
     |  __init__(self)
     |      Initialize self.  See help(type(self)) for accurate signature.
     |
     |  calculate_dt(self) -> float
     |      Calculates the time separation of frames required by the experimental
     |      dataset, assuming uniform spacing. Note that this may be different from
     |      the time separation that the user has given as an input, as it only
     |      depends on the current values for ``self.E``. The relationship between
     |      time and energy comes from the numpy implementation of the FFT for
     |      ``2 * nE`` points where:
     |
     |      .. math::
     |          \nu_{max} &=& \frac{n_E - 1}{2 n_E \Delta t} \\\\
     |          \therefore \Delta t &=& \frac{h (n_E - 1)}{2 n_E E_{max}}
     |
     |      Returns
     |      -------
     |      float
     |          The time separation required by the current values of ``self.E``
     |
     |  calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
     |      Calculate the dynamic structure factor, S(Q, w) from a ``CompactTrajectory``.
     |
     |      If the ``CompactTrajectory`` has more frames than the ``self.maximum_frames()``
     |      that can be used to recreate the grid of energy points, it can slice the
     |      ``CompactTrajectory`` into sub-trajectories of length ``self.maximum_frames()``,
     |      with the slicing specified through the settings ``use_average`` and ``cont_slicing``.
     |
     |      The ``independent_variable`` ``Q`` can either be set previously or defined within
     |      ``**settings``.
     |
     |      Parameters
     |      ----------
     |      MD_input : CompactTrajectory
     |          An MDMC ``CompactTrajectory`` from which to calculate ``SQw``
     |      verbose: int, optional
     |          The level of verbosity:
     |          Verbose level 0 gives no information.
     |          Verbose level 1 gives final time for the whole method.
     |          Verbose level 2 gives final time and also a progress bar.
     |          Verbose level 3 gives final time, a progress bar, and time per step.
     |      **settings
     |          ``n_Q_vectors`` (`int`)
     |              The maximum number of ``Q_vectors`` for any ``Q`` value. The
     |              greater the number of ``Q_vectors``, the more accurate the
     |              calculation, but the longer it will take.
     |          ``dimensions`` (`list`, `tuple`, `numpy.ndarray`)
     |              A 3 element `tuple` or ``array`` of `float` specifying the
     |              dimensions of the ``Universe`` in units of ``Ang``
     |          ``energy_resolution` (`dict`)
     |              Optionally specify energy resolution and function in units of ueV (micro eV),
     |              in the format of the one-line dict {'function': value}, where `function`
     |              is the resolution function and `value` is the desired `FWHM`.
     |              e.g. to pass a Gaussian resolution of 80ueV we use {'gaussian': 80}.
     |              Currently accepted functions are 'gaussian' and 'lorentzian'
     |              Can also be 'lazily' given as `float`, in which case it is assumed to be Gaussian.
     |          ``Q_values`` (`array`)
     |              1D array of Q `float` (in ``Ang^-1``). (optional)
     |          ``use_average`` (`bool`)
     |              Optional parameter if a list of more than one ``Trajectory`` is used. If set to
     |              True (default) then the mean value for S(Q, w) is calculated. Also, the errors
     |              are set to the standard deviation calculated over the list of
     |              ``CompactTrajectory`` objects.
     |           ``cont_slicing`` (`bool`)
     |              Flag to decide between two possible behaviours when the number of ``MD_steps`` is
     |              larger than the minimum required to calculate the observables. If ``False``
     |              (default) then the ``CompactTrajectory`` is sliced into non-overlapping
     |              sub-``CompactTrajectory`` blocks for each of which the observable is calculated.
     |              If ``True``, then the ``CompactTrajectory`` is sliced into as many non-identical
     |              sub-``CompactTrajectory`` blocks as possible (with overlap allowed).
     |
     |  calculate_resolution_functions(self, dt: float) -> dict
     |      Generates a resolution function in momentum and time that can be used in the calculation of
     |      SQw. Note that this uses the ``SQw`` values of the ``Observable`` it is called from, and so
     |      should only be called for an observable which has been created from relevant resolution
     |      data, i.e. a vanadium sample.
     |
     |      Note that if this resolution function is used on data outside its original range, then it
     |      will use nearest neighbour extrapolation. Additionally, the input will be reflected in the
     |      time/energy domain as symmetry about 0 is assumed. If for whatever reason this is not
     |      appropriate for the data in question, this function should not be used.
     |
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          The time spacing to use when performing the inverse Fourier transform in units of `fs`.
     |          Ideally this should be the same as the frame separation expected when applying this
     |          function.
     |
     |      Returns
     |      -------
     |      dict
     |          A dictionary with the key 'SQw' corresponding to function which accepts arrays of time
     |          and momentum (respectively) and returns a 2D array of values for the instrument
     |          resolution.
     |
     |  validate_energy(self, dt: float) -> None
     |      Asserts that the user set frame separation ``dt`` leads to energy
     |      separation that matches that of the experiment. If not, it
     |      includes the time separation required in the error.
     |
     |      Parameters
     |      ----------
     |      dt : float
     |          Frame separation in ``fs``
     |
     |      Returns
     |      -------
     |      None
     |
     |      Raises
     |      ------
     |      AssertionError
     |
     |  ----------------------------------------------------------------------
     |  Static methods inherited from AbstractSQw:
     |
     |  calculate_E(nE: int, dt: float) -> numpy.ndarray
     |      Calculates an array of ``nE`` uniformly spaced energy values from the
     |      time separation of the ``CompactTrajectory`` frames, ``dt``. The
     |      frequencie are determined by the Fast Fourier Transform, as implemented
     |      by numpy, for ``2 * nE`` points in time which we then crop to only
     |      include ``nE`` positive frequencies. As we are dealing with frequency
     |      rather than angular frequency here, the relation to between energy
     |      is given by:
     |
     |      .. math::
     |
     |          E = h \nu
     |
     |      Parameters
     |      ----------
     |      nE : int
     |          The number of energy values to be calculated
     |      dt : float
     |          The step size between frames in ``fs``
     |
     |      Returns
     |      -------
     |      numpy.ndarray
     |          An ``array`` of `float` specifying the energy in units of ``meV``
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from AbstractSQw:
     |
     |  E
     |
     |  SQw
     |
     |  SQw_err
     |
     |  dependent_variables
     |      Get the dependent variables: this is SQw, the
     |      dynamic structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The dependent variables
     |
     |  dependent_variables_structure
     |      The order in which the 'SQw' dependent variable is indexed in terms of 'Q' and 'E'.
     |      Explicitly: we have that self.SQw[Q_index, E_index] is the data point for
     |      given indices of self.Q and self.E
     |      It also means that:
     |      np.shape(self.SQw)=(np.size(self.Q), np.size(self.E))
     |
     |      The purpose of this method is to ensure consistency
     |      between different readers/methods which create ``SQw`` objects.
     |
     |      Return
     |      ------
     |      Dict[str, list]
     |          The shape of the SQw dependent variable
     |
     |  uniformity_requirements
     |      Captures the current limitations on the energy 'E' and reciprocal
     |      lattice points 'Q' within the dynamic structure factor ``Observables``.
     |      If using FFT, then 'E' must be uniform and start at zero, otherwise it
     |      has no restrictions. 'Q' must be uniform but does not need to start at
     |      zero.
     |
     |      Return
     |      ------
     |      Dict[str, Dict[str, bool]]
     |          Dictionary of uniformity restrictions for 'E' and 'Q'.
     |
     |  w
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from AbstractSQw:
     |
     |  errors
     |      Get or set the errors on the dependent variables, the dynamic
     |      structure factor (in ``arb``)
     |
     |      Returns
     |      -------
     |      dict
     |          The errors on the ``dependent_variables``
     |
     |  independent_variables
     |      Get or set the independent variables: these are
     |      the frequency Q (in ``Ang^-1``) and energy E (in``meV``)
     |
     |      Returns
     |      -------
     |      dict
     |          The independent variables
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from SQwMixins:
     |
     |  maximum_frames(self) -> Optional[int]
     |      The maximum number of ``CompactTrajectory`` frames that can be used to
     |      calculate the ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      Otherwise, there is no limit and all frames will contribute to the
     |      calculation.
     |
     |      Returns
     |      -------
     |      int
     |          The maximum number of frames
     |
     |  minimum_frames(self, dt: float = None) -> int
     |      The minimum number of ``CompactTrajectory`` frames needed to calculate the
     |      ``dependent_variables`` depends on ``self.use_FFT``.
     |
     |      If `self.use_FFT == True`, it is the number of energy steps + 1, in order to allow for
     |      a reflection in time which only counts the end points once.
     |
     |      If `self.use_FFT == False`, there is not a hard minimum on number of frames. However, to
     |      distinguish our smallest differences in energy :math:`F(Q,t)` needs to
     |      cover at least a time period :math:`T_{min}` such that:
     |
     |      .. math::
     |
     |          T_{min} \sim \frac{h}{\Delta E_{min}}
     |
     |      Due to the aforementioned reflection in the time domain, to cover a
     |      period of :math:`T_{min}` we only need :math:`N` frames:
     |
     |      .. math::
     |
     |          N = \frac{T_{min}}{2 \Delta t} + 1 = \frac{h}{2 \Delta t \Delta E_{min}} + 1
     |
     |      Parameters
     |      ----------
     |      dt : float, optional
     |          The time separation of frames in ``fs``, default is `None`
     |
     |      Returns
     |      -------
     |      int
     |          The minimum number of frames
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from SQwMixins:
     |
     |  Q
     |
     |  __dict__
     |      dictionary for instance variables (if defined)
     |
     |  __weakref__
     |      list of weak references to the object (if defined)
     |
     |  ----------------------------------------------------------------------
     |  Methods inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  __repr__(self)
     |
     |  read_from_file(self, reader: str, file_name: str) -> None
     |      Reads in experimental data from a file using a specified reader
     |
     |      Parameters
     |      ----------
     |      reader : str
     |          The name of the required file reader
     |      file_name : str
     |          The name of the file
     |
     |  ----------------------------------------------------------------------
     |  Readonly properties inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  data
     |      Get the independent, dependent and error data
     |
     |      Returns
     |      -------
     |      dict
     |          The independent, dependent and error data
     |
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from MDMC.trajectory_analysis.observables.obs.Observable:
     |
     |  origin
     |      Get or set the origin of the observable
     |
     |      Returns
     |      -------
     |      str
     |          The origin of the ``Observable``, either ``'experiment'`` or ``'MD'``
     |
     |  use_FFT
     |      Get or set whether to use FFT when calculating from MD
     |
     |      Returns
     |      -------
     |      bool
     |          Whether to use FFT

DATA
    __all__ = ['CoherentDynamicStructureFactor', 'CoherentIntermediateScat...

FILE
    /usr/local/lib/python3.11/site-packages/MDMC/trajectory_analysis/observables/__init__.py


As is mentioned in the Examples section, each observable may have one or more aliases. So both DynamicStructureFactor or SQw can be used for calculating \(S(Q,\omega)\).

Some of the details given below are specific to calculating the dynamic structure factor, however the general method can be followed for any observable.

Argon has comparable scattering lengths for both coherent and incoherent scattering, so the total scattering has clear contributions from each. For the purposes of this tutorial we will simply calculate \(S(Q,\omega)_{coh}\) and compare it with experimental data; the exercise of calculating the incoherent and total scattering is left as an exercise for the reader.

[5]:
sqw_coh = observables.SQwCoh()

The dynamic structure factor has two independent variables, the scattering wavevector, \(Q\), and \(E\) (or \(\hbar\omega\)) is the energy transfer.

The size of the simulation box defines the spacing (and therefore the lower bound) of \(Q\) values; however any Q values can be specified for calculating \(S(Q,\omega)\) and MDMC will simply calculate it for valid values.

[6]:
# Using the arange function from NumPy - this creates an uniform array of floats with a
# start (0.42), stop (3.8) and step (0.3) specified below
Q = np.arange(0.42, 3.8, 0.3)
print('Q will be calculated for values of: {}'.format(Q))
Q will be calculated for values of: [0.42 0.72 1.02 1.32 1.62 1.92 2.22 2.52 2.82 3.12 3.42 3.72]

The total duration of the trajectory defines the smallest spacing of the \(E\) values. If \(E\) values are not specified, MDMC will simply calculate the \(E\) values with this spacing. However for this setting there will only be two points in the trajectory contributing to each energy bin and the statistics will be poor (should take ~30s to execute):

[7]:
# Set the Q values for the Q independent variable
sqw_coh.independent_variables = {'Q':Q}

# Calculate the coherent dynamic structure factor
sqw_coh.calculate_from_MD(trajectory)

# Use the plotting function defined above to plot the result
plot_surface(sqw_coh.E, sqw_coh.Q, sqw_coh.SQw[0])

Therefore it is strongly recommended that you specify the \(E\) values for calculating the dynamic structure factor.

The allowed values of \(E\) (in meV) are determined by trajectory times. To aid in calculating these, the calulate_E method can be used, which requires the time step of the trajectory (in fs) and the total number of E values to be calculated. The number of E values should be changed to improve the statistics, but somewhere in the range of 1/4 to 1/8 of the total number of trajectory configurations (i.e. the number of times for which a configuration was recorded) will be probably reasonable:

[8]:
# This subtracts the time of the zeroeth step from the time of the first step
# It should be equal to the time_step * traj_step passed to Simulation
trajectory_timestep = trajectory.times[1] - trajectory.times[0]
print('CompactTrajectory time step: {} fs'.format(trajectory_timestep))

n_configurations = len(trajectory.times)
print('Number of trajectory configurations: {}'.format(n_configurations))
CompactTrajectory time step: 250.0 fs
Number of trajectory configurations: 481
[9]:
E = sqw_coh.calculate_E((n_configurations - 1) / 6, trajectory_timestep)
print('Calculated E values are: \n{} meV'.format(E))
Calculated E values are:
[0.         0.10339169 0.20678338 0.31017508 0.41356677 0.51695846
 0.62035015 0.72374185 0.82713354 0.93052523 1.03391692 1.13730862
 1.24070031 1.344092   1.44748369 1.55087539 1.65426708 1.75765877
 1.86105046 1.96444216 2.06783385 2.17122554 2.27461723 2.37800893
 2.48140062 2.58479231 2.688184   2.79157569 2.89496739 2.99835908
 3.10175077 3.20514246 3.30853416 3.41192585 3.51531754 3.61870923
 3.72210093 3.82549262 3.92888431 4.032276   4.1356677  4.23905939
 4.34245108 4.44584277 4.54923447 4.65262616 4.75601785 4.85940954
 4.96280124 5.06619293 5.16958462 5.27297631 5.376368   5.4797597
 5.58315139 5.68654308 5.78993477 5.89332647 5.99671816 6.10010985
 6.20350154 6.30689324 6.41028493 6.51367662 6.61706831 6.72046001
 6.8238517  6.92724339 7.03063508 7.13402678 7.23741847 7.34081016
 7.44420185 7.54759355 7.65098524 7.75437693 7.85776862 7.96116031
 8.06455201 8.1679437 ] meV

Of course if the \(E\) resolution required is lower (i.e. step between the E values can be larger), the number of E values specified can be reduced:

[10]:
print('A reduced E resolution: \n{} meV'.format(sqw_coh.calculate_E((n_configurations - 1) / 24, trajectory_timestep)))
A reduced E resolution:
[0.         0.41356677 0.82713354 1.24070031 1.65426708 2.06783385
 2.48140062 2.89496739 3.30853416 3.72210093 4.1356677  4.54923447
 4.96280124 5.376368   5.78993477 6.20350154 6.61706831 7.03063508
 7.44420185 7.85776862] meV

Now we can use Q and E to set the indepedendent variables of sqw_coh:

[11]:
sqw_coh.independent_variables = {'E':E,
                                 'Q':Q}

Using this binning, recalculate the dynamic structure factor, which is smoother due to better statistics This calculation should take ~30s.:

[12]:
sqw_coh.calculate_from_MD(trajectory)
plot_surface(sqw_coh.E, sqw_coh.Q, sqw_coh.SQw[0])

We can compare this with experimental data measured using quasi-elastic neutron scattering (QENS) data (specifically here the van Well et al. Phys. Rev. A 31 3391 (1985) data, which the authors corrected for instrument resolution) by reading the data into an SQwCoh object:

[13]:
# Create a second SQwCoh object, this time called sqw_exp
sqw_exp = observables.SQwCoh()

# Read the data from the file ./data/Well_s_q_omega_Ar_data.xml using the `xml_SQw` reader
sqw_exp.read_from_file('xml_SQw', './data/Well_s_q_omega_Ar_data.xml')

The independent and dependent variables are read into the same attributes (sqw_coh.E, sqw_exp.Q, and sqw_exp.SQw) as if they had been calculated from MD (as in sqw_coh above).

For many QENS datasets (if not most) the instrument resolution has not been removed, and to compare with MD simulation this requires the simulation output to be convolution with the instrument resolution. One way this can be done is using: the optional energy_resolution:

[14]:
# energy_resolution is the FWHM of the instrumentation's resolution function expressed in ueV (micro eV).
# It is used to smooth the calculated S(Q,w) with a Gaussian window in order to match the values obtained experimentally.
sqw_coh.calculate_from_MD(trajectory, energy_resolution={'gaussian': 1.0e3})

plot_surface(sqw_coh.E, sqw_coh.Q, sqw_coh.SQw[0])

Other observables

The same applies for the observables, such as the pair distribution function \(G(r)\). To determine how to calculate another observables from an MD trajectory, please see the associated help documentation:

[15]:
help(observables.PDF.calculate_from_MD)
Help on function calculate_from_MD in module MDMC.trajectory_analysis.observables.pdf:

calculate_from_MD(self, MD_input: MDMC.trajectory_analysis.compact_trajectory.CompactTrajectory, verbose: int = 0, **settings: dict)
    Calculate the pair distribution function, :math:`G(r)`` from a
    ``CompactTrajectory``

    The partial pair distribution for a pair i-j, :math:`g_{ij}`, is:

    .. math::

        g_{ij}(r) = \frac{h_{ij}(r)}{4 \pi r^2 \rho_{j} \Delta{r}}

    where :math:`h_{ij}`` is the histogram of distances of :math:`j` element
    atoms around atoms of element :math:`i`, with bins of size
    :math:`\Delta{r}`, and :math:`\rho_{j}` is the number density of
    atoms of element :math:`j`. As :math:`g_{ij}(0) = 0`, it is evident that
    :math:`G(0) = -\sum_{i,j}^{N_{elements}} c_ic_jb_ib_j`.

    This corresponds to the equation (8) in the following paper:
    "A comparison of various commonly used correlation functions for
     describing total scattering"
    Keen, D. A. (2001). J. Appl. Cryst. 34, 172-177.
    DOI: https://doi.org/10.1107/S0021889800019993

    The total pair distribution function (``pdf.PDF``) has the form:

    .. math::

        G(r) = \sum_{i,j}^{N_{elements}} c_ic_jb_ib_j(g_{ij}(r) - 1)

    where :math:`c_i` is the proportion of element :math:`i` in the material,
    :math:`b_i` is the (coherent) scattering length of element :math:`i`

    This corresponds to the equation (10) in the above paper.

    Independent variables can either be set previously or defined within
    settings.

    A number of frames can be specified, from which the ``PDF`` and its
    error are calculated. If the number of frames is too large relative to
    the run length, the samples will be correlated, which will result in an
    underestimate of the error.

    Parameters
    ----------
    MD_input : CompactTrajectory
         A single ``CompactTrajectory`` object.
    verbose: int
        Verbose print settings. Not currently implemented for PDF.
    **settings
        n_frames : int
            The number of frames from which the pdf and its error are
            calculated. These frames are selected uniformly, and the step is taken to be
            n_frames / total number of frames rounded to the nearest positive integer.
            If this is not passed, 1% of the total number of frames are used
            (rounded up to the nearest positive integer).
        use_average : bool
            Optional parameter. If set to True then the mean value for PDF is
            calculated across selected frames from the trajectory. Also, the errors
            are set to the standard deviation calculated over the multiple frames.
            If set to False (default), only the last frame of the trajectory is used and
            n_frames will be ignored.
        subset : list of tuples
            The subset of element pairs from which the PDF is calculated.
            This can be used to calculate the partial PDFs of a
            multicomponent system. If this is not passed, all combinations
            of elements are used i.e. the PDF is the total PDF.
        b_coh : dict
            A dictionary containing coherent scattering length values for one or more elements.
            This can be used to calculate the PDF of a system where one or more elements
            has a coherent scattering length different from the coherent scattering length in
            MDMC.common.atom_properties (i.e. if it has been isotopically substituted).
        r_min : float
            The minimum ``r`` (atomic separation) in Angstrom for which the PDF will be
            calculated. If this, ``r_max``, and ``r_step`` are passed then
            these will create a range for the independent variable ``r``,
            which will overwrite any ``r`` which has previously been
            defined. This cannot be passed if ``r`` is passed.
        r_max : float
            The maximum ``r`` (atomic separation) in Angstrom for which the PDF will be
            calculated. If this, ``r_min``, and ``r_step`` are passed then
            these will create a range for the independent variable ``r``,
            which will overwrite any ``r`` which has previously been
            defined. This cannot be passed if ``r`` is passed.
        r_step : float
            The step size of ``r`` (atomic separation) for which the PDF
            will be calculated. If this, ``r_min``, and ``r_max`` are passed
            then these will create a range for the independent variable
            ``r``, which will overwrite any ``r`` which has previously been
            defined. This cannot be passed if ``r`` is passed.
        r : numpy.ndarray
            The uniform ``r`` values in Angstrom for which the PDF will be calculated.
            This cannot be passed if ``r_min``, ``r_max``, and ``r_step``
            are passed.
        dimensions : array-like
            A 3 element `array-like` (`list`, `tuple`) with the dimensions
            of the ``Universe`` in Angstrom.


    Examples
    --------
    To calculate the O-O partial PDF from a simulation of water, use the
    subset keyword:

        .. highlight:: python
        .. code-block:: python

        pdf.calculate_from_MD(trajectory, subset=[(O, O)])

    To calculate the sum of the H-O and O-O partial PDFs:

        .. highlight:: python
        .. code-block:: python

        pdf.calculate_from_MD(trajectory, subset=[(O, O), (H, O)])

    To calculate the total PDF for sodium chloride with 37Cl:

        .. highlight:: python
        .. code-block:: python

        pdf.calculate_from_MD(trajectory, b_coh={'Cl':3.08})

    To calculate the total PDF for r values of [1., 2., 3., 4.]:

        .. highlight:: python
        .. code-block:: python

        pdf.calculate_from_MD(trajectory, r=[1., 2., 3., 4.])

    To calculate the total PDF over an average of 5 frames:

        .. highlight:: python
        .. code-block:: python

        pdf.calculate_from_MD(trajectory, use_average=True, n_frames=5)

[ ]: