Line data Source code
1 : # SPDX-FileCopyrightText: 2025 PairInteraction Developers
2 : # SPDX-License-Identifier: LGPL-3.0-or-later
3 1 : from __future__ import annotations
4 :
5 1 : import logging
6 1 : from dataclasses import dataclass
7 1 : from typing import TYPE_CHECKING
8 :
9 1 : import pairinteraction as pi
10 1 : from pairinteraction_gui.calculate.calculate_base import as_string, dict_to_repl
11 :
12 : if TYPE_CHECKING:
13 : import numpy as np
14 : from numpy.typing import NDArray
15 :
16 : from pairinteraction_gui.config.ket_config import QuantumNumbers
17 : from pairinteraction_gui.page import LifetimesPage
18 :
19 1 : logger = logging.getLogger(__name__)
20 :
21 :
22 1 : @dataclass
23 1 : class ParametersLifetimes:
24 : """Parameters for the lifetimes calculation."""
25 :
26 1 : species: str
27 1 : quantum_numbers: QuantumNumbers
28 1 : temperature: float
29 :
30 1 : @classmethod
31 1 : def from_page(cls, page: LifetimesPage) -> ParametersLifetimes:
32 : """Create ParametersLifetimes from the GUI page state."""
33 1 : return cls(
34 : species=page.ket_config.get_species(),
35 : quantum_numbers=page.ket_config.get_quantum_numbers(),
36 : temperature=page.ket_config.get_temperature(),
37 : )
38 :
39 1 : def to_replacement_dict(self) -> dict[str, str]:
40 : """Return a dictionary with the parameters for template replacement."""
41 1 : return {
42 : "$SPECIES_0": as_string(self.species),
43 : "$QUANTUM_NUMBERS_0": dict_to_repl(self.quantum_numbers),
44 : "$TEMPERATURE": str(self.temperature),
45 : }
46 :
47 :
48 1 : @dataclass
49 1 : class KetData:
50 : """Picklable representation of a KetAtom for inter-process transfer."""
51 :
52 1 : n: int
53 1 : label: str
54 :
55 1 : def __str__(self) -> str:
56 0 : return self.label
57 :
58 :
59 1 : @dataclass
60 1 : class ResultsLifetimes:
61 : """Results for the lifetimes calculation."""
62 :
63 1 : kets_sp: list[KetData]
64 1 : transition_rates_sp: NDArray[np.float64]
65 1 : kets_bbr: list[KetData]
66 1 : transition_rates_bbr: NDArray[np.float64]
67 1 : lifetime: float
68 :
69 :
70 1 : def calculate_lifetimes(parameters: ParametersLifetimes) -> ResultsLifetimes:
71 : """Calculate the transition rates for a given ket."""
72 1 : return _calculate_lifetimes(parameters)
73 :
74 :
75 1 : def _calculate_lifetimes(parameters: ParametersLifetimes) -> ResultsLifetimes:
76 : """Make the unwrapped function available for testing."""
77 1 : ket = pi.KetAtom(parameters.species, **parameters.quantum_numbers)
78 1 : kets_sp, rates_sp = ket.get_spontaneous_transition_rates(unit="1/ms")
79 1 : kets_bbr, rates_bbr = ket.get_black_body_transition_rates(parameters.temperature, "K", unit="1/ms")
80 1 : lifetime = ket.get_lifetime(parameters.temperature, temperature_unit="K", unit="mus")
81 1 : return ResultsLifetimes(
82 : kets_sp=[KetData(n=int(k.n), label=str(k)) for k in kets_sp],
83 : transition_rates_sp=rates_sp,
84 : kets_bbr=[KetData(n=int(k.n), label=str(k)) for k in kets_bbr],
85 : transition_rates_bbr=rates_bbr,
86 : lifetime=lifetime,
87 : )
|