Skip to content

Commit

Permalink
Support Unicode subscripts when parsing spin-{orbitals,configurations} (
Browse files Browse the repository at this point in the history
  • Loading branch information
jagot committed Mar 24, 2021
1 parent 210f66c commit 97f558b
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/AtomicLevels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ using HalfIntegers
using Combinatorics

include("common.jl")
include("unicode.jl")
include("parity.jl")
include("orbitals.jl")
include("relativistic_orbitals.jl")
Expand Down
16 changes: 13 additions & 3 deletions src/spin_orbitals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,19 @@ end

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

"""
Expand Down
17 changes: 17 additions & 0 deletions src/unicode.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
function from_subscript(s)
inverse_subscript_map = Dict('' => '-', '' => '+', '' => '0',
'' => '1', '' => '2', '' => '3',
'' => '4', '' => '5', '' => '6',
'' => '7', '' => '8', '' => '9',
'' => '0')
map(Base.Fix1(getindex, inverse_subscript_map), s)
end

function from_superscript(s)
inverse_superscript_map = Dict('' => '-', '' => '+', '' => '0',
'¹' => '1', '²' => '2', '³' => '3',
'' => '4', '' => '5', '' => '6',
'' => '7', '' => '8', '' => '9',
'' => '0')
map(Base.Fix1(getindex, inverse_superscript_map), s)
end
3 changes: 3 additions & 0 deletions test/configurations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
@test sc"1s(0,α) 2p(1,β)" == Configuration([so"1s(0,α)", so"2p(1,β)"], ones(Int, 2))
@test sc"[He]c 2p(1,β)" == Configuration([so"1s(0,α)", so"1s(0,β)", so"2p(1,β)"], ones(Int, 3), [:closed, :closed, :open])
@test rsc"[He]c 2p(-1/2)" == Configuration([rso"1s(-1/2)", rso"1s(1/2)", rso"2p(-1/2)"], ones(Int, 3), [:closed, :closed, :open])

# Test parsing of Unicode m_ℓ quantum numbers
@test sc"1s₀α 2p₁β" == sc"1s(0,α) 2p(1,β)"
end

@test fill(c"1s 2s 2p") == c"1s2 2s2 2p6"
Expand Down
20 changes: 20 additions & 0 deletions test/orbitals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,26 @@ using Random
@test parse(SpinOrbital{Orbital}, "1s(0,α)") == SpinOrbital(Orbital(1, 0), (0, up))
@test parse(SpinOrbital{Orbital{Int}}, "1s(0,α)") == SpinOrbital(Orbital(1, 0), (0, up))
@test parse(SpinOrbital{Orbital{Symbol}}, "ks(0,α)") == SpinOrbital(Orbital(:k, 0), (0, up))

@test so"1s₀β" == so"1s(0,β)"
@test so"2p₋₁α" == so"2p(-1,α)"
@test so"k[31]₋₁₃α" == so"k[31](-13,α)"

for o in [SpinOrbital(o"1s", (0,-1/2)),
SpinOrbital(o"1s", (0,1/2)),
SpinOrbital(o"2p", (1,-1/2)),
SpinOrbital(ro"1s", (1/2)),
SpinOrbital(ro"2p", (3/2)),
SpinOrbital(ro"3d", (5/2)),
SpinOrbital(ro"3d-", (-3/2)),
SpinOrbital(ro"3p", (-1/2)),
SpinOrbital(ro"3p", (-3/2)),
SpinOrbital(ro"3p", (1/2)),
SpinOrbital(ro"3p-", (-1/2)),
SpinOrbital(ro"3p-", (1/2))]
O = typeof(o.orb)
@test parse(SpinOrbital{O}, string(o)) == o
end
end
end

Expand Down
5 changes: 5 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ using WignerSymbols
using HalfIntegers
using Test

@testset "Unicode super-/subscripts" begin
@test AtomicLevels.from_subscript("₋₊₁₂₃₄₅₆₇₈₉₀") == "-+1234567890"
@test AtomicLevels.from_superscript("⁻⁺¹²³⁴⁵⁶⁷⁸⁹⁰") == "-+1234567890"
end

include("parity.jl")
include("orbitals.jl")
include("configurations.jl")
Expand Down

0 comments on commit 97f558b

Please sign in to comment.