-
Notifications
You must be signed in to change notification settings - Fork 26
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-3721: Simplify ModelContainer #190
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #190 +/- ##
==========================================
+ Coverage 73.29% 76.97% +3.68%
==========================================
Files 25 25
Lines 1917 1920 +3
==========================================
+ Hits 1405 1478 +73
+ Misses 512 442 -70 ☔ View full report in Codecov by Sentry. |
ac93d7c
to
e44fce4
Compare
starting regression tests on jwst main with this PR branch pinned as the stpipe version. This should show whether the stpipe changes are back-compatible with the previous ModelContainer |
Only one failed regtest, but starting a full new run just in case. Edit: all tests passed. |
I have now added several unit tests of the step The passing regression tests in the link above, which use the jwst main branch with stpipe pinned to this PR branch show that these changes are compatible with that pipeline even without making any changes to ModelContainer. Therefore I think we could safely merge this without waiting for the corresponding changes in the jwst repository. I don't think the two failing unit tests in jwst test_downstream are caused by this PR, because the same ones are also present on yesterday's CI on main. Marking this ready for review now. Can someone please start a romancal regtest run with this branch at some point? It would be good to ensure we aren't breaking anything there, either. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here are some minor comments (that I found I had not previously submitted).
I haven't had a chance to look at this PR in detail but I'm surprised by the number of required changes to simplify ModelContainer. Is the expectation that stpipe should be able to treat it like a list of models?
src/stpipe/step.py
Outdated
) | ||
elif isinstance(args[0], AbstractDataModel): | ||
|
||
elif isinstance(args[0], Sequence) and self.class_alias is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
elif isinstance(args[0], Sequence) and self.class_alias is not None: | |
elif isinstance(args[0], Sequence) and not isinstance(args[0], str) and self.class_alias is not None: |
if args[0] = "some_filename.fits" the current if can pass (issubclass(str, Sequence) == True
). I think the suggestion here will fix that.
I'd say we ignore potential issues with 0-length args (as those appear to exist with the current code).
src/stpipe/step.py
Outdated
|
||
elif isinstance(args[0], Sequence) and self.class_alias is not None: | ||
# handle ModelContainer or list of models | ||
if isinstance(args[0][0], AbstractDataModel): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if isinstance(args[0][0], AbstractDataModel): | |
if args[0] and isinstance(args[0][0], AbstractDataModel): |
To avoid an exception for args[0] = []
.
src/stpipe/step.py
Outdated
except AttributeError as e: | ||
self.log.info( | ||
"Could not record skip into DataModel" | ||
" header: %s", | ||
"Could not record skip into DataModel" " header: %s", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Could not record skip into DataModel" " header: %s", | |
"Could not record skip into DataModel header: %s", |
Yes, in the present version of the code a list of datamodels and the new ModelContainer take the same logic path. Some more notes on what changed:
|
Thanks. Is is straightforward to undo that de-duplication? It sounds like it's not required for this PR and would hopefully make it easier to review.
Can this be handled in jwst (either in the Step subclass or by fixing SourceModelContainer to have an API consistent with ModelContainer)? That way the code here that's shared with roman can be kept generic.
I'll have to look at this a bit more to understand it. Are you saying the code on main isn't behaving as expected so this PR is also fixing a different bug? |
No, but it's behaving in an undefined way.
Not sure what isn't generic about the present solution, as it does not check for any jwst-specific data types, just a
I can try. |
What's undefined? I'm expecting the answer might be the lack of documentation.
I sort of expected that a simplification of ModelContainer in jwst wouldn't involve changes to stpipe (or at least wouldn't add code here since ModelContainer isn't used in roman). The comment I'd be curious to hear your thoughts on either:
|
edit: I added the change to this branch, as it seems to be the best thing to do. Restarting regtests with jwst/main and this branch here. All passing! I think I was using the refactor as a crutch to understand the code better. I think you're right that this was possible with many fewer changes to step.py. The regression tests linked above show that this more minimal change is fully back-compatible with the current JWST pipeline on main, and the one failure on the PR branch looks easily fixed |
for more information, see https://pre-commit.ci
Thanks for updating this PR. I think my previous comment and question got missed. My main question is are all of the changes here a result of dropping save from ModelContainer? |
That's part of it, but mainly it's dropping the inheritance of AbstractDataModel from ModelContainer. It's true that ModelContainer used to be saved by its own The changes to the |
Thanks. If save is kept does the simplified ModelContainer pass an |
Not sure what you're asking, of course it doesn't pass such a check unless it's inheriting from AbstractDataModel, which it is not. Those checks can (and, basically, have) been changed to a check whether the input has its own I am not against retaining a |
The subclasshook in AbstractDataModel means explicit inheritance isn't required. Here's an example: import stpipe
class NotAModel:
def save(self):
pass
@property
def crds_observatory(self):
pass
def get_crds_parameters(self):
pass
assert isinstance(NotAModel(), stpipe.datamodel.AbstractDataModel) The assert succeeds even though
My hesitation is that stpipe is mostly unmaintained and a critical part of jwst and roman. It's pretty lacking in tests (it might be a bug in the coverage but this PR shows only 50% of the diff covered) and especially for roman the tests in the downstream packages don't well cover all the expected features from stpipe. Given that the motivation for this change is entirely due to jwst it seems overly risky to change stpipe if not necessary. |
Well, that would have been very good for me to know at the start of all of this. Learning hurts I guess... With that knowledge it does seem likely that retaining
The way I'm hearing this is, "stpipe should be maintained and tests should be expanded to cover any changes." Historically things have changed as a result of ModelContainer specifically. But maintaining the repository requires a human person, of course, so it's a management question and probably beyond either of our control. If I can make things work without changes to |
After discussion with Brett and Perry, I started a regression test run for JWST where stpipe is pinned to this PR branch, and the I also talked with Melanie and Tyler, and they want me to do my best to avoid requiring any stpipe changes with the jwst changes because they don't want the jwst development cycle to rely on changes and testing in stpipe that nobody is responsible for. Therefore, the plan is:
|
Helps to resolve JP-3721
Helps to close spacetelescope/jwst#8738
This PR enables the JWST ModelContainer to no longer inherit from DataModel and to no longer require its own
save
method, as part of an effort to make ModelContainer's usage narrower and easier to understand. This required two changes to the logic of step.py:skip
attributesave
methodTasks
docs/
pageno-changelog-entry-needed
)changes/
:echo "changed something" > changes/<PR#>.<changetype>.rst
(see below for change types)"git+https://github.com/<fork>/stpipe@<branch>"
)jwst
regression testromancal
regression testnews fragment change types...
changes/<PR#>.feature.rst
: new featurechanges/<PR#>.bugfix.rst
: fixes an issuechanges/<PR#>.doc.rst
: documentation changechanges/<PR#>.removal.rst
: deprecation or removal of public APIchanges/<PR#>.misc.rst
: infrastructure or miscellaneous change