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

Initial sky matching implementation #687

Merged
merged 14 commits into from
Jun 6, 2023
Merged

Conversation

bmorris3
Copy link
Collaborator

@bmorris3 bmorris3 commented Apr 26, 2023

Resolves RCAL-498

This PR provides an initial adaptation of the skymatch module in jwst implemented by @mcara. I have made every effort to preserve the same functionality, tests, and docs as jwst.skymatch.

The primary difference between the implementations is that I have (temporarily?) dropped support for associations, since the definition of associations for JWST and Roman is likely to be different in important ways that are still partly TBD.

Locally the tests pass and the docs build successfully only when using roman_datamodels with the fix in: spacetelescope/roman_datamodels#164

The algorithm is summarized nicely in Makovoz et al. (2005). In short, it takes a group of images with different background levels (see the left panel below) and solves a system of equations for the best sky background level in each image to bring all backgrounds into agreement. The resulting matched and subtracted images are shown in the right panel below.

demo

Checklist

  • added entry in CHANGES.rst under the corresponding subsection
  • updated relevant tests
  • updated relevant documentation
  • updated relevant milestone(s)
  • added relevant label(s)

@bmorris3 bmorris3 requested a review from a team as a code owner April 26, 2023 13:52
@github-actions github-actions bot added dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation testing labels Apr 26, 2023
@codecov
Copy link

codecov bot commented Apr 26, 2023

Codecov Report

Patch coverage: 64.34% and project coverage change: +10.59 🎉

Comparison is base (67639b2) 64.55% compared to head (2684287) 75.14%.

Additional details and impacted files
@@             Coverage Diff             @@
##             main     #687       +/-   ##
===========================================
+ Coverage   64.55%   75.14%   +10.59%     
===========================================
  Files          78       88       +10     
  Lines        3950     5243     +1293     
===========================================
+ Hits         2550     3940     +1390     
+ Misses       1400     1303       -97     
Flag Coverage Δ *Carryforward flag
nightly 64.55% <ø> (ø) Carriedforward from 2efec43

*This pull request uses carry forward flags. Click here to find out more.

Impacted Files Coverage Δ
romancal/lib/suffix.py 94.28% <ø> (ø)
romancal/skymatch/skyimage.py 47.07% <47.07%> (ø)
romancal/skymatch/skymatch_step.py 74.35% <74.35%> (ø)
romancal/skymatch/skymatch.py 80.22% <80.22%> (ø)
romancal/skymatch/region.py 80.33% <80.33%> (ø)
romancal/skymatch/skystatistics.py 92.10% <92.10%> (ø)
romancal/skymatch/__init__.py 100.00% <100.00%> (ø)

... and 29 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@schlafly
Copy link
Collaborator

Great! Just out of curiosity---for your simulated data, do we expect to be able to achieve perfect agreement? I feel like I can see a bit of remaining structure by eye in the mosaic, but it looks a bit more like a gradient than an offset, and I wonder if it's an issue in the simulations rather than an issue in the optimization. e.g., something like the simulations having constant sky offsets in terms of sky / pixel, but the code assuming that the sky is constant in terms of sky / unit area, so the pixel scale factor comes into one bit but not the other? Just guessing!

Copy link
Collaborator

@ddavis-stsci ddavis-stsci left a comment

Choose a reason for hiding this comment

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

When I try and run the pytests from your branch I get these errors,
TypeError: Input must be a list of either strings (full path to ASDF files) or Roman datamodels.
and I think the pytests should be self contained.

as well as instrumental (e.g. thermal) background, etc.

The step records information in three keywords that are included in the output
files:
Copy link
Collaborator

Choose a reason for hiding this comment

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

For asdf files we usually refer to keywords (FITS) as attributes.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Got it, thanks!


- BKGLEVEL: the sky level computed for each image

- BKGSUB: a boolean indicating whether or not the sky was subtracted from the
Copy link
Collaborator

Choose a reason for hiding this comment

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

Note: we can expand the attribute names to be longer than the 8 character FITS limit,
so I'd suggest something like
BKGMETH --> background_method

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point! These aren't the names I gave the attributes, I just hadn't changed this part of the docs to match. Correcting them now.

self.log.setLevel(logging.DEBUG)
# for now turn off memory optimization until we have better machinery
# to handle outputs in a consistent way.
self._is_asn = False
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where is the memory optimization?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was recently implemented in jwst by @mcara, but not implemented here. I'll remove this comment.

input_image_model = image_model

if "background" not in image_model.meta:
# TODO: remove this block when ``rad`` has a background schema.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we have an issue for this in the rad project?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

@ddavis-stsci ddavis-stsci left a comment

Choose a reason for hiding this comment

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

You also need to add a link to your successful run of the regression tests,
see the "GitHub PR" section of
https://innerspace.stsci.edu/pages/viewpage.action?spaceKey=SCSB&title=Roman+Calibration+Pipeline

@bmorris3
Copy link
Collaborator Author

bmorris3 commented May 4, 2023

RE @schlafly in #687 (comment): we discussed this a bit in the last pipeline tag-up, but I'll share my response here so others can see too. The slight mismatches that remain in the demo plot above are likely slightly exaggerated by the visualization I made.

I've updated the visualization, and the notebook that generates the plot below is available here:

demo

Each image is labeled with a random index, and the color is chosen from blue to red for images from low to high mean background flux. Left column is before sky match, right column is after. Histograms in the bottom row show all pixel values in each image. The image that seems like the worst match is image "6", which has a post-subtraction mean normalized by its stddev of 2%.

@mcara
Copy link
Member

mcara commented May 5, 2023

What was matched: mode? mean? median? This can affect the quality of the match that you observe. For 'mode', binwidth is important too.

@bmorris3
Copy link
Collaborator Author

bmorris3 commented May 9, 2023

Thanks for the pointers @mcara. I ran the sky match step with:

result = SkyMatchStep.call(image_models, subtract=False, skymethod='global+match')

which would choose the default sky statistic mode. The bin width is also the default 0.1.

@mcara
Copy link
Member

mcara commented May 9, 2023

I would suggest that you re-do the test using skystat='mean' since that is what you use in your script when making those plots.

Copy link
Member

@mcara mcara left a comment

Choose a reason for hiding this comment

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

It looks like 99.9% of the code from JWST pipeline + PEP8 and style improvements + support for units. Should function like JWST code.

@bmorris3
Copy link
Collaborator Author

bmorris3 commented May 9, 2023

I would suggest that you re-do the test using skystat='mean' since that is what you use in your script when making those plots.

Good call @mcara, see below for a version with skystat='mean', which shows even better agreement in this toy example:

demo

@schlafly
Copy link
Collaborator

schlafly commented May 9, 2023

Ah, yes, that looks much better!

@bmorris3
Copy link
Collaborator Author

Here's the regression test link.

Copy link
Collaborator

@ddavis-stsci ddavis-stsci left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Collaborator

@PaulHuwe PaulHuwe left a comment

Choose a reason for hiding this comment

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

I assume regression tests will be done in another PR.

docs/roman/skymatch/description.rst Outdated Show resolved Hide resolved
# temporary) workaround to a limitation of the original code that the
# polygon must be completely contained in the image. It seems that the
# code works fine if we make sure that the bottom-left corner of the
# polygon's bounding box has non-negative coordinates.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this mean the code breaks if a polygon with more than 4 sides is used?

Copy link
Member

Choose a reason for hiding this comment

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

No

self._shiftx = x
if y < self._shifty:
self._shifty = y
v = [(i - self._shiftx, j - self._shifty) for i, j in vertices]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, no the could would shift fine - maybe the above text should be changed a bit? (Since if one has a 6 sided polygon, it isn't moving the bottom-left corner to (0,0), but further positive in order to get other corners in the positive planar quadrant.

romancal/skymatch/region.py Outdated Show resolved Hide resolved
romancal/skymatch/region.py Outdated Show resolved Hide resolved
romancal/skymatch/skyimage.py Outdated Show resolved Hide resolved
romancal/skymatch/skyimage.py Outdated Show resolved Hide resolved
dm.data[...] = sky_image.image[...]

dm.meta.cal_step.skymatch = step_status

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you make an issue to add skymatch to cal_step in RAD?


if self._is_asn:
dm.save(image)
dm.close()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Are you saving the infrastructure to add this to the pipeline for another ticket? (Possibly for a new pipeline - ELPP vs HLPP.)

romancal/skymatch/tests/test_skymatch.py Show resolved Hide resolved
@mcara
Copy link
Member

mcara commented May 18, 2023

I assume regression tests will be done in another PR.

Regression tests for this step were not available in the JWST pipeline until recently: spacetelescope/jwst#7531 They could be added to this PR or in a separate PR but ideally it should be done in this PR.

@bmorris3
Copy link
Collaborator Author

For ease of finding them later, I'll collect upstream issues/links here:

@nden
Copy link
Collaborator

nden commented Jun 5, 2023

Can this be merged or is anyone interested in reviewing it?

@ddavis-stsci
Copy link
Collaborator

Does this have a Roman-Developers-Pull-Requests run?
Other than that it has been reviewed several times (I think).

@ddavis-stsci ddavis-stsci modified the milestones: 23Q3_B10, 23Q4_B11 Jun 6, 2023
@nden
Copy link
Collaborator

nden commented Jun 6, 2023

@nden nden merged commit a026c37 into spacetelescope:main Jun 6, 2023
mairanteodoro pushed a commit to mairanteodoro/romancal that referenced this pull request Jun 6, 2023
Co-authored-by: Paul Huwe <[email protected]>
Co-authored-by: Nadia Dencheva <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
mairanteodoro pushed a commit to mairanteodoro/romancal that referenced this pull request Jun 12, 2023
Co-authored-by: Paul Huwe <[email protected]>
Co-authored-by: Nadia Dencheva <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation skymatch testing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants