"""V1 Calculation based on time and engineering database info."""
import logging
from collections import defaultdict
import roman_datamodels as rdm
from astropy.table import Table
from . import set_telescope_pointing as stp
logger = logging.getLogger(__name__)
logger.addHandler(logging.NullHandler())
__all__ = ["v1_calculate_from_models", "v1_calculate_over_time"]
[docs]
def v1_calculate_from_models(sources, **calc_wcs_from_time_kwargs):
"""
Calculate V1 over the time period for the given models.
Returns a table of V1 pointings for all input models.
The table has the following columns:
* source (`roman_datamodels.datamodels.RomanDataModel`): The model.
* obstime (`astropy.time.Time`): The observation time.
* v1 (float, float, float): 3-tuple or RA, dec, and position angle.
Parameters
----------
sources : [File-like or roman_datamodels.datamodels.RomanDataModel[...]]
The datamodels to get timings other header parameters from.
**calc_wcs_from_time_kwargs : dict
Keyword arguments to pass to ``calc_wcs_from_time``.
Returns
-------
v1_table : `astropy.table.Table`
Table of V1 pointing.
"""
# Initialize structures.
v1_dict = defaultdict(list)
# Calculate V1 for all sources.
for source in sources:
with rdm.open(source) as model:
t_pars = stp.TransformParameters(**calc_wcs_from_time_kwargs)
stp.t_pars_from_model(model, t_pars)
obstimes, _, vinfos = stp.calc_wcs_over_time(
t_pars.obsstart, t_pars.obsend, t_pars
)
sources = [source] * len(obstimes)
v1_dict["source"] += sources
v1_dict["obstime"] += obstimes
v1_dict["v1"] += [(v.ra, v.dec, v.pa) for v in vinfos]
# Format and return.
v1_table = Table(v1_dict, meta=t_pars.as_reprdict())
return v1_table
[docs]
def v1_calculate_over_time(obsstart, obsend, **calc_wcs_from_time_kwargs):
"""
Calculate V1 over the given time period.
Returns a table of all V1 pointings that can be retrieved from the engineering database
that exist between, inclusively, the start and end times.
The table has the following columns:
* source (str): The string "time range".
* obstime (`astropy.time.Time`): The observation time.
* v1 (float, float, float): 3-tuple or RA, dec, and position angle.
Parameters
----------
obsstart, obsend : float
The MJD start and end time to search for pointings.
**calc_wcs_from_time_kwargs : dict
Keyword arguments to pass to ``calc_wcs_from_time``.
Returns
-------
v1_table : `astropy.table.Table`
Table of V1 pointing.
"""
# Initialize structures.
t_pars = stp.TransformParameters(**calc_wcs_from_time_kwargs)
if len(t_pars.aperture) == 0:
t_pars.aperture = "WFI02_FULL"
# Calculate V1 for all sources.
obstimes, _, vinfos = stp.calc_wcs_over_time(obsstart, obsend, t_pars)
v1_dict = {}
v1_dict["source"] = ["time range"] * len(obstimes)
v1_dict["obstime"] = obstimes
v1_dict["v1"] = [(v.ra, v.dec, v.pa) for v in vinfos]
# Format and return.
v1_table = Table(v1_dict, meta=t_pars.as_reprdict())
return v1_table
def simplify_table(v1_table):
"""
Convert pure object-based table to ASCII/Human-friendly.
The tables as produced by the `v1_calculate` functions use native objects.
For instance, the "obstime" column contains `astropy.time.Time` objects and
"v1" is the `romancal.orientation.set_telescope_pointing.WCSREF` object.
This routine converts such objects to strings or Python-native builtin objects.
Parameters
----------
v1_table : `astropy.table.Table`
V1 table as produced by ``v1_calculate`` functions.
Returns
-------
formatted : `astropy.table.Table`
Reformatted table.
"""
source_formatted = [str(v) for v in v1_table["source"]]
obstime_formatted = v1_table["obstime"].isot
ras, decs, pa_v3s, *_ = list(map(list, zip(*v1_table["v1"], strict=False)))
formatted = Table(
[source_formatted, obstime_formatted, ras, decs, pa_v3s],
names=("source", "obstime", "ra", "dec", "pa_v3"),
meta=v1_table.meta,
)
return formatted