Example #1
0
    def dsun(self):
        """The observer distance from the Sun."""
        dsun = self.meta.get('dsun_obs', None)

        if dsun is None:
            warnings.warn_explicit("Missing metadata for Sun-spacecraft separation: assuming Sun-Earth distance",
                                   Warning, __file__, inspect.currentframe().f_back.f_lineno)
            dsun = sun.sunearth_distance(self.date).to(u.m)

        return dsun
    def dsun(self, **kwargs):
        """
        The observer distance from the Sun.
        """
        dsun = self.meta.get('dsun_obs', None)

        if dsun is None:
            warnings.warn("Missing metadata for Sun-spacecraft separation: assuming Sun-Earth distance",
                                   Warning)
            dsun = sun.sunearth_distance(self.date).to(u.m)

        return u.Quantity(dsun, 'm')
Example #3
0
def test_sunearth_distance():
    assert_array_almost_equal(sun.sunearth_distance("2010/02/04"), 0.9858, decimal=4)
    assert_array_almost_equal(sun.sunearth_distance("2009/04/13"), 1.003, decimal=4)
    assert_array_almost_equal(sun.sunearth_distance("2008/06/20"), 1.016, decimal=4)
    assert_array_almost_equal(sun.sunearth_distance("2007/08/15"), 1.013, decimal=4)
    assert_array_almost_equal(sun.sunearth_distance("2007/10/02"), 1.001, decimal=4)
    assert_array_almost_equal(sun.sunearth_distance("2006/12/27"), 0.9834, decimal=4)
Example #4
0
    def dsun(self, **kwargs):
        """
        The observer distance from the Sun.
        """
        dsun = self.meta.get('dsun_obs', None)

        if dsun is None:
            warnings.warn(
                "Missing metadata for Sun-spacecraft separation: assuming Sun-Earth distance",
                Warning)
            dsun = sun.sunearth_distance(self.date).to(u.m)

        return u.Quantity(dsun, 'm')
Example #5
0
def backprojection(calibrated_event_list, pixel_size=(1.0, 1.0), image_dim=(64, 64)):
    """Given a stacked calibrated event list fits file create a back projection image."""
    import sunpy.sun.constants as sun
    from sunpy.sun.sun import angular_size
    from sunpy.sun.sun import sunearth_distance
    from sunpy.time.util import TimeRange

    calibrated_event_list = sunpy.RHESSI_EVENT_LIST
    fits = pyfits.open(calibrated_event_list)
    info_parameters = fits[2]
    xyoffset = info_parameters.data.field("USED_XYOFFSET")[0]
    time_range = TimeRange(info_parameters.data.field("ABSOLUTE_TIME_RANGE")[0])

    image = np.zeros(image_dim)

    # find out what detectors were used
    det_index_mask = fits[1].data.field("det_index_mask")[0]
    detector_list = (np.arange(9) + 1) * np.array(det_index_mask)
    for detector in detector_list:
        if detector > 0:
            image = image + _backproject(
                calibrated_event_list, detector=detector, pixel_size=pixel_size, image_dim=image_dim
            )

    dict_header = {
        "DATE-OBS": time_range.center().strftime("%Y-%m-%d %H:%M:%S"),
        "CDELT1": pixel_size[0],
        "NAXIS1": image_dim[0],
        "CRVAL1": xyoffset[0],
        "CRPIX1": image_dim[0] / 2 + 0.5,
        "CUNIT1": "arcsec",
        "CTYPE1": "HPLN-TAN",
        "CDELT2": pixel_size[1],
        "NAXIS2": image_dim[1],
        "CRVAL2": xyoffset[1],
        "CRPIX2": image_dim[0] / 2 + 0.5,
        "CUNIT2": "arcsec",
        "CTYPE2": "HPLT-TAN",
        "HGLT_OBS": 0,
        "HGLN_OBS": 0,
        "RSUN_OBS": angular_size(time_range.center()),
        "RSUN_REF": sun.radius,
        "DSUN_OBS": sunearth_distance(time_range.center()) * sunpy.sun.constants.au,
    }

    header = sunpy.map.MapHeader(dict_header)
    result_map = sunpy.map.BaseMap(image, header)

    return result_map
Example #6
0
def test_sunearth_distance():
    # Source for these values
    # wolframalpha.com
    # http://www.wolframalpha.com/input/?i=earth-sun+distance+on+2010%2F02%2F04
    assert_array_almost_equal(sun.sunearth_distance("2010/02/04"), 0.9858, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2009/04/13"), 1.003, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2008/06/20"), 1.016, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2007/08/15"), 1.013, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2007/10/02"), 1.001, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2006/12/27"), 0.9834, decimal=3)
Example #7
0
def test_sunearth_distance():
    # Source for these values
    # wolframalpha.com
    # http://www.wolframalpha.com/input/?i=earth-sun+distance+on+2010%2F02%2F04
    assert_array_almost_equal(sun.sunearth_distance("2010/02/04"), 0.9858 * u.AU, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2009/04/13"), 1.003 * u.AU, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2008/06/20"), 1.016 * u.AU, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2007/08/15"), 1.013 * u.AU, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2007/10/02"), 1.001 * u.AU, decimal=3)
    assert_array_almost_equal(sun.sunearth_distance("2006/12/27"), 0.9834 * u.AU, decimal=3)
Example #8
0
def test_sunearth_distance():
    # Source for these values
    # wolframalpha.com
    # http://www.wolframalpha.com/input/?i=earth-sun+distance+on+2010%2F02%2F04
    assert_quantity_allclose(sun.sunearth_distance("2010/02/04"), 0.9858 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2009/04/13"), 1.003 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2008/06/20"), 1.016 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2007/08/15"), 1.013 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2007/10/02"), 1.001 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2006/12/27"), 0.9834 * u.AU, atol=1e-3 * u.AU)
Example #9
0
def test_sunearth_distance():
    # Source for these values
    # wolframalpha.com
    # http://www.wolframalpha.com/input/?i=earth-sun+distance+on+2010%2F02%2F04
    assert_quantity_allclose(sun.sunearth_distance("2010/02/04"), 0.9858 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2009/04/13"), 1.003 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2008/06/20"), 1.016 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2007/08/15"), 1.013 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2007/10/02"), 1.001 * u.AU, atol=1e-3 * u.AU)
    assert_quantity_allclose(sun.sunearth_distance("2006/12/27"), 0.9834 * u.AU, atol=1e-3 * u.AU)
Example #10
0
def _dsunAtSoho(date, rad_d, rad_1au = None):
    """Determines the distance to the Sun from SOhO following
    d_{\sun,Object} =
            D_{\sun\earth} \frac{\tan(radius_{1au}[rad])}{\tan(radius_{d}[rad])}
    though tan x ~ x for x << 1
    d_{\sun,Object} =
            D_{\sun\eart} \frac{radius_{1au}[rad]}{radius_{d}[rad]}
    since radius_{1au} and radius_{d} are dividing each other we can use [arcsec]
    instead. 

    ---
    TODO: Does this apply just to observations on the same Earth-Sun line?
    If not it can be moved outside here.
    """
    if not rad_1au:
        rad_1au = sun.solar_semidiameter_angular_size(date)
    return  sun.sunearth_distance(date) * constants.au * (rad_1au / rad_d)
Example #11
0
def _dsunAtSoho(date, rad_d, rad_1au=None):
    """Determines the distance to the Sun from SOhO following
    d_{\sun,Object} =
            D_{\sun\earth} \frac{\tan(radius_{1au}[rad])}{\tan(radius_{d}[rad])}
    though tan x ~ x for x << 1
    d_{\sun,Object} =
            D_{\sun\eart} \frac{radius_{1au}[rad]}{radius_{d}[rad]}
    since radius_{1au} and radius_{d} are dividing each other we can use [arcsec]
    instead.

    ---
    TODO: Does this apply just to observations on the same Earth-Sun line?
    If not it can be moved outside here.
    """
    if not rad_1au:
        rad_1au = sun.solar_semidiameter_angular_size(date)
    dsun = sun.sunearth_distance(date) * constants.au * (rad_1au / rad_d)
    # return scalar value not astropy.quantity
    return dsun.value
Example #12
0
def backprojection(calibrated_event_list,
                   pixel_size=(1., 1.),
                   image_dim=(64, 64)):
    """
    Given a stacked calibrated event list fits file create a back 
    projection image.
    
    .. warning:: The image is not in the right orientation!

    Parameters
    ----------
    calibrated_event_list : string
        filename of a RHESSI calibrated event list
    detector : int
        the detector number
    pixel_size : 2-tuple
        the size of the pixels in arcseconds. Default is (1,1).
    image_dim : 2-tuple
        the size of the output image in number of pixels

    Returns
    -------
    out : RHESSImap
        Return a backprojection map.

    Examples
    --------
    >>> import sunpy.instr.rhessi as rhessi
    >>> map = rhessi.backprojection(sunpy.RHESSI_EVENT_LIST)
    >>> map.show()

    """

    calibrated_event_list = sunpy.RHESSI_EVENT_LIST
    afits = fits.open(calibrated_event_list)
    info_parameters = afits[2]
    xyoffset = info_parameters.data.field('USED_XYOFFSET')[0]
    time_range = TimeRange(
        info_parameters.data.field('ABSOLUTE_TIME_RANGE')[0])

    image = np.zeros(image_dim)

    #find out what detectors were used
    det_index_mask = afits[1].data.field('det_index_mask')[0]
    detector_list = (np.arange(9) + 1) * np.array(det_index_mask)
    for detector in detector_list:
        if detector > 0:
            image = image + _backproject(calibrated_event_list,
                                         detector=detector,
                                         pixel_size=pixel_size,
                                         image_dim=image_dim)

    dict_header = {
        "DATE-OBS": time_range.center().strftime("%Y-%m-%d %H:%M:%S"),
        "CDELT1": pixel_size[0],
        "NAXIS1": image_dim[0],
        "CRVAL1": xyoffset[0],
        "CRPIX1": image_dim[0] / 2 + 0.5,
        "CUNIT1": "arcsec",
        "CTYPE1": "HPLN-TAN",
        "CDELT2": pixel_size[1],
        "NAXIS2": image_dim[1],
        "CRVAL2": xyoffset[1],
        "CRPIX2": image_dim[0] / 2 + 0.5,
        "CUNIT2": "arcsec",
        "CTYPE2": "HPLT-TAN",
        "HGLT_OBS": 0,
        "HGLN_OBS": 0,
        "RSUN_OBS": solar_semidiameter_angular_size(time_range.center()),
        "RSUN_REF": sun.radius,
        "DSUN_OBS":
        sunearth_distance(time_range.center()) * sunpy.sun.constants.au
    }

    header = sunpy.map.MapHeader(dict_header)
    result_map = sunpy.map.Map(image, header)

    return result_map
Example #13
0
def simulate_raw(params, steps, verbose=False):
    """
    Simulate data in HG' coordinates
    
    HG' = HG, except center at wave epicenter
    """
    cadence = params["cadence"]
    direction = 180. + params["direction"].to('degree').value
    
    width_coeff = prep_coeff(params["width"])
    wave_thickness_coeff = prep_coeff(params["wave_thickness"])
    wave_normalization_coeff = prep_coeff(params["wave_normalization"])
    speed_coeff = prep_speed_coeff(params["speed"], params["acceleration"])

    lat_min = params["lat_min"].to('degree').value
    lat_max = params["lat_max"].to('degree').value
    lat_bin = params["lat_bin"].to('degree').value
    lon_min = params["lon_min"].to('degree').value
    lon_max = params["lon_max"].to('degree').value
    lon_bin = params["lon_bin"].to('degree').value

    # This roundabout approach recalculates lat_bin and lon_bin to produce
    # equally sized bins to exactly span the min/max ranges
    lat_num = int(round((lat_max-lat_min)/lat_bin))
    lat_edges, lat_bin = np.linspace(lat_min, lat_max, lat_num+1, retstep=True)

    lon_num = int(round((lon_max-lon_min)/lon_bin))
    lon_edges, lon_bin = np.linspace(lon_min, lon_max, lon_num+1, retstep=True)

    # Propagates from 90. down to lat_min, irrespective of lat_max
    p = np.poly1d([speed_coeff[2]/3., speed_coeff[1]/2., speed_coeff[0],
                   -(90.-lat_min)])
    # p = np.poly1d([0.0, speed_coeff[1], speed_coeff[2]/2.,
    #               -(90.-lat_min)])
    # Will fail if wave does not propagate all the way to lat_min
    # duration = p.r[np.logical_and(p.r.real > 0, p.r.imag == 0)][0]
    
    # steps = int(duration/cadence)+1
    # if steps > params["max_steps"]:
    #    steps = params["max_steps"]
    
    # Maybe used np.poly1d() instead to do the polynomial calculation?
    time = params["start_time_offset"] + np.arange(steps)*cadence
    time_powers = np.vstack((time**0, time**1, time**2))
    
    width = np.dot(width_coeff, time_powers).ravel()
    wave_thickness = np.dot(wave_thickness_coeff, time_powers).ravel()
    wave_normalization = np.dot(wave_normalization_coeff, time_powers).ravel()

    #Position
    #Propagates from 90., irrespective of lat_max
    wave_peak = 90.-(p(time)+(90.-lat_min))

    out_of_bounds = np.logical_or(wave_peak < lat_min, wave_peak > lat_max)
    if out_of_bounds.any():
        steps = np.where(out_of_bounds)[0][0]

    # Storage for the wave maps
    wave_maps = []

    # Header of the wave maps
    dict_header = {
        "CDELT1": lon_bin,
        "NAXIS1": lon_num,
        "CRVAL1": lon_min,
        "CRPIX1": crpix12_value_for_HG,
        "CUNIT1": "deg",
        "CTYPE1": "HG",
        "CDELT2": lat_bin,
        "NAXIS2": lat_num,
        "CRVAL2": lat_min,
        "CRPIX2": crpix12_value_for_HG,
        "CUNIT2": "deg",
        "CTYPE2": "HG",
        "HGLT_OBS": 0.0,  # (sun.heliographic_solar_center(BASE_DATE))[1],  # the value of HGLT_OBS from Earth at the given date
        "CRLN_OBS": 0.0,  # (sun.heliographic_solar_center(BASE_DATE))[0],  # the value of CRLN_OBS from Earth at the given date
        "DSUN_OBS": sun.sunearth_distance(BASE_DATE.strftime(BASE_DATE_FORMAT)).to('m').value,
        "DATE_OBS": BASE_DATE.strftime(BASE_DATE_FORMAT),
        "EXPTIME": 1.0
    }

    if verbose:
        print("  * Simulating "+str(steps)+" raw maps.")

    for istep in range(0, steps):

        # Current datetime
        current_datetime = BASE_DATE + datetime.timedelta(seconds=time[istep])

        # Update the header to set the correct observation time and earth-sun
        # distance
        dict_header['DATE_OBS'] = current_datetime.strftime(BASE_DATE_FORMAT)

        # Update the Earth-Sun distance
        dict_header['DSUN_OBS'] = sun.sunearth_distance(dict_header['DATE_OBS']).to('m').value

        # Update the heliographic latitude
        dict_header['HGLT_OBS'] = 0.0  # (sun.heliographic_solar_center(dict_header['DATE_OBS']))[1].to('degree').value

        # Update the heliographic longitude
        dict_header['CRLN_OBS'] = 0.0  # (sun.heliographic_solar_center(dict_header['DATE_OBS']))[0].to('degree').value

        # Gaussian profile in longitudinal direction
        # Does not take into account spherical geometry (i.e., change in area
        # element)
        if wave_thickness[istep] <= 0:
            print("  * ERROR: wave thickness is non-physical!")
        z = (lat_edges-wave_peak[istep])/wave_thickness[istep]
        wave_1d = wave_normalization[istep]*(ndtr(np.roll(z, -1))-ndtr(z))[0:lat_num]
        wave_1d /= lat_bin
        
        wave_lon_min = direction-width[istep]/2
        wave_lon_max = direction+width[istep]/2

        if width[istep] < 360.:
            # Do these need to be np.remainder() instead?
            wave_lon_min_mod = ((wave_lon_min+180.) % 360.)-180.
            wave_lon_max_mod = ((wave_lon_max+180.) % 360.)-180.
            
            index1 = np.arange(lon_num+1)[np.roll(lon_edges, -1) > min(wave_lon_min_mod, wave_lon_max_mod)][0]
            index2 = np.roll(np.arange(lon_num+1)[lon_edges < max(wave_lon_min_mod, wave_lon_max_mod)], 1)[0]
    
            wave_lon = np.zeros(lon_num)
            wave_lon[index1+1:index2] = 1.
            # Possible weirdness if index1 == index2
            wave_lon[index1] += (lon_edges[index1+1]-min(wave_lon_min_mod, wave_lon_max_mod))/lon_bin
            wave_lon[index2] += (max(wave_lon_min_mod, wave_lon_max_mod)-lon_edges[index2])/lon_bin
            
            if wave_lon_min_mod > wave_lon_max_mod:
                wave_lon = 1.-wave_lon
        else:
            wave_lon = np.ones(lon_num)
        
        # Could be accomplished with np.dot() without casting as matrices?
        wave = np.mat(wave_1d).T*np.mat(wave_lon)

        # Create the new map
        new_map = Map(wave, MapMeta(dict_header))
        new_map.plot_settings = {'cmap': cm.gray,
                                 'norm': ImageNormalize(stretch=LinearStretch()),
                                 'interpolation': 'nearest',
                                 'origin': 'lower'
                                 }
        # Update the list of maps
        wave_maps += [new_map]

    return Map(wave_maps, cube=True)
Example #14
0
def transform(params, wave_maps, verbose=False):
    """
    Transform raw data in HG' coordinates to HPC coordinates
    
    HG' = HG, except center at wave epicenter
    """
    solar_rotation_rate = params["rotation"]

    hglt_obs = params["hglt_obs"].to('degree').value
    # crln_obs = params["crln_obs"]
    
    epi_lat = params["epi_lat"].to('degree').value
    epi_lon = params["epi_lon"].to('degree').value

    # Parameters for the HPC co-ordinates
    hpcx_min = params["hpcx_min"].to('arcsec').value
    hpcx_max = params["hpcx_max"].to('arcsec').value
    hpcx_bin = params["hpcx_bin"].to('arcsec').value

    hpcy_min = params["hpcy_min"].to('arcsec').value
    hpcy_max = params["hpcy_max"].to('arcsec').value
    hpcy_bin = params["hpcy_bin"].to('arcsec').value

    hpcx_num = int(round((hpcx_max-hpcx_min)/hpcx_bin))
    hpcy_num = int(round((hpcy_max-hpcy_min)/hpcy_bin))

    # Storage for the HPC version of the input maps
    wave_maps_transformed = []

    # The properties of this map are used in the transform
    smap = wave_maps[0]

    # Basic dictionary version of the HPC map header
    dict_header = {
        "CDELT1": hpcx_bin,
        "NAXIS1": hpcx_num,
        "CRVAL1": hpcx_min,
        "CRPIX1": crpix12_value_for_HPC,
        "CUNIT1": "arcsec",
        "CTYPE1": "HPLN-TAN",
        "CDELT2": hpcy_bin,
        "NAXIS2": hpcy_num,
        "CRVAL2": hpcy_min,
        "CRPIX2": crpix12_value_for_HPC,
        "CUNIT2": "arcsec",
        "CTYPE2": "HPLT-TAN",
        "HGLT_OBS": hglt_obs,
        "CRLN_OBS": smap.carrington_longitude.to('degree').value,
        "DSUN_OBS": sun.sunearth_distance(BASE_DATE.strftime(BASE_DATE_FORMAT)).to('meter').value,
        "DATE_OBS": BASE_DATE.strftime(BASE_DATE_FORMAT),
        "EXPTIME": 1.0
    }
    start_date = smap.date

    # Origin grid, HG'
    lon_grid, lat_grid = wcs.convert_pixel_to_data([smap.data.shape[1], smap.data.shape[0]],
                                                   [smap.scale.x.value, smap.scale.y.value],
                                                   [smap.reference_pixel.x.value, smap.reference_pixel.y.value],
                                                   [smap.reference_coordinate.x.value, smap.reference_coordinate.y.value])

    # Origin grid, HG' to HCC'
    # HCC' = HCC, except centered at wave epicenter
    x, y, z = wcs.convert_hg_hcc(lon_grid, lat_grid,
                                 b0_deg=smap.heliographic_latitude.to('degree').value,
                                 l0_deg=smap.carrington_longitude.to('degree').value,
                                 z=True)

    # Origin grid, HCC' to HCC''
    # Moves the wave epicenter to initial conditions
    # HCC'' = HCC, except assuming that HGLT_OBS = 0
    zxy_p = euler_zyz((z, x, y),
                      (epi_lon, 90.-epi_lat, 0.))

    # Destination HPC grid
    hpcx_grid, hpcy_grid = wcs.convert_pixel_to_data([dict_header['NAXIS1'], dict_header['NAXIS2']],
                                                     [dict_header['CDELT1'], dict_header['CDELT2']],
                                                     [dict_header['CRPIX1'], dict_header['CRPIX2']],
                                                     [dict_header['CRVAL1'], dict_header['CRVAL2']])

    for icwm, current_wave_map in enumerate(wave_maps):
        print(icwm, len(wave_maps))
        # Elapsed time
        td = parse_time(current_wave_map.date) - parse_time(start_date)

        # Update the header
        dict_header['DATE_OBS'] = current_wave_map.date
        dict_header['DSUN_OBS'] = current_wave_map.dsun.to('m').value

        # Origin grid, HCC'' to HCC
        # Moves the observer to HGLT_OBS and adds rigid solar rotation
        total_seconds = u.s * (td.microseconds + (td.seconds + td.days * 24.0 * 3600.0) * 10.0**6) / 10.0**6
        solar_rotation = (total_seconds * solar_rotation_rate).to('degree').value
        zpp, xpp, ypp = euler_zyz(zxy_p,
                                  (0., hglt_obs, solar_rotation))

        # Origin grid, HCC to HPC (arcsec)
        xx, yy = wcs.convert_hcc_hpc(xpp, ypp,
                                     dsun_meters=current_wave_map.dsun.to('m').value)

        # Coordinate positions (HPC) with corresponding map data
        points = np.vstack((xx.ravel(), yy.ravel())).T
        values = np.asarray(deepcopy(current_wave_map.data)).ravel()

        # Solar rotation can push the points off disk and into areas that have
        # nans.  if this is the case, then griddata fails
        # Two solutions
        # 1 - replace all the nans with zeros, in order to get the code to run
        # 2 - the initial condition of zpp.ravel() >= 0 should be extended
        #     to make sure that only finite points are used.

        # 2D interpolation from origin grid to destination grid
        valid_points = np.logical_and(zpp.ravel() >= 0,
                                      np.isfinite(points[:, 0]),
                                      np.isfinite(points[:, 1]))
        grid = griddata(points[valid_points],
                        values[valid_points],
                        (hpcx_grid, hpcy_grid),
                        method="linear")
        transformed_wave_map = Map(grid, MapMeta(dict_header))
        transformed_wave_map.plot_settings = deepcopy(current_wave_map.plot_settings)
        # transformed_wave_map.name = current_wave_map.name
        # transformed_wave_map.meta['date-obs'] = current_wave_map.date
        wave_maps_transformed.append(transformed_wave_map)

    return Map(wave_maps_transformed, cube=True)
Example #15
0
def rot_hpc(x, y, tstart, tend, frame_time='synodic', rot_type='howard', **kwargs):
    """Given a location on the Sun referred to using the Helioprojective
    Cartesian co-ordinate system (typically quoted in the units of arcseconds)
    use the solar rotation profile to find that location at some later or
    earlier time.  Note that this function assumes that the data was observed
    from the Earth or near Earth vicinity.  Specifically, data from SOHO and
    STEREO observatories are not supported.  Note also that the function does
    NOT use solar B0 and L0 values provided in source FITS files - these
    quantities are calculated.

    Parameters
    ----------
    x : `~astropy.units.Quantity`
        Helio-projective x-co-ordinate in arcseconds (can be an array).

    y : `~astropy.units.Quantity`
        Helio-projective y-co-ordinate in arcseconds (can be an array).

    tstart : `sunpy.time.time`
        date/time to which x and y are referred.

    tend : `sunpy.time.time`
    date/time at which x and y will be rotated to.

    rot_type : {'howard' | 'snodgrass' | 'allen'}
        | howard: Use values for small magnetic features from Howard et al.
        | snodgrass: Use Values from Snodgrass et. al
        | allen: Use values from Allen, Astrophysical Quantities, and simpler
          equation.

    frame_time: {'sidereal' | 'synodic'}
        Choose type of day time reference frame.

    Returns
    -------
    x : `~astropy.units.Quantity`
        Rotated helio-projective x-co-ordinate in arcseconds (can be an array).

    y : `~astropy.units.Quantity`
        Rotated helio-projective y-co-ordinate in arcseconds (can be an array).

    Examples
    --------
    >>> import astropy.units as u
    >>> from sunpy.physics.transforms.differential_rotation import rot_hpc
    >>> rot_hpc( -570 * u.arcsec, 120 * u.arcsec, '2010-09-10 12:34:56', '2010-09-10 13:34:56')
    (<Angle -562.9105822671319 arcsec>, <Angle 119.31920621992195 arcsec>)

    Notes
    -----
    SSWIDL code equivalent: http://hesperia.gsfc.nasa.gov/ssw/gen/idl/solar/rot_xy.pro .
    The function rot_xy uses arcmin2hel.pro and hel2arcmin.pro to implement the
    same functionality as this function.  These two functions seem to perform
    inverse operations of each other to a high accuracy.  The corresponding
    equivalent functions here are convert_hpc_hg and convert_hg_hpc
    respectively. These two functions seem to perform inverse
    operations of each other to a high accuracy.  However, the values
    returned by arcmin2hel.pro are slightly different from those provided
    by convert_hpc_hg.  This leads to very slightly different results from
    rot_hpc compared to rot_xy.
    """

    # must have pairs of co-ordinates
    if np.array(x).shape != np.array(y).shape:
        raise ValueError('Input co-ordinates must have the same shape.')

    # Make sure we have enough time information to perform a solar differential
    # rotation
    # Start time
    dstart = parse_time(tstart)
    dend = parse_time(tend)
    interval = (dend - dstart).total_seconds() * u.s

    # Get the Sun's position from the vantage point at the start time
    vstart = kwargs.get("vstart", _calc_P_B0_SD(dstart))
    # Compute heliographic co-ordinates - returns (longitude, latitude). Points
    # off the limb are returned as nan
    longitude, latitude = convert_hpc_hg(x.to(u.arcsec).value,
                                         y.to(u.arcsec).value,
                                         b0_deg=vstart["b0"].to(u.deg).value,
                                         l0_deg=vstart["l0"].to(u.deg).value, 
                                         dsun_meters=(constants.au * sun.sunearth_distance(t=dstart)).value,
                                         angle_units='arcsec')
    longitude = Longitude(longitude, u.deg)
    latitude = Angle(latitude, u.deg)
    # Compute the differential rotation
    drot = diff_rot(interval, latitude, frame_time=frame_time,
                    rot_type=rot_type)

    # Convert back to heliocentric cartesian in units of arcseconds
    vend = kwargs.get("vend", _calc_P_B0_SD(dend))

    # It appears that there is a difference in how the SSWIDL function
    # hel2arcmin and the sunpy function below performs this co-ordinate
    # transform.
    newx, newy = convert_hg_hpc(longitude.to(u.deg).value + drot.to(u.deg).value,
                                latitude.to(u.deg).value,
                                b0_deg=vend["b0"].to(u.deg).value,
                                l0_deg=vend["l0"].to(u.deg).value,
                                dsun_meters=(constants.au * sun.sunearth_distance(t=dend)).value,
                                occultation=False)
    newx = Angle(newx, u.arcsec)
    newy = Angle(newy, u.arcsec)
    return newx.to(u.arcsec), newy.to(u.arcsec)
Example #16
0
def backprojection(calibrated_event_list, pixel_size=(1.,1.), image_dim=(64,64)):
    """Given a stacked calibrated event list fits file create a back 
    projection image.
    
    .. warning:: The image is not in the right orientation!

    Parameters
    ----------
    calibrated_event_list : string
        filename of a RHESSI calibrated event list
    detector : int
        the detector number
    pixel_size : 2-tuple
        the size of the pixels in arcseconds. Default is (1,1).
    image_dim : 2-tuple
        the size of the output image in number of pixels

    Returns
    -------
    out : RHESSImap
        Return a backprojection map.

    Examples
    --------
    >>> import sunpy.instr.rhessi as rhessi
    >>> map = rhessi.backprojection(sunpy.RHESSI_EVENT_LIST)
    >>> map.show()

    """
    
    calibrated_event_list = sunpy.RHESSI_EVENT_LIST
    fits = pyfits.open(calibrated_event_list)
    info_parameters = fits[2]
    xyoffset = info_parameters.data.field('USED_XYOFFSET')[0]
    time_range = TimeRange(info_parameters.data.field('ABSOLUTE_TIME_RANGE')[0])
    
    image = np.zeros(image_dim)
    
    #find out what detectors were used
    det_index_mask = fits[1].data.field('det_index_mask')[0]    
    detector_list = (np.arange(9)+1) * np.array(det_index_mask)
    for detector in detector_list:
        if detector > 0:
            image = image + _backproject(calibrated_event_list, detector=detector, pixel_size=pixel_size, image_dim=image_dim)
    
    dict_header = {
        "DATE-OBS": time_range.center().strftime("%Y-%m-%d %H:%M:%S"), 
        "CDELT1": pixel_size[0],
        "NAXIS1": image_dim[0],
        "CRVAL1": xyoffset[0],
        "CRPIX1": image_dim[0]/2 + 0.5, 
        "CUNIT1": "arcsec",
        "CTYPE1": "HPLN-TAN",
        "CDELT2": pixel_size[1],
        "NAXIS2": image_dim[1],
        "CRVAL2": xyoffset[1],
        "CRPIX2": image_dim[0]/2 + 0.5,
        "CUNIT2": "arcsec",
        "CTYPE2": "HPLT-TAN",
        "HGLT_OBS": 0,
        "HGLN_OBS": 0,
        "RSUN_OBS": solar_semidiameter_angular_size(time_range.center()),
        "RSUN_REF": sun.radius,
        "DSUN_OBS": sunearth_distance(time_range.center()) * sunpy.sun.constants.au
    }
    
    header = sunpy.map.MapHeader(dict_header)
    result_map = sunpy.map.Map(image, header)
            
    return result_map
Example #17
0
def backprojection(calibrated_event_list,
                   pixel_size=(1., 1.) * u.arcsec,
                   image_dim=(64, 64) * u.pix):
    """
    Given a stacked calibrated event list fits file create a back
    projection image.

    .. warning:: The image is not in the right orientation!

    Parameters
    ----------
    calibrated_event_list : string
        filename of a RHESSI calibrated event list
    pixel_size : `~astropy.units.Quantity` instance
        the size of the pixels in arcseconds. Default is (1,1).
    image_dim : `~astropy.units.Quantity` instance
        the size of the output image in number of pixels

    Returns
    -------
    out : RHESSImap
        Return a backprojection map.

    Examples
    --------
    >>> import sunpy.data
    >>> import sunpy.data.sample
    >>> import sunpy.instr.rhessi as rhessi
    >>> sunpy.data.download_sample_data(overwrite=False)   # doctest: +SKIP
    >>> map = rhessi.backprojection(sunpy.data.sample.RHESSI_EVENT_LIST)   # doctest: +SKIP
    >>> map.peek()   # doctest: +SKIP

    """
    if not isinstance(pixel_size, u.Quantity):
        raise ValueError("Must be astropy Quantity in arcseconds")
    try:
        pixel_size = pixel_size.to(u.arcsec)
    except:
        raise ValueError("'{0}' is not a valid pixel_size unit".format(
            pixel_size.unit))
    if not (isinstance(image_dim, u.Quantity) and image_dim.unit == 'pix'):
        raise ValueError("Must be astropy Quantity in pixels")

    try:
        import sunpy.data.sample
    except ImportError:
        import sunpy.data
        sunpy.data.download_sample()
    # This may need to be moved up to data from sample
    calibrated_event_list = sunpy.data.sample.RHESSI_EVENT_LIST

    afits = fits.open(calibrated_event_list)
    info_parameters = afits[2]
    xyoffset = info_parameters.data.field('USED_XYOFFSET')[0]
    time_range = TimeRange(
        info_parameters.data.field('ABSOLUTE_TIME_RANGE')[0])

    image = np.zeros(image_dim.value)

    # find out what detectors were used
    det_index_mask = afits[1].data.field('det_index_mask')[0]
    detector_list = (np.arange(9) + 1) * np.array(det_index_mask)
    for detector in detector_list:
        if detector > 0:
            image = image + _backproject(calibrated_event_list,
                                         detector=detector,
                                         pixel_size=pixel_size.value,
                                         image_dim=image_dim.value)

    dict_header = {
        "DATE-OBS":
        time_range.center().strftime("%Y-%m-%d %H:%M:%S"),
        "CDELT1":
        pixel_size[0],
        "NAXIS1":
        image_dim[0],
        "CRVAL1":
        xyoffset[0],
        "CRPIX1":
        image_dim[0].value / 2 + 0.5,
        "CUNIT1":
        "arcsec",
        "CTYPE1":
        "HPLN-TAN",
        "CDELT2":
        pixel_size[1],
        "NAXIS2":
        image_dim[1],
        "CRVAL2":
        xyoffset[1],
        "CRPIX2":
        image_dim[0].value / 2 + 0.5,
        "CUNIT2":
        "arcsec",
        "CTYPE2":
        "HPLT-TAN",
        "HGLT_OBS":
        0,
        "HGLN_OBS":
        0,
        "RSUN_OBS":
        solar_semidiameter_angular_size(time_range.center()).value,
        "RSUN_REF":
        sunpy.sun.constants.radius.value,
        "DSUN_OBS":
        sunearth_distance(time_range.center()) * sunpy.sun.constants.au.value
    }

    header = sunpy.map.MapMeta(dict_header)
    result_map = sunpy.map.Map(image, header)

    return result_map
 def dsun(self):
     """KPVT at earth."""
     dsun = sun.sunearth_distance(self.date).to(u.m)
     return u.Quantity(dsun, 'm')
Example #19
0
    def dsun(self):
        """KPVT at earth."""
        dsun = sun.sunearth_distance(self.date).to(u.m)

        return u.Quantity(dsun, 'm')
Example #20
0
def backprojection(calibrated_event_list, pixel_size=(1.,1.) * u.arcsec, image_dim=(64,64) * u.pix):
    """
    Given a stacked calibrated event list fits file create a back
    projection image.

    .. warning:: The image is not in the right orientation!

    Parameters
    ----------
    calibrated_event_list : string
        filename of a RHESSI calibrated event list
    detector : int
        the detector number
    pixel_size : `~astropy.units.Quantity` instance
        the size of the pixels in arcseconds. Default is (1,1).
    image_dim : `~astropy.units.Quantity` instance
        the size of the output image in number of pixels

    Returns
    -------
    out : RHESSImap
        Return a backprojection map.

    Examples
    --------
    >>> import sunpy.instr.rhessi as rhessi
    >>> map = rhessi.backprojection(sunpy.RHESSI_EVENT_LIST)
    >>> map.peek()

    """
    if not isinstance(pixel_size, u.Quantity):
        raise ValueError("Must be astropy Quantity in arcseconds")
    try:
        pixel_size = pixel_size.to(u.arcsec)
    except:
        raise ValueError("'{0}' is not a valid pixel_size unit".format(pixel_size.unit))
    if not (isinstance(image_dim, u.Quantity) and image_dim.unit == 'pix'):
        raise ValueError("Must be astropy Quantity in pixels")
    calibrated_event_list = sunpy.RHESSI_EVENT_LIST
    afits = fits.open(calibrated_event_list)
    info_parameters = afits[2]
    xyoffset = info_parameters.data.field('USED_XYOFFSET')[0]
    time_range = TimeRange(info_parameters.data.field('ABSOLUTE_TIME_RANGE')[0])
    
    image = np.zeros(image_dim.value)
    
    #find out what detectors were used
    det_index_mask = afits[1].data.field('det_index_mask')[0]
    detector_list = (np.arange(9)+1) * np.array(det_index_mask)
    for detector in detector_list:
        if detector > 0:
            image = image + _backproject(calibrated_event_list, detector=detector, pixel_size=pixel_size.value
										 , image_dim=image_dim.value)
    
    dict_header = {
        "DATE-OBS": time_range.center().strftime("%Y-%m-%d %H:%M:%S"),
        "CDELT1": pixel_size[0],
        "NAXIS1": image_dim[0],
        "CRVAL1": xyoffset[0],
        "CRPIX1": image_dim[0].value/2 + 0.5, 
        "CUNIT1": "arcsec",
        "CTYPE1": "HPLN-TAN",
        "CDELT2": pixel_size[1],
        "NAXIS2": image_dim[1],
        "CRVAL2": xyoffset[1],
        "CRPIX2": image_dim[0].value/2 + 0.5,
        "CUNIT2": "arcsec",
        "CTYPE2": "HPLT-TAN",
        "HGLT_OBS": 0,
        "HGLN_OBS": 0,
        "RSUN_OBS": solar_semidiameter_angular_size(time_range.center()).value,
        "RSUN_REF": sunpy.sun.constants.radius.value,
        "DSUN_OBS": sunearth_distance(time_range.center()) * sunpy.sun.constants.au.value
    }

    header = sunpy.map.MapMeta(dict_header)
    result_map = sunpy.map.Map(image, header)

    return result_map