Skip to content

Commit

Permalink
update TA code: allow proprietary TA data access, refactor plotting t…
Browse files Browse the repository at this point in the history
…o show WCS, OSS, and webbpsf centroids. And PEP8 cleanup.
  • Loading branch information
mperrin committed Mar 28, 2024
1 parent 0d5aaaa commit 749e37f
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 15 deletions.
27 changes: 24 additions & 3 deletions webbpsf/mast_wss.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ def get_corrections(opdtable):


@functools.lru_cache
def get_visit_nrc_ta_image(visitid, verbose=True):
def get_visit_nrc_ta_image(visitid, verbose=True, kind='cal'):
"""Retrieve from MAST the NIRCam target acq image for a given visit.
This retrieves an image from MAST and returns it as a HDUList variable
Expand All @@ -598,7 +598,6 @@ def get_visit_nrc_ta_image(visitid, verbose=True):
from astroquery.mast import Mast
keywords = {
'visit_id': [visitid[1:]], # note: drop the initial character 'V'
#'category': ['CAL'],
'exp_type': ['NRC_TACQ']
}

Expand All @@ -615,9 +614,31 @@ def set_params(parameters):
t = Mast.service_request(service, params)
filename = t[0]['filename']

# If user manually specifies rate or uncal, retrieve that instead
if kind == 'rate' or kind == 'uncal':
filename = filename.replace('_cal.fits', f'_{kind}.fits')

Check warning on line 619 in webbpsf/mast_wss.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/mast_wss.py#L618-L619

Added lines #L618 - L619 were not covered by tests

if verbose:
print(f"TA filename: {filename}")
mast_file_url = f"https://mast.stsci.edu/api/v0.1/Download/file?uri=mast:JWST/product/{filename}"
ta_hdul = fits.open(mast_file_url)
import urllib

Check warning on line 624 in webbpsf/mast_wss.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/mast_wss.py#L624

Added line #L624 was not covered by tests

try:
ta_hdul = fits.open(mast_file_url)
except urllib.error.HTTPError as err:
if err.code == 401: # Unauthorized

Check warning on line 629 in webbpsf/mast_wss.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/mast_wss.py#L626-L629

Added lines #L626 - L629 were not covered by tests
# Use MAST API to allow retrieval of exclusive access data, if relevant
import astroquery
import tempfile
mast_api_token = os.environ.get('MAST_API_TOKEN', None)
mast_obs = astroquery.mast.ObservationsClass(mast_api_token)
uri = f"mast:JWST/product/{filename}"
with tempfile.NamedTemporaryFile() as temp:
mast_obs.download_file(uri, local_path=temp.name, cache=False)
ta_hdul = astropy.io.fits.open(temp.name)

Check warning on line 638 in webbpsf/mast_wss.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/mast_wss.py#L631-L638

Added lines #L631 - L638 were not covered by tests
else:
raise # re-raise any errors other than 401 for permissions denied

Check warning on line 640 in webbpsf/mast_wss.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/mast_wss.py#L640

Added line #L640 was not covered by tests



return ta_hdul
4 changes: 2 additions & 2 deletions webbpsf/match_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ def setup_sim_to_match_file(filename_or_HDUList, verbose=True, plot=False, choic
if header['PUPIL'].startswith('MASK'):
inst.pupil_mask = header['PUPIL']
if 'CORONMSK' in header:
inst.image_mask = header['CORONMSK'].replace('MASKA', 'MASK') # note, have to modify the value slightly for
# consistency with the labels used in webbpsf
inst.image_mask = header['CORONMSK'].replace('MASKA', 'MASK') # note, have to modify the value slightly for

Check warning on line 53 in webbpsf/match_data.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/match_data.py#L52-L53

Added lines #L52 - L53 were not covered by tests
# consistency with the labels used in webbpsf
inst.set_position_from_aperture_name(header['APERNAME']) # Redo this, in case the image_mask setting auto switched it to something else
elif inst.name == 'MIRI':
if inst.filter in ['F1065C', 'F1140C', 'F1550C']:
Expand Down
55 changes: 45 additions & 10 deletions webbpsf/trending.py
Original file line number Diff line number Diff line change
Expand Up @@ -1620,7 +1620,7 @@ def vprint(*args, **kwargs):

#### Functions for image comparisons
def show_nrc_ta_img(visitid, ax=None, return_handles=False):
""" Retrieve and display a WFS target acq image"""
""" Retrieve and display a NIRCam target acq image"""

hdul = webbpsf.mast_wss.get_visit_nrc_ta_image(visitid)

Expand All @@ -1647,6 +1647,7 @@ def show_nrc_ta_img(visitid, ax=None, return_handles=False):
if return_handles:
return hdul, ax, norm, cmap, bglevel


def nrc_ta_image_comparison(visitid, verbose=False, show_centroid=False):
""" Retrieve a NIRCam target acq image and compare to a simulation
Expand All @@ -1668,7 +1669,7 @@ def nrc_ta_image_comparison(visitid, verbose=False, show_centroid=False):

im_obs_clean = im_obs.copy()
im_obs_clean[im_obs_dq & 1] = np.nan # Mask out any DO_NOT_USE pixels.
im_obs_clean = astropy.convolution.interpolate_replace_nans(im_obs_clean, kernel=np.ones((5,5)))
im_obs_clean = astropy.convolution.interpolate_replace_nans(im_obs_clean, kernel=np.ones((5, 5)))

Check warning on line 1672 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1670-L1672

Added lines #L1670 - L1672 were not covered by tests

# Make a matching sim
nrc = webbpsf.setup_sim_to_match_file(hdul, verbose=False)
Expand All @@ -1694,24 +1695,58 @@ def nrc_ta_image_comparison(visitid, verbose=False, show_centroid=False):

# Plot
if show_centroid:

Check warning on line 1697 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1697

Added line #L1697 was not covered by tests
### OSS CENTROIDS ###
# First, see if we can retrieve the on-board TA centroid measurment from the OSS engineering DB in MAST
try:
import misc_jwst # Optional dependency, including engineering database access tools

Check warning on line 1701 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1700-L1701

Added lines #L1700 - L1701 were not covered by tests
# If we have that, retrieve the log for this visit, extract the OSS centroids, and convert to same
# coordinate frame as used here:
osslog = misc_jwst.engdb.get_ictm_event_log(hdul[0].header['VSTSTART'], hdul[0].header['VISITEND'])
oss_cen = misc_jwst.engdb.extract_oss_TA_centroids(osslog, 'V' + hdul[0].header['VISIT_ID'])
# Convert from full-frame (as used by OSS) to detector subarray coords:
oss_cen_sci = nrc._detector_geom_info.aperture.det_to_sci( *oss_cen)
oss_cen_sci_pythonic = np.asarray(oss_cen_sci) - 1 # convert from 1-based pixel indexing to 0-based
oss_centroid_text = f"\n OSS centroid: {oss_cen_sci_pythonic[0]:.2f}, {oss_cen_sci_pythonic[1]:.2f}"
#print(oss_cen_sci_pythonic)
try:
oss_cen = misc_jwst.engdb.extract_oss_TA_centroids(osslog, 'V' + hdul[0].header['VISIT_ID'])

Check warning on line 1706 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1704-L1706

Added lines #L1704 - L1706 were not covered by tests
# Convert from full-frame (as used by OSS) to detector subarray coords:
oss_cen_sci = nrc._detector_geom_info.aperture.det_to_sci(*oss_cen)
oss_cen_sci_pythonic = np.asarray(oss_cen_sci) - 1 # convert from 1-based pixel indexing to 0-based
oss_centroid_text = f"\n OSS centroid: {oss_cen_sci_pythonic[0]:.2f}, {oss_cen_sci_pythonic[1]:.2f}"
axes[0].scatter(oss_cen_sci_pythonic[0], oss_cen_sci_pythonic[1], color='0.5', marker='+', s=50)
axes[0].text(oss_cen_sci_pythonic[0], oss_cen_sci_pythonic[1], 'OSS ', color='0.9', verticalalignment='center', horizontalalignment='right')
if verbose:
print(f"OSS centroid on board: {oss_cen} (full det coord frame, 1-based)")
print(f"OSS centroid converted: {oss_cen_sci_pythonic} (sci frame in {nrc._detector_geom_info.aperture.AperName}, 0-based)")
full_ap = nrc.siaf[nrc._detector_geom_info.aperture.AperName[0:5] + "_FULL"]
oss_cen_full_sci = np.asarray(full_ap.det_to_sci(*oss_cen)) - 1
print(f"OSS centroid converted: {oss_cen_full_sci} (sci frame in {full_ap.AperName}, 0-based)")

Check warning on line 1718 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1708-L1718

Added lines #L1708 - L1718 were not covered by tests

except RuntimeError:
if verbose:
print("Could not parse TA coordinates from log. TA may have failed?")
oss_cen_sci_pythonic = None

Check warning on line 1723 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1720-L1723

Added lines #L1720 - L1723 were not covered by tests

### WCS COORDINATES ###
import jwst.datamodels
model = jwst.datamodels.open(hdul)
targ_coords = astropy.coordinates.SkyCoord(model.meta.target.ra, model.meta.target.dec, frame='icrs', unit=u.deg)
targ_coords_pix = model.meta.wcs.world_to_pixel(targ_coords) # returns x, y
axes[0].scatter(targ_coords_pix[0], targ_coords_pix[1], color='magenta', marker='+', s=50)
axes[0].text(targ_coords_pix[0], targ_coords_pix[1]+2, 'WCS', color='magenta', verticalalignment='bottom', horizontalalignment='center')
axes[0].text(0.95, 0.18, f'From WCS: {targ_coords_pix[0]:.2f}, {targ_coords_pix[1]:.2f}',

Check warning on line 1732 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1726-L1732

Added lines #L1726 - L1732 were not covered by tests
horizontalalignment='right', verticalalignment='bottom',
transform=axes[0].transAxes,
color='white')

if verbose:
print(f"Star coords from WCS: {targ_coords_pix}")
if oss_cen_sci_pythonic is not None:
print(f"WCS offset = {np.asarray(targ_coords_pix) - oss_cen_sci_pythonic} pix")

Check warning on line 1740 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1737-L1740

Added lines #L1737 - L1740 were not covered by tests

except ImportError:
oss_centroid_text = ""

### WEBBPSF CENTROIDS ###
cen = webbpsf.fwcentroid.fwcentroid(im_obs_clean)
axes[0].scatter(cen[1], cen[0], color='red', marker='+', s=50)
axes[0].text(0.95, 0.05, f' Centroid: {cen[1]:.2f}, {cen[0]:.2f}'+oss_centroid_text,
axes[0].text(cen[1], cen[0], ' webbpsf', color='red', verticalalignment='center')
axes[0].text(0.95, 0.05, f' webbpsf Centroid: {cen[1]:.2f}, {cen[0]:.2f}'+oss_centroid_text,

Check warning on line 1749 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1746-L1749

Added lines #L1746 - L1749 were not covered by tests
horizontalalignment='right', verticalalignment='bottom',
transform=axes[0].transAxes,
color='white')
Expand All @@ -1737,6 +1772,6 @@ def nrc_ta_image_comparison(visitid, verbose=False, show_centroid=False):
plt.tight_layout()


outname = f'wfs_ta_comparison_{visitid}.pdf'
outname = f'nrc_ta_comparison_{visitid}.pdf'

Check warning on line 1775 in webbpsf/trending.py

View check run for this annotation

Codecov / codecov/patch

webbpsf/trending.py#L1775

Added line #L1775 was not covered by tests
plt.savefig(outname)
print(f" => {outname}")

0 comments on commit 749e37f

Please sign in to comment.