-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Towards Roman Level 2 ASDF data product support #1822
Conversation
@@ -50,9 +57,18 @@ def parse_data(app, file_obj, ext=None, data_label=None): | |||
pf = rgb2gray(im) | |||
pf = pf[::-1, :] # Flip it | |||
_parse_image(app, pf, data_label, ext=ext) | |||
else: # Assume FITS | |||
elif file_obj_lower.endswith('.fits'): |
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.
This broke the test using download_file
because the file comes back as contents
without any extension. I think we should keep the else
fallback and assume FITS if nothing else matches.
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.
Unless you have a better way to figure out the filetype if the filename has no extension.
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.
Good point, @pllim. Do you think it would be appropriate to make a tiny PR to (update: no PR necessary!)astropy.utils.data
that allows a user to discover file extensions of local caches of remote data? I think I have a working example, so I may open an astropy PR today.
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.
I've implemented a possible workaround in b60872b. 🤞🏻
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.
I am not sure if that is general enough. The solution needs to account for:
- App-wide access. Not only Imviz is affected by this.
- Possibility of URL pointing to a valid file but the URL itself has no file extension. (Unless we decide this is not worth supporting.)
I was thinking about adopting format=
like https://docs.astropy.org/en/latest/table/io.html#getting-started so user can specify what format to look for if we cannot guess. Is that overkill?
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.
True, all parsers are affected by this problem. If that's something we want to fix generally, should that effort get its own ticket/issue so it can get prioritized/pointed? I'm not sure it is a pressing problem yet.
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.
Yes, we can defer, but you need to put "assume FITS" back in else
for this PR.
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.
Agreed! 👍🏻
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #1822 +/- ##
==========================================
- Coverage 91.94% 91.62% -0.32%
==========================================
Files 146 147 +1
Lines 16012 16098 +86
==========================================
+ Hits 14722 14750 +28
- Misses 1290 1348 +58
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
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.
When this is ready to go forward, will need at least one test (possibly multiple to cover all the logic paths) and user facing documentation and declaring new dep in setup.cfg
.
Change log can wait for now.
Thanks!
@@ -50,7 +71,14 @@ def parse_data(app, file_obj, ext=None, data_label=None): | |||
pf = rgb2gray(im) | |||
pf = pf[::-1, :] # Flip it | |||
_parse_image(app, pf, data_label, ext=ext) | |||
else: # Assume FITS | |||
elif file_obj_lower.endswith('.asdf'): | |||
if rdd 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.
What if someone passes in ASDF file that isn't Roman? Is there a way to identify that it is actually Roman data before attempting to read with Roman package?
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.
The roman_datamodels
docs page on the structure of Roman data products suggests that it is a "convention" that data are stored under a roman
attribute. I've confirmed this in the L2 products. If you run:
import asdf
with asdf.open(path) as f:
f.info()
you'll see
root (AsdfObject)
├─asdf_library (Software)
│ ├─author (str): The ASDF Developers
│ ├─homepage (str): http://github.com/asdf-format/asdf
│ ├─name (str): asdf
│ └─version (str): 2.13.0
├─history (dict)
│ └─extensions (list) ...
└─roman (WfiImage) # The schema for WFI Level 2 images.
...
Maybe the right thing to do is (1) open the file with the asdf
package, (2) check for a roman
attribute and load with roman_datamodels
if so, (3) otherwise try passing the ASDF file without roman_datamodels
.
def _roman_2d_asdf_to_glue_data(file_obj, data_label, ext=None): | ||
|
||
if ext == '*': | ||
ext_list = ['data', 'dq', 'err', 'var_poisson', 'var_rnoise'] |
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.
Does this account for all the observing modes or whatever that Roman will churn out?
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.
This line was contributed by @tddesjardins, and the background on the available extensions in the roman_datamodels
docs is rather sparse (e.g.: this page doesn't seem finished). Maybe @tddesjardins can comment?
|
||
for ext in ext_list: | ||
comp_label = ext.lower() | ||
new_data_label = f'{data_label}[{comp_label}]' |
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.
Should this use Jesse's label generator?
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.
I looked around the rest of the imviz/plugins/parsers.py
and found that there are still places where the data label is created by the parser, see for example:
new_data_label = f'{data_label}[{comp_label}]' |
Jesse's data label method from #1672 is within app.py:Application
, and these parser methods don't take the app as an argument, so we'd need to rework the arguments in each of the parser methods to use the centralized data labeler. Maybe @javerbukh can confirm – is there a way to outsource the data label creation linked above to the app's labeler? I'm not opposed to doing that work, but maybe that's a separate PR?
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.
Yeah I did not know what to do with those parser methods when centralizing the label generation. I tried putting app
as an argument but that caused a domino effect of issues so I backed out of that approach. I would think that handling that as a separate PR is a good call.
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.
Imviz has its own rules since it can load wildcard extension and have both FITS and ASDF support, and so on. If the function is hidden, doesn't hurt if you also want to pass in app
to them, but becareful to not break current Imviz labeling behavior. 🤪
|
||
yield data, new_data_label | ||
|
||
# ---- Functions that handle input from non-JWST and non-Roman files ----- |
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.
Do you mean to add this new empty "section" or did you mean to replace the existing section below?
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.
Fixed 👍🏻
The |
Since it is in such early development, what about a new "roman" section here? Line 53 in cbd6695
|
try: | ||
# check for version of roman_datamodels | ||
import roman_datamodels | ||
RDM_LT_0_14_2 = Version(roman_datamodels.__version__) < Version('0.14.2.dev') | ||
except ImportError: | ||
# If roman_datamodels not installed, assume Roman-specific tests can be skipped | ||
RDM_LT_0_14_2 = True | ||
|
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.
roman_datamodels > 0.14.1
will have tools for generating synthetic WFI-like data products on the fly. I've added a switch to allow tests to run when a sufficient version of roman_datamodels is installed.
@@ -327,7 +327,7 @@ def _roman_2d_asdf_to_glue_data(file_obj, data_label, ext=None): | |||
component = Component.autotyped(np.array(getattr(file_obj, ext)), units=bunit) | |||
data.add_component(component=component, label=comp_label) | |||
meta = getattr(file_obj, 'meta') | |||
data.coords = getattr(meta, 'wcs') | |||
data.coords = getattr(meta, 'wcs', 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.
Currently the dev version of roman_datamodels
has a method for generating WFI-like data products, but it doesn't generate artificial WCS yet. I've created an issue over there for requesting this: spacetelescope/roman_datamodels#134.
Progress update: this PR was created when Since then, As of f92fcb2, I'm beginning to develop tests based on the dev version of |
jdaviz/conftest.py
Outdated
# this filtered warning can be removed after resolution of PR: | ||
# https://github.com/spacetelescope/roman_datamodels/pull/138 | ||
@pytest.mark.filterwarnings( | ||
'ignore:erfa.core.ErfaWarning: ERFA function "d2dtf" yielded 1 of "dubious year (Note 5)"' | ||
) |
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.
This can be removed when spacetelescope/roman_datamodels#138 is addressed.
setup.cfg
Outdated
roman = | ||
roman_datamodels @ git+https://github.com/spacetelescope/roman_datamodels.git | ||
rad @ git+https://github.com/spacetelescope/rad.git |
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.
@tddesjardins taught me that roman_datamodels==0.14.0, rad==0.14.0
support old synthetic data products, like the ones I originally built this PR to support. Newer synthetic data will require the dev versions (spacetelescope/roman_datamodels#133).
For now, I'm requiring dev versions of roman_datamodels
and rad
. We can minpin to the next release whenever it's available.
jdaviz/conftest.py
Outdated
} | ||
raw.update(kwargs) | ||
raw["meta"]["photometry"] = create_photometry() | ||
raw["meta"]["wcs"] = create_example_gwcs(image_shape) |
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.
This line is the main difference from the analogous method in roman_datamodels.testing.factories.create_wfi_image
. We need a synthetic GWCS object to use in our example image file, so I adapted a photutils method for creating one, and attach it to the image model. See discussion in spacetelescope/roman_datamodels#134.
@@ -1,6 +1,6 @@ | |||
[tox] | |||
envlist = | |||
py{38,39,310,311}-test{,-alldeps,-devdeps,-predeps}{,-cov} | |||
py{38,39,310,311}-test{,-alldeps,-devdeps,-predeps}{-romandeps}{,-cov} |
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.
I've added a romandeps
testing option, and a CI test that uses it (allowed_fail=True), but I'm not 100% sure I've done this sensibly. Tips welcome!
setup.cfg
Outdated
@@ -61,6 +61,8 @@ test = | |||
docs = | |||
sphinx-rtd-theme | |||
sphinx-astropy | |||
roman = | |||
roman_datamodels @ git+https://github.com/spacetelescope/roman_datamodels.git |
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.
This is temporary, right? I don't think we can release to PyPI with a pin like this.
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.
Correct.
Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com>
Co-authored-by: P. L. Lim <2090236+pllim@users.noreply.github.com>
is not installed in the test suite
CHANGES.rst
Outdated
@@ -10,6 +10,20 @@ New Features | |||
|
|||
- Exact-text filtering for metadata plugin. [#2147] | |||
|
|||
- CLI launchers no longer require data to be specified. [#1890] | |||
|
|||
Mosviz |
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.
im assuming you just need to rebase which is why this extra stuff is in here
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.
Yikes, I think this resulted from a bad rebase. I'll fix that now. Good catch!
Thanks all! |
Background
This PR implements basic support for Roman Level 2 data products in Imviz. This effort was begun by @tddesjardins in his prototyping PR #1361. I am further revising and testing a version of that prototype in this branch/PR. Many of the revisions I've made to the implementation by @tddesjardins came from comments in a helpful review by @pllim in June.
Test data
The Roman team is producing an ever-updating set of synthetic data products. I wrote this PR around a specific set of synthetic data, which you can read more about in the collapsed section below:
Old background on test data
Outdated:
Test dataI am working with simulated exposures in the Roman ASDF format, which are used by the concept notebook. Some notes on these simulated exposures:
SOC Build 22Q4_B7
Test Suite (this link is only for STScI internal folks, sorry others!)The PR will now run tests on tiny synthetic
roman_datamodels.datamodels.ImageModel
objects (~20x20 pixels, plus metadata), instead of the gigantic, synthetic data products.Dependencies
This PR adds
roman_datamodels
as an optional dependency, and falls back on theasdf
package ifroman_datamodels
is not available.Demo
I added a concept notebook in
notebooks/concepts/ImvizExample-asdf.ipynb
, which is a variation onImvizExample.ipynb
adapted for the Roman ASDF L2 data files. Of course, I will plan to add more comprehensive documentation as POs and/or other devs request it. Though I'm not sure how urgent it is to add docs when no one outside of the Roman team knows how to procure the files that are supported by this PR 😅 .Testing
I have not added any tests yet. I could use some ideas from other devs on how to approach testing. Perhaps it would it be wise to make a tiny version of a Roman ASDF file, perhaps one that just has a small subset of the
data
array, but all of the usual metadata. That file could be small enough to put on Box and add to the remote-data tests. Thoughts?Speed
Testing with glue-core v1.6, I find the following load times for one 4k image (from a single WFI detector):
Fixes #1355
Supersedes / closes #1361
🐱
Change log entry
CHANGES.rst
? If you want to avoid merge conflicts,list the proposed change log here for review and add to
CHANGES.rst
before merge. If no, maintainershould add a
no-changelog-entry-needed
label.Checklist for package maintainer(s)
This checklist is meant to remind the package maintainer(s) who will review this pull request of some common things to look for. This list is not exhaustive.
trivial
label.