Skip to content

Commit

Permalink
Add optional Moore Labels to AtomcTermSymbol
Browse files Browse the repository at this point in the history
  • Loading branch information
xnx committed Aug 1, 2023
1 parent 687b1e1 commit 87d023c
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 3 deletions.
10 changes: 10 additions & 0 deletions docs/source/states.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,16 @@ J must satisfy the "triangle rule" (\|L-S\| ≤ J ≤ L+S); if this test fails,
...
pyvalem.states.atomic_term_symbol.AtomicTermSymbolError: Invalid atomic term symbol: 3P_3 |L-S| <= J <= L+S must be satisfied.
A single, lowercase letter label to distinguish term symbols with the same ``S``, ``L`` that arise from the same atomic configuration; the convention assumed to be followed is that of C. E. Moore, NBS Circ, No. 488 (1950). See e.g. G. Nave et al., Astrophys. J. Suppl. Ser. 94:221-459 (1994). Terms with the same ``S`` and ``L`` of even parity are labelled in order of increasing energy as ``a``, ``b``, etc.; terms with odd parity are labelled in order of increasing energy as ``z``, ``y``, ``x``, etc.

.. code-block:: pycon
>>> from pyvalem.states import AtomicTermSymbol
>>> a0 = AtomicTermSymbol('a5D')
>>> a1 = AtomicTermSymbol('b5D')
>>> a2 = AtomicTermSymbol('z3Po')
>>> a3 = AtomicTermSymbol('y3Po')
``DiatomicMolecularConfiguration``
==================================
Expand Down
22 changes: 19 additions & 3 deletions src/pyvalem/states/atomic_term_symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@

integer = pp.Word(pp.nums)

# The single, lowercase letter label given in the Multiplet Table of C. E. Moore
# NBS Circ, No. 488 (1950) and sometimes used to distinguish terms with the same
# S, L from the same configuration. See e.g. G. Nave et al., Astrophys. J. Suppl. Ser.
# 94:221-459 (1994).
moore_label = pp.Char("abcdefghijklmnopqrstuvwxyz").setResultsName("moore_label")
atom_Smult = integer.setResultsName("Smult")
atom_Lletter = pp.oneOf(atom_L_symbols).setResultsName("Lletter")
atom_Jstr = (
integer + pp.Optional(pp.Suppress("/") + "2") + pp.StringEnd()
).setResultsName("Jstr")
atom_parity = pp.Literal("o").setResultsName("parity")
atom_term = (
atom_Smult
pp.Optional(moore_label)
+ atom_Smult
+ atom_Lletter
+ pp.Optional(atom_parity)
+ pp.Optional(pp.Suppress("_") + atom_Jstr)
Expand All @@ -41,6 +47,7 @@ def __init__(self, state_str):
self.L = None
self.parity = None
self.J = None
self.moore_letter = ""
self._parse_state(state_str)

def _parse_state(self, state_str):
Expand All @@ -55,6 +62,7 @@ def _parse_state(self, state_str):
self.Lletter = components.Lletter
self.L = atom_L_symbols.index(components.Lletter)
self.parity = components.get("parity")
self.moore_label = components.get("moore_label", "")
try:
self.J = parse_fraction(components.Jstr)
except ValueError as err:
Expand All @@ -77,7 +85,11 @@ def _validate_j(self):

@property
def html(self):
html_chunks = ["<sup>{0:d}</sup>{1:s}".format(self.Smult, self.Lletter)]
html_chunks = [
"{0}<sup>{1:d}</sup>{2:s}".format(
self.moore_letter, self.Smult, self.Lletter
)
]
if self.parity:
html_chunks.append("<sup>o</sup>")
if self.J is not None:
Expand All @@ -87,7 +99,11 @@ def html(self):

@property
def latex(self):
latex_chunks = [r"{{}}^{{{}}}\mathrm{{{}}}".format(self.Smult, self.Lletter)]
latex_chunks = [
r"{}{{}}^{{{}}}\mathrm{{{}}}".format(
self.moore_letter, self.Smult, self.Lletter
)
]
if self.parity:
latex_chunks.append("^o")
if self.J is not None:
Expand Down
11 changes: 11 additions & 0 deletions tests/test_atomic_term_symbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ def test_atomic_term_symbol_equality(self):
self.assertEqual(a0, a1)
self.assertNotEqual(a0, a2)

def test_moore_label(self):
a0 = AtomicTermSymbol("a5D")
a1 = AtomicTermSymbol("z3Po")
a2 = AtomicTermSymbol("2F")
a3 = AtomicTermSymbol("e5D_4")
self.assertEqual(a0.moore_label, "a")
self.assertEqual(a1.moore_label, "z")
self.assertEqual(a2.moore_label, "")
self.assertEqual(a3.moore_label, "e")
self.assertRaises(AtomicTermSymbolError, AtomicTermSymbol, "A5D")


if __name__ == "__main__":
unittest.main()
8 changes: 8 additions & 0 deletions tests/test_stateful_species.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
class StatefulSpeciesTest(unittest.TestCase):
def test_stateful_species_parsing(self):
_ = StatefulSpecies("Ar *")
_ = StatefulSpecies("Fe e5G")
_ = StatefulSpecies("CrH 1sigma2.2sigma1.1pi4.3sigma1; 6SIGMA+")
_ = StatefulSpecies("H(35Cl) J=2")
_ = StatefulSpecies("OH X(2Π_1/2, J=2")
Expand Down Expand Up @@ -104,6 +105,13 @@ def test_stateful_species_key_value_pair_ordering(self):
ss1 = StatefulSpecies("H n=3;l=1")
self.assertEqual(repr(ss1), "H n=3;l=1")

def test_atomic_term_symbols(self):
ss1 = StatefulSpecies("Fe+ a3D")
self.assertEqual(ss1.states[0].moore_label, "a")
self.assertEqual(ss1.states[0].S, 1)

self.assertRaises(StateParseError, StatefulSpecies, "Ti +2 A5D")


if __name__ == "__main__":
unittest.main()

0 comments on commit 87d023c

Please sign in to comment.