Data types
Molecular NMR parameters, spectra and calculation results are stored in Python objects in the HQS NMR Tool. These data structures are all Pydantic data classes and the data can be accessed as attributes of the class. See NMRResultSpectrum1D
for an example.
Note that for the full signature of each datatype you can check out the API-documentation. Here we will just point out the most important attributes of each class.
NMRResultSpectrum1D
The NMRResultSpectrum1D
is used to store all of the input and output of a NMR spectrum calculation when using the calculate_spectrum routine. It comprises:
-
The molecular data used for the calculation, which can include the full data in a
MolecularData
object or only the NMR parameters with data typeNMRParameters
(molecule_parameters
). -
All the parameters handed to
calculate_spectrum
in form of aNMRCalculationParameters
object (calculation_parameters
). -
The calculated spectrum of data type
NMRSpectrum1D
(spectrum
).
Assuming we have obtained an object called result_spectrum
of data type NMRResultSpectrum1D
the attributes can be accessed as follows:
molecule_parameters = result.molecule_parameters
calculation_parameters = result.calculation_parameters
spectrum = result.spectrum
In the following we will elaborate on the data type of each of these objects in more detail.
NMRResultGreensFunction1D
The NMRResultGreensFunction1D
is the analog data type to NMRResultSpectrum1D
when using calculate_greens_function instead of calculate_spectrum. The only difference is that instead of the attribute spectrum
, it has the attribute greens_function
, which stores a NMRGreensFunction1D
data type.
Assuming we have an object called result_greens_function
of data type NMRResultGreensFunction1D
the greens_function
attribute can be accessed as follows:
greens_function = result_greens_function.greens_function
NMRParameters
The NMRParameters
data type is defined in the hqs-nmr-parameters
repository and holds the reduced set of molecular parameters required for an NMR calculation,
The class holds:
- A list of chemical
shifts
in ppm for every nucleus in the system that has NMR parameters. - A List of isotopes for every nucleus, in the same ordering as
shifts
. TheNamedTuple
Isotope
has the two attributesmass_number
andsymbol
. - A list containing pairs of atomic indices and the associated J-coupling values. The atomic indices refer to the ordering in the
shifts
andisotopes
lists. - The
nspins
property for quick access to the number of spins in the system (same value as the number of shifts).
For an example you may run the following code:
from hqs_nmr_parameters.examples import molecules
# Obtain example molecule.
nmr_parameters = molecules["C10H7Br"].spin_system()
print(type(nmr_parameters)) # NMRParameters
print(nmr_parameters.nspins)
print(nmr_parameters.shifts)
print(nmr_parameters.isotopes)
print(nmr_parameters.j_couplings)
NMRParameters
objects are used as an input when calculating a spectrum using the calculate_spectrum or calculate_greens_function method.
NMRCalculationParameters
The NMRCalculationParameters
data type is defined in the hqs_nmr
repository and stores all possible customization options when performing spectra calculations with calculate_spectrum
or calculate_greens_function
.
The only parameter the user always has to specify is the magnetic field strength in Tesla, so the most simple and often already sufficient instantiation of this data type may look as follows:
from hqs_nmr.datatypes import NMRCalculationParameters
calculation_parameters = NMRCalculationParameters(field_T=11.7433)
Another important option the user can set is the reference_isotope
, which is the Isotope specified as Isotope(mass, symbol)
to define the frequency of the rotating frame. Furthermore, the object contains multiple attributes allowing to improve the resolution. For a detailed explanation of the available customization options check out the tutorial notebooks or take a look at the API-documentation.
NMRSolverSettings
The NMRSolverSettings
data type is also defined in the hqs_nmr
repository and stores customization options specific for the solver backend. It is stored as an attribute of a NMRCalculationParmameters
object and typically does not need to be altered.
It is however important to know that by default a spin-dependent clustering of the molecule into overlapping clusters is performed (for details check here). This is an extremely accurate approximation especially at high field, however in some cases this might not be wanted. In these cases you can set the attribute perform_clustering=False
, such that the spectrum of the entire molecule is calculated at once and symmetries will be exploited where applicable, but no approximations are made. Note that this can lead to a significant increase in runtime, so typically it is more advisable to increase the size of the clusters instead. To do so the attribute max_cluster_size
has to be specified:
from hqs_nmr.datatypes import NMRSolverSettings
solver_settings = NMRSolverSettings(max_cluster_size=16)
To see all customization options check the API-documentation.
NMRSpectrum1D
The NMRSpectrum1D
data type holds an NMR spectrum comprising the frequencies in ppm (omegas_ppm
), an array with the individual spin contributions to the spectrum (spin_contributions
) and the full-width-half-maximum in ppm (fwhm_ppm
).
Assuming we have performed a NMR spectrum calculation using calculate_spectrum and obtained as output an NMRResultSpectrum1D
object we called result_spectrum
, we can obtain an object of data type NMRSpectrum1D
as an attribute of this object:
spectrum = result_spectrum.spectrum
The spin_contributions
are a NumPy array, where each row holds the contribution of the corresponding spin, i.e.:
spectrum.spin_contributions[0,:]
holds the contribution of the first spin (index 0). The total spectrum that would be measured experimentally can be calculated using
import numpy as np
np.sum(spectrum.spin_contributions, axis=0)
NMRGreensFunction1D
The NMRGreensFunction1D
data type basically has the same attributes as NMRSpectrum1D
, however spin_contributions
is a complex array, as it stores the full NMR Green's function and not just the spectral function. This data type is typically only used if one wants to perform post-processing steps that require also the real part of the Green's function.
Assuming we have performed a NMR Green's function calculation using calculate_greens_function and obtained as output an NMRResultGreensFunction1D
object called result_greens_function
, we can obtain an object of data type NMRGreensFunction1D
as an attribute of this object:
greens_function = result_greens_function.greens_function
The total spectrum can then be obtained as follows:
import numpy as np
np.sum(- np.imag(greens_function.spin_contributions), axis=0)
Serialization (Saving and Loading)
The data types described above have a common interface for data serialization. There exists a function called to_json
common to all classes that can take a class object and a file name (with or without the full path) to store the data as a JSON
file. For example, if we have an object called spectrum
of the data class NMRSpectrum1D
and want to save it as spectrum_data.json
:
from hqs_nmr.datatypes import to_json
to_json(spectrum, "spectrum_data.json")
There is also the inverse method from_json
to load the data again. It needs as additional information the type of class the JSON
file has stored, e.g.:
from hqs_nmr.datatypes import from_json, NMRSpectrum1D
spectrum = from_json(NMRSpectrum1D, "spectrum_data.json")