Пример #1
0
def test_solar_rotate_coordinate():
    # Testing along the Sun-Earth line, observer is on the Earth
    obs_time = '2010-09-10 12:34:56'
    observer = get_earth(obs_time)
    c = SkyCoord(-570 * u.arcsec,
                 120 * u.arcsec,
                 obstime=obs_time,
                 observer=observer,
                 frame=frames.Helioprojective)
    new_time = '2010-09-11 12:34:56'
    new_observer = get_earth(new_time)

    # Test that when both the observer and the time are specified, an error is raised.
    with pytest.raises(ValueError):
        d = solar_rotate_coordinate(c, observer=observer, time=new_time)

    # Test that the code properly filters the observer keyword
    with pytest.raises(ValueError):
        d = solar_rotate_coordinate(c, observer='earth')

    # Test that the code properly filters the time keyword
    with pytest.raises(ValueError):
        with pytest.warns(
                UserWarning,
                match="Using 'time' assumes an Earth-based observer"):
            d = solar_rotate_coordinate(c, time='noon')

    # Test that the code gives the same output for multiple different inputs
    # that define the same observer location and time.
    for i, definition in enumerate(
        (1 * u.day, TimeDelta(1 * u.day), new_time, new_observer)):
        if i in (0, 1, 2):
            with pytest.warns(
                    UserWarning,
                    match="Using 'time' assumes an Earth-based observer"):
                d = solar_rotate_coordinate(c, time=definition)
        else:
            d = solar_rotate_coordinate(c, observer=definition)

        # Test that a SkyCoordinate is created
        assert isinstance(d, SkyCoord)

        # Test the coordinate
        np.testing.assert_almost_equal(d.Tx.to(u.arcsec).value,
                                       -371.8885208634674,
                                       decimal=1)
        np.testing.assert_almost_equal(d.Ty.to(u.arcsec).value,
                                       105.35006656251727,
                                       decimal=1)
        np.testing.assert_allclose(d.distance.to(u.km).value,
                                   1.499642e+08,
                                   rtol=1e-5)

        # Test that the SkyCoordinate is Helioprojective
        assert isinstance(d.frame, frames.Helioprojective)
Пример #2
0
def track_ROI(init_submap, fullmap):
    """
    :param init_submap: Subregion of map to crop
    :param fullmap: Map that is to be cropped
    :return: New coordinates for new map
    """
    from sunpy.physics.differential_rotation import solar_rotate_coordinate

    # Subtract Time of current map to previous map
    rotated_coord = solar_rotate_coordinate(init_submap.center, fullmap.date)
    dlon = rotated_coord.Tx - init_submap.center.Tx
    dlat = rotated_coord.Ty - init_submap.center.Ty

    # Get new coordinates for box
    bl_new_lon = init_submap.bottom_left_coord.Tx + dlon
    bl_new_lat = init_submap.bottom_left_coord.Ty + dlat
    tr_new_lon = init_submap.top_right_coord.Tx + dlon
    tr_new_lat = init_submap.top_right_coord.Ty + dlat

    # Return the new box coordinates
    new_coords = [
        bl_new_lon,
        tr_new_lon,
        bl_new_lat,
        tr_new_lat,
    ]  # These are on arcsec quantities!
    return new_coords
Пример #3
0
def test_solar_rotate_coordinate():
    # Testing along the Sun-Earth line, observer is on the Earth
    obstime = '2010-09-10 12:34:56'
    newtime = '2010-09-10 13:34:56'
    c = SkyCoord(-570*u.arcsec, 120*u.arcsec, obstime=obstime, observer=get_earth(obstime),
                 frame=frames.Helioprojective)
    d = solar_rotate_coordinate(c, newtime)

    # Test that a SkyCoordinate is created
    assert isinstance(d, SkyCoord)

    # Test the coordinate
    np.testing.assert_almost_equal(d.Tx.to(u.arcsec).value, -562.3768, decimal=1)
    np.testing.assert_almost_equal(d.Ty.to(u.arcsec).value, 119.2684, decimal=1)
    np.testing.assert_almost_equal(d.distance.to(u.km).value, 150083151.97246578, decimal=1)

    # Test that the SkyCoordinate is Helioprojective
    assert isinstance(d.frame, frames.Helioprojective)

    # Test the observer
    assert d.observer.obstime == Time(parse_time(newtime), scale='utc')
    np.testing.assert_almost_equal(d.observer.lon.to(u.deg).value, 0.0, decimal=5)
    np.testing.assert_almost_equal(d.observer.lat.to(u.deg).value, 7.248, decimal=3)
    np.testing.assert_almost_equal(d.observer.radius.to(u.AU).value, 1.006954, decimal=6)
    assert isinstance(d.observer, frames.HeliographicStonyhurst)
def test_solar_rotate_coordinate():
    # Testing along the Sun-Earth line, observer is on the Earth
    obstime = '2010-09-10 12:34:56'
    newtime = '2010-09-10 13:34:56'
    c = SkyCoord(-570*u.arcsec, 120*u.arcsec, obstime=obstime, observer=get_earth(obstime),
                 frame=frames.Helioprojective)
    d = solar_rotate_coordinate(c, newtime)

    # Test that a SkyCoordinate is created
    assert isinstance(d, SkyCoord)

    # Test the coordinate
    np.testing.assert_almost_equal(d.Tx.to(u.arcsec).value, -562.3768, decimal=1)
    np.testing.assert_almost_equal(d.Ty.to(u.arcsec).value, 119.2684, decimal=1)
    np.testing.assert_almost_equal(d.distance.to(u.km).value, 150083151.97246578, decimal=1)

    # Test that the SkyCoordinate is Helioprojective
    assert isinstance(d.frame, frames.Helioprojective)

    # Test the observer
    assert d.observer.obstime == Time(parse_time(newtime), scale='utc')
    np.testing.assert_almost_equal(d.observer.lon.to(u.deg).value, 0.0, decimal=5)
    np.testing.assert_almost_equal(d.observer.lat.to(u.deg).value, 7.248, decimal=3)
    np.testing.assert_almost_equal(d.observer.radius.to(u.AU).value, 1.006954, decimal=6)
    assert isinstance(d.observer, frames.HeliographicStonyhurst)
Пример #5
0
def track_arcsec(refmap, fullmap):
    """
    By Alexander James (UCL)
    Given a cropped reference map, will return the im cropped in a way that
    tracks solar rotation.
    Example:
        refmap = sunpy.map.Map(sfiles[0])
        bottomleft_ref = [-500*u.arcsec, -600*u.arcsec]
        topright_ref   = [0*u.arcsec, -200*u.arcsec]
        refmap = alexpy.submap(refmap, bottomleft_ref, topright_ref)
        fullmap = (sunpy.map.Map(sfile))
        fullmap = track_arcsec(refmap, fullmap)
    """
    from sunpy.physics.differential_rotation import solar_rotate_coordinate
    from astropy.coordinates import SkyCoord

    # Subtract Time of current map to previous map
    rotated_coord = solar_rotate_coordinate(refmap.center, fullmap.date)
    dlon = rotated_coord.Tx - refmap.center.Tx
    dlat = rotated_coord.Ty - refmap.center.Ty
    # Get new coordinated for box
    bl_new_lon = refmap.bottom_left_coord.Tx + dlon
    bl_new_lat = refmap.bottom_left_coord.Ty + dlat
    tr_new_lon = refmap.top_right_coord.Tx + dlon
    tr_new_lat = refmap.top_right_coord.Ty + dlat
    # Make new coordinates into new coord frame
    bl_new = SkyCoord(bl_new_lon, bl_new_lat, frame=fullmap.coordinate_frame)
    tr_new = SkyCoord(tr_new_lon, tr_new_lat, frame=fullmap.coordinate_frame)
    # Crop map to new location
    fullmap = fullmap.submap(bl_new, tr_new)
    # Give new, fixed map
    return fullmap
Пример #6
0
def rotate_SS(x_pos, y_pos, time1, time2):
    # Rotate centroid of SS for given times
    """Rotates centroid of a sunspot for given times

    Parameters
    -----------
    x_pos, y_pos = centroid coordinates in pixel
    
    time1, time2 = datetime objects that indicate time of x_pos, y_pos (time1)
                   and time to rotate sunspot to (time2)

    Returns
    -----------
    new_x, new_y = estimated centroid position at time2 for sunspot

    -----------------------------------------------------------------

    """
    lon, lat = pixels_to_latlon(x_pos, y_pos)  # convert to latlon

    hgx = astropy.units.Quantity(lon - 90., astropy.units.deg)
    hgy = astropy.units.Quantity(lat - 90., astropy.units.deg)

    start_coord = SkyCoord(hgx,
                           hgy,
                           frame=frames.HeliographicStonyhurst,
                           obstime=time1)
    rotated_coord = solar_rotate_coordinate(start_coord, time2)

    new_lat = rotated_coord.lat.value + 90.
    new_lon = rotated_coord.lon.value + 90.

    new_x, new_y = latlon_to_pixels(new_lon, new_lat)

    return new_x, new_y
Пример #7
0
def map_rot_correct(mmap,refx,refy,reftime):
    """
    Correct the solar rotation.
    
    Parameters
    ----------
    mmap : sunpy.map.GenericMap
        Single map class.
    refx : astropy.units.Quantity
        Horizontal wcs information of reference frame.
    refy : astropy.units.Quantity
        Vertical wcs information of reference frame.
    reftime : astropy.time.Time
        Time for the reference frame.
    
    Returns
    -------
    smap : sunpy.map.GenericMap
        Solar rotation corrected map class.
    
    """
    
    refc = SkyCoord(refx, refy, obstime= reftime,
                    observer= get_earth(reftime),
                    frame= frames.Helioprojective)
    
    date = mmap.date
    res = solar_rotate_coordinate(refc, date ,frame_time= 'synodic')
    x = res.Tx.value
    y = res.Ty.value
    
    sx = x - refx.value
    sy = y - refy.value
    smap = mmap.shift(-sx,-sy)
    return smap
Пример #8
0
def test_consistency_with_rotatedsunframe():
    old_observer = frames.HeliographicStonyhurst(10 * u.deg,
                                                 20 * u.deg,
                                                 1 * u.AU,
                                                 obstime='2001-01-01')
    new_observer = frames.HeliographicStonyhurst(30 * u.deg,
                                                 40 * u.deg,
                                                 2 * u.AU,
                                                 obstime='2001-01-08')

    hpc_coord = SkyCoord(100 * u.arcsec,
                         200 * u.arcsec,
                         frame='helioprojective',
                         observer=old_observer,
                         obstime=old_observer.obstime)

    # Perform the differential rotation using solar_rotate_coordinate()
    result1 = solar_rotate_coordinate(hpc_coord, observer=new_observer)

    # Perform the differential rotation using RotatedSunFrame, with translational motion of the Sun
    # ignored using transform_with_sun_center()
    rsf_coord = RotatedSunFrame(base=hpc_coord,
                                rotated_time=new_observer.obstime)
    with transform_with_sun_center():
        result2 = rsf_coord.transform_to(result1.replicate_without_data())

    assert_quantity_allclose(result1.Tx, result2.Tx)
    assert_quantity_allclose(result1.Ty, result2.Ty)
    assert_quantity_allclose(result1.distance, result2.distance)
Пример #9
0
def rotate_coord(map, coord, date):
    coord_sc = SkyCoord([(float(v[1]), float(v[0])) * u.deg
                         for v in np.array(coord)],
                        obstime=date,
                        frame=frames.HeliographicCarrington)
    coord_sc = coord_sc.transform_to(frames.Helioprojective)
    rotated_coord_sc = solar_rotate_coordinate(coord_sc, map.date)

    px = map.world_to_pixel(rotated_coord_sc)
    return [(int(px.x[i].value), int(px.y[i].value)) for i in range(len(px.x))]
Пример #10
0
    def sub_window(self):
        #3 color image
        if self.color3:
            self.scale = [self.img.scale[0].value,
                          self.img.scale[1].value]  # get x, y image scale
        #single color image
        else:
            self.scale = [self.img.scale[0].value,
                          self.img.scale[1].value]  # get x, y image scale

        #if rotation set get modify cx and cy values
        if self.rotation:
            #make rotation stable across different sunpy version
            #try:
            #    from sunpy.physics.differential_rotation import rot_hpc
            #except ImportError:
            #forcing sunpy > 8.0
            from sunpy.physics.differential_rotation import solar_rotate_coordinate
            #use astropy SkyCoord
            from astropy.coordinates import SkyCoord
            #get frame for coordiantes
            from sunpy.coordinates import frames
            import astropy.units as u

            #create Sky Coord class with intial values
            c = SkyCoord(self.cx * u.arcsec,
                         self.cy * u.arcsec,
                         obstime=self.rot_time,
                         frame=frames.Helioprojective)
            #rotate start points
            nc = solar_rotate_coordinate(c, self.obs_time)
            #update with new rotation values
            self.cx, self.cy = nc.Tx.value, nc.Ty.value

        #set new plot limits
        #flip x and y values if h0>w0
        if self.flip_image:
            self.xlim = [
                self.cy - (self.scale[0] * self.w0 / 2.),
                self.cy + (self.scale[0] * self.w0 / 2.)
            ]
            self.ylim = [
                self.cx - (self.scale[1] * self.h0 / 2.),
                self.cx + (self.scale[1] * self.h0 / 2.)
            ]
        else:
            self.xlim = [
                self.cx - (self.scale[0] * self.w0 / 2.),
                self.cx + (self.scale[0] * self.w0 / 2.)
            ]
            self.ylim = [
                self.cy - (self.scale[1] * self.h0 / 2.),
                self.cy + (self.scale[1] * self.h0 / 2.)
            ]
Пример #11
0
def rot_hpc(xs, ys, start, end, rot_type='meaningless'):
    #xs, ys = calc_poly_values(coor)
    #update deprecated function J. Prchlik 2017/11/03
    c = SkyCoord(xs, ys, obstime=start, frame=frames.Helioprojective)
    #rotate start points to end time
    nc = solar_rotate_coordinate(c, end)

    #split into x and y
    rotx, roty = nc.Tx, nc.Ty

    #return rotated coordinates
    return rotx, roty
Пример #12
0
def test_solar_rotate_coordinate():
    # Testing along the Sun-Earth line, observer is on the Earth
    obs_time = '2010-09-10 12:34:56'
    observer = get_earth(obs_time)
    c = SkyCoord(-570*u.arcsec, 120*u.arcsec, obstime=obs_time, observer=observer, frame=frames.Helioprojective)
    new_time = '2010-09-11 12:34:56'
    new_observer = get_earth(new_time)

    # Test that when both the observer and the time are specified, an error is raised.
    with pytest.raises(ValueError):
        d = solar_rotate_coordinate(c, observer=observer, time=new_time)

    # Test that the code properly filters the observer keyword
    with pytest.raises(ValueError):
        d = solar_rotate_coordinate(c, observer='earth')

    # Test that the code properly filters the time keyword
    with pytest.raises(ValueError):
        d = solar_rotate_coordinate(c, time='noon')

    # Test that the code gives the same output for multiple different inputs
    # that define the same observer location and time.
    for i, definition in enumerate((1 * u.day, TimeDelta(1*u.day), new_time, new_observer)):
        if i in (0, 1, 2):
            d = solar_rotate_coordinate(c, time=definition)
        else:
            d = solar_rotate_coordinate(c, observer=definition)

        # Test that a SkyCoordinate is created
        assert isinstance(d, SkyCoord)

        # Test the coordinate
        np.testing.assert_almost_equal(d.Tx.to(u.arcsec).value, -371.8885208634674, decimal=1)
        np.testing.assert_almost_equal(d.Ty.to(u.arcsec).value, 105.35006656251727, decimal=1)
        np.testing.assert_allclose(d.distance.to(u.km).value, 1.499642e+08, rtol=1e-5)

        # Test that the SkyCoordinate is Helioprojective
        assert isinstance(d.frame, frames.Helioprojective)
Пример #13
0
def astro_track_ROI(ref_map, newmap, observer, large_roi):
    """
    This is a knock-off version to calculate movement for a given amount of time. Use SUNPY?
    :param ref_map: Subregion of map to crop
    :param newmap: Map that is to be cropped
    :param large_roi: Large roi_ref
    :return: New coordinates for new map
    """
    import datetime
    from sunpy.physics.differential_rotation import solar_rotate_coordinate
    from astropy.coordinates import SkyCoord

    t_ref = datetime.datetime.strptime(ref_map.fits_header["DATE-OBS"],
                                       "%Y-%m-%dT%H:%M:%S.%f")
    t_new = datetime.datetime.strptime(newmap.fits_header["DATE-OBS"],
                                       "%Y-%m-%dT%H:%M:%S.%f")

    x_0 = large_roi[0]
    x_f = large_roi[1]
    y_0 = large_roi[2]
    y_f = large_roi[3]

    dx = x_f - x_0
    dy = y_f - y_0

    center_x, center_y = dx / 2 + x_0, dy / 2 + y_0
    start_coord = SkyCoord(center_x,
                           center_y,
                           frame="helioprojective",
                           obstime=t_ref,
                           observer=observer)
    rotated_center = solar_rotate_coordinate(start_coord, time=t_new)

    new_coords = [
        rotated_center.Tx - dx / 2,
        rotated_center.Tx + dx / 2,
        rotated_center.Ty - dy / 2,
        rotated_center.Ty + dy / 2,
    ]
    return new_coords
Пример #14
0
##############################################################################
# Let's define how many days in the future we want to rotate to.

dt = TimeDelta(4 * u.day)
future_date = aia_map.date + dt

##############################################################################
# Now let's plot the original and rotated positions on the AIA map.

fig = plt.figure()
ax = fig.add_subplot(projection=aia_map)
aia_map.plot(axes=ax, clip_interval=(1, 99.99) * u.percent)
ax.set_title('The effect of {} days of differential rotation'.format(
    dt.to(u.day).value))
aia_map.draw_grid(axes=ax)

for this_hpc_x, this_hpc_y in zip(hpc_x, hpc_y):
    start_coord = SkyCoord(this_hpc_x,
                           this_hpc_y,
                           frame=aia_map.coordinate_frame)
    rotated_coord = solar_rotate_coordinate(start_coord, time=future_date)
    coord = SkyCoord([start_coord.Tx, rotated_coord.Tx],
                     [start_coord.Ty, rotated_coord.Ty],
                     frame=aia_map.coordinate_frame)
    ax.plot_coord(coord, 'o-')
ax.set_ylim(0, aia_map.data.shape[1])
ax.set_xlim(0, aia_map.data.shape[0])

plt.show()
Пример #15
0
def calculate_solar_rotate_shift(mc, layer_index=0, **kwargs):
    """
    Calculate the shift that must be applied to each map contained in a mapcube
    in order to compensate for solar rotation.

    The center of the map is used to calculate the position of each mapcube
    layer. Shifts are calculated relative to a specified layer in the mapcube.
    When using this functionality, it is a good idea to check that the shifts
    that were applied to were reasonable and expected. One way of checking this
    is to animate the original mapcube, animate the derotated mapcube, and
    compare the differences you see to the calculated shifts. An example use is
    as follows. If you select data from the SDO cutout service, it is common to
    not use the solar tracking implemented by this service. This is because (at
    time of writing) the solar tracking implemented by that service moves the
    image by single pixels at a time. This is not optimal for many use cases,
    as it introduces artificial jumps in the data. So with solar tracking not
    chosen, the selected area is like a window through which you can see the
    Sun rotating underneath.

    Parameters
    ----------
    mc : `sunpy.map.MapCube`
        The input mapcube.
    layer_index : int
        The index layer.  Shifts are calculated relative to the time of
        this layer.
    ``**kwargs``
        These keywords are passed to the function
        `sunpy.physics.differential_rotation.solar_rotate_coordinate`.
    Returns
    -------
    x, y : `~astropy.units.Quantity`, ~astropy.units.Quantity`
        The shifts relative to the index layer that can be applied
        to the input mapcube in order to compensate for solar rotation.
        The shifts are given in arcseconds as understood in helioprojective
        coordinates systems.
    """
    # Size of the data
    nt = len(mc.maps)

    # Storage for the shifts in arcseconds
    xshift_arcseconds = np.zeros(nt) * u.arcsec
    yshift_arcseconds = np.zeros_like(xshift_arcseconds)

    # Layer that
    rotate_to_this_layer = mc.maps[layer_index]

    # Calculate the rotations and the shifts
    for i, m in enumerate(mc):
        # Calculate the rotation of the center of the map 'm' at its
        # observation time to the observation time of the reference layer
        # indicated by "layer_index".
        new_coordinate = solar_rotate_coordinate(
            m.center,
            rotate_to_this_layer.date,
            new_observer_location=rotate_to_this_layer.observer_coordinate,
            **kwargs)

        # Calculate the shift in arcseconds
        xshift_arcseconds[
            i] = new_coordinate.Tx - rotate_to_this_layer.center.Tx
        yshift_arcseconds[
            i] = new_coordinate.Ty - rotate_to_this_layer.center.Ty

    return {"x": xshift_arcseconds, "y": yshift_arcseconds}
	PRINTER.display_item("Initial time", INIT_TIME)

	#########################

	INIT_LOC = SkyCoord(INIT_COORD.Tx,
						INIT_COORD.Ty,
						obstime = INIT_TIME,
						observer = get_earth(INIT_TIME),
						frame = frames.Helioprojective)

	PRINTER.display_item("Initial location", "(%s arcsec, %s arcsec)" % (INIT_LOC.Tx, INIT_LOC.Ty))

	#########################

	PRINTER.info_text("Calculating future coordinates")
	LOCS = [solar_rotate_coordinate(INIT_LOC, MAPCUBE[i].date) for i in range(len(MAPCUBE))]

#########################

if ask_to_change_default_settings:

	if(PRINTER.input_text("Use default settings (low scale 0, high scale 40000)? [y/n]") == "n"):
		default_low_scale = int(PRINTER.input_text("Enter low scale"))
		default_high_scale = int(PRINTER.input_text("Enter high scale"))

#########################

if not only_fulldisk_images:

	if not auto_sel:
		coord1 = MAPCUBE[0].pixel_to_world(x1, y1)
Пример #17
0
##############################################################################
# Now let's get the boundary of the coronal hole

ch = responses[response_index]
p1 = ch["hpc_boundcc"][9:-2]
p2 = p1.split(',')
p3 = [v.split(" ") for v in p2]
ch_date = parse_time(ch['event_starttime'])

##############################################################################
# The coronal hole was detected at a certain time.  To plot it on a map, we
# need to rotate it to the map observation time.

ch_boundary = SkyCoord(
    [(float(v[0]), float(v[1])) * u.arcsec for v in p3],
    obstime=ch_date,
    frame=frames.Helioprojective)
rotated_ch_boundary = solar_rotate_coordinate(ch_boundary, aia_map.date)

##############################################################################
# Now let's plot the rotated coronal hole boundary on the AIA map, and fill
# it with some matplotlib hatching.

fig = plt.figure()
ax = plt.subplot(projection=aia_map)
aia_map.plot(axes=ax)
ax.plot_coord(rotated_ch_boundary, color='c')
ax.set_title('{:s}\n{:s}'.format(aia_map.name, ch['frm_specificid']))
plt.colorbar()
plt.show()
Пример #18
0
    def plot_rotation(self,
                      start,
                      coor,
                      dh=0,
                      color='teal',
                      linestyle='-',
                      alpha=1.0,
                      ids=None):
        """
        plot_rotation overplots a h alpha filament track accounting for solar roation

        The function plot_rotation uses the current image time to correct the track observation time for solar rotation.
        To correct for rotation the function uses the solar_rotation module from sunpy

        Parameters
        ----------
        start: datetime object
            start is the observed time of the track.
        coor : str
            coor is the polygon string for the track's shape.
        dh   : datetime object
            dh is deprecated, thus no longer used by plot_rotation (default = 0)
        color: str
            color is the numpy string color to used for outlining the track (default = 'red').
        linestyle: str
            linstyle is the matplotlib string to use for the line (default = '-')
        alpha: float
            alpha is the opacity of the line to plot (default = 0.5, range = [0.0,1.0])

        Returns
        -------
        self
       
        """

        xs, ys = self.calc_poly_values(coor)
        #calculate the mean position
        #stopx, stopy = solar_rotation.rot_hpc(xs*u.arcsec,ys*u.arcsec,start,self.stop)
        #update deprecated function J. Prchlik 2017/11/03
        c = SkyCoord(xs * u.arcsec,
                     ys * u.arcsec,
                     obstime=start,
                     frame=frames.Helioprojective)
        #rotate start points to end time
        nc = solar_rotate_coordinate(c, self.stop)

        #get rid of units
        stopx, stopy = nc.Tx.value, nc.Ty.value

        self.ax.plot(stopx,
                     stopy,
                     linestyle=linestyle,
                     color=color,
                     zorder=500,
                     alpha=alpha,
                     linewidth=3)
        self.ax.text(np.mean(stopx),
                     np.max(stopy),
                     str(ids),
                     alpha=1.,
                     color=color,
                     fontweight='bold')
Пример #19
0
def update_fiss_header(file,alignfile,**kwargs):
    """
    Create the new FISS data with update header.
    
    Parameters
    ----------
    file : list
        FISS fts file list
    alignfile : str
        Aligned information binary (.npz) file.
    sil : (optional) bool
        If False, it print the ongoing time index.
            * Default is True.
    sol_rot : (optional) bool
        If True, correct the solar rotation when update the file header.
            * Default is False.
        
    Returns
    -------
    mfts : file
        List of files which updated the header.
        
    Notes
    -----
        Name of saved fits data file is added 'm' to 
        the first character of original data name.
    """
    sil=kwargs.pop('sil',False)
    sol_rot=kwargs.pop('sol_rot',False)
    
    if not sil:
        print('Add the align information to the haeder.')
    level=alignfile[-8:-4]
    inform=np.load(alignfile)
    fissht=[getheader(i) for i in file]
    fissh=[fits.getheader(i) for i in file]
    tlist=[i['date'] for i in fissht]
    
    time=Time(tlist,format='isot',scale='ut1')
    angle=inform['angle']
    ny=fissht[0]['naxis2']
    nx=fissht[0]['naxis3']
    x=np.array((0,nx-1,nx-1,0))
    y=np.array((0,0,ny-1,ny-1))
    xc=inform['xc'].item()
    yc=inform['yc'].item()
    dx=inform['dx']
    dy=inform['dy']
    
    xt1,yt1=rot_trans(x,y,xc,yc,angle.max())
    xt2,yt2=rot_trans(x,y,xc,yc,angle.min())
    
    tmpx=np.concatenate((xt1,xt2))
    tmpy=np.concatenate((yt1,yt2))
    
    xmargin=int(np.abs(np.round(tmpx.min()+dx.min())))+1
    ymargin=int(np.abs(np.around(tmpy.min()+dy.min())))+1
    
    if level=='lev0':
        for i,h in enumerate(fissh):
            h['alignl']=(0,'Alignment level')
            h['reflect']=(False,'Mirror reverse')
            h['reffr']=(inform['reffr'].item(),'Reference frame in alignment')
            h['reffi']=(inform['reffi'].item(),'Reference file name in alignment')
            h['cdelt2']=(0.16,'arcsec per pixel')
            h['cdelt3']=(0.16,'arcsec per pixel')
            h['crota2']=(angle[i],
                        'Roation angle about reference pixel')
            h['crpix3']=(inform['xc'].item(),'Reference pixel in data axis 3')
            h['shift3']=(inform['dx'][i],
                        'Shifting pixel value along data axis 2')
            h['crpix2']=(inform['yc'].item(),'Reference pixel in data axis 2')
            h['shift2']=(inform['dy'][i],
                        'Shifting pixel value along data axis 3')
            h['margin2']=(ymargin,'Rotation margin in axis 2')
            h['margin3']=(xmargin,'Rotation margin in axis 3')
            
            h['history']='FISS aligned (lev0)'
    elif level=='lev1':
        wcsx=inform['wcsx']
        wcsy=inform['wcsy']
        xref=wcsx*u.arcsec
        yref=wcsy*u.arcsec
        reffr=inform['reffr']
        for i,h in enumerate(fissh):
            if sol_rot:
                refc = SkyCoord(xref, yref, obstime = time[reffr],
                                observer= get_earth(time[reffr]),
                                frame= frames.Helioprojective)
                res = solar_rotate_coordinate(refc, time[i],
                                              frame_time= 'synodic')
                wcsx = res.Tx.value
                wcsy = res.Ty.value
                h['crval3']=(wcsx.value,
                            'Location of ref pixel x (arcsec)')
                h['crval2']=(wcsy.value,
                            'Location of ref pixel y (arcsec)')
            else:
                h['crval3']=(wcsx.item(),
                            'Location of ref pixel for ref frame x (arcsec)')
                h['crval2']=(wcsy.item(),
                            'Location of ref pixel for ref frame y (arcsec)')

            h['alignl']=(1,'Alignment level')
            h['reflect']=(inform['reflect'].item(),'Mirror reverse')
            h['reffr']=(inform['reffr'].item(),'Reference frame in alignment')
            h['reffi']=(inform['reffi'].item(),'Reference file name in alignment')
            h['cdelt2']=(0.16,'arcsec per pixel')
            h['cdelt3']=(0.16,'arcsec per pixel')
            h['crota1']=(inform['sdo_angle'].item(),
                        'Rotation angle of reference frame (radian)')
            h['crota2']=(inform['angle'][i],
                        'Rotation angle about reference pixel (radian)')
            h['crpix3']=(inform['xc'].item(),'Reference pixel in data axis 3')
            h['shift3']=(inform['dx'][i],
                        'Shifting pixel value along data axis 3')
            h['crpix2']=(inform['yc'].item(),'Reference pixel in data axis 2')

            h['shift2']=(inform['dy'][i],
                        'Shifting pixel value along data axis 2')
            h['margin2']=(ymargin,'Rotation margin in axis 2')
            h['margin3']=(xmargin,'Rotation margin in axis 3')
            h['srot']=(True,'Solar Rotation correction')
            h['history']='FISS aligned and matched wcs (lev1)'
    else:
        raise ValueError('The level of alignfile is neither lev0 or lev1.')
    
    data=[fits.getdata(i) for i in file]
    
    odirname=os.path.dirname(file[0])
    if not odirname:
        odirname=os.getcwd()
    dirname = os.path.join(odirname, 'match')
    
    try:
        os.mkdir(dirname)
    except:
        pass
    
    for i,oname in enumerate(file):
        name='m'+os.path.basename(oname)
        fits.writeto(os.path.join(dirname, name),data[i],fissh[i])
    try:
        pfilelist=[i['pfile'] for i in fissh]
        pfileset=set(pfilelist)
        for i in pfileset:
            copy2(os.path.join(odirname, i),os.path.join(dirname,i))
    except:
        pass
    
    if not sil:
        print("The align information is updated to the header, "
              "and new fts file is locate %s the file name is 'mFISS*.fts'"%dirname)
hpc_y = u.Quantity(np.arange(-700, 800, 100), u.arcsec)
hpc_x = np.zeros_like(hpc_y)

##############################################################################
# Let's define how many days in the future we want to rotate to

dt = timedelta(days=4)
future_date = aia_map.date + dt

##############################################################################
# Now let's plot the original and rotated positions on the AIA map.

fig = plt.figure()
ax = plt.subplot(projection=aia_map)
aia_map.plot()
ax.set_title('The effect of {0} days of differential rotation'.format(dt.days))
aia_map.draw_grid()

for this_hpc_x, this_hpc_y in zip(hpc_x, hpc_y):
    start_coord = SkyCoord(this_hpc_x, this_hpc_y, frame=aia_map.coordinate_frame)
    rotated_coord = solar_rotate_coordinate(start_coord, future_date)
    coord = SkyCoord([start_coord.Tx, rotated_coord.Tx],
                     [start_coord.Ty, rotated_coord.Ty],
                     frame=aia_map.coordinate_frame)
    ax.plot_coord(coord, 'o-')

plt.ylim(0, aia_map.data.shape[1])
plt.xlim(0, aia_map.data.shape[0])
plt.show()
Пример #21
0
        area = response['area_atdiskcenter']
        response_index = i

##############################################################################
# Next let's get the boundary of the coronal hole
ch = responses[response_index]
p1 = ch["hpc_boundcc"][9:-2]
p2 = p1.split(',')
p3 = [v.split(" ") for v in p2]
ch_date = parse_time(ch['event_starttime'])

##############################################################################
# The coronal hole was detected at different time than the AIA image was
# taken so we need to rotate it to the map observation time.
ch_boundary = SkyCoord([(float(v[0]), float(v[1])) * u.arcsec for v in p3],
                       obstime=ch_date,
                       observer="earth",
                       frame=frames.Helioprojective)
rotated_ch_boundary = solar_rotate_coordinate(ch_boundary, time=aia_map.date)

##############################################################################
# Now let's plot the rotated coronal hole boundary on the AIA map, and fill
# it with hatching.
fig = plt.figure()
ax = plt.subplot(projection=aia_map)
aia_map.plot(axes=ax, clip_interval=(1, 99.99) * u.percent)
ax.plot_coord(rotated_ch_boundary, color='c')
ax.set_title('{:s}\n{:s}'.format(aia_map.name, ch['frm_specificid']))
plt.colorbar()
plt.show()
Пример #22
0
def calculate_solar_rotate_shift(mc, layer_index=0, **kwargs):
    """
    Calculate the shift that must be applied to each map contained in a mapsequence
    in order to compensate for solar rotation.

    The center of the map is used to calculate the position of each mapsequence
    layer. Shifts are calculated relative to a specified layer in the mapsequence.
    When using this functionality, it is a good idea to check that the shifts
    that were applied to were reasonable and expected. One way of checking this
    is to animate the original mapsequence, animate the derotated mapsequence, and
    compare the differences you see to the calculated shifts. An example use is
    as follows. If you select data from the SDO cutout service, it is common to
    not use the solar tracking implemented by this service. This is because (at
    time of writing) the solar tracking implemented by that service moves the
    image by single pixels at a time. This is not optimal for many use cases,
    as it introduces artificial jumps in the data. So with solar tracking not
    chosen, the selected area is like a window through which you can see the
    Sun rotating underneath.

    Parameters
    ----------
    mc : `sunpy.map.MapSequence`
        The input mapsequence.
    layer_index : int
        The index layer.  Shifts are calculated relative to the time of
        this layer.
    ``**kwargs``
        These keywords are passed to the function
        `sunpy.physics.differential_rotation.solar_rotate_coordinate`.
    Returns
    -------
    x, y : `~astropy.units.Quantity`, ~astropy.units.Quantity`
        The shifts relative to the index layer that can be applied
        to the input mapsequence in order to compensate for solar rotation.
        The shifts are given in arcseconds as understood in helioprojective
        coordinates systems.
    """
    # Size of the data
    nt = len(mc.maps)

    # Storage for the shifts in arcseconds
    xshift_arcseconds = np.zeros(nt) * u.arcsec
    yshift_arcseconds = np.zeros_like(xshift_arcseconds)

    # Layer that
    rotate_to_this_layer = mc.maps[layer_index]

    # Calculate the rotations and the shifts
    for i, m in enumerate(mc):
        # Calculate the rotation of the center of the map 'm' at its
        # observation time to the observation time of the reference layer
        # indicated by "layer_index".
        new_coordinate = solar_rotate_coordinate(m.center,
                                                 observer=rotate_to_this_layer.observer_coordinate,
                                                 **kwargs)

        # Calculate the shift in arcseconds
        xshift_arcseconds[i] = new_coordinate.Tx - rotate_to_this_layer.center.Tx
        yshift_arcseconds[i] = new_coordinate.Ty - rotate_to_this_layer.center.Ty

    return {"x": xshift_arcseconds, "y": yshift_arcseconds}