task: metadata: install: pip install -e .[test,docs]
patch: diff --git a/CHANGES.rst b/CHANGES.rst
index d594dd381..62e506adc 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -17,6 +17,8 @@ assign_wcs
 
 - Added SIP approximation to WCS for imaging modes. FITS WCS keywords added to meta.wcsinfo. [#5507]
 
+- Fix bug where subarray bounding boxes were 1 pixel too small. [#5543]
+
 associations
 ------------
 
@@ -163,6 +165,7 @@ set_telescope_pointing
 ----------------------
 
 - Add logging of the found quaternion information [#5495]
+- Handle cases where engineering database's pointing mnemonics are all zero over the requested time range [#5540]
 
 skymatch
 --------
diff --git a/jwst/assign_wcs/util.py b/jwst/assign_wcs/util.py
index 8be97bfec..f3c6870ca 100644
--- a/jwst/assign_wcs/util.py
+++ b/jwst/assign_wcs/util.py
@@ -830,10 +830,9 @@ def bounding_box_from_subarray(input_model):
     bb_yend = -0.5
 
     if input_model.meta.subarray.xsize is not None:
-        # Implicitely there's bb_xstart + 0.5 and xsize -1 - 0.5
-        bb_xend = input_model.meta.subarray.xsize - 1 - 0.5
+        bb_xend = input_model.meta.subarray.xsize - 0.5
     if input_model.meta.subarray.ysize is not None:
-        bb_yend = input_model.meta.subarray.ysize - 1 - 0.5
+        bb_yend = input_model.meta.subarray.ysize - 0.5
 
     bbox = ((bb_ystart, bb_yend), (bb_xstart, bb_xend))
     return bbox
diff --git a/jwst/lib/set_telescope_pointing.py b/jwst/lib/set_telescope_pointing.py
index e710e7657..0038eb5ff 100644
--- a/jwst/lib/set_telescope_pointing.py
+++ b/jwst/lib/set_telescope_pointing.py
@@ -592,8 +592,12 @@ def calc_wcs_over_time(obsstart, obsend, engdb_url=None, tolerance=60, reduce_fu
     vinfos = list()
 
     # Calculate WCS
-    pointings = get_pointing(obsstart, obsend, engdb_url=engdb_url,
+    try:
+        pointings = get_pointing(obsstart, obsend, engdb_url=engdb_url,
                              tolerance=tolerance, reduce_func=reduce_func)
+    except ValueError:
+        logger.warning("Cannot get valid engineering mnemonics from engineering database")
+        raise
     if not isinstance(pointings, list):
         pointings = [pointings]
     for pointing in pointings:
@@ -1546,17 +1550,41 @@ def pointing_from_average(mnemonics):
         eng_param.obstime.unix
         for eng_param in mnemonics['SA_ZATTEST1']
     ]
-    obstime = Time(np.average(times), format='unix')
-
+    goodtimes = []
+    for this_time in times:
+        if this_time != 0.0:
+            goodtimes.append(this_time)
+    if len(goodtimes) > 0:
+        obstime = Time(np.average(goodtimes), format='unix')
+    else:
+        raise ValueError("No valid times in range")
     # Get averages for all the mnemonics.
     mnemonic_averages = {}
+    zero_mnemonics = []
     for mnemonic in mnemonics:
         values = [
             eng_param.value
             for eng_param in mnemonics[mnemonic]
         ]
-        mnemonic_averages[mnemonic] = np.average(values)
-
+        # Weed out mnemonic entries that are zero
+        # 'SA_ZADUCMDX' and 'SA_ZADUCMDY' can be zero
+        if mnemonic not in ['SA_ZADUCMDX', 'SA_ZADUCMDY']:
+            good_mnemonic = []
+            for this_value in values:
+                if this_value != 0.0:
+                    good_mnemonic.append(this_value)
+            if len(good_mnemonic) > 0:
+                mnemonic_averages[mnemonic] = np.average(good_mnemonic)
+            else:
+                zero_mnemonics.append(mnemonic)
+        else:
+            mnemonic_averages[mnemonic] = np.average(values)
+    # Raise exception if there are mnemonics with only zeros in the time range
+    if len(zero_mnemonics):
+        logger.warning("The following engineering mnemonics only contained zeros in the requested time interval:")
+        badmnemonicsstring = ' '.join(zero_mnemonics)
+        logger.info(badmnemonicsstring)
+        raise ValueError("Bad telemetry values")
     # Fill out the pointing matrices.
     q = np.array([
         mnemonic_averages['SA_ZATTEST1'],

problem_statement: subarray bounding boxes are 1 pixel too small
_Issue [JP-1818](https://jira.stsci.edu/browse/JP-1818) was created on JIRA by [James Davies](https://jira.stsci.edu/secure/ViewProfile.jspa?name=jdavies):_

Testing of

#5507

found a bug in `jwst.assign_wcs` where NIRCam time-series subarrays of 64x64 were getting bounding boxes of size

```
In [9]: result
Out[9]: <CubeModel(4, 64, 64) from jw00312006001_02102_00001-seg001_nrcb1_rateints.fits>

In [11]: result.meta.subarray.instance
Out[11]: 
{'fastaxis': 1,
 'name': 'SUB64P',
 'slowaxis': -2,
 'xsize': 64,
 'xstart': 1985,
 'ysize': 64,
 'ystart': 1985}

In [12]: result.meta.wcs.bounding_box
Out[12]: ((-0.5, 62.5), (-0.5, 62.5))
```

It looks like this is a general problem for all subarray bounding boxes.
repo: spacetelescope/jwst
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/jwst/assign_wcs/tests/test_util.py b/jwst/assign_wcs/tests/test_util.py
index 763a939e5..9ffb3a119 100644
--- a/jwst/assign_wcs/tests/test_util.py
+++ b/jwst/assign_wcs/tests/test_util.py
@@ -101,4 +101,4 @@ def test_bounding_box_from_subarray():
     im.meta.subarray.ystart = 6
     im.meta.subarray.xsize = 400
     im.meta.subarray.ysize = 600
-    assert bounding_box_from_subarray(im) == ((-.5, 598.5), (-.5, 398.5))
+    assert bounding_box_from_subarray(im) == ((-.5, 599.5), (-.5, 399.5))