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

Add SFD map code to the DESI utilities #116

Merged
merged 29 commits into from
Sep 5, 2018
Merged

Add SFD map code to the DESI utilities #116

merged 29 commits into from
Sep 5, 2018

Conversation

geordie666
Copy link
Contributor

This PR transfers the dust map code from desitarget.mock.sfdmap to desiutil.

The context for porting this across is that the dust maps are now used in several places in desitarget (not just the mocks) and will likely also be needed for future updates to desispec. Some notes:

  • Changes the default environment variable SFD_DIR to DUST_DIR
  • Adds unit tests, which didn't exist in desitarget

@moustakas
Copy link
Member

This looks outstanding. My only comment is that you consider renaming the sfdmap module something more generic like dust, so we can (in a separate PR) add one or more extinction curves, which will be needed in both desitarget.mock and desispec (to deredden spectra for Galactic extinction).

@weaverba137 weaverba137 self-requested a review August 27, 2018 21:52
@weaverba137
Copy link
Member

There are some very significant problems with this PR. But there is clearly still some active development going on, so please let me know when things are stable so I can review.

@geordie666
Copy link
Contributor Author

geordie666 commented Aug 27, 2018

@weaverba137: Looks like the critical unit tests are now passing, so feel free to elucidate the very significant problems.

@weaverba137
Copy link
Member

The last change came in just as I was about to start a review.

@geordie666
Copy link
Contributor Author

Go for it with the review. That's a completely cosmetic change (hence the [ci skip]). I was just improving coding style, but it's nothing significant.

@weaverba137
Copy link
Member

A GitHub review needs to be attached to a particular commit. If a new commit comes in while the review is going on, you have to refresh the files changed view and sometimes all your review comments can be lost.

@geordie666
Copy link
Contributor Author

Noted. In future I won't make commits while reviews are pending, or I'll wait until I'm done with all commits before requesting a review. Hopefully that didn't happen in this case.

Copy link
Member

@weaverba137 weaverba137 left a comment

Choose a reason for hiding this comment

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

In summary, the code should be rewritten to match DESI standards before it can be accepted.

@@ -0,0 +1,384 @@
# Copied on Nov/20/2016 from https://github.com/kbarbary/sfdmap/ commit: bacdbbd
Copy link
Member

Choose a reason for hiding this comment

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

Desiutil already has a license, and we need to ensure that all code is compatible with that license. Maybe we were sloppy about that when the code was in desitarget, but desiutil is typically held to a much higher standard.

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 remain uncertain as to what to do about reusing code licensed in this manner. Now that you've brought this to my attention I certainly wouldn't merge this until we know the implications. I'm hoping @sbailey has some bright ideas.

desiutil.dust
=============

Get E(B-V) values from the Schlegel, Finkbeiner & Davis (1998) dust map.
Copy link
Member

Choose a reason for hiding this comment

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

It would be helpful to add a link to the paper itself, or the abstract on ADS.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!

except ImportError:
raise ImportError("could not import fitsio or astropy.io.fits")

__all__ = ['SFDMap', 'ebv']
Copy link
Member

Choose a reason for hiding this comment

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

No one in DESI should be doing from desiutil.dust import *, so this line is not necessary.

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 have removed this line.

raise ImportError("could not import fitsio or astropy.io.fits")

__all__ = ['SFDMap', 'ebv']
__version__ = "0.1.0"
Copy link
Member

Choose a reason for hiding this comment

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

Desiutil already has a version, desiutil.__version__, so this really shouldn't be here.

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've removed the version.

__version__ = "0.1.0"


def _isiterable(obj):
Copy link
Member

Choose a reason for hiding this comment

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

There has to be a function in the Python standard library that does this.

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 used np.atleast_1d() instead


# Create rotation matrix about a given axis (x, y, z)

def zrotmat(angle):
Copy link
Member

Choose a reason for hiding this comment

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

All functions need documentation strings, so they can be processed by Sphinx.

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 have gone through the code and added sphinx-compliant doc strings. So, this should be solved, If unit tests pass.



# constant ICRS --> FK5J2000 (See USNO Circular 179, section 3.5)
try:
Copy link
Member

Choose a reason for hiding this comment

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

Why is this computation being performed at the module-level? There is even a comment below that notes that!

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 have removed all of this code and use astropy.coordinates.SkyCoord objects instead.



# -----------------------------------------------------------------------------
# bilinear interpolation (because scipy.ndimage.map_coordinates is really slow
Copy link
Member

Choose a reason for hiding this comment

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

This assertion should be justified, and if it is no longer true, we should use numpy/scipy/astropy.

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 haven't actually checked that (as I have a stable and working new version of the code and don't want to mess around with it much further), but I have removed that assertion. If you feel really strongly that we should use scipy then I'll assess this in detail.

from .. import dust


class TestDust(unittest.TestCase):
Copy link
Member

Choose a reason for hiding this comment

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

Assuming that DUST_DIR is defined, do the tests actually cover the entire module? In other words, if we accept the module into desiutil, the total test coverage of desiutil should at least not decrease.

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've added a unit test and coverage is now ~94%.

import numpy as np

# require a FITS reader of some sort.
try:
Copy link
Member

Choose a reason for hiding this comment

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

This is not a common construction that I have seen in DESI software. In fact, desiutil already requires astropy, so there is no reason to add an additional dependency on fitsio.

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 have explicitly imported astropy.io.fits instead of this construction.

@weaverba137
Copy link
Member

An additional note as part of the previous review: as currently configured, no tests of this module are performed on Travis, because DUST_DIR is not currently defined in the Travis environment. This also means that Travis will report to Coveralls that this module is not covered.

Data files are required to test this module, and would need to be brought into the Travis environment. There are a few ways this could happen:

  1. Download files as needed from a public site.
  2. Include a "trimmed" version of the files in the desiutil test suite.
  3. Use unittest.mock to simulate reading the files and inject appropriate data.

@geordie666
Copy link
Contributor Author

@weaverba137: Regarding your additional note...I chopped the dust maps down to the first 10 columns to reduce them in size to ~150K and use these chopped dust maps as the data for explicit unit tests. Your option (2), in other words.

@weaverba137
Copy link
Member

The code changes all look good to me know. But let's make sure tests pass, & get feedback on license before merging.

@geordie666
Copy link
Contributor Author

I'm going to clean up my code style, so give me 10 minutes before anyone looks at this.

@weaverba137
Copy link
Member

OK, I'll double-check when you're done.

@geordie666
Copy link
Contributor Author

I'm done, now. There are a handful of other recommended code style alterations, but it's for a case where I think it's easier to read as-is.

@weaverba137
Copy link
Member

I'm trying to build the sphinx documentation on my own system and the dust module is not showing up. Watch for additional commits to fix that.

@moustakas
Copy link
Member

@weaverba137 @geordie666 Is this ready to be merged?

If so, @geordie666 can you update desitarget.mock.sfdmap to use the dust utilities in desiutil and add a deprecation warning?

@geordie666
Copy link
Contributor Author

@moustakas: We're waiting for guidance on what to do about reconciling the license for this code with the DESI BSD license from @sbailey.

@moustakas
Copy link
Member

While this PR is still open, should we take the time to add one or more extinction curves?

Kyle Barbary has a very nice package which wraps on Cython for speed --
https://extinction.readthedocs.io/en/latest/

This package is MIT licensed, as was his implementation of reading the SFD dust maps, so we'd have to resolve the same licensing question(s). In addition, these curves would naturally go into the same desiutil.dust module.

@dkirkby
Copy link
Member

dkirkby commented Sep 2, 2018

+1 for adding at least one extinction curve. Schlaflay 2016 is also an option (code here). I doubt this would be a bottleneck for our applications, so straight numpy (w/o cython) should be sufficient if we impement this ourselves.

@djschlegel
Copy link

Let's not pull in another package just to read the SFD maps. That should quite literally be no more than 5 lines of code. Convert to Galactic coordinates, linearly interpolate the 4 nearest pixels from
x = 2048 SQRT {1 - n sin(b)} cos(l) + 2047.5
y = - 2048 n SQRT{1 - n sin(b)} sin(l) + 2047.5
where n=+1 for the NGP, and n=-1 for the SGP. The May 1999 update of the files added the (then-new) FITS header keywords to do the above, so maybe it's only 1 line if your FITS reader supports?

Extinction curves are a different question, and should be a different issue. One needs to de-extinction the standard stars during calibration, but I'd argue to keep the spectra in as-observed fluxes (no de-extinction), analogous to how photometric fluxes are reported. Please include Schlafly on that issue.

@sbailey
Copy link
Contributor

sbailey commented Sep 5, 2018

I'm joining this PR comment stream late, so apologies if I miss the point on something:

  • I think license situation is fine: the main desiutil package is BSD licensed, and the dust.py file includes a comment that some portions were copied from https://github.com/kbarbary/sfdmap/ with the following MIT license, which seems to match both the spirit and the legalities of the open source licenses. It would be slightly better if the comment specifically mentioned which functions / classes were copied (or is it the whole file?).

  • Travis tests: looks like that has been resolved now, but in the future it is ok if Travis only runs a subset of the full tests if that is for a good reason, e.g. to avoid the overhead of large test files. The full suite runs nightly at NERSC so we do get regular coverage.

  • re: "Let's not pull in another package just to read the SFD maps". I agree that we shouldn't pull in a new external dependency that has to be separately installed just to read the dust maps, but it is good to have a standardized convenience way to do that within our own code (e.g. here in desiutil rather than N>1 nearly identical implementations of the same thing in desitarget, desispec, desisurvey, desisim, ...)

@weaverba137
Copy link
Member

Thanks @sbailey.

we do get regular coverage

Yes, but that coverage is not reported to coveralls.io. Thus the coverage reported is lower than it should be, and there is not the immediate feedback of the Travis tests.

@weaverba137
Copy link
Member

PS, should we tag desiutil after this merge?

@sbailey
Copy link
Contributor

sbailey commented Sep 5, 2018

Agreed that having tests included in Travis is better when possible without heroic efforts.

I'll merge this now.

Please go ahead and make a new tag and install at NERSC. I'll let @weaverba137 do that in order to pick the appropriate level of version number incrementing.

@sbailey sbailey merged commit 3fefb5e into master Sep 5, 2018
@sbailey sbailey deleted the ADMsfdmap branch September 5, 2018 20:14
@weaverba137
Copy link
Member

1.9.12 is installed on cori and edison.

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.

6 participants