Giter Club home page Giter Club logo

astroplan's Introduction

astroplan

Observation planning package for astronomers

Documentation Status arXiv paper http://img.shields.io/badge/powered%20by-AstroPy-orange.svg?style=flat Latest release

Attribution

If you use astroplan in your work, please cite Morris et al. 2018:

@ARTICLE{2018AJ....155..128M,
       author = {{Morris}, Brett M. and {Tollerud}, Erik and {Sip{\H{o}}cz}, Brigitta and {Deil}, Christoph and {Douglas}, Stephanie T. and {Berlanga Medina}, Jazmin and {Vyhmeister}, Karl and {Smith}, Toby R. and {Littlefair}, Stuart and {Price-Whelan}, Adrian M. and {Gee}, Wilfred T. and {Jeschke}, Eric},
        title = "{astroplan: An Open Source Observation Planning Package in Python}",
      journal = {\aj},
     keywords = {methods: numerical, methods: observational, Astrophysics - Instrumentation and Methods for Astrophysics},
         year = 2018,
        month = mar,
       volume = {155},
       number = {3},
          eid = {128},
        pages = {128},
          doi = {10.3847/1538-3881/aaa47e},
archivePrefix = {arXiv},
       eprint = {1712.09631},
 primaryClass = {astro-ph.IM},
       adsurl = {https://ui.adsabs.harvard.edu/abs/2018AJ....155..128M},
      adsnote = {Provided by the SAO/NASA Astrophysics Data System}
}

astroplan's People

Contributors

adrn avatar aniketp avatar astrofrog avatar bmorris3 avatar bsipocz avatar cdeil avatar ejeschke avatar emirkmo avatar eteq avatar grant-nations avatar iximeow avatar jberlanga avatar keflavich avatar kvyh avatar larrybradley avatar lpsinger avatar lunarspectrum avatar michaelbaisch avatar mrtommyb avatar mwcraig avatar nstarman avatar pllim avatar rprechelt avatar stephtdouglas avatar stuartlittlefair avatar sultanorazbayev avatar thusser avatar vbrinnel avatar wtgee avatar zlatanvasovic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

astroplan's Issues

TypeError from moon_altaz

With astroplan 0.1, I'm getting this error on one machine (Scientific Linux 6, Python 2.7, in a virtuelenv):

________________________________________________________________________________ test_moon_altaz _________________________________________________________________________________

    @pytest.mark.skipif('not HAS_PYEPHEM')
    def test_moon_altaz():
        time = Time('2012-06-21 03:00:00')
        location = EarthLocation.from_geodetic(-155*u.deg, 19*u.deg, 0*u.m)
        obs = Observer(location=location, pressure=0*u.bar)
>       altaz = obs.moon_altaz(time)

/lfs/l2/hess/software/python/superpy2/lib/python2.7/site-packages/astroplan/tests/test_observer.py:1086: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Observer: location (lon, lat, el)=(-155.0 deg, 19.0 deg, 0.0 m),
    timezone=<UTC>,
    pressure=<Quantity 0.0 bar>>
time = <Time object: scale='utc' format='iso' value=2012-06-21 03:00:00.000>

    def moon_altaz(self, time):
        """
            Returns the position of the moon in alt/az.

            TODO: Currently `moon_altaz` uses PyEphem to calculate the position
            of the moon.

            Parameters
            ----------
            time : `~astropy.time.Time` or other (see below)
                This will be passed in as the first argument to
                the `~astropy.time.Time` initializer, so it can be anything that
                `~astropy.time.Time` will accept (including a `~astropy.time.Time`
                object).

            Returns
            -------
            altaz : `~astropy.coordinates.SkyCoord`
                Position of the moon transformed to altitude and azimuth

            Examples
            --------
            Calculate the altitude and azimuth of the moon at Apache Point
            Observatory:

            >>> from astroplan import Observer
            >>> from astropy.time import Time
            >>> apo = Observer.at_site("APO")
            >>> time = Time("2015-08-29 18:35")
            >>> altaz_moon = apo.moon_altaz(time)
            >>> print("alt: {0.alt}, az: {0.az}".format(altaz_moon)) # doctest: +FLOAT_CMP
            alt: -64.1659594407 deg, az: 345.360401117 deg
            """
        if not isinstance(time, Time):
            time = Time(time)

        try:
            import ephem
        except ImportError:
            raise ImportError("The moon_altaz function currently requires "
                              "PyEphem to compute the position of the moon.")

        moon = ephem.Moon()
        obs = ephem.Observer()
>       obs.lat = self.location.latitude.to(u.degree).to_string(sep=':')
E       TypeError: can only update value with String or number

/lfs/l2/hess/software/python/superpy2/lib/python2.7/site-packages/astroplan/observer.py:1502: TypeError
================================================================ 5 failed, 39 passed, 1 skipped in 117.12 seconds ================================================================

https://gist.github.com/cdeil/da030a53521957f74323

I don't understand why this is happening yet, but @bmorris3 if it doesn't make sense to you from the error message, I should be able to debug this quickly on that machine.

Target rise/set times give negative altitudes.

Not sure if this is a real issue or just a misuse of target_rise_time/target_set_time by me.

I noticed (when wrapping up the current iteration of the Summer Triangle tutorial) that if you plug target rise/set times into an altaz frame, you get negative altitudes on the order of a few arcseconds below the horizon. This is a problem for plot_sky, at least, if users employ the broadest definition of "visible" for targets (sun is down, looking at target at/between rise and set times).

See example below:

altair_rise = subaru.target_rise_time(time, altair)
altair_set = subaru.target_set_time(time, altair)

vega_rise = subaru.target_rise_time(time, vega)
vega_set = subaru.target_set_time(time, vega)

In [128]: subaru.altaz(altair_rise, altair).alt
Out[128]: −0∘00′01.5222′′

In [130]: subaru.altaz(altair_set, altair).alt
Out[130]: −0∘00′01.4204′′

In [132]: subaru.altaz(vega_rise, vega).alt
Out[132]: −0∘00′02.2992′′

In [134]: subaru.altaz(vega_set, vega).alt
Out[134]: −0∘00′05.0659′′

Import error for module _bsddb

Hi everyone,

I installed astroplan using conda (Python 2.7 on a macbook pro with OS X 10.9.5). Nothing seemed to go wrong in the installation but when I try import astroplan I get the following error,

Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Users/alexawork/anaconda/lib/python2.7/site-packages/astroplan/__init__.py", line 31, in <module> get_IERS_A_or_workaround() File "/Users/alexawork/anaconda/lib/python2.7/site-packages/astroplan/utils.py", line 52, in get_IERS_A_or_workaround if IERS_A_in_cache(): File "/Users/alexawork/anaconda/lib/python2.7/site-packages/astroplan/utils.py", line 72, in IERS_A_in_cache with _open_shelve(urlmapfn, True) as url2hash: File "/Users/alexawork/anaconda/lib/python2.7/site-packages/astropy/utils/data.py", line 1214, in _open_shelve shelf = shelve.open(shelffn, protocol=2) File "/Users/alexawork/anaconda/lib/python2.7/shelve.py", line 243, in open return DbfilenameShelf(filename, flag, protocol, writeback) File "/Users/alexawork/anaconda/lib/python2.7/shelve.py", line 227, in __init__ Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback) File "/Users/alexawork/anaconda/lib/python2.7/anydbm.py", line 84, in open mod = __import__(result) File "/Users/alexawork/anaconda/lib/python2.7/dbhash.py", line 7, in <module> import bsddb File "/Users/alexawork/anaconda/lib/python2.7/bsddb/__init__.py", line 67, in <module> import _bsddb ImportError: No module named _bsddb

I'm not sure if this is an issue that's specific to my setup, the module bsddb is in my anaconda package but it doesn't have a file _bsddb. Should my installation have that file?

Thank you,
Alexa

Rename can_see --> is_target_above_horizon

I propose renaming the can_see method to is_target_above_horizon. My thinking is this: can_see mentions words like "observable" in the source, but really all this is doing is checking if the target is above the horizon. A user might see this method and naively think it is taking other things into account (e.g., time of day, wavelength, who knows?).

Gitter room

Hey owners (@cdeil)– would you mind creating a Gitter room for astroplan? I think it would be a convenient way for @jberlanga and I (and all of you as well) to keep in touch for short questions.

Update Observer.at_site to use astropy site machinery

astropy/astropy#4042 is now merged, so it probably makes sense to switch to that in favor of the astroplan get_site machinery.

To clarify one additional thing about this: I think it may make sense for the data.astropy.org/coordinates/sites.json file to get additional information down the road about sites. That info may be used by astroplan even if its ignored by astropy itself. So no need to worry that it's now "out of astroplan's control": astropy-data is an easy thing to change! I don't think that's particularly relevant right now, but it might be if more information gets added to Observer that's not in EarthLocation but should be in the data file.

Differences in calculated times between machines.

Astroplan sometimes gives different calculated times for the same calculation on different machines:

>>> sunset_tonight.iso
Expected:
    '2015-06-16 04:59:11.267'
Got:
    '2015-06-16 04:59:10.593'

Could be due to differences in local IERS tables/interpolation used to calculate rise/set times, etc?

See comment here for existing discussion, and here for original source.

Provide succinct way to get time object in the observer's time zone

Currently, if I want to get a local time for working with astroplan, I have to write a somewhat verbose bit of code:

# Get times for 00:30 and 02:35 in my timezone on July 28, 2015 that I can use with astroplan
t_start = observer.datetime_to_astropy_time(datetime.datetime(2015, 07, 28, 0, 30, 0)) 
t_stop = observer.datetime_to_astropy_time(datetime.datetime(2015, 07, 28, 2, 35, 0)) 

(this works because the naive datetime is localized with the observer's timezone in datetime_to_astropy_time).

However, it would be extremely convenient to be able to write something like:

t_start = observer.get_local_time(2015, 07, 28, 0, 30, 0) 

or even with strings:

observer.get_local_time("2015-07-28 00:30") 
observer.get_local_time("07-28 00:30")        # assume current year
observer.get_local_time("19:20")                  # assume current day

I think if astroplan does not provide such a simple function, many users will be forced to write it over and over again. Basically this applies to anyone who is planning in the timezone of the telescope and not UTC.

Plotting style

Currently we're using the default matplotlib plotting style:

IMO it's not very pretty we should adopt the Astropy plotting style (see here, but it doesn't show up because of Astropy Sphinx bugs, sigh) or define our own.
It's pretty easy to implement, se here and here how it was done in Gammapy.

I think there also was talk about a "dark style" for astroplan, but now I can't find any issue for that.

What do you think?

I've put the 0.2 milestone, but if someone wants to implement this today for 0.1, it should be possible.

Need high-level docs.

Hi @astroplanners/astroplanners-contributors,

I'm starting to write the docs and would like some input for what you would like to see/not see.

My starting point is to take the current RTD site and add:

  • A Tutorials page with separate pages for a few different use cases.
  • Getting Started would have a section explaining how the different types of objects correspond to observing concepts (e.g., target info contained in a Target object, etc.) and the way that you extract attributes/use methods in general. Perhaps also a section for basic tasks (such as creating Observer and Target objects).
  • A How to.. page linking to others that explain how to do specific things (e.g., extract alt/az info).
  • A Plots/Visualization page containing basic examples and linking to a detailed run-through of all the options for each plotting function.

Drop Python 2 support

I propose we drop Python 2 support for astroplan, i.e. make it a Python 3 only package from the start (i.e. the 0.1 release).

This is not a joke, I think it's about time for new packages. The great migration has begun and I started my first Python 3-only package a month ago (ctapipe) and the sky hasn't fallen on my head.

I don't want to argue and list pros / cons for this decision, I think most of us are well-aware.
Just one comment: The biggest con is that some potential users are on Python 2 now and for this reason might not use astroplan for now. I think that's OK, they'll start using it in the coming years after they've moved to Python 3.

@astroplanners/astroplanners-contributors – What do you think?

@ejeschke – Do you need Python 2 support for Subaru?

Get doctests working as widely as possible

This is a bit nebulous, but it's a reminder to try to put in some effort for 0.2 into getting the doctests to run on the tutorials as much as possible. As discussed in #87, it's an important way to keep docs and code in sync.

The biggest challenge to this is #91 - for whatever reason some of the rise/set times seem to be either machine or time-dependent, which makes the doctests harder to write. It might be the best solution is to reprocess these docs to instead print results less sensitive to these things. E.g., render times in ways that only show to the minute like:

>>> from astropy.time import Time
>>> now = Time.now()
>>> now.datetime.strftime('%B %d, %Y %H:%M')
'September 03, 2015 16:40'

cc @adrn @jberlanga @bmorris3 @cdeil @bsipocz (parties to the discussion in #87)

FixedTarget.from_name shows up with Mock docstring in the docs

@bmorris3 – Our mock solution is mocking us ... didn't think of this issue:
http://astroplan.readthedocs.org/en/latest/api/astroplan.FixedTarget.html?highlight=mock#astroplan.FixedTarget.from_name

@bmorris3 – Why is the mock needed again for the Sphinx build?
The doctests are something different, that shouldn't require it to be active during the docs build, right?
Is it because we have .. plot:: directives that use FixedTarget.from_name?

For those that didn't follow that ... the mock was added in #62 and it's here:
https://github.com/astropy/astroplan/blob/master/docs/conf.py#L181

Another open mock related issue: #76

Document how to get help and contribute

Currently we have no information in the docs how to get help or how to contribute:
http://astroplan.readthedocs.org/en/latest/

For help, i.e. user questions how to do XY, why AB doesn't work etc. I think pointing to the Astropy mailing list for now is fine. If there's a lot of questions, we can always set up our own mailing list.
Another good option might be stackoverflow with an astropy and / or astroplan tag.
@eteq – What do you think?

Concerning how to contribute, I think having a lot of text like http://photutils.readthedocs.org/en/latest/#contributing or https://sncosmo.readthedocs.org/en/v1.1.x/contributing.html isn't needed.
So I'd suggest just saying a few sentences like "same as Astropy, use Github" and point to http://astropy.readthedocs.org/en/latest/#contributing.
But a sentence or two like "this is a very young project, we very much welcome contributions of new features like planets, scheduling, GUI, ... just talk to us" are good to have, I think.

@jberlanga or @bmorris3 – Can you try to find a good place and wording for a short section on this in the docs?

Split core into several parts

I propose we split core.py (currently ~ 2000 lines) and test_core.py (currently ~ 1000 lines) into several smaller files.

Add summary table of sites and other site info to docs

The sites functionality in #26 only has API docs - there need to be some narrative docs describing how it's used. @cdeil suggested in #26 that there should be an auto-generated table of the observatories that are built-in (I think just the names/aliases/description/source are sufficient for the docs).

Improve overview for Astroplan in various places

@bmorris3 – Could you please try to improve the overview description for Astroplan in various places before the 0.1 release today?

One place is the "long description" that gets displayed on PyPI, and I think it would be good to have at least a sentence or two and a link e.g. to the docs. Just as an example, see https://pypi.python.org/pypi/gammapy/0.3
The text you see there is from https://github.com/gammapy/gammapy/blob/master/LONG_DESCRIPTION.rst which gets pulled in like this: https://github.com/gammapy/gammapy/blob/master/setup.py#L40

Really, there's four "landing pages" for new users where we could use the same basic info about Astroplan:

  • first part of README.rst for someone that goes to the Github repo or has the code locally
  • LONG_DESCRIPTION.rst for PyPI
  • first part of docs/index.rst for the docs
  • astroplan/__init__.py docstring for someone that does import astroplan and would like to know how to get started.

I think in all cases one sentence and a link to the online repo and the docs is sufficient, but of course some more info is OK as well.

From Gammapy I know that it's hard to implement this without avoiding some duplication, but I guess that's OK if ingesting the description from another file isn't possible somewhere.
One more thing ... eventually I wanted the top-level docs page to be short and added an About page for Gammapy (https://gammapy.readthedocs.org/en/latest/about.html) ... I think that could be a good idea for Astroplan as well.

PS: I think "Observation planning package for astronomers" is a bit boring .... "Observing like a boss! –– Astroplan is is the observation planning Kepler and Hubble wished they had." ... @bmorris3 I trust you can come up with some better slogan / short description for astroplan!

Revisiting the API spec

Since starting to code, some parts of the API haven't been discussed in a while, and @cdeil prompted me to start a discussion among @astroplanners/astroplanners-contributors about how we should modify/remove the API as it is now.

First question: should we discard this document now? If not, we should update it.

Find better way to fix image cropping in docs.

Docs use Matplotlib's .. plot:: directive, which incorrectly crops off edges of images produced by plotting code (see Matplotlib issue here, resulting in behavior like that below:

plot_image_crop_bug

Need to find a better way to fix this other than sticking the following block of code before every plt.show() instance, as this obscures the astroplan code that the docs are meant to illustrate:

# Note that you don't need this code block to produce the plot.
# It reduces the plot size for the documentation.
ax = plt.gca()
box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.75, box.height * 0.75])

Failing tests due to missing pyephem

Some tests are failing due to the missing pyephem package. They shouldn't really as it's listed only as an optional dependency:

=========================================================== test session starts ============================================================
platform darwin -- Python 2.7.10 -- pytest-2.5.1

Running tests with Astropy version 1.1.dev13304.
Running tests in astroplan /Users/bsipocz/munka/devel/astroplan/docs.

Platform: Darwin-14.5.0-x86_64-i386-64bit

Executable: /Users/bsipocz/.virtualenvs/astropy-dev/bin/python

Full Python Version: 
2.7.10 (default, May 26 2015, 20:29:34) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]

encodings: sys: ascii, locale: UTF-8, filesystem: utf-8, unicode bits: 15
byteorder: little
float info: dig: 15, mant_dig: 15

Numpy: 1.9.2
Scipy: 0.16.0
Matplotlib: 1.4.3
pyephem: not available

plugins: mpl
collected 62 items 

astroplan/core.py .........F.........
astroplan/sites.py .
astroplan/plots/tests/test_sky.py F
astroplan/tests/test_core.py .s......................F.
astroplan/tests/test_moon.py F
astroplan/tests/test_sites.py .....
astroplan/tests/test_utils.py s
../../../../../../../../Users/bsipocz/munka/devel/astroplan/docs/api.rst .
../../../../../../../../Users/bsipocz/munka/devel/astroplan/docs/getting_started.rst .
../../../../../../../../Users/bsipocz/munka/devel/astroplan/docs/index.rst .
../../../../../../../../Users/bsipocz/munka/devel/astroplan/docs/installation.rst .
../../../../../../../../Users/bsipocz/munka/devel/astroplan/docs/tutorials/iers.rst .
../../../../../../../../Users/bsipocz/munka/devel/astroplan/docs/tutorials/index.rst .
../../../../../../../../Users/bsipocz/munka/devel/astroplan/docs/tutorials/plots.rst .
../../../../../../../../Users/bsipocz/munka/devel/astroplan/docs/tutorials/summer_triangle.rst .

================================================================= FAILURES =================================================================
_______________________________________________ [doctest] astroplan.core.Observer.moon_altaz _______________________________________________
1497         Examples
1498         --------
1499         Calculate the altitude and azimuth of the moon at Apache Point
1500         Observatory:
1501 
1502         >>> from astroplan import Observer
1503         >>> from astropy.time import Time
1504         >>> apo = Observer.at_site("APO")
1505         >>> time = Time("2015-08-29 18:35")
1506         >>> altaz_moon = apo.moon_altaz(time)
UNEXPECTED EXCEPTION: ImportError(u'The moon_altaz function currently requires PyEphem to compute the position of the moon.',)
Traceback (most recent call last):

  File "/sw/lib/python2.7/doctest.py", line 1315, in __run
    compileflags, 1) in test.globs

  File "<doctest astroplan.core.Observer.moon_altaz[4]>", line 1, in <module>

  File "astroplan/core.py", line 1516, in moon_altaz
    raise ImportError("The moon_altaz function currently requires "

ImportError: The moon_altaz function currently requires PyEphem to compute the position of the moon.

astroplan/core.py:1506: UnexpectedException
_____________________________________________________________ test_moon_altaz ______________________________________________________________

    def test_moon_altaz():
        time = Time('2012-06-21 03:00:00')
        location = EarthLocation.from_geodetic(-155*u.deg, 19*u.deg, 0*u.m)
        obs = Observer(location=location, pressure=0*u.bar)
>       altaz = obs.moon_altaz(time)

astroplan/tests/test_core.py:1102: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Observer: location (lon, lat, el)=(-155.0 deg, 19.0 deg, 0.0 m),
    timezone=<UTC>,
    pressure=<Quantity 0.0 bar>>
time = <Time object: scale='utc' format='iso' value=2012-06-21 03:00:00.000>

    def moon_altaz(self, time):
        """
            Returns the position of the moon in alt/az.

            TODO: Currently `moon_altaz` uses PyEphem to calculate the position
            of the moon.

            Parameters
            ----------
            time : `~astropy.time.Time` or other (see below)
                This will be passed in as the first argument to
                the `~astropy.time.Time` initializer, so it can be anything that
                `~astropy.time.Time` will accept (including a `~astropy.time.Time`
                object).

            Returns
            -------
            altaz : `~astropy.coordinates.SkyCoord`
                Position of the moon transformed to altitude and azimuth

            Examples
            --------
            Calculate the altitude and azimuth of the moon at Apache Point
            Observatory:

            >>> from astroplan import Observer
            >>> from astropy.time import Time
            >>> apo = Observer.at_site("APO")
            >>> time = Time("2015-08-29 18:35")
            >>> altaz_moon = apo.moon_altaz(time)
            >>> print("alt: {0.alt}, az: {0.az}".format(altaz_moon)) # doctest: +FLOAT_CMP
            alt: -64.1659594407 deg, az: 345.360401117 deg
            """
        if not isinstance(time, Time):
            time = Time(time)

        try:
            import ephem
        except ImportError:
>           raise ImportError("The moon_altaz function currently requires "
                              "PyEphem to compute the position of the moon.")
E           ImportError: The moon_altaz function currently requires PyEphem to compute the position of the moon.

astroplan/core.py:1516: ImportError
____________________________________________________________ test_illumination _____________________________________________________________

    def test_illumination():
        time = Time(['1990-01-01 00:00:00', '1990-03-01 06:00:00',
                     '1990-06-01 12:00:00', '1990-11-01 18:00:00'])
        location = EarthLocation.from_geodetic(-155*u.deg, 19*u.deg, 0*u.m)
        obs = Observer(location)
        # Get illumination via time
>       illumination1 = obs.moon_illumination(time)

astroplan/tests/test_moon.py:17: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Observer: location (lon, lat, el)=(-155.0 deg, 19.0 deg, 0.0 m),
    timezone=<UTC>>
time = <Time object: scale='utc' format='iso' value=['1990-01-01 00:00:00.000' '1990-03-01 06:00:00.000'
 '1990-06-01 12:00:00.000' '1990-11-01 18:00:00.000']>

    def moon_illumination(self, time):
        """
            Calculate the illuminated fraction of the moon.

            Parameters
            ----------
            time : `~astropy.time.Time` or other (see below)
                This will be passed in as the first argument to
                the `~astropy.time.Time` initializer, so it can be anything that
                `~astropy.time.Time` will accept (including a `~astropy.time.Time`
                object).

            moon : `~astropy.coordinates.SkyCoord` or `None` (default)
                Position of the moon at time ``time``. If `None`, will calculate
                the position of the moon with `~astroplan.moon.get_moon`.

            sun : `~astropy.coordinates.SkyCoord` or `None` (default)
                Position of the sun at time ``time``. If `None`, will calculate
                the position of the Sun with `~astropy.coordinates.get_sun`.

            Returns
            -------
            float
                Fraction of lunar surface illuminated

            Examples
            --------
            How much of the lunar surface is illuminated at 2015-08-29 18:35 UTC,
            which we happen to know is the time of a full moon?

            >>> from astroplan import Observer
            >>> from astropy.time import Time
            >>> apo = Observer.at_site("APO")
            >>> time = Time("2015-08-29 18:35")
            >>> apo.moon_illumination(time) # doctest: +SKIP
            array([ 0.99972487])
            """
        if not isinstance(time, Time):
            time = Time(time)

>       return moon_illumination(time, self.location)

astroplan/core.py:1430: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

time = <Time object: scale='utc' format='iso' value=['1990-01-01 00:00:00.000' '1990-03-01 06:00:00.000'
 '1990-06-01 12:00:00.000' '1990-11-01 18:00:00.000']>
location = <EarthLocation (-5467562.495834137, -2549566.2632485162, 2063349.463036347) m>

    def moon_illumination(time, location):
        """
        Calculate fraction of the moon illuminated

        Parameters
        ----------
        time : `~astropy.time.Time`
            Time of observation

        location : `~astropy.coordinates.EarthLocation`
            Location of observer

        Returns
        -------
        k : float
            Fraction of moon illuminated
        """
>       i = moon_phase_angle(time, location)

astroplan/moon.py:144: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

time = <Time object: scale='utc' format='iso' value=['1990-01-01 00:00:00.000' '1990-03-01 06:00:00.000'
 '1990-06-01 12:00:00.000' '1990-11-01 18:00:00.000']>
location = <EarthLocation (-5467562.495834137, -2549566.2632485162, 2063349.463036347) m>

    def moon_phase_angle(time, location):
        """
        Calculate lunar orbital phase [radians].

        Parameters
        ----------
        time : `~astropy.time.Time`
            Time of observation

        location : `~astropy.coordinates.EarthLocation`
            Location of observer

        Returns
        -------
        i : float
            Phase angle of the moon [radians]
        """
        # TODO: cache these sun/moon SkyCoord objects
        sun = get_sun(time).transform_to(AltAz(location=location, obstime=time))
>       moon = get_moon(time, location)

astroplan/moon.py:116: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

time = <Time object: scale='utc' format='iso' value=['1990-01-01 00:00:00.000' '1990-03-01 06:00:00.000'
 '1990-06-01 12:00:00.000' '1990-11-01 18:00:00.000']>
location = <EarthLocation (-5467562.495834137, -2549566.2632485162, 2063349.463036347) m>, pressure = None

    def get_moon(time, location, pressure=None):
        """
        Position of the Earth's moon.

        Currently uses PyEphem to calculate the position of the moon by default
        (requires PyEphem to be installed). Set ``use_pyephem`` to `False` to
        calculate the moon position with jplephem (requires jplephem to be
        installed).

        Parameters
        ----------
        time : `~astropy.time.Time` or see below
            Time of observation. This will be passed in as the first argument to
            the `~astropy.time.Time` initializer, so it can be anything that
            `~astropy.time.Time` will accept (including a `~astropy.time.Time`
            object).

        location : `~astropy.coordinates.EarthLocation`
            Location of the observer on Earth

        pressure : `None` or `~astropy.units.Quantity` (optional)

        Returns
        -------
        moon_sc : `~astropy.coordinates.SkyCoord`
            Position of the moon at ``time``
        """
        if not isinstance(time, Time):
            time = Time(time)

        try:
            import ephem
        except ImportError:
>           raise ImportError("The get_moon function currently requires "
                              "PyEphem to compute the position of the moon.")
E           ImportError: The get_moon function currently requires PyEphem to compute the position of the moon.

astroplan/moon.py:66: ImportError

0.1 release

At the start we said that we'll release 0.1 at GSoC mid-term and 0.2 at the end of GSoC.

It's clear that releasing now doesn't make sense, because basic functionality is work in progress and there's no end-user high-level docs yet. So I've just now moved the 0.1 release milestone on Github to August 10, but even that is flexible, we'll just release when we think 0.1 makes sense.

IMO it will be when the basic toolbox is assembled, so that users can try it out and file feature requests / issues, and it becomes possible to parallelise the work more, i.e. should there be other people that want to hack on this package to add features, it's easily possible without too much coordination.

We can use this issue to discuss when we think 0.1 should be released and, if there are any issues how to make a release or with the release, we can discuss solutions here.
(PS: I'd be happy if someone else does releases / announcements / maintenance for this package for the coming months, only if no-one else wants to do it, I can do it.)

Add Astroplan dependencies for tests / docs

@bmorris3 - could you please update setup.py, .travis.yml docs/rtd-pip-requirements and maybe add a section to the docs about required and optional dependencies for Astroplan.

I think required should be:

Optional:

  • matplotlib
  • maybe for now pyephem or skyfield if you plan to use them to implement some functionality?

There's usually some issues getting the builds to run on travis-ci and readthedocs when changing the config, so I think it's worth splitting out into a separate PR instead of mixing it with code implementation PRs.

Failing test_image_example

There is another test failing.

=========================================================== test session starts ============================================================
platform darwin -- Python 2.7.10 -- pytest-2.5.1

Running tests with Astropy version 1.1.dev13304.
Running tests in astroplan /Users/bsipocz/munka/devel/astroplan/docs.

Platform: Darwin-14.5.0-x86_64-i386-64bit

Executable: /Users/bsipocz/.virtualenvs/astropy-dev/bin/python

Full Python Version: 
2.7.10 (default, May 26 2015, 20:29:34) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]

encodings: sys: ascii, locale: UTF-8, filesystem: utf-8, unicode bits: 15
byteorder: little
float info: dig: 15, mant_dig: 15

Numpy: 1.9.2
Scipy: 0.16.0
Matplotlib: 1.4.3
pyephem: not available
____________________________________________________________ test_image_example ____________________________________________________________

args = (), kwargs = {}
baseline_dir = '/private/var/folders/dc/hsm7tqpx2d57n7vb3k1l81xw0000gq/T/astroplan-test-qX407r/lib.macosx-10.10-x86_64-2.7/astroplan/plots/tests/baseline_images'
inspect = <module 'inspect' from '/sw/lib/python2.7/inspect.pyc'>, fig = <matplotlib.figure.Figure object at 0x109d9f8d0>
filename = 'test_image_example.png', result_dir = '/var/folders/dc/hsm7tqpx2d57n7vb3k1l81xw0000gq/T/tmprKJJFT'
test_image = '/var/folders/dc/hsm7tqpx2d57n7vb3k1l81xw0000gq/T/tmprKJJFT/test_image_example.png'
baseline_image_ref = '/private/var/folders/dc/hsm7tqpx2d57n7vb3k1l81xw0000gq/T/astroplan-test-qX407r/lib.macosx-10.10-x86_64-2.7/astroplan/plots/tests/baseline_images/test_image_example.png'
baseline_image = '/var/folders/dc/hsm7tqpx2d57n7vb3k1l81xw0000gq/T/tmprKJJFT/baseline-test_image_example.png'

    @wraps(item.function)
    def item_function_wrapper(*args, **kwargs):

        baseline_dir = compare.kwargs.get('baseline_dir', None)
        if baseline_dir is None:
            if self.baseline_dir is None:
                baseline_dir = os.path.join(os.path.dirname(item.fspath.strpath), 'baseline')
            else:
                baseline_dir = self.baseline_dir
        else:
            baseline_dir = os.path.join(os.path.dirname(item.fspath.strpath), baseline_dir)

        # Run test and get figure object
        import inspect
        if inspect.ismethod(original):  # method
            fig = original(*args[1:], **kwargs)
        else:  # function
            fig = original(*args, **kwargs)

        # Find test name to use as plot name
        filename = compare.kwargs.get('filename', None)
        if filename is None:
            filename = original.__name__ + '.png'

        # What we do now depends on whether we are generating the reference
        # images or simply running the test.
        if self.generate_dir is None:

            # Save the figure
            result_dir = tempfile.mkdtemp()
            test_image = os.path.abspath(os.path.join(result_dir, filename))

            fig.savefig(test_image, **savefig_kwargs)

            # Find path to baseline image
            baseline_image_ref = os.path.abspath(os.path.join(os.path.dirname(item.fspath.strpath), baseline_dir, filename))

            if not os.path.exists(baseline_image_ref):
                raise Exception("""Image file not found for comparison test
                                        Generated Image:
                                        \t{test}
                                        This is expected for new tests.""".format(
                    test=test_image))

            # distutils may put the baseline images in non-accessible places,
            # copy to our tmpdir to be sure to keep them in case of failure
            baseline_image = os.path.abspath(os.path.join(result_dir, 'baseline-' + filename))
            shutil.copyfile(baseline_image_ref, baseline_image)

>           msg = compare_images(baseline_image, test_image, tol=tolerance)

/sw/lib/python2.7/site-packages/pytest_mpl/plugin.py:141: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

expected = '/var/folders/dc/hsm7tqpx2d57n7vb3k1l81xw0000gq/T/tmprKJJFT/baseline-test_image_example.png'
actual = '/var/folders/dc/hsm7tqpx2d57n7vb3k1l81xw0000gq/T/tmprKJJFT/test_image_example.png', tol = 2, in_decorator = False

    def compare_images(expected, actual, tol, in_decorator=False):
        """
        Compare two "image" files checking differences within a tolerance.

        The two given filenames may point to files which are convertible to
        PNG via the `.converter` dictionary. The underlying RMS is calculated
        with the `.calculate_rms` function.

        Parameters
        ----------
        expected : str
            The filename of the expected image.
        actual :str
            The filename of the actual image.
        tol : float
            The tolerance (a color value difference, where 255 is the
            maximal difference).  The test fails if the average pixel
            difference is greater than this value.
        in_decorator : bool
            If called from image_comparison decorator, this should be
            True. (default=False)

        Example
        -------
        img1 = "./baseline/plot.png"
        img2 = "./output/plot.png"
        compare_images( img1, img2, 0.001 ):

        """
        if not os.path.exists(actual):
            msg = "Output image %s does not exist." % actual
            raise Exception(msg)

        if os.stat(actual).st_size == 0:
            msg = "Output image file %s is empty." % actual
            raise Exception(msg)

        verify(actual)

        # Convert the image to png
        extension = expected.split('.')[-1]

        if not os.path.exists(expected):
            raise IOError('Baseline image %r does not exist.' % expected)

        if extension != 'png':
            actual = convert(actual, False)
            expected = convert(expected, True)

        # open the image files and remove the alpha channel (if it exists)
        expectedImage = _png.read_png_int(expected)
        actualImage = _png.read_png_int(actual)
        expectedImage = expectedImage[:, :, :3]
        actualImage = actualImage[:, :, :3]

        actualImage, expectedImage = crop_to_same(
            actual, actualImage, expected, expectedImage)

        # convert to signed integers, so that the images can be subtracted without
        # overflow
        expectedImage = expectedImage.astype(np.int16)
        actualImage = actualImage.astype(np.int16)

>       rms = calculate_rms(expectedImage, actualImage)

/sw/lib/python2.7/site-packages/matplotlib/testing/compare.py:326: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

expectedImage = array([[[255, 255, 255],
        [255, 255, 255],
        [255, 255, 255],
   ...55, 255, 255],
        [255, 255, 255],
        [255, 255, 255]]], dtype=int16)
actualImage = array([[[255, 255, 255],
        [255, 255, 255],
        [255, 255, 255],
   ...55, 255, 255],
        [255, 255, 255],
        [255, 255, 255]]], dtype=int16)

    def calculate_rms(expectedImage, actualImage):
        "Calculate the per-pixel errors, then compute the root mean square error."
        num_values = np.prod(expectedImage.shape)
>       abs_diff_image = abs(expectedImage - actualImage)
E       ValueError: operands could not be broadcast together with shapes (600,800,3) (660,880,3)

/sw/lib/python2.7/site-packages/matplotlib/testing/compare.py:246: ValueError

Add night sky brightness calculator

This is similar to #27 by @ejeschke, but I'm making a new issue because what I propose here is a larger and probably post-GSoC project.

What really matters for observing is the night-sky brightness in the target direction, not just the moon phase or separation to the moon.

There's models for the contribution from scattered moonlight:

It would be great to have some night sky brightness calculator implemented in astroplan.
I don't know if there's a really simple model that can be implemented in a day, or if they are all complex.

Improve findability of example plots in the docs

Currently via the astroplan.plots API docs, it's clear that we currently have three plots ... here's the API docs:

The Plotting with Astroplan section does include examples for plot_airmass and plot_sky, but not for plot_parallactic (it mentions it, but no example shown). It took me a while to find an example of plot_parallactic ... it's in a parallactic angle section in the summer triangle tutorial

One thing that can be improved easily would be to link from the docstrings of the plot functions to the sections of the docs that contain examples of that plot.

Concerning the fact that no example parallactic plot is in the "Plotting with Astroplan" section, I'm not sure. Either add one (or move it from the summer triangle tutorial), or link to the existing example in the summer triangle tutorial.

Suppress PlotBelowHorizonWarning messages in Sphinx build

So far we had a clean (warning-free) Sphinx build, but since yesterday we have a bunch of:

WARNING: PlotBelowHorizonWarning: Target "Algol" is below the horizon at time: 2457235.75 [astroplan.plots.sky]

Full log: https://gist.github.com/cdeil/570c00c055a414b095a9

Personally I don't like packages that emit warnings for things that occur all the time in normal usage and would remove the warnings here. But I think others like to have them in?

If so, could someone please suppress the warnings in the Sphinx build?

Make an astroplan slack

Inspired by @bmorris3's comment in #9 I thought I'd offer another option for our purposes: we could try making a Slack team. The nice thing about slack is that it allows either e-mail like async discussion or real-time chat in the same context. I've used it for a couple science collaborations and it seems good as a replacement for e-mail/chat... Should I make a slack team for us to try it?

Feature request: easy access to hour angle, local sidereal time

I was observing last night and found myself using TUI to find the hour angle of my target, and the local sidereal time at the observatory. It'd be great if there was:

  • a thin wrapper around the time.sidereal_time() function on Observer, i.e. Observer.local_sidereal_time(time, ['mean' or 'apparent'])since it requires location information
  • a little convenience method for hour angle, which is simply the local sidereal time minus the right ascension of the target

Tutorials don't have TOC in sidebar

I noticed something curious about the tutorial docs added in #42 : @jberlanga had to add a table of contents manually, but e.g. the getting started page already indexes the sections of the docuemnt in the sidebar table of contents. It seems like it should be possible to go one level deeper, though, and have the sections show up also for the tutorials. Anyone know how to do this? (@adrn or @cdeil might have encountered this?)

http://sphinx-doc.org/config.html#confval-html_sidebars seems like it should be helpful, but that would seem to suggest we already should be seeing a local TOC...

Does AltAz always fail below horizon?

Question for @eteq / @adrn / @cdeil – the AltAz docs indicate:

Near and below altitudes of 0, [AltAz] can even give meaningless answers, and in this case transforming to AltAz and back to another frame can give highly discrepent results. For much better numerical stability, leaving the pressure at 0 (the default), disabling the refraction correction (yielding “topocentric” horizontal coordinates).

In the constraints module, I'm adding a constraint for finding the targets visible at night, i.e. AtNight(max_solar_altitude=0*u.deg), and I will likely make subclasses of this constraint like BetweenAstronomicalTwilights(max_solar_altitude=-18*u.deg), etc. In order to check if the sun is below those altitudes, I will be trying to use negative altitudes in just the way that the AltAz docs discourage.

Are these altitudes predictably screwy in certain circumstances that we can avoid? For example, should we transform get_sun to AltAz with pressure=0 always, to avoid the wonky computations?

import astroplan should not access the internet

Over in gammapy/gammapy#286 I noticed this error:
https://travis-ci.org/gammapy/gammapy/jobs/68675797#L1092

The reason is that importing astroplan downloads a file:

In [2]: import astroplan
Downloading http://maia.usno.navy.mil/ser7/finals2000A.all
|============================================================================================| 2.9M/2.9M (100.00%)        16s

And because of https://github.com/gammapy/gammapy/blob/master/gammapy/conftest.py#L35 we import astroplan from the Gammapy tests to print it's version number. (We don't use astroplan yet, but we will in the future, so I had already added it).

@eteq @bmorris3 I think the fact that astroplan downloads the IERS table in import is a temp solution anyways. Is there any way to set this up better for now? (if no, no worries, we'll just uncomment that line in Gammapy).

Add `plot_sky_24hr`

As discussed in our telecon today, we merged #30 without any special behavior for scalar inputs (they are just treated like single-element vectors). Instead, there should be a new function called something like plot_sky_24hr or plot_sky_night or plot_sky_somethingelse which plots a target +/- 12 hr from a provided time. This should actually use plot_sky internally, probably just accepting a target, time (which now must be a scalar - should raise an exception otehrwise), and any further keyword arguments would just be passed to plot_sky using **kwargs.

Additional enhancements discussed in the telecon:

  • Include a delta keyword (which defaults to 1 hour), controlling the spacing between the points.
  • Add a keyword for annotations showing the direction of rise/set like #30 (comment)
  • Add a keyword to add an extra marker for the "middle" time (i.e., the time that actually was passed in).

astroplan test failure (scientific linux, py2.7.10)

=================================== FAILURES ===================================
______________________________ test_image_example ______________________________

    @pytest.mark.skipif('not HAS_MATPLOTLIB')
    @pytest.mark.mpl_image_compare
    def test_image_example():
        import matplotlib.pyplot as plt
>       fig = plt.figure()

...

 print("Starting up QApplication")
            app = QtWidgets.QApplication.instance()
            if app is None:
                # check for DISPLAY env variable on X11 build of Qt
                if hasattr(QtGui, "QX11Info"):
                    display = os.environ.get('DISPLAY')
                    if display is None or not re.search(':\d', display):
>                       raise RuntimeError('Invalid DISPLAY variable')
E                       RuntimeError: Invalid DISPLAY variable

../../apps6/anaconda2.0/lib/python2.7/site-packages/matplotlib/backends/backend_qt5.py:138: RuntimeError
=============== 1 failed, 43 passed, 1 skipped in 52.98 seconds ================

Any ideas @cdeil @jberlanga @eteq?

pyephem dependency

@eteq @bmorris3 – What's the plan / timeline for getting rid of the pyephem dependency in astroplan?

If it's likely ~ a year or longer, I'd suggest to change the conda package and put pyephem as a dependency, so that users automatically get the full functionality.

Add MoonTargetSeparationRange constraint

This is a constraint on the distance from target(s) to the moon. It would specify a minimum and maximum angular separation. Either minimum or maximum can be None, in which case there is no constraint in that direction. (Typically we might assume that only a minimum separation would be specified, but I know of engineering items that would require a maximum as well).

This is dependent on having a reliable way to get the moon position and calculate the angular separation.

Add MoonIlluminationRange constraint

This is a constraint on the illumination of the moon. It would specify a minimum and maximum illumination as a percentage. Either minimum or maximum can be None, in which case there is no constraint in that direction. This allows target selection when a user is requesting dark or grey nights.

It would be nice if this could support the case where the moon is below the horizon. In other words, we need to consider not only the orbital phase, but the degree to which the moon is visible. If the user specifies a 0.1 (10%) maximum illumination and the moon phase is 50%, but the moon is not yet risen, the constraint is satisfied.

FixedTarget mock is active even when remote-data flag is used

In #62, we came up with a mock for FixedTarget.from_name when the internet is not accessible during tests. That mocked from_name method currently gets called during the tests whether or not there is an internet connection, but should only be used when the --remote-data flag is not used.

tests cannot be run if matplotlib and pytest-mpl are not installed

I've encountered an issue that I think is caused by pytest-mpl, which it looks to me was integrated into astroplan in #13 (@cdeil ?): if I try to run the tests for astroplan on a machine where matplotlib is installed but pytest-mpl is not, I see the following error before the tests even start:

% python setup.py test
running test
running build
running build_py
usage: -c [options] [file_or_dir] [file_or_dir] [...]
-c: error: unrecognized arguments: --mpl --mpl-baseline-path=astroplan/plots/tests/baseline_images

I think this is due to the line in the pytest section of setup.cfg which says addopts = --mpl --mpl-baseline-path=astroplan/plots/tests/baseline_images. Presumably that fails if pytest-mpl is absent. Is there a way to still use pytest-mpl when present but just skip the tests (and not have the command line failure) if it's absent?

cc @astrofrog as I imagine this might show up in other pytest-mpl situations

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.