def test_no_observer(): # Tests transformations to and from observer-based frames with no observer defined frames_in = [Heliocentric(0*u.km, 0*u.km, 0*u.km, observer=None), Heliocentric(0*u.km, 0*u.km, 0*u.km, observer=None, obstime='2001-01-01'), Helioprojective(0*u.deg, 0*u.deg, observer=None), Helioprojective(0*u.deg, 0*u.deg, observer=None, obstime='2001-01-01')] frames_out = frames_in + [ HeliographicStonyhurst(0*u.deg, 0*u.deg, obstime=None), HeliographicStonyhurst(0*u.deg, 0*u.deg, obstime='2001-01-01'), Heliocentric(0*u.km, 0*u.km, 0*u.km, observer=None, obstime='2012-12-12'), Heliocentric(0*u.km, 0*u.km, 0*u.km, observer="earth", obstime=None), Heliocentric(0*u.km, 0*u.km, 0*u.km, observer="earth", obstime='2001-01-01'), Helioprojective(0*u.deg, 0*u.deg, observer=None, obstime='2012-12-12'), Helioprojective(0*u.deg, 0*u.deg, observer="earth", obstime=None), Helioprojective(0*u.deg, 0*u.deg, observer="earth", obstime='2001-01-01')] # Self-transformations should succeed for f in frames_in: f.transform_to(f.replicate_without_data()) # All other transformations should error for i, f1 in enumerate(frames_in): for f2 in frames_out[i + 1:]: with pytest.raises(ConvertError): f1.transform_to(f2) with pytest.raises(ConvertError): f2.transform_to(f1)
def test_hpc_hpc(): # Use some unphysical values for solar parameters for testing, to make it # easier to calculate expected results. rsun = 1 * u.m D0 = 1 * u.km L0 = 1 * u.deg observer_in = HeliographicStonyhurst(lat=0 * u.deg, lon=0 * u.deg, radius=D0) observer_out = HeliographicStonyhurst(lat=0 * u.deg, lon=L0, radius=D0) hpc_in = Helioprojective(0 * u.arcsec, 0 * u.arcsec, rsun=rsun, observer=observer_in) hpc_out = Helioprojective(observer=observer_out, rsun=rsun) hpc_new = hpc_in.transform_to(hpc_out) assert hpc_new.observer == hpc_out.observer # Calculate the distance subtended by an angle of L0 from the centre of the # Sun. dd = -1 * rsun * np.tan(L0) # Calculate the angle corresponding to that distance as seen by the new # observer. theta = np.arctan2(dd, (D0 - rsun)) assert quantity_allclose(theta, hpc_new.Tx, rtol=1e-3)
def magnetogram(): arr_shape = [50, 50] * u.pixel obs = SkyCoord(lon=0. * u.deg, lat=0. * u.deg, radius=const.au, frame=HeliographicStonyhurst) blc = SkyCoord(-150 * u.arcsec, -150 * u.arcsec, frame=Helioprojective(observer=obs)) trc = SkyCoord(150 * u.arcsec, 150 * u.arcsec, frame=Helioprojective(observer=obs)) centers = SkyCoord(Tx=[65, -65] * u.arcsec, Ty=[0, 0] * u.arcsec, frame=Helioprojective(observer=obs)) sigmas = u.Quantity([[15, 15], [15, 15]], 'arcsec') amplitudes = u.Quantity([1e3, -1e3], 'Gauss') magnetogram = synthesizAR.extrapolate.synthetic_magnetogram(blc, trc, arr_shape, centers, sigmas, amplitudes, observer=obs) return magnetogram
def test_hpc_hpc_null(): hpc_in = Helioprojective(0*u.arcsec, 0*u.arcsec) hpc_out = Helioprojective() hpc_new = hpc_in.transform_to(hpc_out) assert hpc_new is not hpc_in assert quantity_allclose(hpc_new.Tx, hpc_in.Tx) assert quantity_allclose(hpc_new.Ty, hpc_in.Ty) assert hpc_out.observer == hpc_new.observer
def test_hpc_hpc_null(): hpc_in = Helioprojective(0 * u.arcsec, 0 * u.arcsec) hpc_out = Helioprojective() hpc_new = hpc_in.transform_to(hpc_out) assert hpc_new is not hpc_in assert quantity_allclose(hpc_new.Tx, hpc_in.Tx) assert quantity_allclose(hpc_new.Ty, hpc_in.Ty) assert hpc_out.observer == hpc_new.observer
def test_hpc_hcc_different_observer_radius(): # Tests HPC->HCC with a change in observer at different distances from the Sun observer1 = HeliographicStonyhurst(0*u.deg, 0*u.deg, 1*u.AU) hpc = Helioprojective(0*u.arcsec, 0*u.arcsec, 0.5*u.AU, observer=observer1) observer2 = HeliographicStonyhurst(90*u.deg, 0*u.deg, 0.75*u.AU) hcc = hpc.transform_to(Heliocentric(observer=observer2)) assert_quantity_allclose(hcc.x, -0.5*u.AU) assert_quantity_allclose(hcc.y, 0*u.AU, atol=1e-10*u.AU) assert_quantity_allclose(hcc.z, 0*u.AU, atol=1e-10*u.AU)
def test_hgs_cartesian_rep_to_hpc(): # This test checks transformation HGS->HPC when the coordinate is in a Cartesian # representation and that it is the same as a transformation from an HGS frame with a # spherical representation obstime = "2011-01-01" hgscoord_cart = SkyCoord(x=1*u.km, y=0.*u.km, z=0.*u.km, frame=HeliographicStonyhurst(obstime=obstime), representation_type='cartesian') hgscoord_sph = hgscoord_cart.copy() hgscoord_sph.representation_type = 'spherical' hpccoord_cart = hgscoord_cart.transform_to(Helioprojective(obstime=obstime)) hpccoord_sph = hgscoord_sph.transform_to(Helioprojective(obstime=obstime)) assert_quantity_allclose(hpccoord_cart.Tx, hpccoord_sph.Tx) assert_quantity_allclose(hpccoord_cart.Ty, hpccoord_sph.Ty) assert_quantity_allclose(hpccoord_cart.distance, hpccoord_sph.distance)
def calculate_cross_sections(self, field): """ Estimate loop cross-sectional area """ fps = heeq_to_hcc_coord( *u.Quantity([l.coordinates[-1] for l in field.loops]).T, field.magnetogram.observer_coordinate).transform_to( Helioprojective( observer=field.magnetogram.observer_coordinate)) range_x = (min(fps.Tx.min().value, field.magnetogram.bottom_left_coord.Tx.value), max(fps.Tx.max().value, field.magnetogram.top_right_coord.Tx.value)) range_y = (min(fps.Ty.min().value, field.magnetogram.bottom_left_coord.Ty.value), max(fps.Ty.max().value, field.magnetogram.top_right_coord.Ty.value)) fp_dist, x_edges, y_edges = np.histogram2d( fps.Tx.value, fps.Ty.value, range=(range_x, range_y), bins=(field.magnetogram.dimensions.x.value, field.magnetogram.dimensions.y.value)) d_surface = field.magnetogram.dsun - const.R_sun dx = (1. * u.pixel * field.magnetogram.scale.axis1).to( u.radian).value * d_surface dy = (1. * u.pixel * field.magnetogram.scale.axis2).to( u.radian).value * d_surface ix = np.digitize(fps.Tx.value, x_edges, right=False) - 1 iy = np.digitize(fps.Ty.value, y_edges, right=False) - 1 return ((dx * dy).to(u.cm**2) / fp_dist[ix, iy]).value
def make_spatial(self): """ Add a helioprojective spatial pair to the builder. .. note:: This increments the counter by two. """ i = self._i name = self.header[f'DWNAME{self.n}'] name = name.split(' ')[0] axes_names = [(self.header[f'DWNAME{nn}'].rsplit(' ')[1]) for nn in (self.n, self._n(i + 1))] obstime = Time(self.header['DATE-BGN']) self._frames.append( cf.CelestialFrame(axes_order=(i, i + 1), name=name, reference_frame=Helioprojective(obstime=obstime), axes_names=axes_names, unit=self.get_units(self._i, self._i + 1))) self._transforms.append(spatial_model_from_header(self.header)) self._i += 2
def test_rsun_preservation(): # Check that rsun is preserved when transforming between any two frames with that attribute args_in = {'obstime': '2001-01-01', 'rsun': 690*u.Mm} args_out = {'obstime': '2001-02-01', 'rsun': 700*u.Mm} coords_in = [Helioprojective(0*u.deg, 0*u.deg, 1*u.AU, observer='earth', **args_in), HeliographicStonyhurst(0*u.deg, 0*u.deg, 1*u.AU, **args_in), HeliographicCarrington(0*u.deg, 0*u.deg, 1*u.AU, observer='earth', **args_in)] for coord in coords_in: for frame in coords_in: out_coord = coord.transform_to(frame.replicate(**args_out)) assert_quantity_allclose(out_coord.rsun, args_out['rsun'])
def test_array_obstime(): # Validate that you can transform from an array of obstimes to no obstimes, # or different obstimes. a = SkyCoord([10]*2, [10]*2, unit=u.deg, observer="earth", obstime=["2019-01-01", "2019-01-02"], frame="heliographic_carrington") t = a.transform_to(Helioprojective) assert isinstance(t.frame, Helioprojective) t2 = a.transform_to(Helioprojective(obstime=["2019-01-03", "2019-01-04"])) assert isinstance(t2.frame, Helioprojective)
def test_hcc_to_hpc_same_observer(): # This test checks transformation HCC->HPC in the case of same observer rsun = 1*u.m D0 = 1*u.km observer = HeliographicStonyhurst(lat=0*u.deg, lon=0*u.deg, radius=D0) hcc_frame = Heliocentric(observer=observer) hpc_frame = Helioprojective(observer=observer, rsun=rsun) hcccoord = SkyCoord(x=rsun, y=rsun, z=rsun, frame=hcc_frame) hpccoord_out = hcccoord.transform_to(hpc_frame) hpccoord_expected = hcccoord.transform_to(HeliographicStonyhurst).transform_to(hpc_frame) assert_quantity_allclose(hpccoord_out.Tx, hpccoord_expected.Tx) assert_quantity_allclose(hpccoord_out.Ty, hpccoord_expected.Ty) assert_quantity_allclose(hpccoord_out.distance, hpccoord_expected.distance)
def test_hpc_to_hcc_same_observer(): # This test checks transformation HPC->HCC in the case of same observer rsun = 1*u.m D0 = 1 * u.km observer = HeliographicStonyhurst(lat=0 * u.deg, lon=0 * u.deg, radius=D0) hcc_frame = Heliocentric(observer=observer) hpc_frame = Helioprojective(observer=observer, rsun=rsun) hpccoord = SkyCoord(Tx=0 * u.arcsec, Ty=0 * u.arcsec, frame=hpc_frame) hcccoord_out = hpccoord.transform_to(hcc_frame) hcccoord_expected = hpccoord.transform_to(HeliographicStonyhurst).transform_to(hcc_frame) assert_quantity_allclose(hcccoord_out.x, hcccoord_expected.x) assert_quantity_allclose(hcccoord_out.y, hcccoord_expected.y) assert_quantity_allclose(hcccoord_out.z, hcccoord_expected.z)
def test_hpc_hpc(): # Use some unphysical values for solar parameters for testing rsun = 1*u.m D0 = 1*u.km L0 = 1*u.deg hpc_in = Helioprojective(0*u.arcsec, 0*u.arcsec, rsun=rsun, D0=D0) hpc_out = Helioprojective(L0=L0, D0=D0, rsun=rsun) hpc_new = hpc_in.transform_to(hpc_out) assert hpc_new.L0 == hpc_out.L0 assert hpc_new.B0 == hpc_out.B0 assert hpc_new.D0 == hpc_out.D0 # Calculate the distance subtended by an angle of L0 from the centre of the # Sun. dd = -1 * rsun * np.tan(L0) # Calculate the angle corresponding to that distance as seen by the new # observer. theta = np.arctan2(dd, (D0 - rsun)) assert quantity_allclose(theta, hpc_new.Tx, rtol=1e-3)
def test_hpc_hgs_implicit_hcc(): # An HPC->HGS transformation should give the same answer whether the transformation step # through HCC is implicit or explicit start = SkyCoord(0*u.arcsec, 0*u.arcsec, 0.5*u.AU, frame=Helioprojective(obstime='2019-06-01', observer='earth')) frame = HeliographicStonyhurst(obstime='2019-12-01') implicit = start.transform_to(frame) explicit1 = start.transform_to(Heliocentric(obstime=start.obstime, observer='earth')).\ transform_to(frame) explicit2 = start.transform_to(Heliocentric(obstime=frame.obstime, observer='earth')).\ transform_to(frame) assert_quantity_allclose(implicit.separation_3d(explicit1), 0*u.AU, atol=1e-10*u.AU) assert_quantity_allclose(implicit.separation_3d(explicit2), 0*u.AU, atol=1e-10*u.AU)
def test_hpc_hpc(): # Use some unphysical values for solar parameters for testing, to make it # easier to calculate expected results. rsun = 1*u.m D0 = 1*u.km L0 = 1*u.deg observer_in = HeliographicStonyhurst(lat=0*u.deg, lon=0*u.deg, radius=D0) observer_out = HeliographicStonyhurst(lat=0*u.deg, lon=L0, radius=D0) hpc_in = Helioprojective(0*u.arcsec, 0*u.arcsec, rsun=rsun, observer=observer_in) hpc_out = Helioprojective(observer=observer_out, rsun=rsun) hpc_new = hpc_in.transform_to(hpc_out) assert hpc_new.observer == hpc_out.observer # Calculate the distance subtended by an angle of L0 from the centre of the # Sun. dd = -1 * rsun * np.tan(L0) # Calculate the angle corresponding to that distance as seen by the new # observer. theta = np.arctan2(dd, (D0 - rsun)) assert quantity_allclose(theta, hpc_new.Tx, rtol=1e-3)
def test_hpc_to_hcc_different_observer(): # This test checks transformation HPC->HCC in the case where the HCC and HPC frames are # defined by different observers. # NOTE: This test is currently expected to fail because the HCC<->HPC transformation does # not account for observer location. It will be updated once this is fixed. D0 = 1 * u.km L0 = 1 * u.deg observer_1 = HeliographicStonyhurst(lat=0 * u.deg, lon=0 * u.deg, radius=D0) observer_2 = HeliographicStonyhurst(lat=0 * u.deg, lon=L0, radius=D0) hcc_frame = Heliocentric(observer=observer_1) hpc_frame = Helioprojective(observer=observer_2) hpccoord = SkyCoord(Tx=0 * u.arcsec, Ty=0 * u.arcsec, frame=hpc_frame) with pytest.raises(ConvertError): hpccoord.transform_to(hcc_frame)
def test_hpc_to_hcc_different_observer(): # This test checks transformation HPC->HCC in the case where the HCC and HPC frames are # defined by different observers. rsun = 1*u.m D0 = 1*u.km L0 = 1*u.deg observer_1 = HeliographicStonyhurst(lat=0*u.deg, lon=0*u.deg, radius=D0) observer_2 = HeliographicStonyhurst(lat=0*u.deg, lon=L0, radius=D0) hcc_frame = Heliocentric(observer=observer_1) hpc_frame = Helioprojective(observer=observer_2, rsun=rsun) hpccoord = SkyCoord(Tx=0*u.arcsec, Ty=0*u.arcsec, frame=hpc_frame) hcccoord_out = hpccoord.transform_to(hcc_frame) hcccoord_expected = hpccoord.transform_to(HeliographicStonyhurst).transform_to(hcc_frame) assert_quantity_allclose(hcccoord_out.x, hcccoord_expected.x) assert_quantity_allclose(hcccoord_out.y, hcccoord_expected.y) assert_quantity_allclose(hcccoord_out.z, hcccoord_expected.z)
def test_hcc_to_hpc_different_observer(): # This test checks transformation HCC->HPC in the case where the HCC and HPC frames are # defined by different observers. rsun = 1*u.m D0 = 1*u.km L0 = 1*u.deg observer_1 = HeliographicStonyhurst(lat=0*u.deg, lon=0*u.deg, radius=D0) observer_2 = HeliographicStonyhurst(lat=0*u.deg, lon=L0, radius=D0) hcc_frame = Heliocentric(observer=observer_1) hpc_frame = Helioprojective(observer=observer_2) hcccoord = SkyCoord(x=rsun, y=rsun, z=rsun, frame=hcc_frame) hpccoord_out = hcccoord.transform_to(hpc_frame) hpccoord_expected = hcccoord.transform_to(HeliographicStonyhurst).transform_to(hpc_frame) assert_quantity_allclose(hpccoord_out.Tx, hpccoord_expected.Tx) assert_quantity_allclose(hpccoord_out.Ty, hpccoord_expected.Ty) assert_quantity_allclose(hpccoord_out.distance, hpccoord_expected.distance)
def test_hpc_hpc_sc(): # Use some unphysical values for solar parameters for testing, to make it # easier to calculate expected results. rsun = 1*u.m D0 = 1*u.km L0 = 1*u.deg observer_in = HeliographicStonyhurst(lat=0*u.deg, lon=0*u.deg, radius=D0) observer_out = HeliographicStonyhurst(lat=0*u.deg, lon=L0, radius=D0) sc_in = SkyCoord(0*u.arcsec, 0*u.arcsec, rsun=rsun, observer=observer_in, frame='helioprojective') hpc_out = Helioprojective(observer=observer_out, rsun=rsun) hpc_new = sc_in.transform_to(hpc_out) assert hpc_new.observer.lat == hpc_out.observer.lat assert hpc_new.observer.lon == hpc_out.observer.lon assert hpc_new.observer.radius == hpc_out.observer.radius
def corners(observer): hpc_frame = Helioprojective(observer=observer, obstime=observer.obstime) blc = SkyCoord(-150 * u.arcsec, -150 * u.arcsec, frame=hpc_frame) trc = SkyCoord(150 * u.arcsec, 150 * u.arcsec, frame=hpc_frame) return blc, trc
output, _ = reproject_interp(aia_map, out_wcs, out_shape) outmap_default = sunpy.map.Map((output, out_header)) outmap_default.plot_settings = aia_map.plot_settings plt.figure() plt.subplot(projection=outmap_default) outmap_default.plot() ###################################################################### # You can use the different assumption that the image lies on the # surface of a spherical screen centered at AIA, with a radius equal # to the Sun-AIA distance. The curvature of the spherical screen is # not obvious in this plot due to the relatively small field of view # of AIA (compared to, say, a coronagraph). with Helioprojective.assume_spherical_screen(aia_map.observer_coordinate): output, _ = reproject_interp(aia_map, out_wcs, out_shape) outmap_screen_all = sunpy.map.Map((output, out_header)) outmap_screen_all.plot_settings = aia_map.plot_settings plt.figure() plt.subplot(projection=outmap_screen_all) outmap_screen_all.plot() ###################################################################### # Finally, you can specify that the spherical-screen assumption should # be used for only off-disk parts of the image, and continue to map # on-disk parts of the image to the surface of the Sun. with Helioprojective.assume_spherical_screen(aia_map.observer_coordinate, only_off_disk=True):
from sunpy.coordinates import Helioprojective, propagate_with_solar_surface from sunpy.data.sample import AIA_171_IMAGE ############################################################################## # First, load an AIA observation. aiamap = sunpy.map.Map(AIA_171_IMAGE) in_time = aiamap.date ############################################################################## # Let's define the output frame to be five days in the future for an observer # at Earth (i.e., about five degrees offset in heliographic longitude compared # to the location of AIA in the original observation). out_time = in_time + 5*u.day out_frame = Helioprojective(observer='earth', obstime=out_time, rsun=aiamap.coordinate_frame.rsun) ############################################################################## # Construct a WCS object for the output map. If one has an actual ``Map`` # object at the desired output time (e.g., the actual AIA observation at the # output time), one can use the WCS object from that ``Map`` object (e.g., # ``mymap.wcs``) instead of constructing a custom WCS. out_center = SkyCoord(0*u.arcsec, 0*u.arcsec, frame=out_frame) header = sunpy.map.make_fitswcs_header(aiamap.data.shape, out_center, scale=u.Quantity(aiamap.scale)) out_wcs = WCS(header) ############################################################################## # Reproject the map from the input frame to the output frame. We use the
from sunpy.coordinates import Helioprojective, RotatedSunFrame, transform_with_sun_center from sunpy.data.sample import AIA_171_IMAGE ############################################################################## # First, load an AIA observation. aiamap = sunpy.map.Map(AIA_171_IMAGE) in_time = aiamap.date ############################################################################## # Let's define the output frame to be five days in the future for an observer # at Earth (i.e., about five degrees offset in heliographic longitude compared # to the location of AIA in the original observation). out_time = in_time + 5 * u.day out_frame = Helioprojective(observer='earth', obstime=out_time) ############################################################################## # For the reprojection, the definition of the target frame can be # counter-intuitive. We will be transforming from the original frame to the # `~sunpy.coordinates.metaframes.RotatedSunFrame` version of the output frame # with ``rotated_time`` set to the time of the original frame. rot_frame = RotatedSunFrame(base=out_frame, rotated_time=in_time) print(rot_frame) ############################################################################## # Construct a WCS object for the output map with the target # ``RotatedSunHelioprojective`` frame specified instead of the regular # `~sunpy.coordinates.frames.Helioprojective` frame. # If one has an actual ``Map`` object at the desired output