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

MNT: Port from pysynphot to stsynphot #388

Merged
merged 11 commits into from
Apr 1, 2021

Conversation

pllim
Copy link
Contributor

@pllim pllim commented Feb 4, 2021

Fix #362

cc @mperrin

TODO

  • Have stakeholders review and test this.
  • Fix code and tests, if necessary.

Copy link
Contributor Author

@pllim pllim left a comment

Choose a reason for hiding this comment

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

Someone needs to test this manually as I don't think your CI currently run the tests that requires PySynphot.

poppy/instrument.py Outdated Show resolved Hide resolved

wave_bin_edges = np.linspace(minwave, maxwave, nlambda + 1)
wavesteps = (wave_bin_edges[:-1] + wave_bin_edges[1:]) / 2
deltawave = wave_bin_edges[1] - wave_bin_edges[0]
jwst_area = 25.4 * (units.m * units.m)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

stsynphot no longer let you set-and-forget the area like PySynphot does, because I deemed the risk of forgetting and then silently using the wrong value to be not worth the convenience.

elif sptype == "Flat spectrum in F_lambda":
spec = pysynphot.FlatSpectrum(1, fluxunits='flam')
spec.convert('flam')
return spec * (1. / spec.flux.mean())
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 don't know why it is being normalized here. In the refactored package, flat spectrum is analytic and wavelength to evaluate it over isn't known ahead of time, so it is quite hard to normalize like this.

if ans is None:
raise ValueError("Invalid power law specification cannot be parsed to get exponent")
exponent = float(ans.groups(0)[0])
# note that Pysynphot's PowerLaw class implements a power law in terms of lambda, not nu.
# note that synphot's PowerLaw class implements a power law in terms of lambda, not nu.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is now possible to define powerlaw in frequency space but that functionality isn't widely tested.

@codecov
Copy link

codecov bot commented Feb 5, 2021

Codecov Report

Merging #388 (0692a72) into develop (f3feb10) will increase coverage by 2.40%.
The diff coverage is 52.63%.

❗ Current head 0692a72 differs from pull request most recent head aef3cb2. Consider uploading reports for the commit aef3cb2 to get more accurate results
Impacted file tree graph

@@             Coverage Diff             @@
##           develop     #388      +/-   ##
===========================================
+ Coverage    71.44%   73.85%   +2.40%     
===========================================
  Files           18       17       -1     
  Lines         6066     6051      -15     
===========================================
+ Hits          4334     4469     +135     
+ Misses        1732     1582     -150     
Impacted Files Coverage Δ
poppy/matrixDFT.py 98.29% <ø> (+39.77%) ⬆️
poppy/utils.py 52.37% <0.00%> (-0.54%) ⬇️
poppy/instrument.py 67.28% <64.44%> (+10.00%) ⬆️
poppy/__init__.py 83.87% <100.00%> (-0.51%) ⬇️
poppy/active_optics.py
poppy/dms.py 46.13% <0.00%> (+0.55%) ⬆️
poppy/optics.py 81.82% <0.00%> (+0.56%) ⬆️
poppy/poppy_core.py 80.12% <0.00%> (+0.56%) ⬆️
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f3feb10...aef3cb2. Read the comment docs.

MNT: Move conftest.py to root level for tox to pick up test header.

MNT: Modernize test setup a little.

TST: Use tmpdir fixture to avoid generating untracked files.

TST: Add stsynphot to coverage run.
@pllim
Copy link
Contributor Author

pllim commented Feb 5, 2021

Update: I got the tests to pass locally, but I don't know how good is your test coverage, so please review this PR carefully.

p.s. Would be nice if your package uses Quantity throughout; it defeats the purpose of using Quantity to only manually convert the units back and forth; but that is out of scope of this PR.

@pllim
Copy link
Contributor Author

pllim commented Feb 5, 2021

Unrelated to this PR but I see this warning on your test page: Please be aware travis-ci.org will be shutting down in several weeks, with all accounts migrating to travis-ci.com. Please stay tuned here for more information.

So, you either need to move to their .com service and start paying, or port your testing infrastructure to GitHub Actions. I see that you already use tox, so doing the latter should be very easy for you.

@mperrin
Copy link
Collaborator

mperrin commented Feb 5, 2021

Thanks @pllim! @shanosborne can you give this a look, please.

@pllim: on Travis yes we're aware, and @shanosborne has been coordinating on that with others (ideally this should be solved consistently for many/most of the INS packages, not on a case-by-case basis)

About quantities, agreed in principle. However, the quantity framework becomes somewhat complicated to use with Fourier transforms (which is the core of what this package does...), and further there were noticeable performance impacts if I tried to use quantity throughout in one test PR. Admittedly that was a while ago (a couple years). It's possible some of this could be improved, but I agree it's out of scope for this PR

@pllim
Copy link
Contributor Author

pllim commented Feb 5, 2021

Re: Performance of Quantity -- Might worth checking out https://docs.astropy.org/en/latest/units/index.html#performance-tips and see if it is of any use to you.

Copy link
Contributor

@shanosborne shanosborne left a comment

Choose a reason for hiding this comment

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

This PR looks good, thanks @pllim! We can't merge it right now because we've determined that the current dev version of WebbPSF can't run with PR and needs some updates (basically the same pysynphot->stsynphot updates). So we'll merge this PR once we have a comparable PR in WebbPSF ready to go.

@pllim
Copy link
Contributor Author

pllim commented Feb 22, 2021

@shanosborne , not sure what you mean, as I developed this PR against your default branch and it is not showing that there is a conflict, but however you want to do this is fine by me. I do recommend that you test the changes extensively downstream before accepting the changes. Thanks!

@shanosborne
Copy link
Contributor

@pllim You were able to run the development version of webbpsf with the version of poppy in this PR? I agree that this version of poppy runs fine on it's own, but the downstream webbpsf package fails for me with this poppy change with the error of AttributeError: 'ArraySpectralElement' object has no attribute 'waveset'.

@pllim
Copy link
Contributor Author

pllim commented Feb 22, 2021

Ah, sorry, I missed the fact that WebbPSF is a separate repository!

Hard to tell without the full traceback. What would be useful is if you tell me where the corresponding WebbPSF PR is and I can look at its CI log. Thank you!

@shanosborne shanosborne marked this pull request as ready for review March 29, 2021 14:52
Copy link
Collaborator

@mperrin mperrin left a comment

Choose a reason for hiding this comment

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

This looks good. @shanosborne I have a few (minor, optional) suggestions below.

One general question: has anyone done yet any performance benchmarking? I'm not expecting major speed changes either way, I just want to verify at a basic level there aren't any surprises.

Side topic, I see this includes some better usage of temp directories in some of the unit tests - thanks, that's needed to be done for a while.

@@ -0,0 +1,26 @@
# this contains imports plugins that configure py.test for astropy tests.
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's the story with this added contest.py file? This is pretty cryptic in parts, and I'd like to understand whether this is needed for some of the tests of synphot, whether it provides other benefits, and/or whether this causes any other changes in the behavior of the test system.

I'd like to request another sentence or two of comments here to clarify what this stuff is for, and/or simplifying if any of this is not strictly needed.

And also, is the package root directory really the place this file should be? I think in that case it does not get installed into site-packages since it's not within the poppy package subdirectory, right? Is that the intended behavior?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Story: The way tox is being run, pytest is not seeing (some of?) your poppy/conftest.py, so the test header isn't being displayed correctly in the CI logs (go see for yourself). This fixes the header.

Also see astropy/pytest-astropy-header#15 (comment) .

As for how you want to document this story in a way that you understand, feel free to use the "suggestion" feature. I have been doing this for so long that I might not document it the way that make sense to you.


wave_bin_edges = np.linspace(minwave, maxwave, nlambda + 1)
wavesteps = (wave_bin_edges[:-1] + wave_bin_edges[1:]) / 2
deltawave = wave_bin_edges[1] - wave_bin_edges[0]
jwst_area = 25.4 * (units.m * units.m)
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can simply delete this line with the jwst_area and remove the usage of it below. poppy is not interested in absolute fluxes, just normalized PSFs, so we can simplify and avoid hard-coding in this parameter with no change in results.

Copy link
Contributor

Choose a reason for hiding this comment

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

So area is a required parameter for synphot.Observation, but we can change it so it just takes in 1 m^2 rather than a specific number related to JWST.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

area is required but it is up to you what value to give it.

In PySynphot, it was also required but PySynphot just automatically used HST area unless you overwrite the setting.

filterfile = self._filters[self.filter].filename
filterfits = fits.open(filterfile)
filterfits = fits.open(filterfile) # TODO: Use context manager
Copy link
Collaborator

@mperrin mperrin Mar 29, 2021

Choose a reason for hiding this comment

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

This #TODO could be done now simply by replacing this line and the next with filterdata = fits.getdata(filterfile), I think.

@mperrin
Copy link
Collaborator

mperrin commented Mar 29, 2021

Oh and I see we now have some conflicts that need to be resolved before this is mergeable.

Copy link
Contributor Author

@pllim pllim left a comment

Choose a reason for hiding this comment

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

It is my understanding that @shanosborne has taken over the PR, so I'll let her handle the code pushes to address the reviews. I will be available for consultation. Please let me know if you have further concerns or questions. Thanks!

@@ -0,0 +1,26 @@
# this contains imports plugins that configure py.test for astropy tests.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Story: The way tox is being run, pytest is not seeing (some of?) your poppy/conftest.py, so the test header isn't being displayed correctly in the CI logs (go see for yourself). This fixes the header.

Also see astropy/pytest-astropy-header#15 (comment) .

As for how you want to document this story in a way that you understand, feel free to use the "suggestion" feature. I have been doing this for so long that I might not document it the way that make sense to you.

@shanosborne
Copy link
Contributor

@mperrin I've done the updates you requested and fixed the merge conflicts. I'll do some bench-marking next, but will likely not get it done today, just a heads up!

@shanosborne
Copy link
Contributor

@mperrin Quick bench marking results. I ran the following default calculation several times, both with the code in this PR and the code in the current master branch (confirming that stsynphot and pysynphot were called respectively):

import poppy
inst = poppy.Instrument()
%timeit inst.calc_psf()

My average results:
STSynphot Case: 3.08 s ± 103 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Pysynphot Case: 2.86 s ± 51 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

@mperrin
Copy link
Collaborator

mperrin commented Apr 1, 2021

@shanosborne Thanks. Looks like stsynphot is perhaps a little slower than pysynphot (for whatever reason), but in any case not drastically different. Those two measurements are consistent at ~1 sigma in any case. @pllim that sound right to you?

I just wanted to check this to verify no surprises. We want to move to stsynphot in any case so I will go ahead and merge this

@mperrin mperrin merged commit 84b8ceb into spacetelescope:develop Apr 1, 2021
@pllim pllim deleted the pysyn-stsyn-port branch April 1, 2021 14:28
@pllim
Copy link
Contributor Author

pllim commented Apr 1, 2021

Looks like stsynphot is perhaps a little slower than pysynphot

I agree with @mperrin that they are consistent within uncertainty. But if you really want to drill down on it, you can do a more detailed profiling and see where the bulk of the processing time is in both. stsynphot does include overhead of astropy units and models, but it also does not sample until needed, so it really depends on how you are using it.

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.

Migrate from pysynphot to synphot
3 participants