-
-
Notifications
You must be signed in to change notification settings - Fork 591
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
Coordinate frames that include solar differential rotation #3537
Conversation
Hello @ayshih! Thanks for updating this PR. We checked the lines you've touched for PEP 8 issues, and found:
Comment last updated at 2020-02-05 15:01:21 UTC |
Thanks for the pull request @ayshih! Everything looks great! |
dc01ef7
to
f7bd66e
Compare
Multiple rotation durationsYou can work with array >>> hpc = Helioprojective(obstime='2001-01-01', observer='earth')
>>> sc = SkyCoord([0]*9*u.arcsec, [0]*9*u.arcsec, frame=hpc)
>>> series = RotatedSunFrame(base=sc, duration=range(0, 27, 3)*u.day)
>>> series
<RotatedSunHelioprojective Coordinate (base=<Helioprojective Frame (obstime=2001-01-01T00:00:00.000, rsun=695700.0 km, observer=<HeliographicStonyhurst Coordinate for 'earth'>)>, duration=[ 0. 3. 6. 9. 12. 15. 18. 21. 24.] d, rotation_model=howard): (Tx, Ty) in arcsec
[(0., 0.), (0., 0.), (0., 0.), (0., 0.), (0., 0.), (0., 0.), (0., 0.),
(0., 0.), (0., 0.)]>
>>> series.transform(hpc)
<Helioprojective Coordinate (obstime=2001-01-01T00:00:00.000, rsun=695700.0 km, observer=<HeliographicStonyhurst Coordinate for 'earth'>): (Tx, Ty, distance) in (arcsec, arcsec, AU)
[( 0. , 0. , 0.97866506),
( 666.1751848 , -13.91351551, 0.97991384),
( 971.99406549, -48.04083807, 0.98298359),
( 756.05760587, -83.90802534, 0.98622017),
( 137.55563461, -102.40288732, 0.98789324),
(-553.88198072, -93.79075537, 0.98711382),
(-951.06271076, -62.59442403, 0.9842956 ),
(-839.39922086, -25.34560595, 0.98094109),
(-274.84399172, -2.09057135, 0.9788526 )]> |
f7bd66e
to
a8c3287
Compare
Transforming a coordinate to a frame with a different observation timeIn the coordinates framework, a coordinate (e.g., For example, here we try to transform disk center as seen by one observer to an observer 90 degrees separated in longitude and 6 days later in time: >>> observer1 = SkyCoord(HeliocentricInertial(0*u.deg, 0*u.deg, 1*u.AU, obstime='2001-01-01'))
>>> observer2 = SkyCoord(HeliocentricInertial(90*u.deg, 0*u.deg, 1*u.AU, obstime='2001-01-07'))
>>> frame1 = Helioprojective(observer=observer1, obstime=observer1.obstime)
>>> frame2 = Helioprojective(observer=observer2, obstime=observer2.obstime)
>>> sc = SkyCoord(0*u.arcsec, 0*u.arcsec, frame=frame1)
>>> sc.transform_to(frame2)
<SkyCoord (Helioprojective: obstime=2001-01-07T00:00:00.000, rsun=695700.0 km, observer=<HeliographicStonyhurst Coordinate (obstime=2001-01-07T00:00:00.000): (lon, lat, radius) in (deg, deg, AU)
(59.22396701, 0., 1.)>): (Tx, Ty, distance) in (arcsec, arcsec, AU)
(-956.93749939, 1.16033026, 1.00006359)> The output coordinate is on the east limb, which is consistent with not evolving the location with solar rotation. With this PR, you can now include the evolution of solar rotation via this call: >>> RotatedSunFrame(base=sc, rotated_time=frame2.obstime).transform_to(frame2)
<Helioprojective Coordinate (obstime=2001-01-07T00:00:00.000, rsun=695700.0 km, observer=<HeliographicStonyhurst Coordinate (obstime=2001-01-07T00:00:00.000): (lon, lat, radius) in (deg, deg, AU)
(59.22396701, 0., 1.)>): (Tx, Ty, distance) in (arcsec, arcsec, AU)
(-78.69026983, 1.16579504, 0.99537569)> The |
57e1fb2
to
21e1c68
Compare
Differentially rotating a map (versus the old approach)We can use this frame, plus import matplotlib.pyplot as plt
from reproject import reproject_interp
from astropy.coordinates import SkyCoord
import astropy.units as u
import sunpy.map
from astropy.wcs import WCS
from sunpy.coordinates import RotatedSunFrame, get_body_heliographic_stonyhurst, frames as f
from sunpy.data.sample import AIA_171_IMAGE
from sunpy.physics.differential_rotation import differential_rotate
delta_t = 5*u.day
m = sunpy.map.Map(AIA_171_IMAGE)
# Define the output frame with an associated new observer (at Earth)
output_frame = f.Helioprojective(observer='earth', obstime=m.date + delta_t)
# Define the RotatedSunFrame (its `duration` will turn out to be -1 * `delta_t`)
rot_frame = RotatedSunFrame(base=output_frame, rotated_time=m.date)
out_shape = (1024, 1024)
header = sunpy.map.make_fitswcs_header(out_shape,
m.center.transform_to(rot_frame).as_base(),
scale=u.Quantity(m.scale))
out_wcs = WCS(header)
out_wcs.coordinate_frame = rot_frame
with sunpy.coordinates.transformations.ignore_sun_motion():
arr, foot = reproject_interp(m, out_wcs, out_shape)
out_warp = sunpy.map.Map(arr, out_wcs)
out_warp.plot_settings = m.plot_settings
old = differential_rotate(m, time=delta_t)
fig = plt.figure(figsize=(15,8))
ax = plt.subplot(1,2,1, projection=out_warp)
out_warp.plot(ax)
ax.set_title("Reproject using RotatedSunFrame")
overlay = ax.get_coords_overlay(
RotatedSunFrame(base=f.HeliographicStonyhurst(obstime=m.date), rotated_time=output_frame.obstime))
overlay[0].set_ticks(spacing=15. * u.deg)
overlay[1].set_ticks(spacing=90. * u.deg)
with sunpy.coordinates.transformations.ignore_sun_motion():
overlay.grid(ls='-', color='blue')
ax2 = plt.subplot(1,2,2,projection=old)
old.plot(ax2)
ax2.set_title("Using differential_rotate")
plt.show() |
21e1c68
to
27754fb
Compare
81edbcf
to
e57f274
Compare
I've added a tutorial (see this recent build). |
e57f274
to
16e2a66
Compare
The tutorial is awesome! Are we confident in the reproject example doing the right thing? |
We should also open an issue on astropy about specifying the frame for a WCS. I spoke to both Tom and Erik about it at the astropy meeting and they both agreed it would be something useful to workout upstream. |
16e2a66
to
784eea8
Compare
Thanks! I just added another example to show using
Well, I'm confident that the coordinate transformations are correct. Are you confident that |
b0257a2
to
c0e70d2
Compare
Okay, I've committed the test. Who's brave enough to review this? =P |
c35843a
to
18fa69f
Compare
Well it just took me 20 mins to read through your docs so... |
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.
This is amazing! So cool! I particularly love the wcsaxes example, but I think it is exceptionally well documented and tested. Thanks @ayshih 🚀
Super minimal changes below, but looks good to me. Now, are we going to find a second reviewer for this?!
@@ -15,6 +15,9 @@ def solar_wcs_frame_mapping(wcs): | |||
type values in the `astropy.wcs.utils.wcs_to_celestial_frame` registry. | |||
""" | |||
|
|||
if hasattr(wcs, "coordinate_frame"): |
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.
We really need to upstream this into Astropy...
Now needs a rebase because #3540 has been merged. |
18fa69f
to
f103660
Compare
f103660
to
ff1cb6c
Compare
…s coordinate frame attributes
…otated_time property
ff1cb6c
to
bee98cd
Compare
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 haven't thoroughly reviewed the code, but have left some documentation suggestions (and one question).
@@ -0,0 +1,390 @@ | |||
.. _sunpy-coordinates-rotatedsunframe: | |||
|
|||
Differential rotation using coordinate frames |
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 think in this section there should be a clear reference to the available methods (ie. formulae) that can be used for the rotation.
|
||
Creating coordinates | ||
^^^^^^^^^^^^^^^^^^^^ | ||
|
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.
There are lots of class links here that should be intersphinx links and not double-dashes. Happy for another issue to be opened to fix this though.
<HeliographicCarrington Coordinate (obstime=2020-03-04T00:00:00.000): (lon, lat, radius) in (deg, deg, km) | ||
(10., 20., 695700.)> | ||
|
||
Advanced uses of RotatedSunFrame |
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 think these examples would be better in individual gallery examples, since this is already quite an individually long bit of documentation.
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.
Unless @ayshih wants to put my doc suggestions in here, I'm happy for them to be farmed out to another issue and then another PR.
👍 will do |
This PR integrates solar (differential) rotation into the coordinates framework. The approach here is to enable defining a frame that is a modified version of a base coordinate frame by a duration of solar (differential) rotation. The class factory
RotatedSunFrame
is supplied the "base" coordinate frame, and creates a base-specific rotated-Sun frame class.Closes #3357
Still needs:
obstime
/duration
/rotated_time
Walkthrough
Propagating a coordinate
Let's define a coordinate array of points in a rotated-Sun frame that in the base HGS frame were on the meridian as seen from Earth. Here, the rotated-Sun frame applies +1 day of solar rotation.
The coordinate components are relative to the distorted axes of the rotated-Sun frame, and thus are already differentially rotated in real space. Convert the coordinate array back to the HGS frame to see what I mean.
Another example
There are several ways to instantiate a
RotatedSunFrame
frame. Here, the input supplied tobase
has the relevant coordinate data, so that data is automatically "moved" to the correct place in the resulting frame. Also, instead of supplyingduration
directly, therotated_time
keyword is used to indirectly define the duration of rotation.No surprises here: The HPC center of the solar disk moves mostly in the X direction after +2 days of solar rotation.
Because
RotatedSunFrame
frames are in the transformation graph, you can do more creative transformations. Here, we calculate what HPC coordinate when differentially rotated by -1 days corresponds to the disk center when differentially rotated by +2 days.Grid overlay on a Map