spacetelescope / stdatamodels

https://stdatamodels.readthedocs.io
Other
5 stars 24 forks source link

Calling `datamodels.open` on a `SlitModel` clears `wht` #296

Open braingram opened 3 months ago

braingram commented 3 months ago

Minimal example:

import numpy as np
import stdatamodels.jwst.datamodels as dm

m0 = dm.SlitModel((27, 1299))
m0.wht[:] = 1

m1 = dm.open(m0)
np.testing.assert_equal(m1.wht, 0)
braingram commented 3 months ago

@nden @perrygreenfield This is the bug I mentioned.

braingram commented 3 months ago

There appears to be other issues with dm.open on a model. Here's an example with ImageModel:

import numpy as np
import stdatamodels.jwst.datamodels as dm

m0 = dm.ImageModel((256, 256))

np.testing.assert_allclose(m0.data, 0.0)  # data starts as all 0s

m1 = dm.open(m0)  # what should we expect this to do?

assert m1 is not m0   # the models are not the same
assert m1.data is m0.data  # however both use the same data array
m1.data[:] = 42  # modifying m1.data now modifies m0.data
np.testing.assert_allclose(m0.data, 42.0)

Passing a model to open is undocumented: https://stdatamodels.readthedocs.io/en/latest/api/stdatamodels.jwst.datamodels.open.html#stdatamodels.jwst.datamodels.open but is supported and the commented line says this should produce a "copy" https://github.com/spacetelescope/stdatamodels/blob/4041d5f75c2736f4c4131028232d62573c83d732/src/stdatamodels/jwst/datamodels/util.py#L111-L113

Passing a model to open is commonly used in jwst with many steps starting with a call to open(input).

braingram commented 3 months ago

A similar "shared" issue can be seen with the metadata and can persist across model type changes. See the following:

img = dm.ImageModel((256, 256))
assert img.meta.observation.visit_number is None

clone = dm.open(img)
assert clone.meta.observation.visit_number is None
clone.meta.observation.visit_number = '42'

# changing `visit_number` in clone also modified img
assert img.meta.observation.visit_number == '42'

# we can convert img to a CubeModel by doing the following
cube = dm.CubeModel(img)
cube.meta.observation.visit_number = '26'

assert img.meta.observation.visit_number == '26'