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 Trajectory
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 Trajectory
, 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 Trajectory
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=5000)
simulation.run(n_steps=20000, equilibration=True)
simulation.run(12025)
trajectory = simulation.trajectory
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 2)
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 2)
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
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.gca(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
IncoherentIntermediateScatteringFunction / FQtIncoherentFQtIncoh / FQt_incoh
PDF / PairDistributionFunction
CoherentIntermediateScatteringFunction / FQtCoherent / FQtCoh / FQt_coh
Examples

Observables can be instantiated using the names above. For instance an SQw
observable can be instantiated using either of the aliases:
.. codeblock:: 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)
 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose: int = 0, **settings)
 Calculate the dynamic structure factor, S(Q, w) from a ``Trajectory``

 Currently sets all errors to 0 when S(Q, w) is calculated from MD

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 oneline 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.

 calculate_resolution_functions(self, dt)
 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)
 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)
 Calculates an array of ``nE`` uniformly spaced energy values from the
 time separation of the ``Trajectory`` frames, ``dt``. The frequencies
 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 or set 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)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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, resolution: MDMC.resolution.resolution.Resolution = None)
 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.trajectory.Trajectory, verbose=0, **settings)
 Calculates the intermediate scattering function from a trajectory.

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory
 a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 or set 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
 
 array
 1D array of times in ``fs``

 
 Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:

 maximum_frames(self)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose: int = 0, **settings)
 Calculate the dynamic structure factor, S(Q, w) from a ``Trajectory``

 Currently sets all errors to 0 when S(Q, w) is calculated from MD

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 oneline 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.

 calculate_resolution_functions(self, dt)
 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)
 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)
 Calculates an array of ``nE`` uniformly spaced energy values from the
 time separation of the ``Trajectory`` frames, ``dt``. The frequencies
 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 or set 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)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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, resolution: MDMC.resolution.resolution.Resolution = None)
 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.trajectory.Trajectory, verbose=0, **settings)
 Calculates the intermediate scattering function from a trajectory.

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory
 a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 or set 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
 
 array
 1D array of times in ``fs``

 
 Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:

 maximum_frames(self)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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, resolution: MDMC.resolution.resolution.Resolution = None)
 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.trajectory.Trajectory, verbose=0, **settings)
 Calculates the intermediate scattering function from a trajectory.

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory
 a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 or set 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
 
 array
 1D array of times in ``fs``

 
 Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:

 maximum_frames(self)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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, resolution: MDMC.resolution.resolution.Resolution = None)
 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.trajectory.Trajectory, verbose=0, **settings)
 Calculates the intermediate scattering function from a trajectory.

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory
 a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 or set 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
 
 array
 1D array of times in ``fs``

 
 Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:

 maximum_frames(self)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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, resolution: MDMC.resolution.resolution.Resolution = None)
 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.trajectory.Trajectory, verbose=0, **settings)
 Calculates the intermediate scattering function from a trajectory.

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory
 a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 or set 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
 
 array
 1D array of times in ``fs``

 
 Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:

 maximum_frames(self)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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, resolution: MDMC.resolution.resolution.Resolution = None)
 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.trajectory.Trajectory, verbose=0, **settings)
 Calculates the intermediate scattering function from a trajectory.

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory
 a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 or set 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
 
 array
 1D array of times in ``fs``

 
 Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:

 maximum_frames(self)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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, resolution: MDMC.resolution.resolution.Resolution = None)
 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.trajectory.Trajectory, verbose=0, **settings)
 Calculates the intermediate scattering function from a trajectory.

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory
 a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 or set 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
 
 array
 1D array of times in ``fs``

 
 Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:

 maximum_frames(self)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose: int = 0, **settings)
 Calculate the dynamic structure factor, S(Q, w) from a ``Trajectory``

 Currently sets all errors to 0 when S(Q, w) is calculated from MD

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 oneline 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.

 calculate_resolution_functions(self, dt)
 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)
 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)
 Calculates an array of ``nE`` uniformly spaced energy values from the
 time separation of the ``Trajectory`` frames, ``dt``. The frequencies
 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 or set 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)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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, resolution: MDMC.resolution.resolution.Resolution = None)
 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.trajectory.Trajectory, verbose=0, **settings)
 Calculates the intermediate scattering function from a trajectory.

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory
 a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 or set 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
 
 array
 1D array of times in ``fs``

 
 Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:

 maximum_frames(self)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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, resolution: MDMC.resolution.resolution.Resolution = None)
 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.trajectory.Trajectory, verbose=0, **settings)
 Calculates the intermediate scattering function from a trajectory.

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory
 a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 or set 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
 
 array
 1D array of times in ``fs``

 
 Methods inherited from MDMC.trajectory_analysis.observables.sqw.SQwMixins:

 maximum_frames(self)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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

 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose=0, **settings)
 Calculate the pair distribution function, :math:`G(r)`` from a
 ``Trajectory``

 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 number concentration of element :math:`i`,
 :math:`b_i` is the (coherent) scattering length of element :math:`i`,
 and 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`.

 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 : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` 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. If this is not passed, 1% of the total number of
 frames are used (rounded up to nearest int).
 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
 Definitions of the coherent neutron scattering lengths 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) 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) 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 for which the PDF will be calculated.
 This cannot be passed if ``r_min``, ``r_max``, and ``r_step``
 are passed.
 dimensions : arraylike
 A 3 element `arraylike` (`list`, `tuple`) with the dimensions
 of the ``Universe``.

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

 .. highlight:: python
 .. codeblock:: python

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

 To calculate the sum of the HO and OO partial PDFs:

 .. highlight:: python
 .. codeblock:: python

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

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

 .. highlight:: python
 .. codeblock:: 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
 .. codeblock:: python

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

 maximum_frames(self)
 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)
 The minimum number of ``Trajectory`` 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

 dependent_variables
 Get or set the dependent variables: these are
 PDF, the pair distribution function (in ``arb``)

 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 atomc 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, file_name)
 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

 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose=0, **settings)
 Calculate the pair distribution function, :math:`G(r)`` from a
 ``Trajectory``

 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 number concentration of element :math:`i`,
 :math:`b_i` is the (coherent) scattering length of element :math:`i`,
 and 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`.

 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 : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` 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. If this is not passed, 1% of the total number of
 frames are used (rounded up to nearest int).
 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
 Definitions of the coherent neutron scattering lengths 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) 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) 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 for which the PDF will be calculated.
 This cannot be passed if ``r_min``, ``r_max``, and ``r_step``
 are passed.
 dimensions : arraylike
 A 3 element `arraylike` (`list`, `tuple`) with the dimensions
 of the ``Universe``.

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

 .. highlight:: python
 .. codeblock:: python

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

 To calculate the sum of the HO and OO partial PDFs:

 .. highlight:: python
 .. codeblock:: python

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

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

 .. highlight:: python
 .. codeblock:: 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
 .. codeblock:: python

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

 maximum_frames(self)
 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)
 The minimum number of ``Trajectory`` 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

 dependent_variables
 Get or set the dependent variables: these are
 PDF, the pair distribution function (in ``arb``)

 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 atomc 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, file_name)
 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)
 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose: int = 0, **settings)
 Calculate the dynamic structure factor, S(Q, w) from a ``Trajectory``

 Currently sets all errors to 0 when S(Q, w) is calculated from MD

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 oneline 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.

 calculate_resolution_functions(self, dt)
 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)
 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)
 Calculates an array of ``nE`` uniformly spaced energy values from the
 time separation of the ``Trajectory`` frames, ``dt``. The frequencies
 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 or set 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)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose: int = 0, **settings)
 Calculate the dynamic structure factor, S(Q, w) from a ``Trajectory``

 Currently sets all errors to 0 when S(Q, w) is calculated from MD

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 oneline 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.

 calculate_resolution_functions(self, dt)
 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)
 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)
 Calculates an array of ``nE`` uniformly spaced energy values from the
 time separation of the ``Trajectory`` frames, ``dt``. The frequencies
 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 or set 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)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose: int = 0, **settings)
 Calculate the dynamic structure factor, S(Q, w) from a ``Trajectory``

 Currently sets all errors to 0 when S(Q, w) is calculated from MD

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 oneline 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.

 calculate_resolution_functions(self, dt)
 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)
 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)
 Calculates an array of ``nE`` uniformly spaced energy values from the
 time separation of the ``Trajectory`` frames, ``dt``. The frequencies
 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 or set 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)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose: int = 0, **settings)
 Calculate the dynamic structure factor, S(Q, w) from a ``Trajectory``

 Currently sets all errors to 0 when S(Q, w) is calculated from MD

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 oneline 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.

 calculate_resolution_functions(self, dt)
 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)
 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)
 Calculates an array of ``nE`` uniformly spaced energy values from the
 time separation of the ``Trajectory`` frames, ``dt``. The frequencies
 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 or set 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)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose: int = 0, **settings)
 Calculate the dynamic structure factor, S(Q, w) from a ``Trajectory``

 Currently sets all errors to 0 when S(Q, w) is calculated from MD

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 oneline 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.

 calculate_resolution_functions(self, dt)
 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)
 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)
 Calculates an array of ``nE`` uniformly spaced energy values from the
 time separation of the ``Trajectory`` frames, ``dt``. The frequencies
 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 or set 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)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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)
 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose: int = 0, **settings)
 Calculate the dynamic structure factor, S(Q, w) from a ``Trajectory``

 Currently sets all errors to 0 when S(Q, w) is calculated from MD

 ``independent_variables`` can either be set previously or defined within
 ``**settings``.

 Parameters
 
 MD_input : Trajectory or list of Trajectory
 Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` object.
 verbose: int, optional
 If 2, timings are printed for each calculation of FQt and SQw. If 1,
 timings are collected so they can be printed at the end of the refinement.
 If 0, no timings are collected. Default is 0.
 **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 oneline 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.

 calculate_resolution_functions(self, dt)
 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)
 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)
 Calculates an array of ``nE`` uniformly spaced energy values from the
 time separation of the ``Trajectory`` frames, ``dt``. The frequencies
 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 or set 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)
 The maximum number of ``Trajectory`` 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)
 The minimum number of ``Trajectory`` 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, file_name)
 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.9/sitepackages/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('Trajectory time step: {} fs'.format(trajectory_timestep))
n_configurations = len(trajectory.times)
print('Number of trajectory configurations: {}'.format(n_configurations))
Trajectory 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 quasielastic 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: Union[MDMC.trajectory_analysis.trajectory.Trajectory, List[MDMC.trajectory_analysis.trajectory.Trajectory]], verbose=0, **settings)
Calculate the pair distribution function, :math:`G(r)`` from a
``Trajectory``
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 number concentration of element :math:`i`,
:math:`b_i` is the (coherent) scattering length of element :math:`i`,
and 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`.
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 : Trajectory or list of Trajectory
Either a `list` of MD ``Trajectory``s or a single ``Trajectory`` 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. If this is not passed, 1% of the total number of
frames are used (rounded up to nearest int).
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
Definitions of the coherent neutron scattering lengths 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) 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) 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 for which the PDF will be calculated.
This cannot be passed if ``r_min``, ``r_max``, and ``r_step``
are passed.
dimensions : arraylike
A 3 element `arraylike` (`list`, `tuple`) with the dimensions
of the ``Universe``.
Examples

To calculate the OO partial PDF from a simulation of water, use the
subset keyword:
.. highlight:: python
.. codeblock:: python
pdf.calculate_from_MD(trajectory, subset=[(O, O)])
To calculate the sum of the HO and OO partial PDFs:
.. highlight:: python
.. codeblock:: python
pdf.calculate_from_MD(trajectory, subset=[(O, O), (H, O)])
To calculate the total PDF for sodium chloride with 37Cl:
.. highlight:: python
.. codeblock:: 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
.. codeblock:: python
pdf.calculate_from_MD(trajectory, b_coh={'Cl':3.08})
[ ]: