Ejemplo n.º 1
0
def test_find_pixel_radii(smap):
    # The known maximum radius
    known_maximum_pixel_radius = 1.84183121

    # Calculate the pixel radii
    pixel_radii = find_pixel_radii(smap)

    # The shape of the pixel radii is the same as the input map
    assert pixel_radii.shape[0] == int(smap.dimensions[0].value)
    assert pixel_radii.shape[1] == int(smap.dimensions[1].value)

    # Make sure the unit is solar radii
    assert pixel_radii.unit == u.R_sun

    # Make sure the maximum
    assert_quantity_allclose((np.max(pixel_radii)).value, known_maximum_pixel_radius)

    # Test that the new scale is used
    pixel_radii = find_pixel_radii(smap, scale=2 * smap.rsun_obs)
    assert_quantity_allclose(np.max(pixel_radii).value, known_maximum_pixel_radius / 2)
Ejemplo n.º 2
0
def normalizing_radial_gradient_filter(
    smap,
    radial_bin_edges,
    scale=None,
    intensity_summary=np.mean,
    intensity_summary_kwargs=None,
    width_function=np.std,
    width_function_kwargs=None,
    application_radius=1 * u.R_sun,
):
    """
    Implementation of the normalizing radial gradient filter (NRGF) of Morgan, Habbal & Woo, 2006,
    Sol. Phys., 236, 263. https://link.springer.com/article/10.1007%2Fs11207-006-0113-6.

    Note that after applying the NRGF plot settings such as the image normalization
    may have to be changed in order to obtain a good-looking plot.

    Parameters
    ----------
    smap : `sunpy.map.Map`
        A SunPy map

    radial_bin_edges : `astropy.units.Quantity`
        A two-dimensional array of bin edges of size [2, nbins] where nbins is
        the number of bins.

    scale : None | `astropy.units.Quantity`
        The radius of the Sun expressed in map units.  For example, in typical
        helioprojective Cartesian maps the solar radius is expressed in units
        of arcseconds.  If None, then the map scale is used.

    intensity_summary :`function`
        A function that returns a summary statistic of the radial intensity,
        for example `~numpy.mean` and `~numpy.median`.

    intensity_summary_kwargs : None | `dict`
        Keywords applicable to the summary function.

    width_function : `function`
        A function that returns a summary statistic of the distribution of intensity,
        at a given radius, for example `~numpy.std`.

    width_function_kwargs : `function`
        Keywords applicable to the width function.

    application_radius : `astropy.units.Quantity`
        The NRGF is applied to emission at radii above the application_radius.

    Returns
    -------
    new_map : `sunpy.map.Map`
        A SunPy map that has had the NRGF applied to it.
    """

    # Get the radii for every pixel
    map_r = find_pixel_radii(smap).to(u.R_sun)

    # Radial intensity
    radial_intensity = get_radial_intensity_summary(smap,
                                                    radial_bin_edges,
                                                    scale=scale,
                                                    summary=intensity_summary,
                                                    **intensity_summary_kwargs)

    # An estimate of the width of the intensity distribution in each radial bin.
    radial_intensity_distribution_summary = get_radial_intensity_summary(
        smap,
        radial_bin_edges,
        scale=scale,
        summary=width_function,
        **width_function_kwargs)

    # Storage for the filtered data
    data = np.zeros_like(smap.data)

    # Calculate the filter for each radial bin.
    for i in range(0, radial_bin_edges.shape[1]):
        here = np.logical_and(map_r > radial_bin_edges[0, i],
                              map_r < radial_bin_edges[1, i])
        here = np.logical_and(here, map_r > application_radius)
        data[here] = (smap.data[here] - radial_intensity[i]
                      ) / radial_intensity_distribution_summary[i]

    return sunpy.map.Map(data, smap.meta)
Ejemplo n.º 3
0
def intensity_enhance(smap,
                      radial_bin_edges,
                      scale=None,
                      summarize_bin_edges="center",
                      summary=np.mean,
                      degree=1,
                      normalization_radius=1 * u.R_sun,
                      fit_range=[1, 1.5] * u.R_sun,
                      **summary_kwargs):
    """
    Returns a map with the off-limb emission enhanced.  The enhancement is calculated as follows.  A
    summary statistic of the radial dependence of the off-limb emission is calculated.  Since the UV
    and EUV emission intensity drops of quickly off the solar limb, it makes sense to fit the log of
    the intensity statistic using some appropriate function.  The function we use here is a
    polynomial.  To calculate the enhancement, the fitted function is normalized to its value at the
    normalization radius from the center of the Sun (a sensible choice is the solar radius).  The
    offlimb emission is then divided by this normalized function.

    Note that after enhancement plot settings such as the image normalization
    may have to be changed in order to obtain a good-looking plot.

    Parameters
    ----------
    smap : `sunpy.map.Map`
        A SunPy map

    radial_bin_edges : `astropy.units.Quantity`
        A two-dimensional array of bin edges of size [2, nbins] where nbins is
        the number of bins.

    scale : None | `astropy.units.Quantity`
        The radius of the Sun expressed in map units.  For example, in typical
        helioprojective Cartesian maps the solar radius is expressed in units
        of arcseconds.  If None, then the map scale is used.

    summarize_bin_edges : `str`
        How to summarize the bin edges.

    summary : `function`
        A function that returns a summary statistic of the radial intensity,
        for example `~numpy.mean` and `~numpy.median`.

    degree : `int`
        Degree of the polynomial fit to the log of the intensity as a function of
        radius.

    normalization_radius : `astropy.units.Quantity`
        The radius at which the enhancement has value 1.  For most cases
        the value of the enhancement will increase as a function of
        radius.

    fit_range : `astropy.units.Quantity`
        Array like with 2 elements defining the range of radii over which the
        polynomial function is fit.  The preferred units are solar radii.

    summary_kwargs : `dict`
        Keywords applicable to the summary function.

    Returns
    -------
    new_map : `sunpy.map.Map`
        A SunPy map that has the emission above the normalization radius enhanced.
    """

    # Get the radii for every pixel
    map_r = find_pixel_radii(smap).to(u.R_sun)

    # Get the radial intensity distribution
    radial_intensity = get_radial_intensity_summary(smap,
                                                    radial_bin_edges,
                                                    scale=scale,
                                                    summary=summary,
                                                    **summary_kwargs)

    # Summarize the radial bins
    radial_bin_summary = bin_edge_summary(radial_bin_edges,
                                          summarize_bin_edges).to(u.R_sun)

    # Fit range
    if fit_range[0] >= fit_range[1]:
        raise ValueError("The fit range must be strictly increasing.")

    fit_here = np.logical_and(
        fit_range[0].to(u.R_sun).value <= radial_bin_summary.to(u.R_sun).value,
        radial_bin_summary.to(u.R_sun).value <= fit_range[1].to(u.R_sun).value,
    )

    # Fits a polynomial function to the natural logarithm of an estimate of
    # the intensity as a function of radius.
    polynomial = fit_polynomial_to_log_radial_intensity(
        radial_bin_summary[fit_here], radial_intensity[fit_here], degree)

    # Calculate the enhancement
    enhancement = 1 / normalize_fit_radial_intensity(map_r, polynomial,
                                                     normalization_radius)
    enhancement[map_r < normalization_radius] = 1

    # Return a map with the intensity enhanced above the normalization radius
    # and the same meta data as the input map.
    return sunpy.map.Map(smap.data * enhancement, smap.meta)