LCOV - code coverage report
Current view: top level - src/pairinteraction/ket - ket_base.py (source / functions) Hit Total Coverage
Test: coverage.info Lines: 42 47 89.4 %
Date: 2026-04-30 10:43:26 Functions: 8 10 80.0 %

          Line data    Source code
       1             : # SPDX-FileCopyrightText: 2024 PairInteraction Developers
       2             : # SPDX-License-Identifier: LGPL-3.0-or-later
       3           1 : from __future__ import annotations
       4             : 
       5           1 : from abc import ABC
       6           1 : from typing import TYPE_CHECKING, Literal, TypeAlias, overload
       7             : 
       8           1 : from pairinteraction.enums import get_python_parity
       9           1 : from pairinteraction.units import QuantityScalar
      10             : 
      11             : if TYPE_CHECKING:
      12             :     from typing_extensions import Self
      13             : 
      14             :     from pairinteraction import _backend
      15             :     from pairinteraction.enums import Parity
      16             :     from pairinteraction.units import PintFloat
      17             : 
      18           1 : UnionCPPKet: TypeAlias = "_backend.KetAtom | _backend.KetPairComplex"
      19             : 
      20             : 
      21           1 : class KetBase(ABC):
      22             :     """Base class for all Ket objects.
      23             : 
      24             :     The ket objects are meant to represent mathematically the canonical basis states, with respect to which
      25             :     the coefficient matrix of the basis objects are defined.
      26             :     For single atoms we simply choose the atomic states defined by their quantum numbers,
      27             :     therefore all KetAtom objects are orthogonal to each other.
      28             :     For pair systems, we choose the product states of the single-atom eigenstates, which depends on the system
      29             :     and the applied fields. Thus for different pair systems the KetPair objects are not necessarily orthogonal anymore.
      30             : 
      31             :     All ket objects share a few common attributes and methods, that are defined in this base class.
      32             :     E.g. each ket has a total momentum quantum number f, a magnetic quantum number m, a parity, an energy,
      33             :     as well as a label that represents the ket.
      34             :     """
      35             : 
      36           1 :     _cpp: UnionCPPKet
      37             : 
      38           1 :     @classmethod
      39           1 :     def _from_cpp_object(cls: type[Self], cpp_obj: UnionCPPKet) -> Self:
      40           1 :         obj = cls.__new__(cls)
      41           1 :         obj._cpp = cpp_obj
      42           1 :         return obj
      43             : 
      44           1 :     def __repr__(self) -> str:
      45           0 :         return f"{type(self).__name__}({self.get_label('raw')})"
      46             : 
      47           1 :     def __str__(self) -> str:
      48           1 :         return self.get_label("ket")
      49             : 
      50           1 :     def __hash__(self) -> int:
      51           0 :         return self._cpp.__hash__()
      52             : 
      53           1 :     def __eq__(self, other: object) -> bool:
      54           1 :         if not isinstance(other, KetBase):
      55           0 :             return NotImplemented
      56           1 :         if type(self._cpp) is not type(other._cpp):
      57           0 :             return False
      58           1 :         return self._cpp == other._cpp  # type: ignore [operator]
      59             : 
      60           1 :     @property
      61           1 :     def m(self) -> float:
      62             :         """The magnetic quantum number m (int or half-int)."""
      63           1 :         return self._cpp.get_quantum_number_m()
      64             : 
      65           1 :     @property
      66           1 :     def f(self) -> float:
      67             :         """The total momentum quantum number f (int or half-int)."""
      68           1 :         return self._cpp.get_quantum_number_f()
      69             : 
      70           1 :     @property
      71           1 :     def parity(self) -> Parity:
      72             :         """The parity of the ket."""
      73           1 :         parity_cpp = self._cpp.get_parity()
      74           1 :         return get_python_parity(parity_cpp)
      75             : 
      76           1 :     def get_label(self, fmt: Literal["raw", "ket", "bra"] = "raw") -> str:
      77             :         """Label representing the ket.
      78             : 
      79             :         Args:
      80             :             fmt: The format of the label, i.e. whether to return the raw label, or the label in ket or bra notation.
      81             : 
      82             :         Returns:
      83             :             The label of the ket in the given format.
      84             : 
      85             :         """
      86           1 :         raw = self._cpp.get_label()
      87           1 :         if fmt == "raw":
      88           1 :             return raw
      89           1 :         if fmt == "ket":
      90           1 :             return f"|{raw}⟩"
      91           1 :         if fmt == "bra":
      92           1 :             return f"⟨{raw}|"
      93           0 :         raise ValueError(f"Unknown fmt {fmt}")
      94             : 
      95             :     @overload
      96             :     def get_energy(self, unit: None = None) -> PintFloat: ...
      97             : 
      98             :     @overload
      99             :     def get_energy(self, unit: str) -> float: ...
     100             : 
     101           1 :     def get_energy(self, unit: str | None = None) -> float | PintFloat:
     102             :         """Get the energy of the ket in the given unit.
     103             : 
     104             :         Args:
     105             :             unit: The unit to which to convert the energy to.
     106             :                 Default None will return a `pint.Quantity`.
     107             : 
     108             :         Returns:
     109             :             The energy as float if a unit was given, otherwise a `pint.Quantity`.
     110             : 
     111             :         """
     112           1 :         energy_au = self._cpp.get_energy()
     113           1 :         return QuantityScalar.convert_au_to_user(energy_au, "energy", unit)

Generated by: LCOV version 1.16