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 CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = "0.2.10"
1
+ __version__ = "0.2.12"
2
2
 
3
3
  from .config import config, get_config_path, ConfigManager
4
4
  from .logger import logger
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(config=config, dump=dump, add=add)[ctx.invoked_subcommand]
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."""
@@ -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
- self._targets = tuple([factory(**r) for r in rows])
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
@@ -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", default=-1)
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
- self.fiber_id = -1 # unpopulated fiber
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sdss-almanac
3
- Version: 0.2.10
3
+ Version: 0.2.12
4
4
  Summary: Everything we've got
5
5
  Author-email: Andy Casey <andrew.casey@monash.edu>
6
6
  License: BSD 3-Clause License
@@ -1,7 +1,7 @@
1
- almanac/__init__.py,sha256=o_bowgFBdkGVkmnHzBWUTrlCXvLvGJqYQuBojDtBv6Q,110
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=MUqE9kBfRfJPl6FLw-pJ1EUpIfZcami5IakGqxCvXsQ,26523
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=aUzavB8Xdv5rizVJI1jSdN0KaIf7UvxiPp5kTKqXakE,12834
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=hehFKr35PL_iaqLHcAHBxnDraB1_y_S7sc9wL6z7vYQ,6618
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.10.dist-info/licenses/LICENSE.md,sha256=_7dAUQQ5Ph_x1hcFXhi9aHBcqq9H11zco12eO4B3Cyg,1504
24
- sdss_almanac-0.2.10.dist-info/METADATA,sha256=p7n9LIOz_DFzxqvuM9GVmYJpYaL3Lno_IV3u-Sq-nr0,6995
25
- sdss_almanac-0.2.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- sdss_almanac-0.2.10.dist-info/entry_points.txt,sha256=5Obfm-uaVxE3RnRm2W7dYaX_O_j5ggGvAW5UQG5AtuE,45
27
- sdss_almanac-0.2.10.dist-info/top_level.txt,sha256=sWBGH9a-2-nFB2-rGqioyigbkcz14t1u8rqAs_RYe_w,8
28
- sdss_almanac-0.2.10.dist-info/RECORD,,
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,,