diff --git a/mapcat/alembic/versions/b809eded6421_add_planet_map_tables.py b/mapcat/alembic/versions/b809eded6421_add_planet_map_tables.py new file mode 100644 index 0000000..2887c80 --- /dev/null +++ b/mapcat/alembic/versions/b809eded6421_add_planet_map_tables.py @@ -0,0 +1,242 @@ +"""add planet map tables + +Revision ID: b809eded6421 +Revises: 0762b3c7694d +Create Date: 2026-10-07 11:21:13.132297 + +""" +from collections.abc import Sequence + +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = 'b809eded6421' +down_revision: str | None = '0762b3c7694d' +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + # ------------------------------------------------------------------ + # planet_map + # ------------------------------------------------------------------ + op.create_table( + "planet_map", + sa.Column("obs_id", sa.String(), nullable=False), + sa.Column("telescope", sa.String(), nullable=False), + sa.Column("freq_channel", sa.String(), nullable=False), + sa.Column("wafer", sa.String(), nullable=False), + sa.Column("source", sa.String(), nullable=False), + + sa.Column("ctime", sa.DateTime(), nullable=False), + + sa.Column("hit_path", sa.String(), nullable=True), + sa.Column("map_path", sa.String(), nullable=True), + sa.Column("weight_path", sa.String(), nullable=True), + sa.Column("weighted_map_path", sa.String(), nullable=True), + + sa.Column("elevation", sa.Float(), nullable=True), + sa.Column("duration", sa.Float(), nullable=True), + sa.Column("azimuth", sa.Float(), nullable=True), + + sa.Column("pwv", sa.Float(), nullable=True), + sa.Column("pwv_std", sa.Float(), nullable=True), + sa.Column("pwv_p2p", sa.Float(), nullable=True), + + sa.Column("pwv_apex", sa.Float(), nullable=True), + sa.Column("pwv_apex_std", sa.Float(), nullable=True), + sa.Column("pwv_apex_p2p", sa.Float(), nullable=True), + + sa.Column("f_hwp", sa.Float(), nullable=True), + sa.Column("roll_angle", sa.Float(), nullable=True), + sa.Column("scan_speed", sa.Float(), nullable=True), + sa.Column("scan_acc", sa.Float(), nullable=True), + + sa.Column("sun_distance", sa.Float(), nullable=True), + sa.Column("moon_distance", sa.Float(), nullable=True), + + sa.Column("wind_speed", sa.Float(), nullable=True), + sa.Column("wind_direction", sa.Float(), nullable=True), + sa.Column("ambient_temperature", sa.Float(), nullable=True), + sa.Column("uv", sa.Float(), nullable=True), + + sa.Column( + "detnum_before_fitselection", + sa.Integer(), + nullable=True, + ), + sa.Column( + "total_detnum", + sa.Integer(), + nullable=True, + ), + sa.Column( + "recenter", + sa.Boolean(), + nullable=True, + ), + + sa.Column("yc", sa.Float(), nullable=True), + sa.Column("xc", sa.Float(), nullable=True), + + sa.Column( + "Tmap_variance", + sa.Float(), + nullable=True, + ), + sa.Column( + "Qmap_variance", + sa.Float(), + nullable=True, + ), + sa.Column( + "Umap_variance", + sa.Float(), + nullable=True, + ), + + sa.Column( + "proc", + sa.JSON(), + nullable=True, + ), + sa.Column( + "detnum", + sa.JSON(), + nullable=True, + ), + sa.Column( + "detid", + sa.JSON(), + nullable=True, + ), + + sa.PrimaryKeyConstraint( + "obs_id", + "telescope", + "freq_channel", + "wafer", + "source", + ), + ) + + # ------------------------------------------------------------------ + # planet_map_fits + # ------------------------------------------------------------------ + op.create_table( + "planet_map_fits", + sa.Column("obs_id", sa.String(), nullable=False), + sa.Column("telescope", sa.String(), nullable=False), + sa.Column("freq_channel", sa.String(), nullable=False), + sa.Column("wafer", sa.String(), nullable=False), + sa.Column("source", sa.String(), nullable=False), + + # Main-beam fit result (T map) + sa.Column("peak", sa.Float(), nullable=True), + sa.Column("amplitude", sa.Float(), nullable=True), + sa.Column("xo", sa.Float(), nullable=True), + sa.Column("yo", sa.Float(), nullable=True), + sa.Column("sigmax", sa.Float(), nullable=True), + sa.Column("sigmay", sa.Float(), nullable=True), + sa.Column("theta", sa.Float(), nullable=True), + sa.Column("redchit", sa.Float(), nullable=True), + + # Leakage-beam fit result (Q map) + sa.Column("mq", sa.Float(), nullable=True), + sa.Column("d0q", sa.Float(), nullable=True), + sa.Column("d1q", sa.Float(), nullable=True), + sa.Column("sigmaq", sa.Float(), nullable=True), + sa.Column("redchiq", sa.Float(), nullable=True), + + # Leakage-beam fit result (U map) + sa.Column("mu", sa.Float(), nullable=True), + sa.Column("d0u", sa.Float(), nullable=True), + sa.Column("d1u", sa.Float(), nullable=True), + sa.Column("sigmau", sa.Float(), nullable=True), + sa.Column("redchiu", sa.Float(), nullable=True), + + sa.ForeignKeyConstraint( + [ + "obs_id", + "telescope", + "freq_channel", + "wafer", + "source", + ], + [ + "planet_map.obs_id", + "planet_map.telescope", + "planet_map.freq_channel", + "planet_map.wafer", + "planet_map.source", + ], + ondelete="CASCADE", + ), + + sa.PrimaryKeyConstraint( + "obs_id", + "telescope", + "freq_channel", + "wafer", + "source", + ), + ) + + # ------------------------------------------------------------------ + # planet_todfit + # ------------------------------------------------------------------ + op.create_table( + "planet_todfit", + sa.Column("obs_id", sa.String(), nullable=False), + sa.Column("telescope", sa.String(), nullable=False), + sa.Column("freq_channel", sa.String(), nullable=False), + sa.Column("wafer", sa.String(), nullable=False), + sa.Column("source", sa.String(), nullable=False), + sa.Column("detid", sa.String(), nullable=False), + + sa.Column("ctime", sa.DateTime(), nullable=False), + + sa.Column("amplitude", sa.Float(), nullable=True), + sa.Column("xo", sa.Float(), nullable=True), + sa.Column("yo", sa.Float(), nullable=True), + sa.Column("sigmax", sa.Float(), nullable=True), + sa.Column("sigmay", sa.Float(), nullable=True), + sa.Column("theta", sa.Float(), nullable=True), + + sa.Column("defla", sa.Float(), nullable=True), + sa.Column("deflp", sa.Float(), nullable=True), + + sa.Column("amplitude_err", sa.Float(), nullable=True), + sa.Column("xo_err", sa.Float(), nullable=True), + sa.Column("yo_err", sa.Float(), nullable=True), + sa.Column("sigmax_err", sa.Float(), nullable=True), + sa.Column("sigmay_err", sa.Float(), nullable=True), + sa.Column("theta_err", sa.Float(), nullable=True), + + sa.Column("defla_err", sa.Float(), nullable=True), + sa.Column("deflp_err", sa.Float(), nullable=True), + + sa.Column("chisq", sa.Float(), nullable=True), + sa.Column("dof", sa.Integer(), nullable=True), + + sa.Column("xi", sa.Float(), nullable=True), + sa.Column("eta", sa.Float(), nullable=True), + sa.Column("gamma", sa.Float(), nullable=True), + + sa.PrimaryKeyConstraint( + "obs_id", + "telescope", + "freq_channel", + "wafer", + "source", + "detid", + ), + ) + + + +def downgrade() -> None: + op.drop_table("planet_map_fits") + op.drop_table("planet_todfit") + op.drop_table("planet_map") \ No newline at end of file diff --git a/mapcat/database/__init__.py b/mapcat/database/__init__.py index 6839745..4b37801 100644 --- a/mapcat/database/__init__.py +++ b/mapcat/database/__init__.py @@ -7,6 +7,8 @@ from .depth_one_coadd import DepthOneCoaddTable from .depth_one_map import DepthOneMapTable from .pipeline_information import PipelineInformationTable +from .planet_map import PlanetMapFitTable, PlanetMapTable +from .planet_todfit import PlanetTodFitTable from .pointing_residual import PointingResidualTable from .sky_coverage import SkyCoverageTable from .time_domain_processing import TimeDomainProcessingTable @@ -18,6 +20,9 @@ "DepthOneCoaddTable", "DepthOneMapTable", "PipelineInformationTable", + "PlanetMapFitTable", + "PlanetMapTable", + "PlanetTodFitTable", "PointingResidualTable", "SkyCoverageTable", "TODDepthOneTable", @@ -34,4 +39,7 @@ TODDepthOneTable, PipelineInformationTable, SkyCoverageTable, + PlanetMapTable, + PlanetMapFitTable, + PlanetTodFitTable, ] diff --git a/mapcat/database/planet_map.py b/mapcat/database/planet_map.py new file mode 100644 index 0000000..71ea4bc --- /dev/null +++ b/mapcat/database/planet_map.py @@ -0,0 +1,334 @@ +""" +Table for planet maps. +""" + +from datetime import datetime +from typing import Any, Optional + +from astropy.time import Time +from astropydantic import AstroPydanticTime +from sqlalchemy import JSON, Column, ForeignKeyConstraint +from sqlmodel import Field, Relationship, SQLModel + + +class PlanetMap(SQLModel): + obs_id: str + telescope: str + freq_channel: str + wafer: str + ctime: AstroPydanticTime + source: str + + hit_path: str | None + map_path: str | None + weight_path: str | None + weighted_map_path: str | None + + azimuth: float | None + elevation: float | None + duration: float| None + pwv: float | None + pwv_std: float | None + pwv_p2p: float | None + pwv_apex: float | None + pwv_apex_std: float | None + pwv_apex_p2p: float | None + + f_hwp: float | None + roll_angle: float | None + scan_speed: float | None + scan_acc: float | None + sun_distance: float | None + moon_distance: float | None + wind_speed: float | None + wind_direction: float | None + ambient_temperature: float | None + uv: float | None + + detnum_before_fitselection: int | None + total_detnum: int | None + recenter: bool | None + yc: float | None + xc: float | None + + Tmap_variance: float | None + Qmap_variance: float | None + Umap_variance: float | None + + proc: dict[str, Any] | list[Any] | None = None + detnum: list[int] | None = None + detid: list[str] | None = None + + +class PlanetMapTable(SQLModel, table=True): + """ + A planet map. + + Attributes + ---------- + obs_id : str + observation id + telescope : str + Telescope + freq_channel : str + frequency channel of map + wafer : str + wafer slot + source : str + source. eg jupiter + ctime : datetime + unix time of map + hit_path : str + path of hit map + map_path : str + path of map + weight_path : str + path of weight + weighted_map_path : str + path of weighted_map + elevation : float + elevation of telescope + azimuth : float + azimuth of telescope + pwv: float + mean of precipitable water vapor + pwv_std: float + standard deviation of pwv + pwv_p2p: float + peak-to-peak of pwv + pwv_apex: float + mean of pwv taken by apex + pwv_apex_std: float + standard deviation of pwv apex + pwv_apex_p2p: float + peak-to-peak of pwv apex + f_hwp: float + hwp rotation frequency + roll_angle: float + roll angle + scan_speed: float + scan speed in deg/s + scan_acc: float + scan acceleration in deg/s^2 + sun_distance: float + distance to sun + moon_distance: float + distance to moon + wind_speed: float + wind speed + wind_direction: float + wind direction + ambient_temperature: float + ambient temperature + uv: float + uv index + detnum_before_fitselection: int + number of detectors before fit selection + total_detnum: int + total number of detectors + recenter: bool + recenter flag + yc: float + center of map in y direction + xc: float + center of map in x direction + Tmap_variance: float + variance of T map in pW + Qmap_variance: float + variance of Q map in pW + Umap_variance: float + variance of U map in pW + proc: dict + preprocessing names + detnum: list + list of detector numbers on each proc + detid: list + list of detector ids + """ + + __tablename__ = "planet_map" + + obs_id: str = Field(primary_key=True) + telescope: str = Field(primary_key=True) + freq_channel: str = Field(primary_key=True) + wafer: str = Field(primary_key=True) + source: str = Field(primary_key=True) + + ctime: datetime = Field(nullable=False) + hit_path: str | None = Field() + map_path: str | None = Field() + weight_path: str | None = Field() + weighted_map_path: str | None = Field() + + elevation: float | None = Field() + duration: float | None = Field() + azimuth: float | None = Field() + pwv: float | None = Field() + pwv_std: float | None = Field() + pwv_p2p: float | None = Field() + pwv_apex: float | None = Field() + pwv_apex_std: float | None = Field() + pwv_apex_p2p: float | None = Field() + f_hwp: float | None = Field() + roll_angle: float | None = Field() + scan_speed: float | None = Field() + scan_acc: float | None = Field() + sun_distance: float | None = Field() + moon_distance: float | None = Field() + wind_speed: float | None = Field() + wind_direction: float | None = Field() + ambient_temperature: float | None = Field() + uv: float | None = Field() + + detnum_before_fitselection: int | None = Field() + total_detnum: int | None = Field() + recenter: bool | None = Field() + yc: float | None = Field() + xc: float | None = Field() + + Tmap_variance: float | None = Field() + Qmap_variance: float | None = Field() + Umap_variance: float | None = Field() + + proc: dict[str, Any] | list[Any] | None = Field( + default=None, + sa_column=Column(JSON, nullable=True), + ) + detnum: list[int] | None = Field( + default=None, + sa_column=Column(JSON, nullable=True), + ) + detid: list[str] | None = Field( + default=None, + sa_column=Column(JSON, nullable=True), + ) + + fit: Optional["PlanetMapFitTable"] = Relationship( + back_populates="map", + cascade_delete=True, + sa_relationship_kwargs={ + "uselist": False, + }, + ) + + def to_model(self) -> PlanetMap: + """ + Return an PlanetMap model from this table entry. + + Returns + ------- + PlanetMap : PlanetMap + The PlanetMap model corresponding to this table entry. + """ + return PlanetMap( + obs_id=self.obs_id, + telescope=self.telescope, + freq_channel=self.freq_channel, + wafer=self.wafer, + ctime=Time(self.ctime, format="unix", scale="utc"), + source=self.source, + hit_path=self.hit_path, + map_path=self.map_path, + weight_path=self.weight_path, + weighted_map_path=self.weighted_map_path, + azimuth=self.azimuth, + elevation=self.elevation, + duration=self.duration, + pwv=self.pwv, + pwv_std=self.pwv_std, + pwv_p2p=self.pwv_p2p, + pwv_apex=self.pwv_apex, + pwv_apex_std=self.pwv_apex_std, + pwv_apex_p2p=self.pwv_apex_p2p, + f_hwp=self.f_hwp, + roll_angle=self.roll_angle, + scan_speed=self.scan_speed, + scan_acc=self.scan_acc, + sun_distance=self.sun_distance, + moon_distance=self.moon_distance, + wind_speed=self.wind_speed, + wind_direction=self.wind_direction, + ambient_temperature=self.ambient_temperature, + uv=self.uv, + detnum_before_fitselection=self.detnum_before_fitselection, + total_detnum=self.total_detnum, + recenter=self.recenter, + yc=self.yc, + xc=self.xc, + Tmap_variance=self.Tmap_variance, + Qmap_variance=self.Qmap_variance, + Umap_variance=self.Umap_variance, + proc=self.proc, + detnum=self.detnum, + detid=self.detid, + ) + +class PlanetMapFitTable(SQLModel, table=True): + """ + Table for Main-beam and leakage-beam fit results for a planet map. + + Attributes + ---------- + map_id : int + Internal ID of the depth one map + residual_model: ConstantPointingModel | PolynomialPointingModel + The pointing model to actually store in the database. + residual_stats: PointingModelStats + Statistics about the pointing residuals, such as mean and stddev of RA and Dec offsets + """ + + __tablename__ = "planet_map_fits" + __table_args__ = ( + ForeignKeyConstraint( + [ + "obs_id", + "telescope", + "freq_channel", + "wafer", + "source", + ], + [ + "planet_map.obs_id", + "planet_map.telescope", + "planet_map.freq_channel", + "planet_map.wafer", + "planet_map.source", + ], + ondelete="CASCADE", + ), + ) + + # Same primary key as PlanetMapTable + obs_id: str = Field(primary_key=True) + telescope: str = Field(primary_key=True) + freq_channel: str = Field(primary_key=True) + wafer: str = Field(primary_key=True) + source: str = Field(primary_key=True) + + # Main-beam fit result (T map) + peak: float | None = Field() + amplitude: float | None = Field() + xo: float | None = Field() + yo: float | None = Field() + sigmax: float | None = Field() + sigmay: float | None = Field() + theta: float | None = Field() + redchit: float | None = Field() + + # Leakage-beam fit result (Q map) + mq: float | None = Field() + d0q: float | None = Field() + d1q: float | None = Field() + sigmaq: float | None = Field() + redchiq: float | None = Field() + + # Leakage-beam fit result (U map) + mu: float | None = Field() + d0u: float | None = Field() + d1u: float | None = Field() + sigmau: float | None = Field() + redchiu: float | None = Field() + + map: "PlanetMapTable" = Relationship( + back_populates="fit", + ) diff --git a/mapcat/database/planet_todfit.py b/mapcat/database/planet_todfit.py new file mode 100644 index 0000000..1c0149c --- /dev/null +++ b/mapcat/database/planet_todfit.py @@ -0,0 +1,178 @@ +""" +Table for planet todfit. +""" + +from datetime import datetime + +from astropy.time import Time +from astropydantic import AstroPydanticTime +from sqlmodel import Field, SQLModel + + +class PlanetTodFit(SQLModel): + obs_id: str + telescope: str + freq_channel: str + wafer: str + ctime: AstroPydanticTime + source: str + detid: str + + amplitude: float | None + xo: float | None + yo: float | None + sigmax: float | None + sigmay: float | None + theta: float | None + defla: float | None + deflp: float | None + amplitude_err: float | None + xo_err: float | None + yo_err: float | None + sigmax_err: float | None + sigmay_err: float | None + theta_err: float | None + defla_err: float | None + deflp_err: float | None + chisq: float | None + dof: int | None + xi: float | None + eta: float | None + gamma: float | None + + +class PlanetTodFitTable(SQLModel, table=True): + """ + Table for a todfit result of planet observation. + Attributes + ---------- + obs_id : str + observation id + telescope : str + Telescope + freq_channel : str + Frequency band + wafer : str + Wafer slot + source : str + source. eg jupiter + detid : str + detector id + ctime : datetime + start unix time of map + amplitude : float + amplitude of planet signal normalized by solid angle with an unit of degree + xo : float + x offset of planet signal. Unit in degree + yo : float + y offset of planet signal. Unit in degree + sigmax : float + sigma of planet signal in x direction. Unit in degree + sigmay : float + sigma of planet signal in y direction. Unit in degree + theta : float + angle of elliptical gaussian. Unit in degree + defla : float + deflection amplitude. Unit in radian + deflp : float + deflection phase. Unit in radian + amplitude_err : float + error of amplitude + xo_err : float + error of xo + yo_err : float + error of yo + sigmax_err : float + error of sigmax + sigmay_err : float + error of sigmay + theta_err : float + error of theta + defla_err : float + error of defla + deflp_err : float + error of deflp + chisq : float + chi square + dof : int + degree of freedom + xi : float + detector xi position in focal plane coordinate. Unit in radian + eta : float + detector eta position in focal plane coordinate. Unit in radian + gamma : float + detector gamma angle in focal plane coordinate. Unit in radian + + """ + __tablename__ = "planet_todfit" + + obs_id: str = Field(primary_key=True) + telescope: str = Field(primary_key=True) + freq_channel: str = Field(primary_key=True) + wafer: str = Field(primary_key=True) + source: str = Field(primary_key=True) + detid: str = Field(primary_key=True) + + ctime: datetime = Field(nullable=False) + amplitude: float | None = Field() + xo: float | None = Field() + yo: float | None = Field() + sigmax: float | None = Field() + sigmay: float | None = Field() + theta: float | None = Field() + defla: float | None = Field() + deflp: float | None = Field() + amplitude_err: float | None = Field() + xo_err: float | None = Field() + yo_err: float | None = Field() + sigmax_err: float | None = Field() + sigmay_err: float | None = Field() + theta_err: float | None = Field() + defla_err: float | None = Field() + deflp_err: float | None = Field() + chisq: float | None = Field() + dof: int | None = Field() + xi: float | None = Field() + eta: float | None = Field() + gamma: float | None = Field() + + + def to_model(self) -> PlanetTodFit: + """ + Return an PlanetTodFit model from this table entry. + + Returns + ------- + PlanetTodFit : PlanetTodFit + The PlanetTodFit model corresponding to this table entry. + """ + return PlanetTodFit( + obs_id=self.obs_id, + telescope=self.telescope, + freq_channel=self.freq_channel, + wafer=self.wafer, + ctime=Time(self.ctime, format="unix", scale="utc"), + source=self.source, + detid=self.detid, + amplitude=self.amplitude, + xo=self.xo, + yo=self.yo, + sigmax=self.sigmax, + sigmay=self.sigmay, + theta=self.theta, + defla=self.defla, + deflp=self.deflp, + amplitude_err=self.amplitude_err, + xo_err=self.xo_err, + yo_err=self.yo_err, + sigmax_err=self.sigmax_err, + sigmay_err=self.sigmay_err, + theta_err=self.theta_err, + defla_err=self.defla_err, + deflp_err=self.deflp_err, + chisq=self.chisq, + dof=self.dof, + xi=self.xi, + eta=self.eta, + gamma=self.gamma, + ) diff --git a/tests/test_planet_mapmaking.py b/tests/test_planet_mapmaking.py new file mode 100644 index 0000000..ab48258 --- /dev/null +++ b/tests/test_planet_mapmaking.py @@ -0,0 +1,179 @@ +from datetime import datetime, timezone + +from mapcat.database import PlanetMapFitTable, PlanetMapTable, PlanetTodFitTable + + +def test_build_obslists(database_sessionmaker): + # Make some planet maps + with database_sessionmaker() as session: + data1 = PlanetMapTable( + obs_id="obs_1736469509_satp3_1111111", + telescope="satp3", + freq_channel="f150", + wafer="ws0", + source='jupiter', + ctime=datetime.fromtimestamp(1755787524.0, tz=timezone.utc), + ) + data1.hit_path = "/path/to/hit/file1" + data1.map_path = "/path/to/hit/file2" + data1.proc = ['hoge1', 'hoge2'] + data1.detnum = [10, 20] + data1.detid = ['det1', 'det2'] + mapfit1 = PlanetMapFitTable() + mapfit1.amplitude = 1 + mapfit1.xo = 0 + mapfit1.yo = 0 + mapfit1.sigmax = 1 + mapfit1.sigmay = 1 + mapfit1.theta = 0 + mapfit1.redchit = 1 + mapfit1.mq = 0.1 + mapfit1.d0q = 0.1 + mapfit1.d1q = 0.1 + mapfit1.sigmaq = 0.1 + mapfit1.redchiq = 1 + mapfit1.mu = 0.2 + mapfit1.d0u = 0.2 + mapfit1.d1u = 0.2 + mapfit1.sigmau = 0.2 + mapfit1.redchiu = 1.1 + + data1.fit = mapfit1 + + + data2 = PlanetMapTable( + obs_id="obs_1736469509_satp1_1111111", + telescope="satp1", + freq_channel="f090", + wafer="ws1", + source='saturn', + ctime=datetime.fromtimestamp(1755787530.0, tz=timezone.utc), + ) + data2.proc = ['hoge12', 'hoge2'] + data2.detnum = [12, 22] + data2.detid = ['det12', 'det22'] + + mapfit2 = PlanetMapFitTable() + mapfit2.amplitude = 1 + mapfit2.xo = 0 + mapfit2.yo = 0 + mapfit2.sigmax = 1 + mapfit2.sigmay = 1 + mapfit2.theta = 0 + mapfit2.redchit = 1 + mapfit2.mq = 0.2 + mapfit2.d0q = 0.2 + mapfit2.d1q = 0.2 + mapfit2.sigmaq = 0.2 + mapfit2.redchiq = 2 + mapfit2.mu = 0.3 + mapfit2.d0u = 0.3 + mapfit2.d1u = 0.3 + mapfit2.sigmau = 0.3 + mapfit2.redchiu = 3 + + data2.fit = mapfit2 + + session.add(data1) + session.commit() + session.refresh(data1) + + session.add(data2) + session.commit() + session.refresh(data2) + + key1 = { + "obs_id": data1.obs_id, + "telescope": data1.telescope, + "freq_channel": data1.freq_channel, + "wafer": data1.wafer, + "source": data1.source, + } + + key2 = { + "obs_id": data2.obs_id, + "telescope": data2.telescope, + "freq_channel": data2.freq_channel, + "wafer": data2.wafer, + "source": data2.source, + } + # Get depth one map back + with database_sessionmaker() as session: + data1 = session.get(PlanetMapTable, key1) + data2 = session.get(PlanetMapTable, key2) + + with database_sessionmaker() as session: + x1 = session.get(PlanetMapTable, key1) + session.delete(x1) + session.commit() + assert x1 is not None + + + with database_sessionmaker() as session: + todfit1 = PlanetTodFitTable( + obs_id="obs_1736469509_satp3_1111111", + telescope="satp3", + freq_channel="f150", + wafer="ws0", + source="jupiter", + detid="det1", + ctime=datetime.fromtimestamp( + 1755787524.0, + tz=timezone.utc, + ), + amplitude=1.0, + xo=0.0, + yo=0.0, + sigmax=1.0, + sigmay=1.0, + theta=0.0, + chisq=1.0, + dof=100, + ) + + todfit2 = PlanetTodFitTable( + obs_id="obs_1736469509_satp1_1111111", + telescope="satp1", + freq_channel="f090", + wafer="ws1", + source="saturn", + detid="det12", + ctime=datetime.fromtimestamp( + 1755787526.0, + tz=timezone.utc, + ), + amplitude=1.1, + xo=0.1, + yo=0.1, + sigmax=1.1, + sigmay=1.1, + theta=0.1, + chisq=1.1, + dof=101, + ) + + session.add(todfit1) + session.commit() + session.refresh(todfit1) + + session.add(todfit2) + session.commit() + session.refresh(todfit2) + + key_tod1 = { + "obs_id": todfit1.obs_id, + "telescope": todfit1.telescope, + "freq_channel": todfit1.freq_channel, + "wafer": todfit1.wafer, + "source": todfit1.source, + "detid": todfit1.detid, + } + + with database_sessionmaker() as session: + y1 = session.get(PlanetTodFitTable, key_tod1) + + with database_sessionmaker() as session: + y1 = session.get(PlanetTodFitTable, key_tod1) + session.delete(y1) + session.commit() + assert y1 is not None \ No newline at end of file