-
-
Notifications
You must be signed in to change notification settings - Fork 111
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
Beginning in the FixedTarget and Observer classes #11
Changes from 8 commits
15322ca
7883eb2
2d62aba
4082c63
0cddae5
e4516e4
cd215d9
9c65d7a
1ba6312
94443af
4dd152a
615bc8c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,21 @@ | |
from __future__ import (absolute_import, division, print_function, | ||
unicode_literals) | ||
|
||
from astropy.coordinates import (EarthLocation, Latitude, Longitude, SkyCoord, | ||
AltAz) | ||
import astropy.units as u | ||
from astropy.units import Quantity | ||
|
||
import pytz | ||
|
||
################################################################################ | ||
# TODO: Temporary solution to IERS tables problems | ||
from astropy.utils.data import download_file | ||
from astropy.utils import iers | ||
import datetime | ||
iers.IERS.iers_table = iers.IERS_A.open(download_file(iers.IERS_A_URL, cache=True)) | ||
################################################################################ | ||
|
||
#from ..extern import six | ||
|
||
#import sys | ||
|
@@ -25,82 +40,137 @@ class Observer(object): | |
Some comments. | ||
""" | ||
|
||
def __init__(self, name, longitude, latitude, elevation, pressure, | ||
relative_humidity, temperature, timezone, description=None): | ||
def __init__(self, name=None, location=None, latitude=None, longitude=None, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we instead use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think my preference is no to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 to @adrn here. Also makes it easier to see what the default is. |
||
elevation=None, timezone='UTC', pressure=None, | ||
relative_humidity=None, temperature=None, description=None): | ||
""" | ||
Initializes an Observer object. | ||
|
||
<longer description> | ||
TODO: <longer description> | ||
|
||
Parameters | ||
---------- | ||
name : str | ||
A short name for the telescope, observatory or location. | ||
|
||
longitude : str or `~astropy.units.quantity`? | ||
The longitude of the observing location. | ||
pressure : `~astropy.units.Quantity` | ||
The ambient pressure. | ||
|
||
latitude : str or `~astropy.units.quantity`? | ||
The latitude of the observing location. | ||
location : `~astropy.coordinates.EarthLocation` | ||
The location (latitude, longitude, elevation) of the observatory. | ||
|
||
longitude : str or `~astropy.units.Quantity` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add |
||
The longitude of the observing location. If str, should be a string | ||
that initializes a `~astropy.coordinates.Longitude` object with | ||
units in degrees. | ||
|
||
latitude : str or `~astropy.units.Quantity` | ||
The latitude of the observing location. If str, should be a string | ||
that initializes a `~astropy.coordinates.Latitude` object with | ||
units in degrees. | ||
|
||
elevation : `~astropy.units.Quantity` | ||
The elevation of the observing location, with respect to sea | ||
level. | ||
|
||
pressure : `~astropy.units.Quantity` | ||
The ambient pressure. | ||
|
||
relative_humidity : float | ||
The ambient relative humidity. | ||
|
||
temperature : `~astropy.units.Quantity` | ||
The ambient temperature. | ||
|
||
timezone : WHAT TYPE IS pytz.timezone ? | ||
The local timezone. | ||
timezone : str or `datetime.tzinfo` | ||
The local timezone, as either an instance of `pytz.timezone()` or | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The way you've phrased it here you're duplicating information because you're just saying the type. Maybe instead "The local timezone to assume. If a string, it will be passed through |
||
the string accepted by `pytz.timezone()`. | ||
|
||
description : str | ||
A short description of the telescope, observatory or observing | ||
location. | ||
""" | ||
raise NotImplementedError() | ||
|
||
def set_environment(self, pressure, relative_humidity, temperature): | ||
""" | ||
Updates the Observer object with environmental conditions. | ||
if name is not None: | ||
self.name = name | ||
|
||
<longer description> | ||
if pressure is None: | ||
pressure = 0 | ||
|
||
Parameters | ||
---------- | ||
pressure : `~astropy.units.Quantity` | ||
The ambient pressure. | ||
if temperature is None: | ||
temperature = 0 * u.deg_C | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure we want to set the default (unset) values to 0 -- this is a valid number that will work in arithmetic operations but may return weird results. I think we want them to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another way to think about it: there is a conceptual difference between " There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @adrn – The place where that became handy for me was in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I recall, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the right pattern for calling |
||
|
||
relative_humidity : `~astropy.units.Quantity` | ||
The ambient relative humidity. | ||
if relative_humidity is None: | ||
relative_humidity = 0 | ||
|
||
temperature : | ||
The ambient temperature. | ||
""" | ||
raise NotImplementedError() | ||
self.pressure = pressure | ||
self.temperature = temperature | ||
self.relative_humidity = relative_humidity | ||
|
||
def get_date(self, input_date_time, timezone=None): | ||
""" | ||
Builds an object containing date and time information. | ||
# If lat/long given instead of EarthLocation, convert them | ||
# to EarthLocation | ||
if location is None and (latitude is not None and longitude is not None): | ||
accepted_latlon_types = [str, Quantity] | ||
if (type(latitude) in accepted_latlon_types and | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I'm wrong here (@eteq let me know), but is this necessary? The initializer for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seemed to me from the EarthLocation docs that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Works with e.g., this works: loc = coord.EarthLocation.from_geodetic(lon="150:21:41.1", lat=45*u.deg, height=15*u.m) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (that is, you're just repeating code that already exists in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Awesome, maybe this is an indication that the EarthLocation docs can be updated to specify their awesome input flexibility :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, it's useful for developers to know, but I think it is not in the docs because we want to encourage users to use quantities or objects (rather than strings! strings are baaaad! bad!) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (willing to reconsider that decision, if that was a decision and not just an oversight in the first place..) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean, I'm an insider now? 😄 |
||
type(longitude) in accepted_latlon_types): | ||
latitude = Latitude(latitude, unit=u.degree) | ||
longitude = Longitude(longitude, unit=u.degree) | ||
|
||
self.location = EarthLocation.from_geodetic(longitude, latitude, | ||
elevation) | ||
|
||
elif isinstance(location, EarthLocation): | ||
self.location = location | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is my compromise between @ejeschke 's accepting attitude towards input formats and @adrn 's preference for accepting one type - |
||
|
||
Default time zone is UTC. | ||
If time zone (local or otherwise) requested, then uses `datetime.datetime` | ||
and pytz.timezone to convert from UTC. | ||
else: | ||
raise TypeError('Observatory location must be specified with ' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make me happy, and put There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Anything to make you happy, @adrn! |
||
'either (1) latitude and longitude in degrees as ' | ||
'accepted by astropy.coordinates.Latitude and ' | ||
'astropy.coordinates.Latitude, or (2) as an ' | ||
'instance of astropy.coordinates.EarthLocation.') | ||
|
||
Must first create date_time object with get_date() before using any other | ||
Observer methods, all of which require one as an argument. | ||
# Accept various timezone inputs, default to UTC | ||
if isinstance(timezone, datetime.tzinfo): | ||
self.timezone = timezone | ||
elif isinstance(timezone, str) or isinstance(timezone, unicode): | ||
self.timezone = pytz.timezone(timezone) | ||
else: | ||
raise TypeError('timezone keyword should be a string, or an ' | ||
'instance of datetime.tzinfo') | ||
|
||
def altaz(self, time, target=None, obswl=None): | ||
""" | ||
Returns an instance of `~astropy.coordinates.SkyCoord` with altitude and | ||
azimuth of the `FixedTarget` called `target` at time `time`. | ||
|
||
Parameters | ||
---------- | ||
input_date_time : WHAT TYPE IS astropy.time OBJECT? | ||
time : `~astropy.time.Time` | ||
Astropy time object. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a repeat of the type information. Instead maybe |
||
|
||
target : None (default) or `~astroplan.FixedTarget` or `~astropy.coordinates.SkyCoord` | ||
Celestial object of interest. If `target`=None, return just the | ||
`~astropy.coordinates.AltAz` frame without coordinates. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I think this should go in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My strategy was that the |
||
""" | ||
raise NotImplementedError() | ||
if obswl is None: | ||
obswl = 1*u.micron | ||
|
||
altaz_frame = AltAz(location=self.location, obstime=time, | ||
pressure=self.pressure, obswl=obswl, | ||
temperature=self.temperature, | ||
relative_humidity=self.relative_humidity) | ||
|
||
if target is None: | ||
return altaz_frame | ||
else: | ||
if not (isinstance(target, FixedTarget) or | ||
isinstance(target, SkyCoord)): | ||
raise TypeError('The target must be an instance of FixedTarget ' | ||
'or SkyCoord.') | ||
|
||
if hasattr(target, 'coord'): | ||
coordinate = target.coord | ||
else: | ||
coordinate = target | ||
return coordinate.transform_to(altaz_frame) | ||
|
||
# Sun-related methods. | ||
|
||
|
@@ -273,7 +343,7 @@ class Target(object): | |
""" | ||
__metaclass__ = ABCMeta | ||
|
||
def __init__(self, name, ra, dec, marker=None): | ||
def __init__(self, name=None, ra=None, dec=None, marker=None): | ||
""" | ||
Defines a single observation target. | ||
|
||
|
@@ -296,21 +366,40 @@ def ra(self): | |
""" | ||
Right ascension. | ||
""" | ||
raise NotImplementedError | ||
if isinstance(self, FixedTarget): | ||
return self.coord.ra | ||
raise NotImplementedError() | ||
|
||
@property | ||
def dec(self): | ||
""" | ||
Declination. | ||
""" | ||
raise NotImplementedError | ||
if isinstance(self, FixedTarget): | ||
return self.coord.dec | ||
raise NotImplementedError() | ||
|
||
|
||
class FixedTarget(Target): | ||
""" | ||
An object that is "fixed" with respect to the celestial sphere. | ||
""" | ||
|
||
def __init__(self, coord, **kwargs): | ||
''' | ||
TODO: Docstring. | ||
''' | ||
if not isinstance(coord, SkyCoord): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably accept a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't played much with the other |
||
raise TypeError('Coordinate must be a SkyCoord.') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oops, you don't want to do this. We do want to allow people to pass in the "low-level" frame classes like |
||
|
||
self.name = kwargs.get('name', None) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make |
||
self.coord = coord | ||
|
||
@classmethod | ||
def from_name(cls, query_name, **kwargs): | ||
# Allow manual override for name keyword so that the target name can | ||
# be different from the query name, otherwise assume name=queryname. | ||
name = kwargs.pop('name', query_name) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to having an explicit keyword arg for name! |
||
return cls(SkyCoord.from_name(query_name), name=name, **kwargs) | ||
|
||
class NonFixedTarget(Target): | ||
""" | ||
|
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.
@bmorris3 – Do you understand this? https://travis-ci.org/astroplanners/astroplan/jobs/67568895#L372 (I don't)
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 don't either, maybe @eteq can give us some hints on how to read these logs on Monday or in the Hangout on Tuesday.
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 still don't understand why that line gave an error on travis-ci:
But if you fix the other errors mentioned below and
python setup.py test
(which imports this file) works locally, it should work on travis-ci, too.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.
Just adding a line note to remind us that this was resolved by a later commit -- the issue was a missing indentation in
astroplan/__init__.py
for a line that was importing fromastroplan.core
.