SpinSystem

class mrsimulator.SpinSystem(*, name: str = None, description: str = None, label: str = None, property_units: Dict = {'abundance': 'pct'}, sites: Union[List[Site], ndarray] = [], couplings: Union[List[Coupling], ndarray] = [], abundance: ConstrainedFloatValue = 100.0, transition_pathways: List = None)

Bases: Parseable

Base class representing an isolated spin system containing multiple sites and couplings amongst them.

Attribute Documentation

sites

A list of Site or equivalent dict objects within the spin system. Each site object represents single-site nuclear spin interaction (nuclear shielding and EFG) tensor parameters. The default value is an empty list.

Example

>>> sys1 = SpinSystem()
>>> sys1.sites = [Site(isotope="17O"), Site(isotope="1H")]
>>> # or equivalently
>>> sys1.sites = [{"isotope": "17O"}, {"isotope": "1H"}]
Type:

list of Site or equivalent dict objects (optional)

couplings

A list of Coupling or equivalent dict objects within the spin system. Each coupling object represents a two-site spin interaction (J-coupling and Dipolar) tensor parameters. The default value is an empty list.

Example

>>> sys1 = SpinSystem()
>>> sys1.couplings = [
...     Coupling(site_index=[0, 1], isotropic_j=10.1),
...     Coupling(site_index=[2, 1], dipolar={"D": 1500})
... ]
>>> # or equivalently
>>> sys1.couplings = [
...     {"site_index": [0, 1], "isotropic_j": 10.1},
...     {"site_index": [2, 1], "dipolar": {"D": 1500}}
... ]
Type:

list of Coupling or equivalent dict objects (optional)

abundance

The abundance of the spin system in units of %. The default value is 100. The value of this attribute is useful when multiple spin systems are present.

Example

>>> sys1.abundance = 10
Type:

float (optional).

name

The value is the name or ID of the spin system. The default value is None.

Example

>>> sys1.name = "1H-17O-0"
>>> print(sys1.name)
1H-17O-0
Type:

str (optional).

label

The value is a label for the spin system. The default value is None.

Example

>>> sys1.label = "Heteronuclear spin system"
>>> print(sys1.label)
Heteronuclear spin system
Type:

str (optional).

description

The value is a description of the spin system. The default value is None.

Example

>>> sys1.description = "A test for the spin system"
>>> print(sys1.description)
A test for the spin system
Type:

str (optional).

transition_pathways

A list of TransitionPathway or equivalent dict objects. Each transition pathway is a list of Transition objects. The resulting spectrum is a sum of the resonances arising from individual transition pathways. The default value is None.

Example

>>> sys1.transition_pathways = [
...     [
...         {"initial": [-2.5, 0.5], "final": [2.5, 0.5]},
...         {"initial": [0.5, 0.5], "final": [-0.5, 0.5]}
...     ]
... ]
>>> print(sys1.transition_pathways)
[|2.5, 0.5⟩⟨-2.5, 0.5| ⟶ |-0.5, 0.5⟩⟨0.5, 0.5|, weight=(1+0j)]

Note

From any given spin system, the list of relevant transition pathways is determined by the NMR method. For example, consider a single site I=3/2 spin system. For this system, a Bloch decay spectrum method will select three transition pathways, one corresponding to the central and two to the satellite transitions. On the other hand, a Bloch decay central transition selective method will only select one transition pathway, corresponding to the central transition.

Since the spin system is independent of the NMR method, the value of this attribute is, therefore, transient. You may use this attribute to override the default transition pathway query selection criterion of the NMR method objects.

Only use this attribute if you know what you are doing.

At times, this attribute may provide a significant improvement in the performance, especially in iterative algorithms, such as the least-squares algorithm, where a one-time transition pathway query is sufficient. Repeated queries for the transition pathways will add significant overhead to the computation.

See also

Fitting example

Type:

list of TransitionPathway (optional).

all_transitions() TransitionList

Returns a list of all possible spin Transition objects in the given spin system.

Example

>>> spin_system_1H_13C.all_transitions()  # 16 two energy level transitions
[|-0.5, -0.5⟩⟨-0.5, -0.5|,
|-0.5, 0.5⟩⟨-0.5, -0.5|,
|0.5, -0.5⟩⟨-0.5, -0.5|,
|0.5, 0.5⟩⟨-0.5, -0.5|,
|-0.5, -0.5⟩⟨-0.5, 0.5|,
|-0.5, 0.5⟩⟨-0.5, 0.5|,
|0.5, -0.5⟩⟨-0.5, 0.5|,
|0.5, 0.5⟩⟨-0.5, 0.5|,
|-0.5, -0.5⟩⟨0.5, -0.5|,
|-0.5, 0.5⟩⟨0.5, -0.5|,
|0.5, -0.5⟩⟨0.5, -0.5|,
|0.5, 0.5⟩⟨0.5, -0.5|,
|-0.5, -0.5⟩⟨0.5, 0.5|,
|-0.5, 0.5⟩⟨0.5, 0.5|,
|0.5, -0.5⟩⟨0.5, 0.5|,
|0.5, 0.5⟩⟨0.5, 0.5|]
Returns

A list of Transition objects.

get_isotopes(spin_I: Optional[float] = None, symbol: bool = False) list

An ordered list of Isotope objects from the sites within the spin system corresponding to the given value of spin quantum number I. If I is None, a list of all Isotope objects is returned instead.

Parameters:
  • spin_I (float) – An optional spin quantum number. The valid inputs are the multiples of 0.5.

  • symbol (bool) – If true, return a list of str with isotope symbols.

Returns:

A list of Isotope objects.

Example

>>> spin_systems.get_isotopes() # three spin systems
[Isotope(symbol='13C'), Isotope(symbol='1H'), Isotope(symbol='27Al')]
>>> spin_systems.get_isotopes(symbol=True) # three spin systems
['13C', '1H', '27Al']
>>> spin_systems.get_isotopes(spin_I=0.5) # isotopes with I=0.5
[Isotope(symbol='13C'), Isotope(symbol='1H')]
>>> spin_systems.get_isotopes(spin_I=0.5, symbol=True) # isotopes with I=0.5
['13C', '1H']
>>> spin_systems.get_isotopes(spin_I=1.5) # isotopes with I=1.5
[]
>>> spin_systems.get_isotopes(spin_I=2.5) # isotopes with I=2.5
[Isotope(symbol='27Al')]
>>> spin_systems.get_isotopes(spin_I=2.5, symbol=True) # isotopes with I=2.5
['27Al']
json(exclude={}, units=True) dict

Parse the class object to a JSON compliant Python dictionary object.

Parameters:
  • exclude – Set of keys that will be excluded from the result.

  • units – If true, the attribute value is a physical quantity expressed as a string with a number and a unit, else a float.

Returns: dict

classmethod parse_dict_with_units(py_dict: dict)

Parse physical quantities from a dictionary representation of the SpinSystem object, where the physical quantity is expressed as a string with a number and a unit.

Parameters:

py_dict (dict) – A required Python dict object.

Returns:

SpinSystem object.

Example

>>> spin_system_dict = {
...     "sites": [{
...         "isotope":"13C",
...         "isotropic_chemical_shift": "20 ppm",
...         "shielding_symmetric": {
...             "zeta": "10 ppm",
...             "eta": 0.5
...         }
...     }]
... }
>>> spin_system_1 = SpinSystem.parse_dict_with_units(spin_system_dict)
reduced_dict(exclude={}) dict

Returns a reduced dictionary representation of the class object by removing all key-value pairs corresponding to keys listed in the exclude argument, and keys with a value of None.

Parameters:

exclude – A list of keys to exclude from the dictionary.

Return: A dict.

rotate(euler_angles: list) None

Rotate the spin system coupling tensors and sites by the given list of Euler angle rotations. Euler angles are given as a list of (alpha, beta, gamma) tuples, and rotations happen in the Haeberlen (ZYZ) convention.

Parameters:

euler_angles ((list)) – An ordered list of angle tuples (alpha, beta, gamma) to rotate through each tensor.

Example

>>> sys = SpinSystem(
...     sites=[Site(isotope="1H"), Site(isotope="13C")],
...     couplings=[Coupling(site_index=[0, 1], dipolar={"D": 3})]
... )
>>> angles = [(3.1415, 0, -3.1415), (1.5701, 1.5701, 1.5701)]
>>> sys.rotate(angles)
simplify()

Simplifies user-defined spin systems into irreducible spin system objects.

Example

>>> sites = [
...     Site(isotope="1H", isotropic_chemical_shift=0, name="A"),
...     Site(isotope="1H", isotropic_chemical_shift=2, name="B"),
...     Site(isotope="1H", isotropic_chemical_shift=4, name="C"),
...     Site(isotope="1H", isotropic_chemical_shift=6, name="D"),
...     Site(isotope="1H", isotropic_chemical_shift=8, name="E"),
...     Site(isotope="1H", isotropic_chemical_shift=10, name="F")
... ]
>>> couplings = [
...     Coupling(site_index=[0, 1], isotropic_j=10, name="AB"),
...     Coupling(site_index=[1, 2], isotropic_j=10, name="BC"),
...     Coupling(site_index=[3, 5], isotropic_j=30, name="DF")
... ]
>>> sys = SpinSystem(sites=sites, couplings=couplings, abundance=30)
>>> simplified_sys = sys.simplify()
>>> simple_sys = [sub_sys.json() for sub_sys in simplified_sys]
>>> pprint(simple_sys)
[{'abundance': '30.0 %',
  'couplings': [{'isotropic_j': '10.0 Hz', 'name': 'AB', 'site_index': [0, 1]},
                {'isotropic_j': '10.0 Hz', 'name': 'BC', 'site_index': [1, 2]}],
  'sites': [{'isotope': '1H',
             'isotropic_chemical_shift': '0.0 ppm',
             'name': 'A'},
            {'isotope': '1H',
             'isotropic_chemical_shift': '2.0 ppm',
             'name': 'B'},
            {'isotope': '1H',
             'isotropic_chemical_shift': '4.0 ppm',
             'name': 'C'}]},
 {'abundance': '30.0 %',
  'couplings': [{'isotropic_j': '30.0 Hz', 'name': 'DF', 'site_index': [0, 1]}],
  'sites': [{'isotope': '1H',
             'isotropic_chemical_shift': '6.0 ppm',
             'name': 'D'},
            {'isotope': '1H',
             'isotropic_chemical_shift': '10.0 ppm',
             'name': 'F'}]},
 {'abundance': '30.0 %',
  'sites': [{'isotope': '1H',
             'isotropic_chemical_shift': '8.0 ppm',
             'name': 'E'}]}]
zeeman_energy_states() list

Return a list of all ZeemanState objects of the spin system, where the energy states are represented by a list of quantum numbers,

(57)\[|\Psi\rangle = [m_1, m_2,.. m_n],\]

where \(m_i\) is the quantum number associated with the \(i^\text{th}\) site within the spin system, and \(\Psi\) is the energy state.

Example

>>> spin_system_1H_13C.zeeman_energy_states()  # four energy level system.
[|-0.5, -0.5⟩, |-0.5, 0.5⟩, |0.5, -0.5⟩, |0.5, 0.5⟩]
Returns

A list of ZeemanState objects.