LCOV - code coverage report
Current view: top level - src/pairinteraction/ket - ket_base.py (source / functions) Hit Total Coverage
Test: coverage.info Lines: 34 38 89.5 %
Date: 2026-07-22 07:03:46 Functions: 6 7 85.7 %

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

Generated by: LCOV version 1.16