Skip to content

Commit

Permalink
Adds sdssid lookup using alternative id (#61)
Browse files Browse the repository at this point in the history
* adding new queries to lookup target by altid

* adding new or updating endpoints to use altid lookup
  • Loading branch information
havok2063 authored Oct 21, 2024
1 parent 2871bf8 commit b496410
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 2 deletions.
100 changes: 100 additions & 0 deletions python/valis/db/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -831,3 +831,103 @@ def starfields(model: peewee.ModelSelect) -> peewee.NodeList:
pw_ver = peewee.__version__
oldver = packaging.version.parse(pw_ver) < packaging.version.parse('3.17.1')
return model.star if oldver else model.__star__


def get_sdssid_by_altid(id: str | int, idtype: str = None) -> peewee.ModelSelect:
""" Get an sdss_id by an alternative id
This query attempts to identify a target sdss_id from an
alternative id, which can be a string or integer. It tries
to distinguish between the following formats:
- a (e)BOSS plate-mjd-fiberid, e.g. "10235-58127-0020"
- a BOSS field-mjd-catalogid, e.g. "101077-59845-27021603187129892"
- an SDSS-IV APOGEE ID, e.g "2M23595980+1528407"
- an SDSS-V catalogid, e.g. 2702160318712989
- a GAIA DR3 ID, e.g. 4110508934728363520
It queries either the boss_drp.boss_spectrum or astra.source
tables for the sdss_id.
Parameters
----------
id : str | int
the input alternative id
idtype : str, optional
the type of integer id, by default None
Returns
-------
peewee.ModelSelect
the ORM query
"""

# cast to str
if isinstance(id, int):
id = str(id)

# temp for now; maybe we make a single "altid" db column somewhere
ndash = id.count('-')
final = id.rsplit('-', 1)[-1]
if ndash == 2 and len(final) <= 4 and final.isdigit() and int(final) <= 1000:
# boss/eboss plate-mjd-fiberid e.g '10235-58127-0020'
return
elif ndash == 2 and len(final) > 5:
# field-mjd-catalogid, e.g. '101077-59845-27021603187129892'
field, mjd, catalogid = id.split('-')
targ = boss.BossSpectrum.select(boss.BossSpectrum.sdss_id).\
where(boss.BossSpectrum.catalogid == catalogid,
boss.BossSpectrum.mjd == mjd, boss.BossSpectrum.field == field)
elif ndash == 1:
# apogee south, e.g. '2M17282323-2415476'
targ = astra.Source.select(astra.Source.sdss_id).\
where(astra.Source.sdss4_apogee_id.in_([id]))
elif ndash == 0 and not id.isdigit():
# apogee obj id
targ = astra.Source.select(astra.Source.sdss_id).\
where(astra.Source.sdss4_apogee_id.in_([id]))
elif ndash == 0 and id.isdigit():
# single integer id
if idtype == 'catalogid':
# catalogid , e.g. 27021603187129892
field = 'catalogid'
elif idtype == 'gaiaid':
# gaia dr3 id , e.g. 4110508934728363520
field = 'gaia_dr3_source_id'
else:
field = 'catalogid'

targ = astra.Source.select(astra.Source.sdss_id).\
where(getattr(astra.Source, field).in_([id]))

return targ


def get_target_by_altid(id: str | int, idtype: str = None) -> peewee.ModelSelect:
""" Get a target by an alternative id
This retrieves the target info from vizdb.sdss_id_stacked,
given an alternative id. It first tries to identify the proper
sdss_id for the given altid, then it retrieves the basic target
info. See ``get_sdssid_by_altid`` for details on the altid formats.
Parameters
----------
id : str | int
the input alternative id
idtype : str, optional
the type of integer id, by default None
Returns
-------
peewee.ModelSelect
the ORM query
"""
# get the sdss_id
targ = get_sdssid_by_altid(id, idtype=idtype)
res = targ.get_or_none() if targ else None
if not res:
return

# get the sdss_id metadata info
return get_targets_by_sdss_id(res.sdss_id)
9 changes: 8 additions & 1 deletion python/valis/routes/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
from valis.db.queries import (cone_search, append_pipes, carton_program_search,
carton_program_list, carton_program_map,
get_targets_by_sdss_id, get_targets_by_catalog_id,
get_targets_obs, get_paged_target_list_by_mapper)
get_targets_obs, get_paged_target_list_by_mapper,
get_target_by_altid)
from sdssdb.peewee.sdss5db import database, catalogdb

# convert string floats to proper floats
Expand All @@ -35,6 +36,8 @@ class SearchModel(BaseModel):
radius: Optional[Float] = Field(None, description='Search radius in specified units', example=0.02)
units: Optional[SearchCoordUnits] = Field('degree', description='Units of search radius', example='degree')
id: Optional[Union[int, str]] = Field(None, description='The SDSS identifier', example=23326)
altid: Optional[Union[int, str]] = Field(None, description='An alternative identifier', example=27021603187129892)
idtype: Optional[str] = Field(None, description='The type of integer id, for ambiguous ids', example="catalogid")
program: Optional[str] = Field(None, description='The program name', example='bhm_rm')
carton: Optional[str] = Field(None, description='The carton name', example='bhm_rm_core')
observed: Optional[bool] = Field(True, description='Flag to only include targets that have been observed', example=True)
Expand Down Expand Up @@ -93,6 +96,10 @@ async def main_search(self, body: SearchModel):
elif body.id:
query = get_targets_by_sdss_id(body.id)

# build the altid query
elif body.altid:
query = get_target_by_altid(body.altid, body.idtype)

# build the program/carton query
if body.program or body.carton:
query = carton_program_search(body.program or body.carton,
Expand Down
14 changes: 13 additions & 1 deletion python/valis/routes/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from valis.routes.base import Base
from valis.db.queries import (get_target_meta, get_a_spectrum, get_catalog_sources,
get_parent_catalog_data, get_target_cartons,
get_target_pipeline)
get_target_pipeline, get_target_by_altid, append_pipes)
from valis.db.db import get_pw_db
from valis.db.models import CatalogResponse, CartonModel, ParentCatalogModel, PipesModel, SDSSModel

Expand Down Expand Up @@ -167,6 +167,18 @@ async def get_target(self, sdss_id: int = Path(title="The sdss_id of the target
""" Return target metadata for a given sdss_id """
return get_target_meta(sdss_id, self.release) or {}

@router.get('/sdssid/{id}', summary='Retrieve a target sdss_id from an alternative id',
dependencies=[Depends(get_pw_db)],
response_model=Union[SDSSModel, dict],
response_model_exclude_unset=True, response_model_exclude_none=True)
async def get_target_altid(self,
id: Annotated[int | str, Path(title="The alternative id of the target to get", example="2M23595980+1528407")],
idtype: Annotated[str, Query(enum=['catalogid', 'gaiaid'], description='For ambiguous integer ids, the type of id, e.g. "catalogid"', example=None)] = None
):
""" Return target metadata for a given sdss_id """
query = append_pipes(get_target_by_altid(id, idtype=idtype), observed=False)
return query.dicts().first() or {}

@router.get('/spectra/{sdss_id}', summary='Retrieve a spectrum for a target sdss_id',
dependencies=[Depends(get_pw_db)],
response_model=List[SpectrumModel])
Expand Down

0 comments on commit b496410

Please sign in to comment.