Querying the MOONS Instrument Specific Tables¶

Examples using the ESO TAP service and pyvo.

1. Connect to ESO TAP with authentication¶

ist.moons and ist.moons_ext currently contain no public records. To query their restricted content, authenticate with an ESO account that has the necessary permissions. The password is requested interactively and is not stored in the notebook.

In [ ]:
import json
import getpass
import requests
import pyvo


tap_url = "https://archive.eso.org/tap_obs"
token_url = "https://www.eso.org/sso/oidc/token"


def getToken(username, password, url):
    """Token based authentication to ESO: provide username and password to receive back a JSON Web Token."""
    if username is None or password is None:
        return None

    token = None

    try:
        response = requests.get(
            url,
            params={
                "response_type": "id_token token",
                "grant_type": "password",
                "client_id": "clientid",
                "username": username,
                "password": password
            }
        )
        token_response = json.loads(response.content)
        token = token_response["id_token"] + "=="

    except NameError as e:
        print(e)

    except:
        print(
            "*** AUTHENTICATION ERROR: Invalid credentials provided "
            "for username %s" % username
        )

    return token


def createSession(token=None):
    session = requests.Session()

    if token:
        session.headers["Authorization"] = "Bearer " + token

    return session


token = None

while token is None:
    username = input("Type your ESO username: ")
    password = getpass.getpass(
        prompt="%s user's password: " % username,
        stream=None
    )

    token = getToken(username, password, url=token_url)

    if token is None:
        print("Could not authenticate, login again...")


session = createSession(token)
print("Session created.")

tap = pyvo.dal.TAPService(tap_url, session=session)

2. Inspect the columns available in ist.moons¶

In [ ]:
query = """
SELECT
    column_name,
    datatype,
    description
FROM TAP_SCHEMA.columns
WHERE table_name = 'ist.moons'
ORDER BY column_index
"""

moons_columns = tap.search(query).to_table()
moons_columns

3. Query some records from ist.moons¶

ist.moons contains one record per MOONS raw file.

In [ ]:
query = """
SELECT TOP 20 *
FROM ist.moons
"""

moons = tap.search(query).to_table()
moons

4. Inspect the columns available in ist.moons_ext¶

In [ ]:
query = """
SELECT
    column_name,
    datatype,
    description
FROM TAP_SCHEMA.columns
WHERE table_name = 'ist.moons_ext'
ORDER BY column_index
"""

moons_ext_columns = tap.search(query).to_table()
moons_ext_columns

5. Query some records from ist.moons_ext¶

ist.moons_ext contains one record per FITS extension.

In [ ]:
query = """
SELECT TOP 20 *
FROM ist.moons_ext
"""

moons_ext = tap.search(query).to_table()
moons_ext

6. Look at all extensions belonging to one raw file¶

Choose a dp_id returned by the previous queries.

In [ ]:
dp_id = "MOONS.2026-05-23T23:42:46.794"

query = f"""
SELECT *
FROM ist.moons_ext
WHERE dp_id = '{dp_id}'
"""

extensions = tap.search(query).to_table()
extensions

7. Optionally convert results to Pandas¶

In [ ]:
df_moons = moons.to_pandas()
df_moons_ext = moons_ext.to_pandas()

df_moons.head()
In [ ]:
df_moons_ext.head()