sdss-almanac 0.2.10__py3-none-any.whl → 0.2.12__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- almanac/__init__.py +1 -1
- almanac/cli.py +95 -1
- almanac/data_models/exposure.py +12 -2
- almanac/data_models/plate.py +8 -2
- {sdss_almanac-0.2.10.dist-info → sdss_almanac-0.2.12.dist-info}/METADATA +1 -1
- {sdss_almanac-0.2.10.dist-info → sdss_almanac-0.2.12.dist-info}/RECORD +10 -10
- {sdss_almanac-0.2.10.dist-info → sdss_almanac-0.2.12.dist-info}/WHEEL +0 -0
- {sdss_almanac-0.2.10.dist-info → sdss_almanac-0.2.12.dist-info}/entry_points.txt +0 -0
- {sdss_almanac-0.2.10.dist-info → sdss_almanac-0.2.12.dist-info}/licenses/LICENSE.md +0 -0
- {sdss_almanac-0.2.10.dist-info → sdss_almanac-0.2.12.dist-info}/top_level.txt +0 -0
almanac/__init__.py
CHANGED
almanac/cli.py
CHANGED
@@ -41,7 +41,12 @@ def main(
|
|
41
41
|
|
42
42
|
# This keeps the default behaviour as 'query mode' but allows for commands like 'config'.
|
43
43
|
if ctx.invoked_subcommand is not None:
|
44
|
-
command = dict(
|
44
|
+
command = dict(
|
45
|
+
config=config,
|
46
|
+
dump=dump,
|
47
|
+
add=add,
|
48
|
+
lookup=lookup
|
49
|
+
)[ctx.invoked_subcommand]
|
45
50
|
return ctx.invoke(command, **ctx.params)
|
46
51
|
|
47
52
|
import h5py as h5
|
@@ -196,6 +201,95 @@ def main(
|
|
196
201
|
for item in buffered_critical_logs:
|
197
202
|
logger.critical(item)
|
198
203
|
|
204
|
+
|
205
|
+
@main.command()
|
206
|
+
@click.argument("identifier", type=int)
|
207
|
+
@click.option("--careful", is_flag=True, help="Don't assume unique field for a given (obs, mjd, catalogid)")
|
208
|
+
def lookup(identifier, careful, **kwargs):
|
209
|
+
"""Lookup a target by catalog identifier or SDSS identifier."""
|
210
|
+
|
211
|
+
if not identifier:
|
212
|
+
return
|
213
|
+
|
214
|
+
from peewee import fn
|
215
|
+
from itertools import chain, starmap
|
216
|
+
from almanac.database import database
|
217
|
+
from almanac.apogee import get_exposures
|
218
|
+
from sdssdb.peewee.sdss5db.targetdb import (
|
219
|
+
Assignment, AssignmentStatus,CartonToTarget, Target, Hole, Observatory,
|
220
|
+
Design, DesignToField
|
221
|
+
)
|
222
|
+
from sdssdb.peewee.sdss5db.catalogdb import SDSS_ID_flat
|
223
|
+
|
224
|
+
from rich.table import Table as RichTable
|
225
|
+
from rich.console import Console
|
226
|
+
from rich.live import Live
|
227
|
+
|
228
|
+
identifiers = (
|
229
|
+
SDSS_ID_flat
|
230
|
+
.select(
|
231
|
+
SDSS_ID_flat.catalogid,
|
232
|
+
SDSS_ID_flat.sdss_id,
|
233
|
+
)
|
234
|
+
.where(
|
235
|
+
(SDSS_ID_flat.sdss_id == identifier)
|
236
|
+
| (SDSS_ID_flat.catalogid == identifier)
|
237
|
+
)
|
238
|
+
.tuples()
|
239
|
+
)
|
240
|
+
|
241
|
+
identifiers = { catalogid: sdss_id for catalogid, sdss_id in identifiers }
|
242
|
+
if not identifiers:
|
243
|
+
raise click.ClickException(f"Identifier {identifier} not found in SDSS-V database")
|
244
|
+
|
245
|
+
q = (
|
246
|
+
Target
|
247
|
+
.select(
|
248
|
+
fn.Lower(Observatory.label),
|
249
|
+
AssignmentStatus.mjd,
|
250
|
+
)
|
251
|
+
.join(CartonToTarget)
|
252
|
+
.join(Assignment)
|
253
|
+
.join(AssignmentStatus)
|
254
|
+
.switch(Assignment)
|
255
|
+
.join(Hole)
|
256
|
+
.join(Observatory)
|
257
|
+
.where(
|
258
|
+
Target.catalogid.in_(tuple(identifiers.keys()))
|
259
|
+
& (AssignmentStatus.status == 1)
|
260
|
+
)
|
261
|
+
.tuples()
|
262
|
+
)
|
263
|
+
q = tuple(set([(obs, int(mjd)) for obs, mjd in q]))
|
264
|
+
|
265
|
+
console = Console()
|
266
|
+
|
267
|
+
title = "; ".join([f"SDSS ID {sdss_id} / Catalog ID {catalogid}" for catalogid, sdss_id in identifiers.items()])
|
268
|
+
|
269
|
+
# Create Rich table
|
270
|
+
rich_table = RichTable(title=f"{title}", title_style="bold blue", show_header=True, header_style="bold cyan")
|
271
|
+
|
272
|
+
for field_name in ("obs", "mjd", "exposure", "field", "fiber_id", "catalogid"):
|
273
|
+
rich_table.add_column(field_name, justify="center")
|
274
|
+
|
275
|
+
fields = {}
|
276
|
+
with Live(rich_table, console=console, refresh_per_second=4, screen=False) as live:
|
277
|
+
for exposure in chain(*starmap(get_exposures, q)):
|
278
|
+
key = (exposure.observatory, exposure.mjd)
|
279
|
+
if (key not in fields or fields[key] == exposure.field_id) or careful:
|
280
|
+
for target in exposure.targets:
|
281
|
+
if target.catalogid in identifiers:
|
282
|
+
fields[key] = exposure.field_id
|
283
|
+
rich_table.add_row(*list(map(str, (
|
284
|
+
exposure.observatory,
|
285
|
+
exposure.mjd,
|
286
|
+
exposure.exposure,
|
287
|
+
exposure.field_id,
|
288
|
+
target.fiber_id,
|
289
|
+
target.catalogid
|
290
|
+
))))
|
291
|
+
break
|
292
|
+
|
199
293
|
@main.group()
|
200
294
|
def add(**kwargs):
|
201
295
|
"""Add new information to an existing Almanac file."""
|
almanac/data_models/exposure.py
CHANGED
@@ -77,6 +77,13 @@ class Exposure(BaseModel):
|
|
77
77
|
#def sparse_pak(self) -> bool:
|
78
78
|
# return "sparse" in self.observer_comment.lower()
|
79
79
|
|
80
|
+
def __str__(self):
|
81
|
+
return (
|
82
|
+
f"<Exposure(observatory={self.observatory},"
|
83
|
+
f" mjd={self.mjd}, exposure={self.exposure},"
|
84
|
+
f" image_type={self.image_type})>"
|
85
|
+
)
|
86
|
+
|
80
87
|
@computed_field
|
81
88
|
def flagged_bad(self) -> bool:
|
82
89
|
marked_bad = (self.observatory, self.mjd, self.exposure) in lookup_bad_exposures
|
@@ -342,8 +349,11 @@ class Exposure(BaseModel):
|
|
342
349
|
# went wrong in early plate era.
|
343
350
|
rows["plugged_mjd"] = self.plugged_mjd
|
344
351
|
rows["observatory"] = self.observatory
|
345
|
-
|
346
|
-
|
352
|
+
try:
|
353
|
+
self._targets = tuple([factory(**r) for r in rows])
|
354
|
+
except Exception as e:
|
355
|
+
e.add_note(f"Originated from {self}")
|
356
|
+
raise
|
347
357
|
else:
|
348
358
|
self._targets = tuple()
|
349
359
|
return self._targets
|
almanac/data_models/plate.py
CHANGED
@@ -49,7 +49,7 @@ class PlateTarget(BaseModel):
|
|
49
49
|
|
50
50
|
# Instrument identifiers
|
51
51
|
spectrograph_id: int = Field(alias="spectrographId", description="Spectrograph ID", default=-1)
|
52
|
-
fiber_id: int = Field(alias="fiberId", description="Fiber ID",
|
52
|
+
fiber_id: int = Field(alias="fiberId", description="Fiber ID", ge=1, le=300)
|
53
53
|
planned_fiber_id: int = Field(alias="fiberid", description="Fiber ID", default=-1)
|
54
54
|
throughput: int = Field(description="Throughput value", default=-1)
|
55
55
|
|
@@ -137,6 +137,12 @@ class PlateTarget(BaseModel):
|
|
137
137
|
break
|
138
138
|
|
139
139
|
if self.fiber_id in (53, 60):
|
140
|
-
|
140
|
+
# The DRP indicates that these are unpopulated fibers.
|
141
|
+
self.hole_type = "unplugged"
|
142
|
+
self.category = "unplugged"
|
143
|
+
self.planned_hole_type = "unplugged"
|
144
|
+
self.ra = np.nan
|
145
|
+
self.dec = np.nan
|
146
|
+
self.obj_type = "na"
|
141
147
|
|
142
148
|
return self
|
@@ -1,7 +1,7 @@
|
|
1
|
-
almanac/__init__.py,sha256=
|
1
|
+
almanac/__init__.py,sha256=vR2wU2aXGUfju14ePXTgSjjq-pHXFyWCqs8ZlD17mO0,110
|
2
2
|
almanac/apogee.py,sha256=Q7juc7BJdnP56-4UZ4CSg6FCULr22KHinHly2d0KMt8,10390
|
3
3
|
almanac/catalog.py,sha256=tVwlLtVaUbSt1hoTpIPP2bMhgd4rpcUUP_zdr6uks2c,11633
|
4
|
-
almanac/cli.py,sha256=
|
4
|
+
almanac/cli.py,sha256=4nlH0zjdeW_kMXvkCoxaNmfpUhUAJbFFjzZNvIKy88k,29678
|
5
5
|
almanac/config.py,sha256=5oRO-mrtaCKIcqGxcrfeNHZIjHkULDRrI_Bv1CU5uxE,3259
|
6
6
|
almanac/database.py,sha256=6YeuRSFU5zfIen7zU-nI4pN_Z_fnYkglPcYxzVF4Xqo,758
|
7
7
|
almanac/display.py,sha256=IflM5Y3yOJEDkvyUYQe3bOFs1iEwoe3mUj8mbODsYDk,15388
|
@@ -10,19 +10,19 @@ almanac/logger.py,sha256=N7U610gLP6JVDUGcua3UaV9DLoWg1njfkg4F7t11UW4,665
|
|
10
10
|
almanac/qa.py,sha256=hws0YLjD6C-yC81LKmEZPRXOvucfmZE4cYEZot1R9mk,776
|
11
11
|
almanac/utils.py,sha256=0ditIHNb41_OKjaMHxEnicHnTT0NAp3SAW3QZ196JL0,4832
|
12
12
|
almanac/data_models/__init__.py,sha256=OVLgGYbJmmetYJ7pKUs5jylzC6XAyk2BnC6arjZnuMY,89
|
13
|
-
almanac/data_models/exposure.py,sha256=
|
13
|
+
almanac/data_models/exposure.py,sha256=NaokIebZCQ2i167S6qjJvDuqkYSMCiFJUP8UPovtlFs,13194
|
14
14
|
almanac/data_models/fps.py,sha256=6wM3TgCOnq2cEiGe_rKAp2pW-klGya9Fx9Y_5EbBHRU,5319
|
15
15
|
almanac/data_models/metadata.py,sha256=49Gkhw-saVJbx5t_B61SyV2qMmvXgB-yLCFQk5Kpw5M,10990
|
16
|
-
almanac/data_models/plate.py,sha256=
|
16
|
+
almanac/data_models/plate.py,sha256=xWovW5Rjjt56OK3MP2TZslquv1b0zLtUS5nvw-xz7QQ,6905
|
17
17
|
almanac/data_models/types.py,sha256=An2xrTDb4UT1DVsySiFv94pAbJZnY06kkiS9PPYZLwM,2247
|
18
18
|
almanac/data_models/utils.py,sha256=FBmY2OMRrOr6elisq910Uj5ZvaXmLQWOGAbMPqA2_T4,6232
|
19
19
|
almanac/etc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
20
|
almanac/etc/bad_exposures.csv,sha256=VQQoq6uXDhnnIyp6vw0cfeTaoyNqPi5dW0MwfKsDRCk,25394
|
21
21
|
almanac/stash/data_models.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
22
22
|
almanac/stash/plugmap_models.py,sha256=8yxw6ZXuLP1ZdFuT7wCW_Z5JSJll4uymiIWRb6WvSOk,8973
|
23
|
-
sdss_almanac-0.2.
|
24
|
-
sdss_almanac-0.2.
|
25
|
-
sdss_almanac-0.2.
|
26
|
-
sdss_almanac-0.2.
|
27
|
-
sdss_almanac-0.2.
|
28
|
-
sdss_almanac-0.2.
|
23
|
+
sdss_almanac-0.2.12.dist-info/licenses/LICENSE.md,sha256=_7dAUQQ5Ph_x1hcFXhi9aHBcqq9H11zco12eO4B3Cyg,1504
|
24
|
+
sdss_almanac-0.2.12.dist-info/METADATA,sha256=QVqM9dBL87gm9bXuiqEOE8ED10-G45NUvkysBkRfdek,6995
|
25
|
+
sdss_almanac-0.2.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
26
|
+
sdss_almanac-0.2.12.dist-info/entry_points.txt,sha256=5Obfm-uaVxE3RnRm2W7dYaX_O_j5ggGvAW5UQG5AtuE,45
|
27
|
+
sdss_almanac-0.2.12.dist-info/top_level.txt,sha256=sWBGH9a-2-nFB2-rGqioyigbkcz14t1u8rqAs_RYe_w,8
|
28
|
+
sdss_almanac-0.2.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|