Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add miri lrs spec wcs model #393

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions changes/393.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
added MIRI LRS specwcs datamodel to jwst models
2 changes: 2 additions & 0 deletions src/stdatamodels/jwst/datamodels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
DisperserModel,
NIRCAMGrismModel,
NIRISSGrismModel,
MiriLRSSpecwcsModel,
WaveCorrModel,
)
from .wfssbkg import WfssBkgModel
Expand Down Expand Up @@ -175,6 +176,7 @@
"Level1bModel",
"LinearityModel",
"MaskModel",
"MiriLRSSpecwcsModel",
"MSAModel",
"MultiCombinedSpecModel",
"MultiExposureModel",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
%YAML 1.1
---
$schema: "http://stsci.edu/schemas/asdf/asdf-schema-1.1.0"
id: "http://stsci.edu/schemas/jwst_datamodel/specwcs_miri_lrs.schema"
title: MIRI LRS Fixed Slit Specwcs Schema
allOf:
- $ref: referencefile.schema
- $ref: keyword_pexptype.schema
- $ref: keyword_exptype.schema
- $ref: keyword_filter.schema
- $ref: subarray.schema
- type: object
properties:
wavetable:
title: Wavelengths and x, y locations of wavelengths
fits_hdu: WAVETABLE
datatype:
- name: x_center
datatype: float32
title: "[pixels] x location of the center of a given wavelength element"
- name: y_center
datatype: float32
title: "[pixels] y location of the center of a given wavelength element"
- name: wavelength
datatype: float32
title: "[microns] central wavelength of the wavelength element at x_center, y_center"
- name: x0
datatype: float32
title: "[pixels] x location of the upper left corner of a given wavelength element"
- name: y0
datatype: float32
title: "[pixels] y location of the upper left corner of a given wavelength element"
- name: x1
datatype: float32
title: "[pixels] x location of the upper right corner of a given wavelength element"
- name: y1
datatype: float32
title: "[pixels] y location of the upper right corner of a given wavelength element"
- name: x2
datatype: float32
title: "[pixels] x location of the lower right corner of a given wavelength element"
- name: y2
datatype: float32
title: "[pixels] y location of the lower right corner of a given wavelength element"
- name: x3
datatype: float32
title: "[pixels] x location of the lower left corner of a given wavelength element"
- name: y3
datatype: float32
title: "[pixels] y location of the lower left corner of a given wavelength element"
- type: object
properties:
meta:
type: object
properties:
x_ref:
type: number
title: "[pixels] x coord of ref position of MIRIM_SLIT"
fits_keyword: IMX
y_ref:
type: number
title: "[pixels] y coord of ref position of MIRIM_SLIT"
fits_keyword: IMY
x_ref_slitless:
type: number
title: "[pixels] x coord of ref position of MIRIM_SLITLESS"
fits_keyword: IMXSLTL
y_ref_slitless:
type: number
title: "[pixels] y coord of ref position of MIRIM_SLITLESS"
fits_keyword: IMYSLTL
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this schema going to be used for SLITLESS mode? Do we expect a slitless mode reference file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This schema is supposed to work for both FIX slit and slitless. The slitless data does not need the v2/v3 vertices just the FIXED slit case

v2_vert1:
type: number
title: Slit vertex 1 in V2 frame
fits_keyword: V2VERT1
v2_vert2:
type: number
title: Slit vertex 2 in V2 frame
fits_keyword: V2VERT2
v2_vert3:
type: number
title: Slit vertex 3 in V2 frame
fits_keyword: V2VERT3
v2_vert4:
type: number
title: Slit vertex 4 in V2 frame
fits_keyword: V2VERT4
v3_vert1:
type: number
title: Slit vertex 1 in V3 frame
fits_keyword: V3VERT1
v3_vert2:
type: number
title: Slit vertex 2 in V3 frame
fits_keyword: V3VERT2
v3_vert3:
type: number
title: Slit vertex 3 in V3 frame
fits_keyword: V3VERT3
v3_vert4:
type: number
title: Slit vertex 4 in V3 frame
fits_keyword: V3VERT4
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ allOf:
- $ref: keyword_module.schema
- $ref: keyword_pupil.schema
- $ref: keyword_exptype.schema
- $ref: keyword_filter.schema
- type: object
properties:
displ:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ def flatten(xs):
"other": dm.ResolutionModel,
}

specwcs_model_map = {
"MIR_LRS-FIXEDSLIT": dm.MiriLRSSpecwcsModel,
"MIR_LRS-SLITLESS": dm.MiriLRSSpecwcsModel,
"NRC_WFSS": dm.NIRCAMGrismModel,
"NIS_WFSS": dm.NIRISSGrismModel,
"other": dm.SpecwcsModel,
}

ref_to_multiples_dict = {
"apcorr": apcorr_model_map,
"area": area_model_map,
Expand All @@ -120,6 +128,7 @@ def flatten(xs):
"pathloss": pathloss_model_map,
"photom": photom_model_map,
"resol": resol_model_map,
"specwcs": specwcs_model_map,
}

ref_to_datamodel_dict = {
Expand Down Expand Up @@ -167,7 +176,6 @@ def flatten(xs):
"speckernel": dm.SpecKernelModel,
"specprofile": dm.SpecProfileModel,
"spectrace": dm.SpecTraceModel,
"specwcs": dm.SpecwcsModel,
"straymask": dm.StrayLightModel,
"superbias": dm.SuperBiasModel,
"throughput": dm.ThroughputModel,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import numpy as np
from stdatamodels.jwst import datamodels


def test_miri_lrs_specwcs():
"""Test the MIRI LRS specwcs data is loaded correctly."""
xc = np.array([1.0, 2.0, 3.0])
yc = np.array([4.0, 5.0, 6.0])
wave = np.array([12.4, 13.4, 14.5])
x0 = np.array([1.0, 2.0, 3.0])
x1 = np.array([1, 2, 3])
x2 = np.array([1, 2, 3])
x3 = np.array([1, 2, 3])
y0 = np.array([1, 2, 3])
y1 = np.array([1, 2, 3])
y2 = np.array([1, 2, 3])
y3 = np.array([1, 2, 3])

d = np.dtype(
[
("x_center", np.float32),
("y_center", np.float32),
("wavelength", np.float32),
("x0", np.float32),
("y0", np.float32),
("x1", np.float32),
("y1", np.float32),
("x2", np.float32),
("y2", np.float32),
("x3", np.float32),
("y3", np.float32),
]
)
wavetable = np.array(
[
(xc[0], yc[0], wave[0], x0[0], y0[0], x1[0], y1[0], x2[0], y2[0], x3[0], y3[0]),
(xc[1], yc[1], wave[1], x0[1], y0[1], x1[1], y1[1], x2[1], y2[1], x3[1], y3[1]),
(xc[2], yc[2], wave[2], x0[2], y0[2], x1[2], y1[2], x2[2], y2[2], x3[2], y3[2]),
],
dtype=d,
)

model = datamodels.MiriLRSSpecwcsModel(x_ref=430, y_ref=400, wavetable=wavetable)
model.meta.description = "MIRI LRS SPECWCS reference file"
model.meta.author = "Jane Morrison"
model.meta.pedigree = "FLIGHT"
model.meta.useafter = "2022-05-01T00:00:00"
assert model.meta.instrument.name == "MIRI"
assert model.meta.instrument.detector == "MIRIMAGE"
assert model.meta.reftype == "specwcs"
assert model.meta.x_ref == 430
assert model.meta.y_ref == 400

# for slitless case assert the v2/v3 vertices are None if not in the file
assert model.meta.v2_vert1 is None
assert model.meta.v2_vert2 is None
assert model.meta.v2_vert3 is None
assert model.meta.v2_vert4 is None

assert model.meta.v3_vert1 is None
assert model.meta.v3_vert2 is None
assert model.meta.v3_vert3 is None
assert model.meta.v3_vert4 is None
model.validate()
107 changes: 107 additions & 0 deletions src/stdatamodels/jwst/datamodels/wcs_ref_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"NIRCAMGrismModel",
"NIRISSGrismModel",
"WaveCorrModel",
"MiriLRSSpecwcsModel",
]


Expand Down Expand Up @@ -398,6 +399,112 @@
raise NotImplementedError("FITS format is not supported for this file.")


class MiriLRSSpecwcsModel(ReferenceFileModel):
"""
A model for a reference file of type "specwcs" for MIRI LRS Slit.
The model is for the specwcs for LRS Fixed Slit and LRSSlitless
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we expect an LRS slitless reference file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nden Let me clarify as understand it there is a reference file for FIXED slit and a reference file for SLITLESS. But Both of these files are read in with the same datamodel. The existing slitless reference on CRDS will be used.
A new reference file for FIXED SLIT LRS will have the v2,v3 vertices.
Do you see any problem with this. I tested reading in the new reference file for LRS FIXED slit and the existing slitless reference file using this 1 datamodel model and they are read in correctly

Parameters
----------
x_ref : float
x coordinate of reference position of fixed slit aperture
y_ref : float
y coordinate of reference position of fixed slit aperture
x_ref_slitless : float
x coordinate of reference position of slitless aperture
y_ref_slitless : float
y coordinate of reference position of slitless aperture
v2vert1 : float
slit vertex 1 in V2 frame
v2vert2 : float
slit vertex 2 in V2 frame
v2vert3 : float
slit vertex 3 in V2 frame
v2vert4 : float
slit vertex 4 in V2 frames
v3vert1 : float
slit vertex 1 in V3 frames
v3vert2 : float
slit vertex 2 in V3 frames
v3vert3 : float
slit vertex 3 in V3 frames
v3vert4 : float
slit vertex 4 in V3 frames
wavetable : numpy 2-D array
For each row in the slit hold wavelength, and
x center, ycenter, x and y box region corresponding to the wavelength
"""

schema_url = "http://stsci.edu/schemas/jwst_datamodel/specwcs_miri_lrs.schema"
reftype = "specwcs"

def __init__(
self,
init=None,
wavetable=None,
x_ref=None,
y_ref=None,
x_ref_slitless=None,
y_ref_slitless=None,
v2_vert1=None,
v2_vert2=None,
v2_vert3=None,
v2_vert4=None,
v3_vert1=None,
v3_vert2=None,
v3_vert3=None,
v3_vert4=None,
**kwargs,
):
super().__init__(init=init, **kwargs)

if init is None:
self.populate_meta()
if wavetable is not None:
self.wavetable = wavetable
if x_ref is not None:
self.meta.x_ref = x_ref
if y_ref is not None:
self.meta.y_ref = y_ref
if x_ref_slitless is not None:
self.meta.x_ref_slitless = x_ref_slitless

Check warning on line 469 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L469

Added line #L469 was not covered by tests
if y_ref_slitless is not None:
self.meta.y_ref_slitless = y_ref_slitless

Check warning on line 471 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L471

Added line #L471 was not covered by tests
if v2_vert1 is not None:
self.meta.v2_vert1 = v2_vert1

Check warning on line 473 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L473

Added line #L473 was not covered by tests
if v2_vert2 is not None:
self.meta.v2_vert2 = v2_vert2

Check warning on line 475 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L475

Added line #L475 was not covered by tests
if v2_vert3 is not None:
self.meta.v2_vert3 = v2_vert3

Check warning on line 477 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L477

Added line #L477 was not covered by tests
if v2_vert4 is not None:
self.meta.v2_vert4 = v2_vert4

Check warning on line 479 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L479

Added line #L479 was not covered by tests
if v3_vert1 is not None:
self.meta.v3_vert1 = v3_vert1

Check warning on line 481 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L481

Added line #L481 was not covered by tests
if v3_vert2 is not None:
self.meta.v3_vert2 = v3_vert2

Check warning on line 483 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L483

Added line #L483 was not covered by tests
if v3_vert3 is not None:
self.meta.v3_vert3 = v3_vert3

Check warning on line 485 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L485

Added line #L485 was not covered by tests
if v3_vert4 is not None:
self.meta.v3_vert4 = v3_vert4

Check warning on line 487 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L487

Added line #L487 was not covered by tests

def populate_meta(self):
self.meta.instrument.name = "MIRI"
self.meta.instrument.detector = "MIRIMAGE"
self.meta.reftype = self.reftype
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs more keywords to define a LRS fixed slit mode - filter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added self.meta.instrument.filter = 'P750L'

self.meta.instrument.filter = "P750L"

def validate(self):
super(MiriLRSSpecwcsModel, self).validate()
try:
assert self.meta.instrument.name == "MIRI"
assert self.meta.instrument.detector == "MIRIMAGE"
assert self.meta.reftype.lower() == self.reftype
except AssertionError:
if self._strict_validation:
raise

Check warning on line 503 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L501-L503

Added lines #L501 - L503 were not covered by tests
else:
warnings.warn(traceback.format_exc(), ValidationWarning, stacklevel=2)

Check warning on line 505 in src/stdatamodels/jwst/datamodels/wcs_ref_models.py

View check run for this annotation

Codecov / codecov/patch

src/stdatamodels/jwst/datamodels/wcs_ref_models.py#L505

Added line #L505 was not covered by tests


class RegionsModel(ReferenceFileModel):
"""
A model for a reference file of type "regions".
Expand Down