Skip to content

Conversation

@mhvk
Copy link
Contributor

@mhvk mhvk commented Dec 23, 2013

Triggered by #1924 and its follow-up, I decided to make Time take heights or a simple EarthLocation class. I realise that this may well need to be a bit more complicated, but the pulsar timing work provides a case where it is good to have something that works now. As written, the EarthLocation class is a subclass from CartesianPoints, with the only addition that it can convert from and to geodetic coordinates using the erfa routines gd2gc and gc2gd (the former was already there; the latter is now included in erfa_time). Example:

In [1]: from astropy.time import Time, TimeDelta; import astropy.units as u
In [2]: t = Time('2010-01-01', scale='utc', lon='-75d', lat='30d', height=300 * u.m)
In [3]: t.location, t.lon, t.lat, t.height
Out[3]: 
(<EarthLocation [ 1430885.34762385,-5340136.81713808, 3170523.73538364] m>,
 <Longitude -75.0 deg>,
 <Latitude 29.999999999999986 deg>,
 <Quantity 299.99999999940826 m>)

In [4]: t = Time('2010-01-01', scale='utc', location=(1e4 * u.m, 1e3 * u.m, 1e3 * u.m))
In [5]: t.location, t.lon, t.lat, t.height
Out[5]: 
(<EarthLocation [ 10000.,  1000.,  1000.] m>,
 <Longitude 5.710593137499643 deg>,
 <Latitude -1.6731805108259852 deg>,
 <Quantity -6368102.40678084 m>)

@eteq: as you started with a Location class as well, could you check whether you think my approach makes sense? I think for now, since the locations are only used internally, a simple approach should be fine, but we should ensure that it doesn't preclude a more complete implementation later on. Also, do you have a suggestion for where this should live?

@taldcroft: do you think the suggested changes to Time are OK?

@scottransom: would this fulfill the requirements for PINT?

p.s. This supercedes #1927, but is complementary to #1925

p̶.̶s̶.̶2̶ ̶T̶h̶i̶s̶ ̶s̶t̶i̶l̶l̶ ̶n̶e̶e̶d̶s̶ ̶d̶o̶c̶s̶t̶r̶i̶n̶g̶s̶ ̶f̶o̶r̶ ̶t̶h̶e̶ ̶E̶a̶r̶t̶h̶L̶o̶c̶a̶t̶i̶o̶n̶ ̶c̶l̶a̶s̶s̶,̶ ̶a̶s̶ ̶w̶e̶l̶l̶ ̶a̶s̶ ̶t̶e̶s̶t̶ ̶c̶a̶s̶e̶s̶ ̶a̶n̶d̶ ̶a̶n̶ ̶u̶p̶d̶a̶t̶e̶ ̶t̶o̶ ̶t̶h̶e̶ ̶T̶i̶m̶e̶ ̶d̶o̶c̶u̶m̶e̶n̶t̶a̶t̶i̶o̶n̶.̶ ̶W̶i̶l̶l̶ ̶d̶o̶ ̶i̶f̶ ̶i̶t̶ ̶i̶s̶ ̶a̶g̶r̶e̶e̶d̶ ̶t̶h̶a̶t̶ ̶t̶h̶i̶s̶ ̶i̶s̶ ̶t̶h̶e̶ ̶r̶i̶g̶h̶t̶ ̶a̶p̶p̶r̶o̶a̶c̶h̶.̶

@taldcroft
Copy link
Member

@mhvk - I would be inclined to drop lon and lat entirely in favor of location (which also implies not adding height). Of course this needs to be done with a deprecation release. Even though we are trying for API stability, I suspect that lat and lon are not being used that much yet for Time, and we should not accumulate this mess of overlapping keyword args in the API.

I would say that location should accept a location object or any tuple that can reasonably instantiate an EarthLocation object (e.g. two angles => lon, lat; two angles and a length => lon, lat, height; three lengths => x, y, z).

@scottransom
Copy link

@mvhk: yes, I think that this makes sense. And I'm also fine with having it accept a Location object rather than lat/lon/hgt.

This seems like it would be useful beyond internally, though, so maybe it should be available outside of the Time routines? I would use it for the observatory positions in PINT if that were the case.

@taldcroft
Copy link
Member

I agree that EarthLocation should live outside of time. Since it's basically a coordinate it seems like it should live in that package.

Copy link
Member

Choose a reason for hiding this comment

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

This code looks a lot nicer now!

Choose a reason for hiding this comment

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

Note that for that calculation, hypot would probably be even better (because of numerical precision issues if nothing else):
u = np.hypot(location.x, location.y).to('m').value

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, np.hypot is indeed better; using that now.

@mhvk
Copy link
Contributor Author

mhvk commented Dec 26, 2013

@taldcroft - I agree that it may be best to just move away from lon and lat in favour of location, so have implemented that suggestion, as well as others by you and @scottransom. Also updated the tests, etc.

It also makes most sense to make the EarthLocation class not Time-specific, but I'll wait for comments from @eteq and @astrofrog before moving it (and before updating the documentation).

@eteq
Copy link
Member

eteq commented Dec 27, 2013

Just to let you know, @mhvk, this is on my radar to review (along with #1927), but it might be a few more days yet before I get to it (holidays and all)...

@mhvk
Copy link
Contributor Author

mhvk commented Dec 27, 2013

@eteq - no worries; is good to get this at least in the right direction.

@mhvk
Copy link
Contributor Author

mhvk commented Dec 28, 2013

As the new location class is based in Quantity, the correction for the erfa problem with output being in 'm' and input being in 'km' (#1929) was rather trivial to solve. It does beg the question whether our interface to erfa should handle quantities generally, so these types of problems do not recur. Added a note to #1453 to that extent (and do the conversion to "km" inside the erfa function call, as a reminder of why this is necessary at all)

@mhvk
Copy link
Contributor Author

mhvk commented Jan 3, 2014

@demorest - on the e-mail you sent separately:

The only thing we are directly using ERFA for in PINT is computing observatory positions/velocities (ie turning ITRS xyz into ICRS xyz). This stuff would probably be a nice thing to put in your EarthLocation class in astropy.

I think this would indeed be great to add, though it sounds like this is more properly done as part of coordinates (where the EarthLocation class should move anyway). Could you point me to where in PINT this is done, so we can see what it would entail?

cc @eteq: this is about which erfa routines are needed for pulsar timing besides those in erfa_time; of course, also directly relevant to #1453.

@demorest
Copy link

demorest commented Jan 4, 2014

@mhvk - look at this pint source file: http://github.com/demorest/PINT/blob/master/pint/erfautils.py

It's not too complicated, and I think it very closely follows another one of the SOFA usage examples (maybe @scottransom remembers where to find that in the SOFA docs).

@astrofrog
Copy link
Member

@taldcroft - regarding your comment about this needing to live in astropy.coordinates (which I agree with) do you think that in the long term, all of astropy.time should also live in astropy.coordinates? After all, time is just another coordinate?

@mhvk
Copy link
Contributor Author

mhvk commented Jan 5, 2014

@astrofrog - am not sure coordinates is necessarily the best place (though better than Time!). An alternative would be to separate out the mathematical coordinates (Angle, Longitude, Latitude, CartesianPoints, etc.) from sky and surface-based coordinates. Another thought would be to have an astropy.observatories or astropy.earth subpackage. (Indirectly related: we also should still move iers out of utils; the agreement seems to have been to make this an upper-level package as well, possibly as part of earth; see #1620).

@eteq
Copy link
Member

eteq commented Jan 5, 2014

@astrofrog @mhvk - I do not think time should live in coordinates. While @astrofrog is right that unifying them seems attractive from a physics/relativity standpoint, there still a conceptual difference. When someone asks "how do I convert from ISO time stamps to MJD?", I think almost no one will find it natural if we say "it's in the celestial coordinates subpackage." They'll definitely have to be rather interconnected, but I don't think it makes sense to actually make them the same.

As for where Observatory should go, I see @mhvk's point that something like astropy.observatories makes sense - in the future that might also include information like telescopes and their limits, instruments, or whatever. And maybe also tools like observing charts belong there. All of the actual location stuff (e.g. an EarthLocation class) should definitely live in coordinates, though - they would be part of the coordinate transformation graph, after all.

@taldcroft
Copy link
Member

👎 on Time in coordinates for the reasons @eteq mentioned. The fact that there is a certain cross-coupling in terms of usage doesn't mean they have to be in the same top level package. I also (still) agree that EarthLocation definitely belongs in coordinates.

I don't see a big benefit to splitting out mathematical coordinates like @mhvk suggested, that would just add confusion in terms of where to import relevant classes etc., not to mention a huge API change when we've been promising that coordinates will settle down.

@mhvk
Copy link
Contributor Author

mhvk commented Jan 14, 2014

@eteq - I moved EarthLocation to coordinates (earth.py). I know I should also add test cases for the class itself, as well as documentation to coordinates, but would like to be sure you think the overall concept is solid before I do so.

Note that I kept the erfa interface routines in Time, since those are better dealt with as part of #1453.

@eteq
Copy link
Member

eteq commented Apr 12, 2014

I was looking through some of the backlog and realized this is still hanging. @mhvk, do you think we should hold off on this until we get through APE5 implementation? It may be that we'll need to move the ERFA stuff as part of that, in which case it might be awkward to merge this in beforehand... But it might also just be a matter of rebasing before merging APE5. (although this also needs a rebase now.)

@mhvk
Copy link
Contributor Author

mhvk commented Apr 12, 2014

@eteq - I'd be in favour of putting it in, as long as everybody is happy with the overall API (and it would be hard to think how else one would initialize it that from lon, lat, height or x, y, z). I'll rebase.

Includes erfa gc2gd so that one can transform XYZ to geodetic
@taldcroft
Copy link
Member

OK, I had assumed you wrote a wrapper around CartesianPoints to mimic the CartesianRepresentation API. Should've looked at the code.

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps this should just say "use an EarthLocation object"? That at least should point the user to relevant documentation. (Not a big deal either way, though)

@eteq
Copy link
Member

eteq commented Apr 16, 2014

Aside from that one minor bit it seems fine to me. @taldcroft, did you want to actually look more, or is this good to go now as far as you're concerned?

@astrofrog
Copy link
Member

Just to check, currently what is passed to location is assumed to be an EarthLocation - is the idea that in future we could have non-Earth locations but that by default if one only passes a tuple it is interpreted as an Earth-based location? This is fine, but just want to check that is that long-term plan?

@taldcroft
Copy link
Member

I was just scanning the tests and noticed there doesn't seem to be any explicit use of EarthLocation anywhere in the tests. There should probably be at least one test of actually passing in an EarthLocation object for location.

Copy link
Member

Choose a reason for hiding this comment

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

This doesn't explicitly say you can provide an EarthLocation object, through of course that does qualify as being able to initialize an EarthLocation. Maybe ..., using an |EarthLocation| object or any form that can initialize an |EarthLocation|, i.e. ..

@taldcroft
Copy link
Member

OK, I'm done with my review!

@mhvk
Copy link
Contributor Author

mhvk commented Apr 18, 2014

@astrofrog - Not sure about non-Earth based locations, since many timescales do not make sense off the Earth, but I certainly hope that we can pass, e.g., observatory names (or classes, which might be subclassed from EarthLocation).

@taldcroft, @eteq - Good suggestions. All implemented.

@taldcroft
Copy link
Member

This is good from my perspective.

@eteq
Copy link
Member

eteq commented Apr 18, 2014

@astrofrog @mhvk - I think it definitely will make sense in the future to allow something more than just EarthLocation... And once we have the IAU2000 stack in, that will be a lot easier because we can use those transforms.

But the question, now that @astrofrog brought it up, is this: should we drop the tuple form entirely, and only allow EarthLocation? I'm actually 👍 to that, as it's a lot less ambiguous... what do you think, @mhvk ?

@scottransom
Copy link

I do think that it is probably good that at least some non-earth-based locations are handled. I'm thinking specifically of satellite observatories, which often use UTC-based timescales and then do conversions to TDB etc as appropriate....

@mhvk
Copy link
Contributor Author

mhvk commented Apr 20, 2014

@scottransom - I think there is nothing here that would stop us from expanding to satellite locations, especially if one has their geocentric coordinates.

@eteq - I can see the point of requiring an EarthLocation, but somewhat like the convenience of not having to import it... Also, eventually we hoped to do something like location='cfht', which would also requiring the ability to pass on what are essentially initialisation arguments.

@astrofrog
Copy link
Member

I think I'm ok with strings and tuples being a convenience for earth locations, but I guess I just meant that I wanted to make sure that we make it clear tuples get passed to that class and are just a convenience.

@mhvk
Copy link
Contributor Author

mhvk commented Apr 20, 2014

@astrofrog - OK, that makes sense. I looked at the PR again and think over the various iterations all documentation has become fairly clear that it is an EarthLocation or something that initialises one; I only changed the entry in CHANGES.rst to make that clear as well.

Copy link
Member

Choose a reason for hiding this comment

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

Typo: lon -> lat

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The perils of cut&paste yet again exposed... Now fixed.

@astrofrog
Copy link
Member

@mhvk - sounds good! Once the above typo is fixed we can merge this!

mhvk added a commit that referenced this pull request Apr 20, 2014
EarthLocation class for Time
@mhvk mhvk merged commit afc30a6 into astropy:master Apr 20, 2014
@mhvk mhvk deleted the time-location branch April 20, 2014 22:14
@eteq
Copy link
Member

eteq commented Apr 21, 2014

To add one item for the future, @scottransom : I think this will be pretty straightforward once we've got the full IAU2000 stack working, which is the next step after APE5 is done (and shouldn't be too onerous once we figure out the easiest way of getting all the ERFA parts to talk easily with astropy).

@eteq
Copy link
Member

eteq commented Apr 21, 2014

And nice work on this, @mhvk : took a while, but I like how it turned out!

@cdeil
Copy link
Member

cdeil commented Apr 21, 2014

Looking at EarthLocation in the API docs, there's a few minor things in the docstrings that should be cleaned up:

  • The longitude and latitude attributes are called lon and lat in a few places (and cross-links in the html output don't work).
  • The following attributes should have one-line descriptions: ellipsoid, height, latitude, longitude, x, y, z
  • In the from_geocentric, from_geodetic and to_geodetic method docstrings the first sentence should end with a dot ., so that they format correctly in the API docs method list.
    There should also be a dot . after "Location on Earth" on the class docstring.

@mhvk
Copy link
Contributor Author

mhvk commented Apr 21, 2014

@cdeil - OK, will issue a new PR for those. One item that requires a bit of thought (put here, so people can comment), is whether it makes sense to initialize longitude, latitude, and height with the short forms in from_geodetic(lon=..., lat=..., height=...) and have long-form attributes. Now that this is not yet in use, shall I change to short or long form in both? My tendency would be to go for the full names also for the arguments.

@mhvk
Copy link
Contributor Author

mhvk commented Apr 21, 2014

@cdeil - see #2346.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants