Repository: spacetelescope/jwst

Issue:
Improve how image group name is computed in the tweakreg step
_Issue [JP-3442](https://jira.stsci.edu/browse/JP-3442) was created on JIRA by [Mihai Cara](https://jira.stsci.edu/secure/ViewProfile.jspa?name=mcara):_

Current algorithm is quite simple and does not look for duplicate names and has a check to ensure that input file names have equal length. However, some users may want to  use different length file names. See help desk ticket INC0194239 for more details.

CC: [Paul Goudfrooij](https://jira.stsci.edu/secure/ViewProfile.jspa?name=goudfroo) 

Comments:

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index e951c3763..3ac9f225b 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -28,6 +28,11 @@ resample
   results in modified values in the resampled images. New computations
   significantly reduce photometric errors. [#7894]
 
+tweakreg
+--------
+
+- Improved how a image group name is determined. [#8012]
+
 
 1.12.5 (2023-10-19)
 ===================
diff --git a/jwst/tweakreg/tweakreg_step.py b/jwst/tweakreg/tweakreg_step.py
index 5bb32303f..1f0202dc0 100644
--- a/jwst/tweakreg/tweakreg_step.py
+++ b/jwst/tweakreg/tweakreg_step.py
@@ -276,11 +276,12 @@ class TweakRegStep(Step):
         elif len(grp_img) > 1:
             # create a list of WCS-Catalog-Images Info and/or their Groups:
             imcats = []
+            all_group_names = []
             for g in grp_img:
                 if len(g) == 0:
                     raise AssertionError("Logical error in the pipeline code.")
                 else:
-                    group_name = _common_name(g)
+                    group_name = _common_name(g, all_group_names)
                     wcsimlist = list(map(self._imodel2wcsim, g))
                     # Remove the attached catalogs
                     for model in g:
@@ -541,13 +542,31 @@ class TweakRegStep(Step):
         return im
 
 
-def _common_name(group):
+def _common_name(group, all_group_names=None):
     file_names = [path.splitext(im.meta.filename)[0].strip('_- ')
                   for im in group]
-    fname_len = list(map(len, file_names))
-    assert all(fname_len[0] == length for length in fname_len)
+
     cn = path.commonprefix(file_names)
-    assert cn
+
+    if all_group_names is None:
+        if not cn:
+            return 'Unnamed Group'
+    else:
+        if not cn or cn in all_group_names:
+            # find the smallest group number to make "Group #..." unique
+            max_id = 1
+            if not cn:
+                cn = "Group #"
+            for name in all_group_names:
+                try:
+                    cid = int(name.lstrip(cn))
+                    if cid >= max_id:
+                        max_id = cid + 1
+                except ValueError:
+                    pass
+            cn = f"{cn}{max_id}"
+        all_group_names.append(cn)
+
     return cn
 
 


Test patch:
diff --git a/jwst/tweakreg/tests/test_tweakreg.py b/jwst/tweakreg/tests/test_tweakreg.py
index 7f6e37ec2..ad45bf523 100644
--- a/jwst/tweakreg/tests/test_tweakreg.py
+++ b/jwst/tweakreg/tests/test_tweakreg.py
@@ -5,7 +5,8 @@ import asdf
 from astropy.modeling.models import Shift
 import pytest
 
-from jwst.tweakreg import TweakRegStep
+from jwst.tweakreg import tweakreg_step
+from stdatamodels.jwst.datamodels import ImageModel
 
 
 @pytest.mark.parametrize("offset, is_good", [(1 / 3600, True), (11 / 3600, False)])
@@ -20,6 +21,37 @@ def test_is_wcs_correction_small(offset, is_good):
     step.transform = step.transform | Shift(offset) & Shift(offset)
     twcs.bounding_box = wcs.bounding_box
 
-    step = TweakRegStep()
+    step = tweakreg_step.TweakRegStep()
 
     assert step._is_wcs_correction_small(wcs, twcs) == is_good
+
+
+@pytest.mark.parametrize(
+    "groups, all_group_names, common_name",
+    [
+        ([['abc1_cal.fits', 'abc2_cal.fits']], [], ['abc']),
+        (
+            [
+                ['abc1_cal.fits', 'abc2_cal.fits'],
+                ['abc1_cal.fits', 'abc2_cal.fits'],
+                ['abc1_cal.fits', 'abc2_cal.fits'],
+                ['def1_cal.fits', 'def2_cal.fits'],
+            ],
+            [],
+            ["abc", "abc1", "abc2", "def"],
+        ),
+        ([['cba1_cal.fits', 'abc2_cal.fits']], [], ['Group #1']),
+        ([['cba1_cal.fits', 'abc2_cal.fits']], ['Group #1'], ['Group #2']),
+        ([['cba1_cal.fits', 'abc2_cal.fits']], None, ['Unnamed Group']),
+    ]
+)
+def test_common_name(groups, all_group_names, common_name):
+    for g, cn_truth in zip(groups, common_name):
+        group = []
+        for fname in g:
+            model = ImageModel()
+            model.meta.filename = fname
+            group.append(model)
+
+        cn = tweakreg_step._common_name(group, all_group_names)
+        assert cn == cn_truth