Skip to content

Commit ef5b19a

Browse files
committed
Support Unicode subscripts when parsing spin-{orbitals,configurations} (#41)
1 parent 21a71bb commit ef5b19a

File tree

5 files changed

+56
-3
lines changed

5 files changed

+56
-3
lines changed

src/AtomicLevels.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ using HalfIntegers
99
using Combinatorics
1010

1111
include("common.jl")
12+
include("unicode.jl")
1213
include("parity.jl")
1314
include("orbitals.jl")
1415
include("relativistic_orbitals.jl")

src/spin_orbitals.jl

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,19 @@ end
132132

133133
function Base.parse(::Type{O}, orb_str) where {OO<:AbstractOrbital,O<:SpinOrbital{OO}}
134134
m = match(r"^(.*)\((.*)\)$", orb_str)
135-
m === nothing && throw(ArgumentError("Invalid spin-orbital string: $(orb_str)"))
136-
o = parse(OO, m[1])
137-
SpinOrbital(o, (split(m[2], ",")...,))
135+
# For non-relativistic spin-orbitals, we also support specifying
136+
# the m_ℓ quantum number using Unicode subscripts and the spin
137+
# label using α/β
138+
m2 = match(r"^(.*?)([₋]{0,1}[₁₂₃₄₅₆₇₈₉₀]+)([αβ])$", orb_str)
139+
if !isnothing(m)
140+
o = parse(OO, m[1])
141+
SpinOrbital(o, (split(m[2], ",")...,))
142+
elseif !isnothing(m2) && OO <: Orbital
143+
o = parse(OO, m2[1])
144+
SpinOrbital(o, from_subscript(m2[2]), m2[3])
145+
else
146+
throw(ArgumentError("Invalid spin-orbital string: $(orb_str)"))
147+
end
138148
end
139149

140150
"""

src/unicode.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function from_subscript(s)
2+
inverse_subscript_map = Dict('' => '-', '' => '+', '' => '0',
3+
'' => '1', '' => '2', '' => '3',
4+
'' => '4', '' => '5', '' => '6',
5+
'' => '7', '' => '8', '' => '9',
6+
'' => '0')
7+
map(Base.Fix1(getindex, inverse_subscript_map), s)
8+
end
9+
10+
function from_superscript(s)
11+
inverse_superscript_map = Dict('' => '-', '' => '+', '' => '0',
12+
'¹' => '1', '²' => '2', '³' => '3',
13+
'' => '4', '' => '5', '' => '6',
14+
'' => '7', '' => '8', '' => '9',
15+
'' => '0')
16+
map(Base.Fix1(getindex, inverse_superscript_map), s)
17+
end

test/orbitals.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,26 @@ using Random
311311
@test parse(SpinOrbital{Orbital}, "1s(0,α)") == SpinOrbital(Orbital(1, 0), (0, up))
312312
@test parse(SpinOrbital{Orbital{Int}}, "1s(0,α)") == SpinOrbital(Orbital(1, 0), (0, up))
313313
@test parse(SpinOrbital{Orbital{Symbol}}, "ks(0,α)") == SpinOrbital(Orbital(:k, 0), (0, up))
314+
315+
@test so"1s₀β" == so"1s(0,β)"
316+
@test so"2p₋₁α" == so"2p(-1,α)"
317+
@test so"k[31]₋₁₃α" == so"k[31](-13,α)"
318+
319+
for o in [SpinOrbital(o"1s", (0,-1/2)),
320+
SpinOrbital(o"1s", (0,1/2)),
321+
SpinOrbital(o"2p", (1,-1/2)),
322+
SpinOrbital(ro"1s", (1/2)),
323+
SpinOrbital(ro"2p", (3/2)),
324+
SpinOrbital(ro"3d", (5/2)),
325+
SpinOrbital(ro"3d-", (-3/2)),
326+
SpinOrbital(ro"3p", (-1/2)),
327+
SpinOrbital(ro"3p", (-3/2)),
328+
SpinOrbital(ro"3p", (1/2)),
329+
SpinOrbital(ro"3p-", (-1/2)),
330+
SpinOrbital(ro"3p-", (1/2))]
331+
O = typeof(o.orb)
332+
@test parse(SpinOrbital{O}, string(o)) == o
333+
end
314334
end
315335
end
316336

test/runtests.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ using WignerSymbols
33
using HalfIntegers
44
using Test
55

6+
@testset "Unicode super-/subscripts" begin
7+
@test AtomicLevels.from_subscript("₋₊₁₂₃₄₅₆₇₈₉₀") == "-+1234567890"
8+
@test AtomicLevels.from_superscript("⁻⁺¹²³⁴⁵⁶⁷⁸⁹⁰") == "-+1234567890"
9+
end
10+
611
include("parity.jl")
712
include("orbitals.jl")
813
include("configurations.jl")

0 commit comments

Comments
 (0)