Skip to content
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

DM-39842: Configurable exception handling in CalibrateImageTask #835

Merged
merged 2 commits into from Mar 22, 2024

Conversation

parejkoj
Copy link
Contributor

No description provided.

applied_photo_calib=None,
astrometry_matches=None,
photometry_matches=None,
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm torn as to whether it's better to spell out the possible fields here with None values, vs. letting run be the sole source of truth on those. I think the QuantumContext changes in pipe_base should allow either to work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To simplify the call to annotate below (so it's not a mess of getattr), I need to at least specify the items that are passed to annotate. I don't like specifying a result list in both places (runQuantum and the top of run); I've changed it so run just makes an empty Struct (this caught a bug!) which is a bit better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like it could be fragile if we ever change this task to output more things in the result Struct. Is it not possible to construct a list of arguments to feed the error annotation by iterating over all the existing things in the Struct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not without using a whole bunch of getattr and tests of whether those things have a metadata property. In this design, the PipelineTask author has to specifically choose which output datasets could get annotated on failure and pass them to annotate individually. It might be nice to just pass the result struct and let annotate figure it out, but that's probably more complicated than it's worth (not all datasets support metadata, e.g. AstropyArrow).


butlerQC.put(outputs, outputRefs)
# This should not happen with a properly configured execution context.
assert not inputs, "runQuantum got more inputs than expected"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If/when this falls over, will the error message specify that the runQuantum being talked about is the one from calibrateImage?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the assert will give where it happened. This is a "this should absolutely never happen" error, hence the bare assert.

butlerQC.put(result, outputRefs)
raise error from e

butlerQC.put(result, outputRefs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in a finally block?

Copy link
Contributor Author

@parejkoj parejkoj Mar 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. We only butler.put if the task succeeded, or if AlgorithmError is caught, all other errors can't be annotated, so writing partial outputs is unhelpful (and potentially harmful, as downstream tasks won't know that they're partial).

applied_photo_calib=None,
astrometry_matches=None,
photometry_matches=None,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like it could be fragile if we ever change this task to output more things in the result Struct. Is it not possible to construct a list of arguments to feed the error annotation by iterating over all the existing things in the Struct?


self._summarize(exposure, stars, background)
self._summarize(result.exposure, result.stars_footprints, result.background)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this using result.stars_footprints and not result.stars ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ComputeExposureSummaryStatsTask takes a SourceCatalog. result.stars is just for the output. Eventually we'll start converting downstream tasks (like ipdiffim, maybe?) to take AstropyArrow input catalogs, but that's a long ways off.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so stars_footprints and stars has the same information but in different formats? Cute, OK, carry on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the Connections here: https://github.com/lsst/pipe_tasks/blob/main/python/lsst/pipe/tasks/calibrateImage.py#L87

Eventually, the goal will be fore the stars_footprints to only contain the footprints and none of the catalog information, but that's a long ways off.

@@ -448,7 +471,7 @@ def run(self, *, exposures, id_generator=None):
result : `lsst.pipe.base.Struct`
Results as a struct with attributes:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the results Struct guaranteed to have all of the documented attributes, now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean?

If the task completes, it returns result. If an exception is raised, the input parameter has (hopefully!) been modified, but nothing is returned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, but apparently I never added docs for the result parameter: I'll do that now.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's what I added:

        result : `lsst.pipe.base.Struct`, optional
            Result struct that is modified to allow saving of partial outputs
            for some failure conditions. If the task completes successfully,
            this is also returned.

tests/test_calibrateImage.py Outdated Show resolved Hide resolved
@parejkoj parejkoj force-pushed the tickets/DM-39842 branch 2 times, most recently from ed3e79f to 3314006 Compare March 21, 2024 21:41
Use the new Task exceptions and a pre-defined results struct to manage partial
outputs for failures of CalibrateImage subtasks.
Add tests of runQuantum exception handling.
The input is now a multiple `exposures`, so we can use that to simplify
the code by renaming output_exposure->exposure.
This didn't actually affect the tests, but it's better to have two
distinct exposures in the test butler.
@parejkoj parejkoj merged commit 88ce0b6 into main Mar 22, 2024
2 checks passed
@parejkoj parejkoj deleted the tickets/DM-39842 branch March 22, 2024 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants