LCOV - code coverage report
Current view: top level - src/pairinteraction_gui/config - system_config.py (source / functions) Hit Total Coverage
Test: coverage.info Lines: 73 74 98.6 %
Date: 2025-09-29 10:28:29 Functions: 11 22 50.0 %

          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 : from typing import TYPE_CHECKING, Literal
       6             : 
       7           1 : import numpy as np
       8           1 : from PySide6.QtWidgets import (
       9             :     QLabel,
      10             : )
      11             : 
      12           1 : from pairinteraction_gui.config.base_config import BaseConfig
      13           1 : from pairinteraction_gui.qobjects import Item, QnItemInt, RangeItem
      14             : 
      15             : if TYPE_CHECKING:
      16             :     from pairinteraction_gui.page import OneAtomPage, TwoAtomsPage
      17             : 
      18             : 
      19           1 : RangesKeys = Literal["Ex", "Ey", "Ez", "Bx", "By", "Bz", "Distance", "Angle"]
      20             : 
      21             : 
      22           1 : class SystemConfig(BaseConfig):
      23             :     """Section for configuring the system parameters."""
      24             : 
      25           1 :     margin = (5, 15, 5, 5)
      26           1 :     spacing = 10
      27             : 
      28           1 :     title = "System"
      29           1 :     page: OneAtomPage | TwoAtomsPage
      30             : 
      31           1 :     def setupEField(self) -> None:
      32           1 :         efield_label = QLabel("<b>Electric field</b>")
      33           1 :         self.layout().addWidget(efield_label)
      34             : 
      35           1 :         self.Ex = RangeItem(self, "Ex", unit="V/cm", tooltip_label="electric field in x-direction")
      36           1 :         self.Ey = RangeItem(self, "Ey", unit="V/cm", tooltip_label="electric field in y-direction")
      37           1 :         self.Ez = RangeItem(self, "Ez", unit="V/cm", tooltip_label="electric field in z-direction")
      38             : 
      39           1 :         self.layout().addWidget(self.Ex)
      40           1 :         self.layout().addWidget(self.Ey)
      41           1 :         self.layout().addWidget(self.Ez)
      42             : 
      43           1 :     def setupBField(self) -> None:
      44           1 :         bfield_label = QLabel("<b>Magnetic field</b>")
      45           1 :         self.layout().addWidget(bfield_label)
      46             : 
      47           1 :         self.Bx = RangeItem(self, "Bx", unit="Gauss", tooltip_label="magnetic field in x-direction")
      48           1 :         self.By = RangeItem(self, "By", unit="Gauss", tooltip_label="magnetic field in y-direction")
      49           1 :         self.Bz = RangeItem(self, "Bz", unit="Gauss", tooltip_label="magnetic field in z-direction")
      50             : 
      51           1 :         self.layout().addWidget(self.Bx)
      52           1 :         self.layout().addWidget(self.By)
      53           1 :         self.layout().addWidget(self.Bz)
      54             : 
      55           1 :     def setupDiamagnetism(self) -> None:
      56           1 :         self.layout().addWidget(QLabel("<b>Diamagnetism</b>"))
      57           1 :         self.diamagnetism = Item(self, "Enable diamagnetism", checked=True)
      58           1 :         self.layout().addWidget(self.diamagnetism)
      59             : 
      60           1 :     def get_ranges_dict(self) -> dict[RangesKeys, list[float]]:
      61             :         """Return the electric and magnetic field ranges."""
      62           1 :         steps = self.page.calculation_config.steps.value()
      63           1 :         all_ranges = self._get_all_ranges()
      64           1 :         ranges_min_max: dict[str, tuple[float, float]] = {
      65             :             item.label.text(): item.values() for item in all_ranges if item.isChecked()
      66             :         }
      67           1 :         if len(ranges_min_max) == 0:
      68           0 :             ranges_min_max["Bz"] = (0, 0)
      69             : 
      70           1 :         return {key: np.linspace(value[0], value[1], steps).tolist() for key, value in ranges_min_max.items()}  # type: ignore [misc]
      71             : 
      72           1 :     def _get_all_ranges(self) -> list[RangeItem]:
      73             :         """Return all range items."""
      74           1 :         return [self.Ex, self.Ey, self.Ez, self.Bx, self.By, self.Bz]
      75             : 
      76             : 
      77           1 : class SystemConfigOneAtom(SystemConfig):
      78           1 :     page: OneAtomPage
      79             : 
      80           1 :     def setupWidget(self) -> None:
      81           1 :         self.setupEField()
      82           1 :         self.setupBField()
      83           1 :         self.setupDiamagnetism()
      84             : 
      85             : 
      86           1 : class SystemConfigTwoAtoms(SystemConfig):
      87           1 :     page: TwoAtomsPage
      88             : 
      89           1 :     def setupWidget(self) -> None:
      90           1 :         self.setupEField()
      91           1 :         self.setupBField()
      92           1 :         self.setupDiamagnetism()
      93           1 :         self.setupDistance()
      94           1 :         self.setupAngle()
      95           1 :         self.setupOrder()
      96             : 
      97           1 :     def setupDistance(self) -> None:
      98           1 :         label = QLabel("<b>Distance</b>")
      99           1 :         self.layout().addWidget(label)
     100             : 
     101           1 :         self.distance = RangeItem(self, "Distance", vdefaults=(3, 8), vrange=(0, np.inf), unit="<span>&mu;m</span>")
     102           1 :         self.layout().addWidget(self.distance)
     103             : 
     104           1 :     def setupAngle(self) -> None:
     105           1 :         label = QLabel("<b>Angle</b> (0° = z-axis, 90° = x-axis)")
     106           1 :         self.layout().addWidget(label)
     107             : 
     108           1 :         self.angle = RangeItem(self, "Angle", vdefaults=(0, 0), vrange=(0, 360), unit="degree")
     109           1 :         self.layout().addWidget(self.angle)
     110             : 
     111           1 :     def setupOrder(self) -> None:
     112           1 :         self.layout().addWidget(QLabel("<b>Multipole expansion order</b>"))
     113           1 :         self.order = QnItemInt(
     114             :             self,
     115             :             "Multipole order",
     116             :             vmin=3,
     117             :             vmax=5,
     118             :             vdefault=3,
     119             :             tooltip="Select the order of the multipole expansion",
     120             :             checkable=False,
     121             :         )
     122           1 :         self.layout().addWidget(self.order)
     123             : 
     124           1 :     def _get_all_ranges(self) -> list[RangeItem]:
     125             :         """Return all range items."""
     126           1 :         return [*super()._get_all_ranges(), self.distance, self.angle]

Generated by: LCOV version 1.16