Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c405635
feat: initial function for finding tiles from bounding box and tmap
Sulla2012 Feb 12, 2026
c141f11
feat: update docs and make composite ID
Sulla2012 Feb 12, 2026
252c0fc
feat: init function to get a list of sky coverage table entries from …
Sulla2012 Feb 12, 2026
c0162ed
fix: ruff formating
Sulla2012 Feb 12, 2026
b451ed3
fix: more ruff formating
Sulla2012 Feb 12, 2026
e31e3f1
feat: switching from passing box to getting box using pixell
Sulla2012 Feb 12, 2026
90db8e4
feat: moving sky coverage tools
Sulla2012 Feb 12, 2026
3d7ef76
fix: fixing composite key generation
Sulla2012 Feb 12, 2026
9e30a6f
feat: starting skycoverage update function
Sulla2012 Feb 12, 2026
9c64131
Merge remote-tracking branch 'origin/main' into sky_coverage
Sulla2012 Feb 12, 2026
0064a15
feat: add sqlite to gitignore
Sulla2012 Feb 12, 2026
dbe9283
fix: updating outerjoin query
Sulla2012 Feb 12, 2026
98d5d85
feat: move core functionaliy of ingestact to a separate function for …
Sulla2012 Feb 13, 2026
5649579
feat: move core functionality of update_sky_coverage to its own funct…
Sulla2012 Feb 13, 2026
281f19c
feat: adding test for ingestact and update_sky_coverage
Sulla2012 Feb 13, 2026
0d445ca
fix: map=d1table is redundant
Sulla2012 Feb 16, 2026
a18fb0b
fix: move update_sky_coverage
Sulla2012 Feb 16, 2026
bbe3fe6
fix: ruff
Sulla2012 Feb 16, 2026
c9c046f
Fix tests
JBorrow Feb 16, 2026
718265b
Add h5py as dependency
JBorrow Feb 16, 2026
c33501e
Satisfy tyg
JBorrow Feb 16, 2026
0fccbb6
fix: remove unneccesary update statement
Sulla2012 Feb 17, 2026
3311448
fix: remove unused imports
Sulla2012 Feb 17, 2026
a877896
feat: switch to env variables for file paths
Sulla2012 Feb 20, 2026
4d5366a
fix: updating to latest ruff
Sulla2012 Feb 20, 2026
c4410f5
temp: checking DEPTH_ONE_MAP path
Sulla2012 Feb 20, 2026
34ec728
temp: echo DEPTH_ONE_PATH
Sulla2012 Feb 20, 2026
38cbe26
fix: wrong variable name for DEPTH_ONE_PARENT
Sulla2012 Feb 20, 2026
2cf5e0f
feat: change dec to 0-17, ra to 0-35 and add plotting util
Sulla2012 Mar 25, 2026
1c129a8
fix: update test to new ra/dec conventions and plot with ACT (e.g., r…
Sulla2012 Mar 25, 2026
13a2740
fix: improper tuple construction
Sulla2012 Mar 25, 2026
e2c71d1
Add CLI script
JBorrow Mar 26, 2026
8fa38fc
Merge branch 'main' into sky_coverage
JBorrow Mar 26, 2026
d4f2343
fix: updating coverage tests to new ra/dec conventions
Sulla2012 Mar 26, 2026
9699857
fix: clean up some tests and increase coverage
Sulla2012 Mar 26, 2026
115cefc
fix: making index_to_skybox consistent with ra_to_index and changing …
Sulla2012 Apr 1, 2026
ac9b30d
feat: update plot tiles to use argparse
Sulla2012 Apr 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ dist/*
*.egg-info
*.fits
*.hdf
.coverage
5 changes: 5 additions & 0 deletions mapcat/core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from .core import get_maps_by_coverage

__all__ = [
"get_maps_by_coverage",
]
52 changes: 52 additions & 0 deletions mapcat/core/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from astropy.coordinates import ICRS
from sqlalchemy import select
from sqlalchemy.orm import Session

from mapcat.database import DepthOneMapTable
from mapcat.toolkit.update_sky_coverage import dec_to_index, ra_to_index


def get_maps_by_coverage(
position: ICRS,
session: Session,
) -> list[DepthOneMapTable]:
"""
Get the depth one maps that cover a given position.

Parameters
----------
position : ICRS
The position to query for coverage. Should be in ICRS coordinates.
session : Session
The database session to use for the query.

Returns
-------
session.execute(stmt).scalars().all() : list[DepthOneMapTable]
A list of depth one maps that cover the given position.

Raises
------
ValueError
If the RA or Dec of the position is out of bounds.
"""
ra = position.ra.deg
dec = position.dec.deg

# These aren't covered since ICRS automatically wraps
# values back aground to 0-360 for RA and -90 to 90 for Dec.
if ra < 0 or ra > 360: # pragma: no cover
raise ValueError("RA must be between 0 and 360 degrees")
if dec < -90 or dec > 90: # pragma: no cover
raise ValueError("Dec must be between -90 and 90 degrees")

ra_idx = ra_to_index(ra)
dec_idx = dec_to_index(dec)

stmt = (
select(DepthOneMapTable)
.join(DepthOneMapTable.depth_one_sky_coverage)
.filter_by(x=ra_idx, y=dec_idx)
)

return session.execute(stmt).scalars().all()
2 changes: 1 addition & 1 deletion mapcat/database/atomic_coadd.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
if TYPE_CHECKING:
from .atomic_map import AtomicMapTable

from .links import AtomicMapToCoaddTable, CoaddMapToCoaddTable
from .links import AtomicMapToCoaddTable, CoaddMapToCoaddTable # pragma: no cover


class AtomicMapCoaddTable(SQLModel, table=True):
Expand Down
2 changes: 1 addition & 1 deletion mapcat/database/atomic_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from .links import AtomicMapToCoaddTable

if TYPE_CHECKING:
from .atomic_coadd import AtomicMapCoaddTable
from .atomic_coadd import AtomicMapCoaddTable # pragma: no cover


class AtomicMapTable(SQLModel, table=True):
Expand Down
2 changes: 1 addition & 1 deletion mapcat/database/depth_one_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from sqlmodel import JSON, Field, Relationship, SQLModel

if TYPE_CHECKING:
if TYPE_CHECKING: # pragma: no cover
from .depth_one_coadd import DepthOneCoaddTable
from .pipeline_information import PipelineInformationTable
from .pointing_residual import PointingResidualTable
Expand Down
2 changes: 1 addition & 1 deletion mapcat/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def session(self) -> sessionmaker:
settings = Settings()


def migrate():
def migrate(): # pragma: no cover
"""
CLI script to run 'alembic upgrade head' with the correct location.
"""
Expand Down
99 changes: 99 additions & 0 deletions mapcat/toolkit/plot_tiles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import argparse as ap

import matplotlib.pyplot as plt
import numpy as np
from pixell import enmap

from mapcat.toolkit.update_sky_coverage import *

parser = ap.ArgumentParser()
parser.add_argument("--imap_path", type=str)
parser.add_argument("--d1map_path", type=str)
parser.add_argument("--opath", type=str)

args = parser.parse_args()
imap_path = args.imap_path
d1map_path = args.d1map_path
opath = args.opath

imap = enmap.read_map(str(imap_path))

box = imap.box()

dec_min, ra_max = np.rad2deg(box[0])
dec_max, ra_min = np.rad2deg(box[1])

pad_low = int((90 + dec_min) * 6 * 2)
pad_high = int((90 - dec_max) * 6 * 2)

imap = imap[0][::10, ::10]

pad_map = np.pad(
imap, ((pad_low, pad_high), (0, 0)), mode="constant", constant_values=0
)
del imap

left_limit = pad_map.shape[1]
right_limit = 0
top_limit = pad_map.shape[0]
bottom_limit = 0
extent = [left_limit, right_limit, bottom_limit, top_limit]


plt.imshow(pad_map, vmin=-300, vmax=300, origin="lower", extent=extent)
plt.vlines(
np.arange(0, 360 * 6 * 2, 10 * 6 * 2), ymin=0, ymax=180 * 6 * 2, color="black", lw=1
)
plt.hlines(
np.arange(0, 180 * 6 * 2, 10 * 6 * 2), xmin=0, xmax=360 * 6 * 2, color="black", lw=1
)
plt.xticks(np.arange(0, 360 * 6 * 2, 20 * 6 * 2), labels=np.arange(0, 360, 20))
plt.yticks(np.arange(0, 180 * 6 * 2, 10 * 6 * 2), labels=np.arange(-90, 90, 10))
plt.xlabel("RA (degrees)")
plt.ylabel("Dec (degrees)")

d1map = enmap.read_map(str(d1map_path))
coverage_tiles = get_sky_coverage(d1map)

d1box = d1map.box()

d1dec_min, d1ra_max = np.rad2deg(d1box[0])
d1dec_max, d1ra_min = np.rad2deg(d1box[1])

d1pad_low_dec = int((90 + d1dec_min) * 6 * 2)
d1pad_high_dec = int((90 - d1dec_max) * 6 * 2)

d1pad_low_ra = int((180 + d1ra_min) * 6 * 2)
d1pad_high_ra = int((180 - d1ra_max) * 6 * 2)

d1map = d1map[0][::10, ::10]
d1pad_map = np.pad(
d1map,
((d1pad_low_dec, d1pad_high_dec), (d1pad_high_ra, d1pad_low_ra)),
mode="constant",
constant_values=0,
)

plt.imshow(
d1pad_map,
vmin=-300,
vmax=300,
origin="lower",
alpha=0.5,
cmap="seismic",
extent=extent,
)

for tile in coverage_tiles:
plt.gca().add_patch(
plt.Rectangle(
(tile[0] * 10 * 6 * 2, tile[1] * 10 * 6 * 2),
10 * 6 * 2,
10 * 6 * 2,
fill=False,
edgecolor="red",
lw=2,
)
)

plt.savefig(opath + "act_coverage.png", dpi=300)
6 changes: 2 additions & 4 deletions mapcat/toolkit/reset.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ def main():
type=float,
default=None,
help=(
"Only reset entries for maps whose ctime is >= START_TIME "
"(unix timestamp)."
"Only reset entries for maps whose ctime is >= START_TIME (unix timestamp)."
),
)

Expand All @@ -133,8 +132,7 @@ def main():
type=float,
default=None,
help=(
"Only reset entries for maps whose ctime is <= END_TIME "
"(unix timestamp)."
"Only reset entries for maps whose ctime is <= END_TIME (unix timestamp)."
),
)

Expand Down
102 changes: 92 additions & 10 deletions mapcat/toolkit/update_sky_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,88 @@ def resolve_tmap(d1table: DepthOneMapTable) -> Path:
return settings.depth_one_parent / d1table.mean_time_path


def index_to_skybox(ra_idx: int, dec_idx: int) -> np.ndarray:
"""
Convert a sky coverage tile index to a sky box in radians

Parameters
----------
ra_idx : int
The RA index of the sky coverage tile
dec_idx : int
The Dec index of the sky coverage tile

Returns
-------
skybox : np.ndarray
A 2x2 array containing the corners of the sky box in radians, in the format [[dec_min, ra_max], [dec_max, ra_min]]
"""
ra_min = ra_idx * 10
ra_max = ra_min + 10
dec_min = (dec_idx - 9) * 10
dec_max = dec_min + 10

return np.array(
[
[np.deg2rad(dec_min), np.deg2rad(ra_max)],
[np.deg2rad(dec_max), np.deg2rad(ra_min)],
]
)


def ra_to_index(ra: float) -> int:
"""
Convert an ra in degrees to a sky coverage tile index

Parameters
----------
ra : float
The ra in degrees to convert

Returns
-------
idx : int
The sky coverage tile index corresponding to the input ra
"""
return int(np.floor(ra / 10))


def dec_to_index(dec: float) -> int:
"""
Convert a dec in degrees to a sky coverage tile index

Parameters
----------
dec : float
The dec in degrees to convert

Returns
-------
idx : int
The sky coverage tile index corresponding to the input dec
"""
return int(np.floor(dec / 10)) + 9


def _ra_to_index_pixell(ra: float) -> int:
"""
Convert an ra in degrees to a sky coverage tile index using the
pixell convention where -180 < ra < 180. You should probably
not ever touch this function.

Parameters
----------
ra : float
The ra in degrees to convert

Returns
-------
idx : int
The sky coverage tile index corresponding to the input ra
"""
return int(np.floor(ra / 10)) + 18


def get_sky_coverage(tmap: enmap.ndmap) -> list:
"""
Given the time map of a depth1 map, return the list
Expand All @@ -49,27 +131,27 @@ def get_sky_coverage(tmap: enmap.ndmap) -> list:
dec_max = np.ceil(dec_max / 10) * 10
ra_min = np.floor(ra_min / 10) * 10
ra_max = np.ceil(ra_max / 10) * 10
ra_min += 180 # Convert from pixel standard to normal RA convention
ra_max += 180

ras = np.arange(ra_min, ra_max, 10)
decs = np.arange(dec_min, dec_max, 10)

ra_idx = []
dec_id = []
dec_idx = []

for ra in ras:
for dec in decs:
skybox = np.array(
[
[np.deg2rad(dec), np.deg2rad(ra + 10)],
[np.deg2rad(dec + 10), np.deg2rad(ra)],
]
)
ra_id = ra_to_index(ra)
dec_id = dec_to_index(dec)
skybox = index_to_skybox(ra_id, dec_id)
skybox[..., 1] -= np.pi # Convert from standard RA to pixell convention
submap = enmap.submap(tmap, skybox)
if np.any(submap):
ra_idx.append(int(ra / 10))
dec_id.append(int(dec / 10) + 9)
ra_idx.append(ra_id)
dec_idx.append(dec_id)

return list(zip(ra_idx, dec_id))
return list(zip(ra_idx, dec_idx))


def coverage_from_depthone(d1table: DepthOneMapTable) -> list[SkyCoverageTable]:
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ dependencies = [
[project.scripts]
actingest = "mapcat.toolkit.act:main"
mapcatmigrate = "mapcat.helper:migrate"
updatesky = "mapcat.toolkit.update_sky_coverage:main"
mapcatreset = "mapcat.toolkit.reset:main"

[project.optional-dependencies]
Expand Down
Loading
Loading