Coverage for middle_layer/propose/domain_layer/entities/spectral_specification.py: 96.15%
26 statements
« prev ^ index » next coverage.py v7.10.5, created at 2026-03-09 06:13 +0000
« prev ^ index » next coverage.py v7.10.5, created at 2026-03-09 06:13 +0000
1# Copyright 2024 Associated Universities, Inc.
2#
3# This file is part of Telescope Time Allocation Tools (TTAT).
4#
5# TTAT is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# any later version.
9#
10# TTAT is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with TTAT. If not, see <https://www.gnu.org/licenses/>.
17#
19from typing import TYPE_CHECKING
21from sqlalchemy import Column, ForeignKey, Integer, Table
22from sqlalchemy.orm import Mapped, mapped_column, relationship
24from common.domain_layer.entities.base import Base
25from propose.domain_layer.entities.proposal import CapabilityRequest
27if TYPE_CHECKING:
28 from propose.domain_layer.entities.science_target import ScienceTarget
31science_targets_spectral_specifications = Table(
32 "science_targets_spectral_specifications",
33 Base.metadata,
34 Column(
35 "science_target_id",
36 Integer,
37 ForeignKey("science_targets.science_target_id", ondelete="CASCADE"),
38 unique=True,
39 primary_key=True,
40 ),
41 Column(
42 "spectral_specification_id",
43 Integer,
44 ForeignKey("spectral_specifications.spectral_specification_id", ondelete="CASCADE"),
45 unique=True,
46 primary_key=True,
47 ),
48 extend_existing=True,
49)
52class SpectralSpecification(Base):
53 __tablename__: str = "spectral_specifications"
55 spectral_specification_id: Mapped[int] = mapped_column(primary_key=True)
56 capability_request_id: Mapped[int] = mapped_column(
57 ForeignKey("capability_requests.capability_request_id", ondelete="CASCADE"), nullable=False
58 )
59 capability_request: Mapped["CapabilityRequest"] = relationship(
60 "CapabilityRequest", foreign_keys=[capability_request_id], back_populates="spectral_specifications"
61 )
62 spectral_specification_name: Mapped[str] = mapped_column()
63 center_frequency: Mapped[float] = mapped_column()
64 bandwidth: Mapped[float] = mapped_column()
65 spectral_resolution: Mapped[float] = mapped_column()
66 science_targets: Mapped[list["ScienceTarget"]] = relationship(
67 "ScienceTarget", secondary=science_targets_spectral_specifications, back_populates="spectral_specifications"
68 )
70 def __init__(
71 self,
72 spectral_specification_name: str,
73 center_frequency: float,
74 bandwidth: float,
75 spectral_resolution: float,
76 capability_request: "CapabilityRequest|None" = None,
77 ):
78 super().__init__(
79 spectral_specification_name=spectral_specification_name,
80 center_frequency=center_frequency,
81 bandwidth=bandwidth,
82 spectral_resolution=spectral_resolution,
83 capability_request=capability_request,
84 )
86 # Handle the capability_request relationship if provided
87 if capability_request:
88 self.capability_request = capability_request
89 # If no ID was provided but we have a capability_request object, get ID from it
90 if not self.capability_request_id and capability_request.capability_request_id:
91 self.capability_request_id = capability_request.capability_request_id
93 def clone(self, parent: "CapabilityRequest|None" = None) -> "SpectralSpecification":
94 return SpectralSpecification(
95 spectral_specification_name=self.spectral_specification_name,
96 center_frequency=self.center_frequency,
97 bandwidth=self.bandwidth,
98 spectral_resolution=self.spectral_resolution,
99 capability_request=parent if parent else self.capability_request,
100 )