diff --git a/CHANGES.rst b/CHANGES.rst index 0e56957067..3069853c64 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -40,6 +40,8 @@ associations for S1600A1 with 5 point dithers, to reduce overlap between background nods and science exposure. [#8744] +- Added association rule for level 3 image mosaic candidates. [#8798] + badpix_selfcal -------------- diff --git a/jwst/associations/lib/rules_level3.py b/jwst/associations/lib/rules_level3.py index ac64e1128e..bd1b4d1f54 100644 --- a/jwst/associations/lib/rules_level3.py +++ b/jwst/associations/lib/rules_level3.py @@ -25,6 +25,7 @@ 'Asn_Lv3ACQ_Reprocess', 'Asn_Lv3AMI', 'Asn_Lv3Image', + 'Asn_Lv3ImageMosaic', 'Asn_Lv3ImageBackground', 'Asn_Lv3MIRCoron', 'Asn_Lv3MIRMRS', @@ -466,7 +467,7 @@ def __init__(self, *args, **kwargs): value = ('T') )], reduce=Constraint.notany - ), + ), DMSAttrConstraint( name='channel', sources=['channel'], @@ -1172,3 +1173,72 @@ def __init__(self, *args, **kwargs): @property def dms_product_name(self): return dms_product_name_sources(self) + + +@RegistryMarker.rule +class Asn_Lv3ImageMosaic(AsnMixin_Science): + """Level 3 Science Image Mosaic Association + + Characteristics: + - Association type: ``image3`` + - Pipeline: ``calwebb_image3`` + - Non-TSO + - Non-WFS&C + - Collect separate tiles of mosaic into one product + """ + + def __init__(self, *args, **kwargs): + + # Setup constraints + self.constraints = Constraint([ + Constraint_Optical_Path(), + Constraint_Image(), + DMSAttrConstraint( + name='wfsvisit', + sources=['visitype'], + value='((?!wfsc).)*', + required=False + ), + Constraint( + [ + DMSAttrConstraint( + name='bkgdtarg', + sources=['bkgdtarg'], + ), + Constraint_TSO() + ], + reduce=Constraint.notany + ), + ]) + + # Only valid if candidate type is 'mosaic'. + self.validity.update({ + 'is_type_mosaic': { + 'validated': False, + 'check': self._validate_candidates + } + }) + + # Now check and continue initialization. + super(Asn_Lv3ImageMosaic, self).__init__(*args, **kwargs) + + def _init_hook(self, item): + """Post-check and pre-add initialization""" + + self.data['asn_type'] = 'image3' + super(Asn_Lv3ImageMosaic, self)._init_hook(item) + + def _validate_candidates(self, item): + """Allow only mosaic asn candidates + + Returns + ------- + True if candidate type is mosaic. + False otherwise. + """ + + # If a group candidate, reject. + if self.acid.type.lower() != 'mosaic': + return False + + return True diff --git a/jwst/regtest/test_associations_sdp_pools.py b/jwst/regtest/test_associations_sdp_pools.py index 3c63554fda..3cbe4afe08 100644 --- a/jwst/regtest/test_associations_sdp_pools.py +++ b/jwst/regtest/test_associations_sdp_pools.py @@ -147,6 +147,12 @@ 'xfail': None, 'slow': False, }, + # This association tests the Asn_Lv3ImageMosaic rule + 'jw02739_20230710t150016_pool': { + 'args': ['-i', 'c1000'], + 'xfail': None, + 'slow': False, + }, 'jw80600_20171108T041522_pool': { 'args': [], 'xfail': 'PR #3450',