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-3702: Fix filenames for level3 NIRSpec #8699

Merged
merged 9 commits into from
Aug 27, 2024
Merged
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ assign_wcs
- Moved `update_s_region_imaging`, `update_s_region_keyword`, and `wcs_from_footprints`
into stcal. [#8624]

associations
------------

- Restored slit name to level 3 product names for NIRSpec BOTS and background
fixed slit targets. [#8699]

cube_build
----------

Expand Down
6 changes: 2 additions & 4 deletions jwst/associations/lib/dms_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -765,17 +765,15 @@ def _get_slit_name(self):
else:
values.sort(key=str.lower)
value = format_list(values)
if value not in _EMPTY:
if value not in _EMPTY and value not in slit_names:
slit_names.append(value)

# Build the string. Sort the elements in order to
# create data-independent results
slit_names.sort(key=str.lower)
slit_name = '-'.join(slit_names)

if slit_name == '':
slit_name = None

# Slit name may be empty string
return slit_name

def _get_subarray(self):
Expand Down
24 changes: 16 additions & 8 deletions jwst/associations/lib/rules_level3_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ def _dms_product_name(association):

opt_elem = association._get_opt_element()

slit_name = association._get_slit_name()
if slit_name:
slit_name = '-' + slit_name

exposure = association._get_exposure()
if exposure:
exposure = '-' + exposure
Expand All @@ -170,14 +174,15 @@ def _dms_product_name(association):
'jw{program}-{acid}'
'_{target}'
'_{instrument}'
'_{opt_elem}{subarray}'
'_{opt_elem}{slit_name}{subarray}'
)
product_name = product_name.format(
program=association.data['program'],
acid=association.acid.id,
target=target,
instrument=instrument,
opt_elem=opt_elem,
slit_name=slit_name,
subarray=subarray,
exposure=exposure
)
Expand Down Expand Up @@ -633,6 +638,10 @@ def dms_product_name_sources(asn):

opt_elem = asn._get_opt_element()

slit_name = asn._get_slit_name()
if slit_name:
slit_name = '-' + slit_name

subarray = asn._get_subarray()
if subarray:
subarray = '-' + subarray
Expand All @@ -641,23 +650,26 @@ def dms_product_name_sources(asn):
'jw{program}-{acid}'
'_{source_id}'
'_{instrument}'
'_{opt_elem}{subarray}'
'_{opt_elem}{slit_name}{subarray}'
)
product_name = format_product(
product_name_format,
program=asn.data['program'],
acid=asn.acid.id,
instrument=instrument,
opt_elem=opt_elem,
slit_name=slit_name,
subarray=subarray,
)

return product_name.lower()


def dms_product_name_nrsfs_sources(asn):
"""Produce source-based product names for
NIRSpec fixed-slit observations.
"""Produce source-based product names for NIRSpec fixed-slit observations.

For this mode, the product names have a placeholder for the
slit name, to be filled in later by the pipeline.

Parameters
---------
Expand All @@ -674,10 +686,6 @@ def dms_product_name_nrsfs_sources(asn):

opt_elem = asn._get_opt_element()

slit_name = asn._get_slit_name()
if slit_name:
slit_name = '-' + slit_name

subarray = asn._get_subarray()
if subarray:
subarray = '-' + subarray
Expand Down
64 changes: 55 additions & 9 deletions jwst/associations/tests/test_level3_product_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
t_path,
)

from jwst.associations import (AssociationPool, generate)
from jwst.associations import generate
from jwst.associations.lib.dms_base import DMSAttrConstraint


Expand Down Expand Up @@ -96,7 +96,7 @@ def test_level3_names(pool_file, global_constraints):
rules = registry_level3_only(
global_constraints=global_constraints
)
pool = AssociationPool.read(pool_file)
pool = combine_pools(pool_file)
asns = generate(pool, rules)
for asn in asns:
product_name = asn['products'][0]['name']
Expand All @@ -110,18 +110,64 @@ def test_level3_names(pool_file, global_constraints):

def test_multiple_optelems(pool_file):
rules = registry_level3_only()
pool = AssociationPool.read(pool_file)
asns = generate(pool, rules)
pool = combine_pools(pool_file)
asns = generate(pool, rules, finalize=False)
for asn in asns:
product_name = asn['products'][0]['name']
if asn['asn_rule'] != 'Asn_Lv3MIRMRS':
m = re.match(LEVEL3_PRODUCT_NAME_REGEX, product_name)
assert m is not None

# there should always be an opt_elem
values = ['-'.join(asn.constraints['opt_elem'].found_values)]

# there may also be an opt_elem2, fixed slit or 2, or a subarray
for extra in ['opt_elem2', 'fxd_slit', 'fxd_slit2', 'subarray']:

# special rules for fixed slit for NRS FS:
# it gets a format placeholder instead of the value
if asn['asn_rule'] == 'Asn_Lv3NRSFSS':
if extra == 'fxd_slit':
values.append('{slit_name}')
continue
elif extra == 'fxd_slit2':
continue

try:
value = '-'.join(asn.constraints[extra].found_values)
except KeyError:
value = None

# empty values and subarray = full are not recorded
if value not in EMPTY and value != 'full':
values.append(value)

assert m.groupdict()['opt_elem'] == '-'.join(values)


def test_tso3_names():
rules = registry_level3_only()
tso_pool = t_path('data/pool_021_tso.csv')
pool = combine_pools(tso_pool)
asns = generate(pool, rules, finalize=False)
for asn in asns:
product_name = asn['products'][0]['name']

m = re.match(LEVEL3_PRODUCT_NAME_REGEX, product_name)
assert m is not None

# there should always be an opt_elem
values = ['-'.join(asn.constraints['opt_elem'].found_values)]

# there may also be an opt_elem2, fixed slit or 2, or a subarray
for extra in ['opt_elem2', 'fxd_slit', 'fxd_slit2', 'subarray']:
try:
value = '-'.join(asn.constraints['opt_elem2'].found_values)
value = '-'.join(asn.constraints[extra].found_values)
except KeyError:
value = None
if value in EMPTY:
assert '-' not in m.groupdict()['opt_elem']
else:
assert '-' in m.groupdict()['opt_elem']

# empty values and subarray = full are not recorded
if value not in EMPTY and value != 'full':
values.append(value)

assert m.groupdict()['opt_elem'] == '-'.join(values)
Loading