# Term symbols

AtomicLevels provides types and methods to work and determine term symbols. The "Term symbol" and "Angular momentum coupling" Wikipedia articles give a good basic overview of the terminology.

For term symbols in LS coupling, AtomicLevels provides the `Term`

type.

`AtomicLevels.Term`

— Type`struct Term`

Represents a term symbol with specific parity in LS-coupling.

Only the $L$, $S$ and parity values of the symbol ${}^{2S+1}L_{J}$ are specified. To specify a *level*, the $J$ value would have to be specified separately. The valid $J$ values corresponding to given $L$ and $S$ fall in the following range:

\[|L - S| \leq J \leq L+S\]

**Constructors**

`Term(L::Real, S::Real, parity::Union{Parity,Integer})`

Constructs a `Term`

object with the given $L$ and $S$ quantum numbers and parity. `L`

and `S`

both have to be convertible to `HalfInteger`

s and `parity`

must be of type `Parity`

or `±1`

.

See also: `@T_str`

**Properties**

To access the quantum number values, you can use the `.L`

, `.S`

and `.parity`

properties to access the $L$, $S$ and parity values (represented with `Parity`

), respectively. E.g.:

```
julia> t = Term(2, 1//2, p"odd")
²Dᵒ
julia> t.L, t.S, t.parity
(2, 1/2, odd)
```

The `Term`

objects can also be constructed with the `@T_str`

string macro.

`AtomicLevels.@T_str`

— Macro`@T_str -> Term`

Constructs a `Term`

object out of its canonical string representation.

```
julia> T"1S"
¹S
julia> T"4Po"
⁴Pᵒ
julia> T"⁴Pᵒ"
⁴Pᵒ
julia> T"2[3/2]o" # jK coupling, common in noble gases
²[3/2]ᵒ
```

`Base.parse`

— Method`parse(::Type{Term}, ::AbstractString) -> Term`

Parses a string into a `Term`

object.

```
julia> parse(Term, "4Po")
⁴Pᵒ
julia> parse(Term, "⁴Pᵒ")
⁴Pᵒ
```

See also: `@T_str`

The `terms`

function can be used to generate all possible term symbols. In the case of relativistic orbitals, the term symbols are simply the valid $J$ values, represented using the `HalfInteger`

type.

`AtomicLevels.terms`

— Function`terms(orb::Orbital, w::Int=one(Int))`

Returns a list of valid LS term symbols for the orbital `orb`

with `w`

occupancy.

**Examples**

```
julia> terms(o"3d", 3)
8-element Vector{Term}:
²P
²D
²D
²F
²G
²H
⁴P
⁴F
```

`terms(config)`

Generate all final $LS$ terms for `config`

.

**Examples**

```
julia> terms(c"1s")
1-element Vector{Term}:
²S
julia> terms(c"1s 2p")
2-element Vector{Term}:
¹Pᵒ
³Pᵒ
julia> terms(c"[Ne] 3d3")
7-element Vector{Term}:
²P
²D
²F
²G
²H
⁴P
⁴F
```

`terms(o::RelativisticOrbital, w = 1) -> Vector{HalfInt}`

Returns a sorted list of valid $J$ values of `w`

equivalent $jj$-coupled particles on orbital `o`

(i.e. `oʷ`

).

When there are degeneracies (i.e. multiple states with the same $J$ and $M$ quantum numbers), the corresponding $J$ value is repeated in the output array.

**Examples**

```
julia> terms(ro"3d", 3)
3-element Vector{HalfIntegers.Half{Int64}}:
3/2
5/2
9/2
julia> terms(ro"3d-", 3)
1-element Vector{HalfIntegers.Half{Int64}}:
3/2
julia> terms(ro"4f", 4)
8-element Vector{HalfIntegers.Half{Int64}}:
0
2
2
4
4
5
6
8
```

`AtomicLevels.count_terms`

— Function`count_terms(orbital, occupation, term)`

Count how many times `term`

occurs among the valid terms of `orbital^occupation`

.

```
julia> count_terms(o"1s", 2, T"1S")
1
julia> count_terms(ro"6h", 4, 8)
4
```

`AtomicLevels.multiplicity`

— Method`multiplicity(t::Term)`

Returns the spin multiplicity of the `Term`

`t`

, i.e. the number of possible values of $J$ for a given value of $L$ and $S$.

**Examples**

```
julia> multiplicity(T"¹S")
1
julia> multiplicity(T"²S")
2
julia> multiplicity(T"³P")
3
```

`AtomicLevels.weight`

— Method`weight(t::Term)`

Returns the statistical weight of the `Term`

`t`

, i.e. the number of possible microstates: $(2S+1)(2L+1)$.

**Examples**

```
julia> weight(T"¹S")
1
julia> weight(T"²S")
2
julia> weight(T"³P")
9
```

## Term multiplicity and intermediate terms

For subshells starting with `d³`

, a term symbol can occur multiple times, each occurrence corresponding to a different physical state (multiplicity higher than one). This happens when there are distinct ways of coupling the electrons, but they yield the same total angular momentum. E.g. a `d³`

subshell can be coupled in 8 different ways, two of which are both described by the `²D`

term symbol:

```
julia> terms(o"3d", 3)
8-element Vector{Term}:
²P
²D
²D
²F
²G
²H
⁴P
⁴F
julia> count_terms(o"3d", 3, T"2D")
2
```

The multiplicity can be even higher if more electrons and higher angular momenta are involved:

```
julia> count_terms(o"4f", 5, T"2Do")
5
```

To distinguish these subshells, extra quantum numbers must be specified. In AtomicLevels, that can be done with the `IntermediateTerm`

type. This is primarily used when specifying the subshell couplings in CSFs.

`AtomicLevels.IntermediateTerm`

— Type`struct IntermediateTerm{T,S}`

Represents a term together with its extra disambiguating quantum number(s), labelled by `ν`

.

The term symbol (`::T`

) can either be a `Term`

(for $LS$-coupling) or a `HalfInteger`

(for $jj$-coupling).

The disambiguating quantum number(s) (`::S`

) can be anything as long as they are sortable (i.e. implementing `isless`

). It is up to the user to pick a scheme that is suitable for their application. See "Disambiguating quantum numbers" in the manual for discussion on how it is used in AtomicLevels.

**Constructors**

`IntermediateTerm(term, ν)`

Constructs an intermediate term with the term symbol `term`

and disambiguating quantum number(s) `ν`

.

**Properties**

To access the term symbol and the disambiguating quantum number(s), you can use the `.term :: T`

and `.ν :: S`

(or `.nu :: S`

) properties, respectively. E.g.:

```
julia> it = IntermediateTerm(T"2D", 2)
₍₂₎²D
julia> it.term, it.ν
(²D, 2)
julia> it = IntermediateTerm(5//2, Seniority(2))
₂5/2
julia> it.term, it.nu
(5/2, ₂)
```

`AtomicLevels.intermediate_terms`

— Function`intermediate_terms(orb::Orbital, w::Int=one(Int))`

Generates all `IntermediateTerm`

for a given non-relativstic orbital `orb`

and occupation `w`

.

**Examples**

```
julia> intermediate_terms(o"2p", 2)
3-element Vector{IntermediateTerm{Term, Seniority}}:
₀¹S
₂¹D
₂³P
```

The preceding subscript is the seniority number, which indicates at which occupancy a certain term is first seen, cf.

```
julia> intermediate_terms(o"3d", 1)
1-element Vector{IntermediateTerm{Term, Seniority}}:
₁²D
julia> intermediate_terms(o"3d", 3)
8-element Vector{IntermediateTerm{Term, Seniority}}:
₁²D
₃²P
₃²D
₃²F
₃²G
₃²H
₃⁴P
₃⁴F
```

In the second case, we see both `₁²D`

and `₃²D`

, since there are two ways of coupling 3 `d`

electrons to a `²D`

symmetry.

`intermediate_terms(config)`

Generate the intermediate terms for each subshell of `config`

.

**Examples**

```
julia> intermediate_terms(c"1s 2p3")
2-element Vector{Vector{IntermediateTerm{Term, Seniority}}}:
[₁²S]
[₁²Pᵒ, ₃²Dᵒ, ₃⁴Sᵒ]
julia> intermediate_terms(rc"3d2 5g3")
2-element Vector{Vector{IntermediateTerm{HalfIntegers.Half{Int64}, Seniority}}}:
[₀0, ₂2, ₂4]
[₁9/2, ₃3/2, ₃5/2, ₃7/2, ₃9/2, ₃11/2, ₃13/2, ₃15/2, ₃17/2, ₃21/2]
```

### Disambiguating quantum numbers

The `IntermediateTerm`

type does not specify how to interpret the disambiguating quantum number(s) $ν$, or even what the type of it should be. In AtomicLevels, we use two different types, depending on the situation:

**A simple**In this case, the quantum number $\nu$ must be in the range $1 \leq \nu \leq N_{\rm{terms}}$, where $N_{\rm{terms}}$ is the multiplicity of the term symbol (i.e. the number of times this term symbol appears for this subshell $\ell^w$ or $\ell_j^w$).`Integer`

.AtomicLevels does not prescribe any further interpretation for the quantum number. It can be used as a simple counter to distinguish the different terms, or the user can define their own mapping from the set of integers to physical states.

In this case the number is interpreted to be`Seniority`

.*Racah's seniority number*. This gives the intermediate term a specific physical interpretation, but only works for certain subshells. See the`Seniority`

type for more information.

`AtomicLevels.Seniority`

— Type`Seniority(ν)`

Seniority is an extra quantum number introduced by Giulio Racah (1943) to disambiguate between terms belonging to a subshell with a specific occupancy, that are assigned the same term symbols. For partially filled f-shells (in $LS$ coupling) or partially filled $9/2$ shells (in $jj$ coupling), seniority alone is not enough to disambiguate all the arising terms.

The seniority number is defined as the minimum occupancy number `ν ∈ n:-2:0`

for which the term first appears, e.g. the ²D term first occurs in the d¹ configuration, then twice in the d³ configuration (which will then have the terms ₁²D and ₃²D).

## Term couplings

The angular momentum coupling method is based on the vector model, where two angular momenta can be combined via vector addition to form a total angular momentum:

\[\vec{J} = \vec{L} + \vec{S},\]

where the length of the resultant momentum $\vec{J}$ obeys

\[|L-S| \leq J \leq L+S.\]

Relations such as these are used to couple the term symbols in both $LS$ and $jj$ coupling; however, not all values of $J$ predicted by the vector model are valid physical states, see `couple_terms`

.

To generate the possible `terms`

of a configuration, all the possible terms of the individual subshells, have to be coupled together to form the final terms; this is done from left-to-right. When generating all possible `CSFs`

from a configuration, it is also necessary to find the intermediate couplings of the individual subshells. As an example, if we want to find the possible terms of `3p² 4s 5p²`

, we first find the possible terms of the individual subshells:

```
julia> its = intermediate_terms(c"3p2 4s 5p2")
3-element Vector{Vector{IntermediateTerm{Term, Seniority}}}:
[₀¹S, ₂¹D, ₂³P]
[₁²S]
[₀¹S, ₂¹D, ₂³P]
```

where the seniority numbers are indicated as preceding subscripts. We then need to couple each intermediate term of the first subshell with each of the second subshell, and couple each of the resulting terms with each of the third subshell, and so on. E.g. coupling the `₂³P`

intermediate term with `₁²S`

produces two terms:

```
julia> couple_terms(T"3P", T"2S")
2-element Vector{Term}:
²P
⁴P
```

each of which need to be coupled with e.g. `₂¹D`

:

```
julia> couple_terms(T"2P", T"1D")
3-element Vector{Term}:
²P
²D
²F
julia> couple_terms(T"4P", T"1D")
3-element Vector{Term}:
⁴P
⁴D
⁴F
```

`terms`

uses `couple_terms`

(through `AtomicLevels.final_terms`

) to produce all possible terms coupling trees, folding from left-to-right:

```
julia> a = couple_terms([T"1S", T"1D", T"3P"], [T"2S"])
4-element Vector{Term}:
²S
²P
²D
⁴P
julia> couple_terms(a, [T"1S", T"1D", T"3P"])
12-element Vector{Term}:
²S
²P
²D
²F
²G
⁴S
⁴P
⁴D
⁴F
⁶S
⁶P
⁶D
```

which gives the same result as

```
julia> terms(c"3p2 4s 5p2")
12-element Vector{Term}:
²S
²P
²D
²F
²G
⁴S
⁴P
⁴D
⁴F
⁶S
⁶P
⁶D
```

Note that for the generation of final terms, the intermediate terms need not be kept (and their seniority is not important). However, for the generation of `CSFs`

, we need to form all possible combinations of intermediate terms for each subshell, and couple them, again left-to-right, to form all possible coupling chains (each one corresponding to a unique physical state). E.g. for the last term of each subshell of `3p² 4s 5p²`

```
julia> last.(its)
3-element Vector{IntermediateTerm{Term, Seniority}}:
₂³P
₁²S
₂³P
```

we find the following chains:

```
julia> intermediate_couplings(last.(its))
15-element Vector{Vector{Term}}:
[¹S, ³P, ²P, ²S]
[¹S, ³P, ²P, ²P]
[¹S, ³P, ²P, ²D]
[¹S, ³P, ²P, ⁴S]
[¹S, ³P, ²P, ⁴P]
[¹S, ³P, ²P, ⁴D]
[¹S, ³P, ⁴P, ²S]
[¹S, ³P, ⁴P, ²P]
[¹S, ³P, ⁴P, ²D]
[¹S, ³P, ⁴P, ⁴S]
[¹S, ³P, ⁴P, ⁴P]
[¹S, ³P, ⁴P, ⁴D]
[¹S, ³P, ⁴P, ⁶S]
[¹S, ³P, ⁴P, ⁶P]
[¹S, ³P, ⁴P, ⁶D]
```

`AtomicLevels.couple_terms`

— Function`couple_terms(t1, t2)`

Generate all possible coupling terms between `t1`

and `t2`

. It is assumed that `t1`

and `t2`

originate from non-equivalent electrons (i.e. from *different* subshells), since the vector model does not predict correct term couplings for equivalent electrons; some of the generated terms would violate the Pauli principle; cf. Cowan p. 108–109.

**Examples**

```
julia> couple_terms(T"1Po", T"2Se")
1-element Vector{Term}:
²Pᵒ
julia> couple_terms(T"3Po", T"2Se")
2-element Vector{Term}:
²Pᵒ
⁴Pᵒ
julia> couple_terms(T"3Po", T"2De")
6-element Vector{Term}:
²Pᵒ
²Dᵒ
²Fᵒ
⁴Pᵒ
⁴Dᵒ
⁴Fᵒ
```

`couple_terms(t1s, t2s)`

Generate all coupling between all terms in `t1s`

and all terms in `t2s`

.

`AtomicLevels.final_terms`

— Function`final_terms(ts::Vector{<:Vector{<:Union{Term,Real}}})`

Generate all possible final terms from the vector of vectors of individual subshell terms by coupling from left to right.

**Examples**

```
julia> ts = [[T"1S", T"3S"], [T"2P", T"2D"]]
2-element Vector{Vector{Term}}:
[¹S, ³S]
[²P, ²D]
julia> AtomicLevels.final_terms(ts)
4-element Vector{Term}:
²P
²D
⁴P
⁴D
```

`AtomicLevels.intermediate_couplings`

— Function`intermediate_couplings(its::Vector{IntermediateTerm,Integer,HalfInteger}, t₀ = T"1S")`

Generate all intermediate coupling trees from the vector of intermediate terms `its`

, starting from the initial term `t₀`

.

**Examples**

```
julia> intermediate_couplings([IntermediateTerm(T"2S", 1), IntermediateTerm(T"2D", 1)])
2-element Vector{Vector{Term}}:
[¹S, ²S, ¹D]
[¹S, ²S, ³D]
```

`intermediate_couplings(J::Vector{<:Real}, j₀ = 0)`

**Examples**

```
julia> intermediate_couplings([1//2, 3//2])
2-element Vector{Vector{HalfIntegers.Half{Int64}}}:
[0, 1/2, 1]
[0, 1/2, 2]
```

## Levels & States

Coupling $L$ and $S$ to a total $J$, as discussed under Term couplings above, yields a `Level`

; in $jj$ coupling, final term of the `CSF`

already has its final $J$ given. In both coupling schemes, the same values of final $J$ will result, but via different intermediate couplings. As an example, we will consider the configuration $1s\;2p$, which in the $LS$ and $jj$ coupling schemes has the following `CSF`

s:

```
julia> csls = csfs(c"1s 2p")
2-element Vector{NonRelativisticCSF{Orbital{Int64}, Seniority}}:
1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-
1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-
julia> csjj = vcat(csfs(rc"1s 2p"), csfs(rc"1s 2p-"))
4-element Vector{RelativisticCSF{RelativisticOrbital{Int64}, Seniority}}:
1s(₁1/2|1/2) 2p(₁3/2|1)-
1s(₁1/2|1/2) 2p(₁3/2|2)-
1s(₁1/2|1/2) 2p-(₁1/2|0)-
1s(₁1/2|1/2) 2p-(₁1/2|1)-
```

If we now generate the permissible `Level`

s, we find the valid values of $J$, i.e. $0$, $2\times 1$, and $2$:

```
julia> levels.(csls)
2-element Vector{Vector{Level{Orbital{Int64}, Term, Seniority}}}:
[|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1⟩]
[|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 0⟩, |1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 1⟩, |1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 2⟩]
julia> levels.(csjj)
4-element Vector{Vector{Level{RelativisticOrbital{Int64}, HalfIntegers.Half{Int64}, Seniority}}}:
[|1s(₁1/2|1/2) 2p(₁3/2|1)-, J = 1⟩]
[|1s(₁1/2|1/2) 2p(₁3/2|2)-, J = 2⟩]
[|1s(₁1/2|1/2) 2p-(₁1/2|0)-, J = 0⟩]
[|1s(₁1/2|1/2) 2p-(₁1/2|1)-, J = 1⟩]
```

`AtomicLevels.Level`

— Type`Level(csf, J)`

Given a `CSF`

with a final `Term`

, a `Level`

additionally specifies a total angular momentum $J$. By further specifying a projection quantum number $M_J$, we get a `State`

.

`AtomicLevels.weight`

— Method`weight(l::Level)`

Returns the statistical weight of the `Level`

`l`

, i.e. the number of possible microstates: $2J+1$.

**Example**

```
julia> l = Level(first(csfs(c"1s 2p")), 1)
|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1⟩
julia> weight(l)
3
```

`AtomicLevels.J_range`

— Function`J_range(term::Term)`

List the permissible values of the total angular momentum $J$ for `term`

.

**Examples**

```
julia> J_range(T"¹S")
0:0
julia> J_range(T"²S")
1/2:1/2
julia> J_range(T"³P")
0:2
julia> J_range(T"²D")
3/2:5/2
```

`J_range(J)`

The permissible range of the total angular momentum $J$ in $jj$ coupling is simply the value of $J$ for the final term.

`AtomicLevels.levels`

— Function`levels(csf)`

Generate all permissible `Level`

s given `csf`

.

**Examples**

```
julia> levels.(csfs(c"1s 2p"))
2-element Vector{Vector{Level{Orbital{Int64}, Term, Seniority}}}:
[|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1⟩]
[|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 0⟩, |1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 1⟩, |1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 2⟩]
julia> levels.(csfs(rc"1s 2p"))
2-element Vector{Vector{Level{RelativisticOrbital{Int64}, HalfIntegers.Half{Int64}, Seniority}}}:
[|1s(₁1/2|1/2) 2p(₁3/2|1)-, J = 1⟩]
[|1s(₁1/2|1/2) 2p(₁3/2|2)-, J = 2⟩]
julia> levels.(csfs(rc"1s 2p-"))
2-element Vector{Vector{Level{RelativisticOrbital{Int64}, HalfIntegers.Half{Int64}, Seniority}}}:
[|1s(₁1/2|1/2) 2p-(₁1/2|0)-, J = 0⟩]
[|1s(₁1/2|1/2) 2p-(₁1/2|1)-, J = 1⟩]
```

Similarly, by additionally specifying the projection quantum number $M_J$, we get a fully quantified `State`

. In the same way, the permissible values of $M_J$ must agree between the coupling schemes, sorting by $M_J$ for clarity:

```
julia> sort(reduce(vcat, reduce(vcat, states.(csls))), by=s->s.M_J)
12-element Vector{State{Orbital{Int64}, Term, Seniority}}:
|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 2, M_J = -2⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1, M_J = -1⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 1, M_J = -1⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 2, M_J = -1⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1, M_J = 0⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 0, M_J = 0⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 1, M_J = 0⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 2, M_J = 0⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1, M_J = 1⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 1, M_J = 1⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 2, M_J = 1⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|³Pᵒ)-, J = 2, M_J = 2⟩
julia> sort(reduce(vcat, reduce(vcat, states.(csjj))), by=s->s.M_J)
12-element Vector{State{RelativisticOrbital{Int64}, HalfIntegers.Half{Int64}, Seniority}}:
|1s(₁1/2|1/2) 2p(₁3/2|2)-, J = 2, M_J = -2⟩
|1s(₁1/2|1/2) 2p(₁3/2|1)-, J = 1, M_J = -1⟩
|1s(₁1/2|1/2) 2p(₁3/2|2)-, J = 2, M_J = -1⟩
|1s(₁1/2|1/2) 2p-(₁1/2|1)-, J = 1, M_J = -1⟩
|1s(₁1/2|1/2) 2p(₁3/2|1)-, J = 1, M_J = 0⟩
|1s(₁1/2|1/2) 2p(₁3/2|2)-, J = 2, M_J = 0⟩
|1s(₁1/2|1/2) 2p-(₁1/2|0)-, J = 0, M_J = 0⟩
|1s(₁1/2|1/2) 2p-(₁1/2|1)-, J = 1, M_J = 0⟩
|1s(₁1/2|1/2) 2p(₁3/2|1)-, J = 1, M_J = 1⟩
|1s(₁1/2|1/2) 2p(₁3/2|2)-, J = 2, M_J = 1⟩
|1s(₁1/2|1/2) 2p-(₁1/2|1)-, J = 1, M_J = 1⟩
|1s(₁1/2|1/2) 2p(₁3/2|2)-, J = 2, M_J = 2⟩
```

`AtomicLevels.State`

— Type`State(level, M_J)`

A states defines, in addition to the total angular momentum $J$ of `level`

, its projection $M_J\in -J..J$.

`AtomicLevels.states`

— Functionstates(level)

Generate all permissible `State`

given `level`

.

**Example**

```
julia> l = Level(first(csfs(c"1s 2p")), 1)
|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1⟩
julia> states(l)
3-element Vector{State{Orbital{Int64}, Term, Seniority}}:
|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1, M_J = -1⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1, M_J = 0⟩
|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1, M_J = 1⟩
```

`states(csf)`

Directly generate all permissible `State`

s for `csf`

.

**Example**

```
julia> c = first(csfs(c"1s 2p"))
1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-
julia> states(c)
1-element Vector{Vector{State{Orbital{Int64}, Term, Seniority}}}:
[|1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1, M_J = -1⟩, |1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1, M_J = 0⟩, |1s(₁²S|²S) 2p(₁²Pᵒ|¹Pᵒ)-, J = 1, M_J = 1⟩]
```

## Index

`AtomicLevels.IntermediateTerm`

`AtomicLevels.Level`

`AtomicLevels.Seniority`

`AtomicLevels.State`

`AtomicLevels.Term`

`AtomicLevels.J_range`

`AtomicLevels.count_terms`

`AtomicLevels.couple_terms`

`AtomicLevels.final_terms`

`AtomicLevels.intermediate_couplings`

`AtomicLevels.intermediate_terms`

`AtomicLevels.levels`

`AtomicLevels.multiplicity`

`AtomicLevels.states`

`AtomicLevels.terms`

`AtomicLevels.weight`

`AtomicLevels.weight`

`Base.parse`

`AtomicLevels.@T_str`