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

JP-3858-srctype #9239

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ repos:
jwst/saturation/.* |
jwst/scripts/.* |
jwst/spectral_leak/.* |
jwst/srctype/.* |
jwst/straylight/.* |
jwst/tests/.* |
jwst/tso_photometry/.* |
Expand Down
2 changes: 0 additions & 2 deletions .ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ exclude = [
"jwst/saturation/**.py",
"jwst/scripts/**.py",
"jwst/spectral_leak/**.py",
"jwst/srctype/**.py",
"jwst/straylight/**.py",
"jwst/tso_photometry/**.py",
"jwst/wfs_combine/**.py",
Expand Down Expand Up @@ -144,7 +143,6 @@ ignore-fully-untyped = true # Turn off annotation checking for fully untyped co
"jwst/saturation/**.py" = ["D", "N", "A", "ARG", "B", "C4", "ICN", "INP", "ISC", "LOG", "NPY", "PGH", "PTH", "S", "SLF", "SLOT", "T20", "TRY", "UP", "YTT", "E501"]
"jwst/scripts/**.py" = ["D", "N", "A", "ARG", "B", "C4", "ICN", "INP", "ISC", "LOG", "NPY", "PGH", "PTH", "S", "SLF", "SLOT", "T20", "TRY", "UP", "YTT", "E501"]
"jwst/spectral_leak/**.py" = ["D", "N", "A", "ARG", "B", "C4", "ICN", "INP", "ISC", "LOG", "NPY", "PGH", "PTH", "S", "SLF", "SLOT", "T20", "TRY", "UP", "YTT", "E501"]
"jwst/srctype/**.py" = ["D", "N", "A", "ARG", "B", "C4", "ICN", "INP", "ISC", "LOG", "NPY", "PGH", "PTH", "S", "SLF", "SLOT", "T20", "TRY", "UP", "YTT", "E501"]
"jwst/straylight/**.py" = ["D", "N", "A", "ARG", "B", "C4", "ICN", "INP", "ISC", "LOG", "NPY", "PGH", "PTH", "S", "SLF", "SLOT", "T20", "TRY", "UP", "YTT", "E501"]
"jwst/tso_photometry/**.py" = ["D", "N", "A", "ARG", "B", "C4", "ICN", "INP", "ISC", "LOG", "NPY", "PGH", "PTH", "S", "SLF", "SLOT", "T20", "TRY", "UP", "YTT", "E501"]
"jwst/wfs_combine/**.py" = ["D", "N", "A", "ARG", "B", "C4", "ICN", "INP", "ISC", "LOG", "NPY", "PGH", "PTH", "S", "SLF", "SLOT", "T20", "TRY", "UP", "YTT", "E501"]
Expand Down
4 changes: 3 additions & 1 deletion jwst/srctype/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Determine if a spectroscopic source should be considered to be a point or extended object."""

from .srctype_step import SourceTypeStep

__all__ = ['SourceTypeStep']
__all__ = ["SourceTypeStep"]
120 changes: 62 additions & 58 deletions jwst/srctype/srctype.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

def set_source_type(input_model, source_type=None):
"""
Set source_type based on APT input, user specification, exposure type,
or default values.
Set source_type based on APT input, user specification, exposure type, or default values.

Parameters
----------
Expand All @@ -29,24 +28,29 @@
or `~jwst.datamodels.SlitModel`
The updated model.
"""

# Get the exposure type of the input model
exptype = input_model.meta.exposure.type
if exptype is None:
log.error('EXP_TYPE value not found in input')
raise RuntimeError('Step cannot be executed without an EXP_TYPE value')
log.error("EXP_TYPE value not found in input")
raise RuntimeError("Step cannot be executed without an EXP_TYPE value")
else:
log.info(f'Input EXP_TYPE is {exptype}')
log.info(f"Input EXP_TYPE is {exptype}")
# For exposure types that have a single source specification, get the
# user-supplied source type from the selection they provided in the APT
if exptype in ['MIR_LRS-FIXEDSLIT', 'MIR_LRS-SLITLESS', 'MIR_MRS',
'NRC_TSGRISM', 'NIS_SOSS', 'NRS_FIXEDSLIT',
'NRS_BRIGHTOBJ', 'NRS_IFU']:

if exptype in [
"MIR_LRS-FIXEDSLIT",
"MIR_LRS-SLITLESS",
"MIR_MRS",
"NRC_TSGRISM",
"NIS_SOSS",
"NRS_FIXEDSLIT",
"NRS_BRIGHTOBJ",
"NRS_IFU",
]:
# Get info about the exposure, including whether it's a background
# target and the dither pattern type
bkg_target = input_model.meta.observation.bkgdtarg
if exptype == 'MIR_MRS':
if exptype == "MIR_MRS":
patttype = input_model.meta.dither.optimized_for
else:
patttype = input_model.meta.dither.primary_type
Expand All @@ -59,13 +63,13 @@
# SRCTYPE as both input and output (as before).
try:
user_type = input_model.meta.target.source_type_apt
log.info(f'Input SRCTYAPT = {user_type}')
log.info(f"Input SRCTYAPT = {user_type}")
if user_type is None:
log.warning('SRCTYAPT keyword not found in input; using SRCTYPE instead')
log.warning("SRCTYAPT keyword not found in input; using SRCTYPE instead")
user_type = input_model.meta.target.source_type
input_model.meta.target.source_type_apt = user_type
except AttributeError:
log.warning('SRCTYAPT keyword not found in input; using SRCTYPE instead')
log.warning("SRCTYAPT keyword not found in input; using SRCTYPE instead")

Check warning on line 72 in jwst/srctype/srctype.py

View check run for this annotation

Codecov / codecov/patch

jwst/srctype/srctype.py#L72

Added line #L72 was not covered by tests
user_type = input_model.meta.target.source_type
input_model.meta.target.source_type_apt = user_type

Expand All @@ -74,49 +78,49 @@
source_type = str(source_type).upper()

# Check if the exposure type is a mode that allows setting
if exptype in ['MIR_LRS-FIXEDSLIT', 'MIR_LRS-SLITLESS',
'MIR_MRS', 'NRC_TSGRISM', 'NRS_FIXEDSLIT',
'NRS_BRIGHTOBJ', 'NRS_IFU']:

if exptype in [
"MIR_LRS-FIXEDSLIT",
"MIR_LRS-SLITLESS",
"MIR_MRS",
"NRC_TSGRISM",
"NRS_FIXEDSLIT",
"NRS_BRIGHTOBJ",
"NRS_IFU",
]:
src_type = source_type

log.warning(f'Based on user-input, setting SRCTYPE = {src_type}')
log.warning(f"Based on user-input, setting SRCTYPE = {src_type}")
input_model.meta.target.source_type = src_type

elif bkg_target:

# If this image is flagged as a BACKGROUND target, set the
# source type to EXTENDED regardless of any other settings
src_type = 'EXTENDED'
log.info(f'Exposure is a background target; setting SRCTYPE = {src_type}')
src_type = "EXTENDED"
log.info(f"Exposure is a background target; setting SRCTYPE = {src_type}")

elif pipe_utils.is_tso(input_model):

# Treat all TSO exposures as a point source
src_type = 'POINT'
log.info(f'Input is a TSO exposure; setting SRCTYPE = {src_type}')

elif user_type in ['POINT', 'EXTENDED']:
src_type = "POINT"
log.info(f"Input is a TSO exposure; setting SRCTYPE = {src_type}")

elif user_type in ["POINT", "EXTENDED"]:
# Use the value supplied by the user
src_type = user_type
log.info(f'Using input source type = {src_type}')

elif (patttype is not None) and (('NOD' in patttype) or ('POINT-SOURCE' in patttype)):
log.info(f"Using input source type = {src_type}")

elif (patttype is not None) and (("NOD" in patttype) or ("POINT-SOURCE" in patttype)):
# Set all nodded exposures to POINT source type
src_type = 'POINT'
log.info(f'Exposure is nodded; setting SRCTYPE = {src_type}')
src_type = "POINT"
log.info(f"Exposure is nodded; setting SRCTYPE = {src_type}")

Check warning on line 114 in jwst/srctype/srctype.py

View check run for this annotation

Codecov / codecov/patch

jwst/srctype/srctype.py#L113-L114

Added lines #L113 - L114 were not covered by tests

else:

# Set a default value based on the exposure type
if exptype in ['MIR_MRS', 'NRS_IFU']:
src_type = 'EXTENDED'
if exptype in ["MIR_MRS", "NRS_IFU"]:
src_type = "EXTENDED"
else:
src_type = 'POINT'
src_type = "POINT"

log.info(f'Input source type is unknown; setting default SRCTYPE = {src_type}')
log.info(f"Input source type is unknown; setting default SRCTYPE = {src_type}")

# Set the source type in the global meta attribute
input_model.meta.target.source_type = src_type
Expand All @@ -126,31 +130,29 @@
if isinstance(input_model, datamodels.SlitModel):
input_model.source_type = src_type

elif input_model.meta.exposure.type == 'NRS_FIXEDSLIT':

elif input_model.meta.exposure.type == "NRS_FIXEDSLIT":
# NIRSpec fixed-slit is a special case: Apply the source type
# determined above to only the primary slit (the one in which
# the target is located). Set all other slits to the default
# value, which for NRS_FIXEDSLIT is 'EXTENDED'.
default_type = 'EXTENDED'
default_type = "EXTENDED"
primary_slit = input_model.meta.instrument.fixed_slit
log.debug(f' primary_slit = {primary_slit}')
log.debug(f" primary_slit = {primary_slit}")
for slit in input_model.slits:
if slit.name == primary_slit:
slit.source_type = src_type
# Ensure x,y position reset to zero if source type is EXTENDED
if src_type == 'EXTENDED':
if src_type == "EXTENDED":
slit.source_xpos = 0.0
slit.source_ypos = 0.0
else:
slit.source_type = default_type
log.debug(f' slit {slit.name} = {slit.source_type}')
log.debug(f" slit {slit.name} = {slit.source_type}")

# For NIRSpec MSA exposures, read the stellarity value for the
# source in each extracted slit and set the point/extended value
# based on the stellarity.
elif exptype == 'NRS_MSASPEC':

elif exptype == "NRS_MSASPEC":
# Loop over the input slits
for slit in input_model.slits:
stellarity = slit.stellarity
Expand All @@ -159,38 +161,40 @@
# a threshold value from a reference file. For now, the
# threshold is hardwired.
if stellarity < 0.0:
slit.source_type = 'POINT'
slit.source_type = "POINT"
elif stellarity > 0.75:
slit.source_type = 'POINT'
slit.source_type = "POINT"
else:
slit.source_type = 'EXTENDED'
slit.source_type = "EXTENDED"

log.info(f'source_id={slit.source_id}, stellarity={stellarity:.4f}, type={slit.source_type}')
log.info(
f"source_id={slit.source_id}, stellarity={stellarity:.4f}, type={slit.source_type}"
)

# Remove the global target source type, so that it never mistakenly
# gets used for MOS data, which should always use slit-specific values
input_model.meta.target.source_type = None

# Set all TSO exposures to POINT
elif pipe_utils.is_tso(input_model):
src_type = 'POINT'
log.info(f'Input is a TSO exposure; setting default SRCTYPE = {src_type}')
src_type = "POINT"
log.info(f"Input is a TSO exposure; setting default SRCTYPE = {src_type}")

Check warning on line 181 in jwst/srctype/srctype.py

View check run for this annotation

Codecov / codecov/patch

jwst/srctype/srctype.py#L180-L181

Added lines #L180 - L181 were not covered by tests
input_model.meta.target.source_type = src_type

# For WFSS modes check slit values of is_extended to set SRCTYPE
elif exptype in ['NIS_WFSS', 'NRC_WFSS']:
elif exptype in ["NIS_WFSS", "NRC_WFSS"]:
for slit in input_model.slits:
if slit.is_extended:
slit.source_type = 'EXTENDED'
slit.source_type = "EXTENDED"

Check warning on line 188 in jwst/srctype/srctype.py

View check run for this annotation

Codecov / codecov/patch

jwst/srctype/srctype.py#L188

Added line #L188 was not covered by tests
else:
slit.source_type = 'POINT'
log.info(f'source_id={slit.source_id}, type={slit.source_type}')
slit.source_type = "POINT"
log.info(f"source_id={slit.source_id}, type={slit.source_type}")

Check warning on line 191 in jwst/srctype/srctype.py

View check run for this annotation

Codecov / codecov/patch

jwst/srctype/srctype.py#L190-L191

Added lines #L190 - L191 were not covered by tests

# Unrecognized exposure type; set to UNKNOWN as default
else:
log.warning(f'EXP_TYPE {exptype} not applicable to this operation')
src_type = 'UNKNOWN'
log.warning(f'Setting SRCTYPE = {src_type}')
log.warning(f"EXP_TYPE {exptype} not applicable to this operation")
src_type = "UNKNOWN"
log.warning(f"Setting SRCTYPE = {src_type}")
input_model.meta.target.source_type = src_type

# We're done
Expand Down
25 changes: 19 additions & 6 deletions jwst/srctype/srctype_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

class SourceTypeStep(Step):
"""
SourceTypeStep: Selects and sets a source type based on various inputs.
Select and set a source type based on various inputs.

The source type is used in later calibrations to determine the appropriate
methods to use. Input comes from either the SRCTYAPT keyword value, which
is populated from user info in the APT, or the NIRSpec MSA planning tool.
Expand All @@ -21,25 +22,37 @@

spec = """
source_type = option('POINT','EXTENDED', default=None) # user-supplied source type
""" # noqa: E501
"""

def process(self, step_input):
"""
Determine the source type.

def process(self, input):
Parameters
----------
step_input : str, IFUImageModel, MultiSlitModel, or SlitModel
Either the path to the file or the science data model to be corrected.

Returns
-------
datamodel : IFUImageModel, MultiSlitModel, or SlitModel
Data model with keyword “SRCTYPE” populated with either “POINT” or “EXTENDED”.
"""
if self.source_type is not None:
self.source_type = self.source_type.upper()

source_type = self.source_type # retrieve command line override

input_model = datamodels.open(input)
input_model = datamodels.open(step_input)

# Call the source selection routine
result = set_source_type(input_model, source_type)

# Set the step status in the output model
if result is None:
result = input_model
result.meta.cal_step.srctype = 'SKIPPED'
result.meta.cal_step.srctype = "SKIPPED"

Check warning on line 54 in jwst/srctype/srctype_step.py

View check run for this annotation

Codecov / codecov/patch

jwst/srctype/srctype_step.py#L54

Added line #L54 was not covered by tests
else:
result.meta.cal_step.srctype = 'COMPLETE'
result.meta.cal_step.srctype = "COMPLETE"

return result
Loading