Esempio n. 1
0
    def detect(self, channel, i_time, header, bins, bin_range):
        """
        For a given timestep, map the intensity along the loop to the 3D field and
        return the Hi-C data product.

        Parameters
        ----------
        channel : `dict`
        i_time : `int`
        header : `~sunpy.util.metadata.MetaDict`
        bins : `~synthesizAR.util.SpatialPair`
        bin_range : `~synthesizAR.util.SpatialPair`

        Returns
        -------
        AIA data product : `~sunpy.map.Map`
        """
        with h5py.File(self.counts_file, 'r') as hf:
            weights = np.array(hf[channel['name']][i_time, :])
            units = u.Unit(get_keys(hf[channel['name']].attrs, ('unit','units')))

        hpc_coordinates = self.total_coordinates
        dz = np.diff(bin_range.z)[0].cgs / bins.z * (1. * u.pixel)
        visible = is_visible(hpc_coordinates, self.observer_coordinate)
        hist, _, _ = np.histogram2d(hpc_coordinates.Tx.value, hpc_coordinates.Ty.value,
                                    bins=(bins.x.value, bins.y.value),
                                    range=(bin_range.x.value, bin_range.y.value),
                                    weights=visible * weights * dz.value)
        header['bunit'] = (units * dz.unit).to_string()

        counts = gaussian_filter(hist.T, (channel['gaussian_width']['y'].value,
                                          channel['gaussian_width']['x'].value))
        return Map(counts.astype(np.float32), header)
Esempio n. 2
0
def make_los_velocity_map(time: u.s, field, instr, **kwargs):
    """
    Return map of LOS velocity at a given time for a given instrument resolution.
    """
    plot_settings = {
        'cmap': cm.get_cmap('bwr'),
        'norm': colors.SymLogNorm(10, vmin=-1e8, vmax=1e8)
    }
    plot_settings.update(kwargs.get('plot_settings', {}))

    bins, bin_range = instr.make_detector_array(field)
    visible = is_visible(instr.total_coordinates, instr.observer_coordinate)
    hist_coordinates, _, _ = np.histogram2d(instr.total_coordinates.Tx.value,
                                            instr.total_coordinates.Ty.value,
                                            bins=(bins.x.value, bins.y.value),
                                            range=(bin_range.x.value,
                                                   bin_range.y.value),
                                            weights=visible)
    with h5py.File(instr.counts_file, 'r') as hf:
        try:
            i_time = np.where(
                np.array(hf['time']) *
                u.Unit(hf['time'].attrs['units']) == time)[0][0]
        except IndexError:
            raise IndexError(
                f'{time} is not a valid time in observing time for {instr.name}'
            )
        v_x = u.Quantity(hf['velocity_x'][i_time, :],
                         hf['velocity_x'].attrs['units'])
        v_y = u.Quantity(hf['velocity_y'][i_time, :],
                         hf['velocity_y'].attrs['units'])
        v_z = u.Quantity(hf['velocity_z'][i_time, :],
                         hf['velocity_z'].attrs['units'])
        v_los = instr.los_velocity(v_x, v_y, v_z)

    hist, _, _ = np.histogram2d(instr.total_coordinates.Tx.value,
                                instr.total_coordinates.Ty.value,
                                bins=(bins.x.value, bins.y.value),
                                range=(bin_range.x.value, bin_range.y.value),
                                weights=v_los.value * visible)
    hist /= np.where(hist_coordinates == 0, 1, hist_coordinates)
    meta = instr.make_fits_header(field, instr.channels[0])
    del meta['wavelnth']
    del meta['waveunit']
    meta['bunit'] = v_los.unit.to_string()
    meta['detector'] = 'LOS Velocity'
    meta['comment'] = 'LOS velocity calculated by synthesizAR'

    return GenericMap(hist.T, meta, plot_settings=plot_settings)
Esempio n. 3
0
def peek_fieldlines(magnetogram, fieldlines, **kwargs):
    """
    Quick plot of streamlines overplotted on magnetogram

    Parameters
    ----------
    magnetogram : `~sunpy.map.Map`
    fieldlines : `list`
    """
    fig = plt.figure(figsize=kwargs.get('figsize', (8, 8)))
    ax = fig.gca(projection=magnetogram)
    # Plot map
    norm = kwargs.get('norm', Normalize(vmin=-1.5e3, vmax=1.5e3))
    magnetogram.plot(axes=ax,
                     title=False,
                     cmap=kwargs.get('cmap', 'hmimag'),
                     norm=norm)
    # Grid
    ax.grid(alpha=0.)
    magnetogram.draw_grid(axes=ax,
                          grid_spacing=10 * u.deg,
                          alpha=0.75,
                          color='k')
    # Lines
    line_frequency = kwargs.get('line_frequency', 5)
    for line in fieldlines[::line_frequency]:
        try:
            coord = line.transform_to(magnetogram.coordinate_frame)
        except AttributeError:
            # This try-catch is due to a bug where to convert out of an HEEQ frame
            # one must first transform to a polar HGS frame
            # FIXME:  once this is fixed upstream in SunPy, this can be removed
            coord = line.transform_to(HeliographicStonyhurst).transform_to(
                magnetogram.coordinate_frame)
        # Mask lines behind the solar disk
        i_visible = np.where(is_visible(coord,
                                        magnetogram.observer_coordinate))
        coord_visible = SkyCoord(Tx=coord.Tx[i_visible],
                                 Ty=coord.Ty[i_visible],
                                 distance=coord.distance[i_visible],
                                 frame=magnetogram.coordinate_frame)
        ax.plot_coord(coord_visible,
                      '-',
                      color=kwargs.get('color', 'k'),
                      lw=kwargs.get('lw', 1),
                      alpha=kwargs.get('alpha', 0.5))

    plt.show()
Esempio n. 4
0
def make_temperature_map(time: u.s, field, instr, **kwargs):
    """
    Return map of column-averaged electron temperature at a given time for a given instrument
    resolution.
    """
    plot_settings = {'cmap': cm.get_cmap('inferno')}
    plot_settings.update(kwargs.get('plot_settings', {}))
    bins, bin_range = instr.make_detector_array(field)
    visible = is_visible(instr.total_coordinates, instr.observer_coordinate)
    hist_coordinates, _, _ = np.histogram2d(instr.total_coordinates.Tx.value,
                                            instr.total_coordinates.Ty.value,
                                            bins=(bins.x.value, bins.y.value),
                                            range=(bin_range.x.value,
                                                   bin_range.y.value),
                                            weights=visible)
    with h5py.File(instr.counts_file, 'r') as hf:
        try:
            i_time = np.where(
                u.Quantity(hf['time'], get_keys(hf['time'].attrs), (
                    'unit', 'units')) == time)[0][0]
        except IndexError:
            raise IndexError(
                f'{time} is not a valid time in observing time for {instr.name}'
            )
        weights = np.array(hf['electron_temperature'][i_time, :])
        units = u.Unit(
            get_keys(hf['electron_temperature'].attrs, ('unit', 'units')))
    hist, _, _ = np.histogram2d(instr.total_coordinates.Tx.value,
                                instr.total_coordinates.Ty.value,
                                bins=(bins.x.value, bins.y.value),
                                range=(bin_range.x.value, bin_range.y.value),
                                weights=weights * visible)
    hist /= np.where(hist_coordinates == 0, 1, hist_coordinates)
    meta = instr.make_fits_header(field, instr.channels[0])
    del meta['wavelnth']
    del meta['waveunit']
    meta['bunit'] = units.to_string()
    meta['detector'] = 'Electron Temperature'
    meta[
        'comment'] = 'Column-averaged electron temperature calculated by synthesizAR'

    return GenericMap(hist.T, meta, plot_settings=plot_settings)
Esempio n. 5
0
    def integrate_los(self, time, channel, skeleton, coordinates,
                      coordinates_centers):
        client = distributed.get_client()
        # Get Coordinates
        coords = coordinates_centers.transform_to(self.projected_frame)
        # Compute weights
        i_time = np.where(time == self.observing_time)[0][0]
        widths = np.concatenate(
            [l.field_aligned_coordinate_width for l in skeleton.loops])
        loop_area = np.concatenate(
            [l.cross_sectional_area for l in skeleton.loops])
        root = skeleton.loops[0].zarr_root
        # NOTE: do this outside of the client.map call to make Dask happy
        path = f'{{}}/{self.name}/{channel.name}'
        kernels = np.concatenate(
            client.gather(
                client.map(
                    lambda l: root[path.format(l.name)][i_time, :],
                    skeleton.loops,
                )))
        unit_kernel = u.Unit(
            root[f'{skeleton.loops[0].name}/{self.name}/{channel.name}'].
            attrs['unit'])
        area_ratio = (loop_area / self.pixel_area).decompose()
        weights = area_ratio * widths * (kernels * unit_kernel)
        visible = is_visible(coords, self.observer)
        # Bin
        bins, (blc, trc) = self.get_detector_array(coordinates)
        hist, _, _ = np.histogram2d(
            coords.Tx.value,
            coords.Ty.value,
            bins=bins,
            range=((blc.Tx.value, trc.Tx.value), (blc.Ty.value, trc.Ty.value)),
            weights=weights.value * visible,
        )
        header = self.get_header(channel, coordinates)
        header['bunit'] = weights.unit.decompose().to_string()
        header['date-obs'] = (self.observer.obstime + time).isot

        return Map(hist.T, header)
Esempio n. 6
0
    def _detect(self, channel, i_time, header, bins, bin_range):
        """
        For a given channel and timestep, map the intensity along the loop to the 3D field and
        return the XRT data product.

        Parameters
        ----------
        channel : `dict`
        i_time : `int`
        header : `~sunpy.util.metadata.MetaDict`
        bins : `SpatialPair`
        bin_range : `SpatialPair`

        Returns
        -------
        XRT data product : `~sunpy.Map`
        """
        with h5py.File(self.counts_file, 'r') as hf:
            weights = np.array(hf[channel['name']][i_time, :])
            units = u.Unit(
                get_keys(hf[channel['name']].attrs, ('unit', 'units')))

        hpc_coordinates = self.total_coordinates
        dz = np.diff(bin_range.z).cgs[0] / bins.z * (1. * u.pixel)
        visible = is_visible(hpc_coordinates, self.observer_coordinate)
        hist, _, _ = np.histogram2d(hpc_coordinates.Tx.value,
                                    hpc_coordinates.Ty.value,
                                    bins=(bins.x.value, bins.y.value),
                                    range=(bin_range.x.value,
                                           bin_range.y.value),
                                    weights=visible * weights * dz.value)
        header['bunit'] = (units * dz.unit).to_string()

        if self.apply_psf:
            counts = self.psf_smooth(hist.T, header)
        return Map(counts, header)
Esempio n. 7
0
def make_emission_measure_map(time: u.s,
                              field,
                              instr,
                              temperature_bin_edges=None,
                              **kwargs):
    """
    Compute true emission meausure in each pixel as a function of electron temperature.

    Parameters
    ----------
    time : `~astropy.units.Quantity`
    field : `~synthesizAR.Field`
    instr : `~synthesizAR.instruments.InstrumentBase`
    temperature_bin_edges : `~astropy.units.Quantity`

    Other Parameters
    ----------------
    plot_settings : `dict`

    Returns
    -------
    `~synthesizAR.maps.EMCube`
    """
    plot_settings = {
        'cmap': cm.get_cmap('magma'),
        'norm': colors.SymLogNorm(1, vmin=1e25, vmax=1e29)
    }
    plot_settings.update(kwargs.get('plot_settings', {}))

    # read unbinned temperature and density
    with h5py.File(instr.counts_file, 'r') as hf:
        try:
            i_time = np.where(
                np.array(hf['time']) *
                u.Unit(hf['time'].attrs['units']) == time)[0][0]
        except IndexError:
            raise IndexError(
                f'{time} is not a valid time in observing time for {instr.name}'
            )
        unbinned_temperature = np.array(hf['electron_temperature'][i_time, :])
        temperature_unit = u.Unit(hf['electron_temperature'].attrs['units'])
        unbinned_density = np.array(hf['density'][i_time, :])
        density_unit = u.Unit(hf['density'].attrs['units'])

    # setup bin edges and weights
    if temperature_bin_edges is None:
        temperature_bin_edges = 10.**(np.arange(5.5, 7.5, 0.1)) * u.K
    bins, bin_range = instr.make_detector_array(field)
    x_bin_edges = (
        np.diff(bin_range.x) / bins.x.value * np.arange(bins.x.value + 1) +
        bin_range.x[0])
    y_bin_edges = (
        np.diff(bin_range.y) / bins.y.value * np.arange(bins.y.value + 1) +
        bin_range.y[0])
    dh = np.diff(bin_range.z).cgs[0] / bins.z * (1. * u.pixel)
    visible = is_visible(instr.total_coordinates, instr.observer_coordinate)
    emission_measure_weights = (unbinned_density**2) * dh * visible
    # bin in x,y,T space with emission measure weights
    xyT_coordinates = np.append(np.stack(
        [instr.total_coordinates.Tx, instr.total_coordinates.Ty], axis=1),
                                unbinned_temperature[:, np.newaxis],
                                axis=1)
    hist, _ = np.histogramdd(
        xyT_coordinates,
        bins=[x_bin_edges, y_bin_edges, temperature_bin_edges.value],
        weights=emission_measure_weights)

    meta_base = instr.make_fits_header(field, instr.channels[0])
    del meta_base['wavelnth']
    del meta_base['waveunit']
    meta_base['detector'] = r'Emission measure'
    meta_base['comment'] = 'LOS Emission Measure distribution'
    em_unit = density_unit * density_unit * dh.unit
    data = np.transpose(hist, (1, 0, 2)) * em_unit

    return EMCube(data,
                  meta_base,
                  temperature_bin_edges,
                  plot_settings=plot_settings)