Skip to content

Commit

Permalink
feat: Add future annotations and update version to 1.4.4 (#124)
Browse files Browse the repository at this point in the history
* docs(deps): complete docs

* feat: update version to 1.4.4 and add future annotations

- Updated package version in __init__.py
- Added future annotations import in tools.py and cmd.py
- Refactored calculation method signature in batch.py
- Added new dependencies in pyproject.toml and updated poetry.lock

* feat: add future annotations for improved type hinting

* refactor: adjust TypeAlias definition for Float64Array
Anselmoo authored Oct 23, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 687625b commit 19b791d
Showing 10 changed files with 452 additions and 418 deletions.
53 changes: 52 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -49,6 +49,7 @@ exclude = ["test/**/*.py", "example/**", "ts-diagrams/**"]
matplotlib = "^3.4.2"
prettytable = ">=2.1,<4.0"
plotly = { version = "^5.13.1", optional = true }
update = "^0.0.1"

[tool.poetry.group.dev.dependencies]
pytest = ">=7.2,<9.0"
@@ -58,6 +59,7 @@ exclude = ["test/**/*.py", "example/**", "ts-diagrams/**"]
black = ">=22.12,<25.0"
isort = "^5.11.4"
pytest-console-scripts = "^1.3.1"
ruff = "^0.7.0"

[build-system]
requires = ["poetry-core>=1.0.0"]
@@ -68,3 +70,17 @@ tanabesugano = "tanabesugano.cmd:cmd_line"

[tool.poetry.extras]
plotly = ["plotly"]

[tool.ruff]
lint.select = ["ALL"]
lint.ignore = ["N806"]
target-version = "py38"
src = ["tanabesugano"]

[tool.ruff.lint.isort]
known-first-party = ["umf"]
force-single-line = true
lines-between-types = 1
lines-after-imports = 2
known-third-party = ["poetry.core"]
required-imports = ["from __future__ import annotations"]
5 changes: 4 additions & 1 deletion tanabesugano/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
"""tanabesugano: A Python package for Tanabe-Sugano diagrams."""
__version__ = "1.4.3"
from __future__ import annotations


__version__ = "1.4.4"
49 changes: 23 additions & 26 deletions tanabesugano/batch.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from __future__ import annotations

from typing import List

import numpy as np

from tanabesugano import matrices, tools
from tanabesugano import matrices
from tanabesugano import tools


class Batch:
@@ -22,26 +25,23 @@ def __init__(
C = [3600.0, 4000, 10]
if len(Dq) != 3:
raise KeyError(
"The range of `Dq` is based on the three values: start, stop, steps!"
"The range of `Dq` is based on the three values: start, stop, steps!",
)
else:
self.Dq = np.linspace(Dq[0], Dq[1], int(Dq[2])) # Oh-crystalfield-splitting
self.Dq = np.linspace(Dq[0], Dq[1], int(Dq[2])) # Oh-crystalfield-splitting
if len(B) != 3:
raise KeyError(
"The range of `B` is based on the three values: start, stop, steps!"
"The range of `B` is based on the three values: start, stop, steps!",
)
else:
self.B = np.linspace(
B[0], B[1], int(B[2])
) # Racah-Parameter B in wavenumbers
self.B = np.linspace(
B[0], B[1], int(B[2]),
) # Racah-Parameter B in wavenumbers
if len(C) != 3:
raise KeyError(
"The range of `C` is based on the three values: start, stop, steps!"
"The range of `C` is based on the three values: start, stop, steps!",
)
else:
self.C = np.linspace(
C[0], C[1], int(C[2])
) # Racah-Parameter C in wavenumbers
self.C = np.linspace(
C[0], C[1], int(C[2]),
) # Racah-Parameter C in wavenumbers

if slater:
# Transformin Racah to Slater-Condon
@@ -58,14 +58,11 @@ def __init__(
self._size = 10
self.result: List[dict] = []

def calculation(self):
"""
Is filling the self.result with the iTS states of over-iterated energy range
"""
def calculation(self) -> None:
"""Is filling the self.result with the iTS states of over-iterated energy range."""
for _Dq in self.Dq:
for _B in self.B:
for _C in self.C:

if self.d_count == 2: # d3
states = matrices.d2(Dq=_Dq, B=_B, C=_C).solver()
self.result.append(
@@ -75,7 +72,7 @@ def calculation(self):
"B": _B,
"C": _C,
"states": states,
}
},
)

elif self.d_count == 3: # d3
@@ -87,7 +84,7 @@ def calculation(self):
"B": _B,
"C": _C,
"states": states,
}
},
)
elif self.d_count == 4: # d4
states = matrices.d4(Dq=_Dq, B=_B, C=_C).solver()
@@ -98,7 +95,7 @@ def calculation(self):
"B": _B,
"C": _C,
"states": states,
}
},
)
elif self.d_count == 5: # d5
states = matrices.d5(Dq=_Dq, B=_B, C=_C).solver()
@@ -109,7 +106,7 @@ def calculation(self):
"B": _B,
"C": _C,
"states": states,
}
},
)
elif self.d_count == 6: # d6
states = matrices.d6(Dq=_Dq, B=_B, C=_C).solver()
@@ -120,7 +117,7 @@ def calculation(self):
"B": _B,
"C": _C,
"states": states,
}
},
)
elif self.d_count == 7: # d7
states = matrices.d7(Dq=_Dq, B=_B, C=_C).solver()
@@ -131,7 +128,7 @@ def calculation(self):
"B": _B,
"C": _C,
"states": states,
}
},
)
elif self.d_count == 8: # d8
states = matrices.d8(Dq=_Dq, B=_B, C=_C).solver()
@@ -142,7 +139,7 @@ def calculation(self):
"B": _B,
"C": _C,
"states": states,
}
},
)
else:
raise ValueError("not a correct value!")
77 changes: 38 additions & 39 deletions tanabesugano/cmd.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
#!/usr/bin/env python

from __future__ import annotations

import argparse

from pathlib import Path

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from prettytable import PrettyTable
from pathlib import Path


try:
import plotly.express as px
except ImportError: # pragma: no cover
px = None

from tanabesugano import __version__, matrices, tools
from tanabesugano import __version__
from tanabesugano import matrices
from tanabesugano import tools


class CMDmain(object):
class CMDmain:
def __init__(
self,
Dq: float = 4000.0,
@@ -41,13 +49,13 @@ def __init__(
Electron count, by default 5
slater : bool, optional
Transforming from Racah to Slater-Condon, by default False
"""
self.Dq = Dq
self.B = B
self.C = C

if slater:

self.B, self.C = tools.racah(B, C)
self.nroot = nroots
energy = np.linspace(0.0, self.Dq, nroots)
@@ -62,7 +70,7 @@ def __init__(
self.result = np.zeros((self._size + 1, nroots))

self.df = pd.DataFrame(
{"Energy": energy, "delta_B": energy / self.B, "10Dq": energy * 10.0}
{"Energy": energy, "delta_B": energy / self.B, "10Dq": energy * 10.0},
)
self.title_TS = (
f"TS-diagram_d{self.d_count}_10Dq_{int(self.Dq * 10.0)}_"
@@ -74,7 +82,6 @@ def __init__(
)

def plot(self) -> None:

# Figure one for classical Tanabe-Sugano-Diagram with B-dependency
plt.figure(1)

@@ -86,7 +93,7 @@ def plot(self) -> None:
self.df.drop(["Energy", "delta_B", "10Dq"], axis=1).to_numpy() / self.B,
ls="--",
)
self.label_plot("Tanabe-Sugano-Diagram", "$E/B$", "$\Delta/B$")
self.label_plot("Tanabe-Sugano-Diagram", "$E/B$", r"$\Delta/B$")
# Figure one for Energy-Correlation-Diagram Dq-Energy versus State-Energy
plt.figure(2)

@@ -96,7 +103,7 @@ def plot(self) -> None:
ls="--",
)
self.label_plot(
"DD excitations -Diagram", "$dd-state-energy\,(1/cm)$", "$10Dq\,(1/cm)$"
"DD excitations -Diagram", r"$dd-state-energy\,(1/cm)$", r"$10Dq\,(1/cm)$",
)
plt.show()

@@ -107,7 +114,6 @@ def label_plot(self, arg0: str, arg1: str, arg2: str) -> None:
plt.xlabel(arg2)

def savetxt(self) -> None:

pd.concat(
[
self.df["delta_B"],
@@ -122,55 +128,55 @@ def savetxt(self) -> None:
).to_csv(Path(f"{self.title_DD}.csv"), index=False)

def calculation(self) -> None:
"""
Is filling the self.result with the iTS states of over-iterated energy range
"""Is filling the self.result with the iTS states of over-iterated energy range
"""
result = []
for dq in self.df["Energy"]:
if self.d_count == 2: # d2
result.append(
self.subsplit_states(
matrices.d2(Dq=dq, B=self.B, C=self.C).solver()
)
matrices.d2(Dq=dq, B=self.B, C=self.C).solver(),
),
)
elif self.d_count == 3: # d3
result.append(
self.subsplit_states(
matrices.d3(Dq=dq, B=self.B, C=self.C).solver()
)
matrices.d3(Dq=dq, B=self.B, C=self.C).solver(),
),
)
elif self.d_count == 4: # d4
result.append(
self.subsplit_states(
matrices.d4(Dq=dq, B=self.B, C=self.C).solver()
)
matrices.d4(Dq=dq, B=self.B, C=self.C).solver(),
),
)
elif self.d_count == 5: # d5
result.append(
self.subsplit_states(
matrices.d5(Dq=dq, B=self.B, C=self.C).solver()
)
matrices.d5(Dq=dq, B=self.B, C=self.C).solver(),
),
)
elif self.d_count == 6: # d6
result.append(
self.subsplit_states(
matrices.d6(Dq=dq, B=self.B, C=self.C).solver()
)
matrices.d6(Dq=dq, B=self.B, C=self.C).solver(),
),
)
elif self.d_count == 7: # d7
result.append(
self.subsplit_states(
matrices.d7(Dq=dq, B=self.B, C=self.C).solver()
)
matrices.d7(Dq=dq, B=self.B, C=self.C).solver(),
),
)
elif self.d_count == 8: # d8
result.append(
self.subsplit_states(
matrices.d8(Dq=dq, B=self.B, C=self.C).solver()
)
matrices.d8(Dq=dq, B=self.B, C=self.C).solver(),
),
)
else:
raise ValueError("`d_count` must be in {2,3,4,5,6,7,8}")
msg = "The number of unpaired electrons should be between 2 and 8."
raise ValueError(msg)

# Transform list of dictionaries to dictionary of arrays
result = {
@@ -191,41 +197,33 @@ def subsplit_states(states: dict) -> dict:
return rearranged_states

def ci_cut(self, dq_ci: float = None) -> None:
"""
Extracting the atomic-termsymbols for a specific dq depending on the oxidation state
"""Extracting the atomic-termsymbols for a specific dq depending on the oxidation state
"""
if self.d_count == 2: # d2

states = matrices.d2(Dq=dq_ci / 10.0, B=self.B, C=self.C).solver()
self.ts_print(states, dq_ci=dq_ci)

elif self.d_count == 3: # d3

states = matrices.d3(Dq=dq_ci / 10.0, B=self.B, C=self.C).solver()
self.ts_print(states, dq_ci=dq_ci)

elif self.d_count == 4: # d4

states = matrices.d4(Dq=dq_ci / 10.0, B=self.B, C=self.C).solver()
self.ts_print(states, dq_ci=dq_ci)

elif self.d_count == 5: # d5

states = matrices.d5(Dq=dq_ci / 10.0, B=self.B, C=self.C).solver()
self.ts_print(states, dq_ci=dq_ci)

elif self.d_count == 6: # d6

states = matrices.d6(Dq=dq_ci / 10.0, B=self.B, C=self.C).solver()
self.ts_print(states, dq_ci=dq_ci)

elif self.d_count == 7: # d7

states = matrices.d7(Dq=dq_ci / 10.0, B=self.B, C=self.C).solver()
self.ts_print(states, dq_ci=dq_ci)

elif self.d_count == 8: # d8

states = matrices.d8(Dq=dq_ci / 10.0, B=self.B, C=self.C).solver()
self.ts_print(states, dq_ci=dq_ci)

@@ -241,11 +239,12 @@ def ts_print(self, states: dict, dq_ci: float = None) -> None:
List of atomic-termsymbols for a specific oxidation state
dq_ci : float, optional
Specific crystalfield-splitting in Dq, by default None
"""
count = 0
cut = np.zeros(
self._size + 1,
dtype=[("state", np.unicode_, 7), ("cm", int), ("eV", float)],
dtype=[("state", np.str_, 7), ("cm", int), ("eV", float)],
)
for irreducible in states:
for energy in states[irreducible]:
@@ -288,7 +287,7 @@ def interactive_plot(self) -> None:
if px is None:
raise ImportError(
"Plotly is not installed. Please install plotly "
"with 'pip install tanabesugano[plotly]'!"
"with 'pip install tanabesugano[plotly]'!",
)

_col = self.df.drop(["Energy", "delta_B", "10Dq"], axis=1).columns
@@ -367,7 +366,7 @@ def cmd_line() -> None:

parser = argparse.ArgumentParser(description=description)
parser.add_argument(
"-d", type=int, default=6, help="Number of unpaired electrons (default d5)"
"-d", type=int, default=6, help="Number of unpaired electrons (default d5)",
)
parser.add_argument(
"-Dq",
@@ -399,7 +398,7 @@ def cmd_line() -> None:
"1.)",
)
parser.add_argument(
"-n", type=int, default=500, help="Number of roots (default nroots = 500)"
"-n", type=int, default=500, help="Number of roots (default nroots = 500)",
)
parser.add_argument(
"-ndisp",
646 changes: 302 additions & 344 deletions tanabesugano/matrices.py

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions tanabesugano/test/test_batch.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from tanabesugano.batch import Batch


4 changes: 3 additions & 1 deletion tanabesugano/test/test_front.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from __future__ import annotations

from typing import Any

from tanabesugano import cmd as frontapp


def test_frontapp():
return frontapp.CMDmain(
Dq=4000.0, B=400.0, C=3600.0, nroots=100, d_count=5
Dq=4000.0, B=400.0, C=3600.0, nroots=100, d_count=5,
).calculation()


10 changes: 6 additions & 4 deletions tanabesugano/test/test_num.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import numpy as np

from tanabesugano import matrices
@@ -8,16 +10,16 @@ def state_check(x):
if x == 3:
states = matrices.d3(Dq=i).solver()
return len(states)
elif x == 4:
if x == 4:
states = matrices.d4(Dq=i).solver()
return len(states)
elif x == 5:
if x == 5:
states = matrices.d5(Dq=i).solver()
return len(states)
elif x == 6:
if x == 6:
states = matrices.d6(Dq=i).solver()
return len(states)
elif x == 7:
if x == 7:
states = matrices.d7(Dq=i).solver()
return len(states)

8 changes: 6 additions & 2 deletions tanabesugano/tools.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from typing import Tuple, Union
from __future__ import annotations

from typing import Tuple
from typing import Union

import numpy as np


def racah(
F2: Union[float, np.array], F4: Union[float, np.array]
F2: Union[float, np.array], F4: Union[float, np.array],
) -> Union[Tuple[float, float], Tuple[np.array, np.array]]:
"""Transform the Slater-Condon-Parameter to Racah-Parameter.
@@ -17,6 +20,7 @@ def racah(
Returns:
Union[Tuple[float, float], Tuple[np.array, np.array]]: Return the racah parameters.
"""
eVcm = 8065.54
B = eVcm * (F2 / 49.0 - 5 / 441.0 * F4)

0 comments on commit 19b791d

Please sign in to comment.