Exemplo n.º 1
0
 def __init__(self, magnetogram, width_z: u.cm, shape_z: u.pixel):
     self.magnetogram = magnetogram
     self.shape = SpatialPair(x=magnetogram.dimensions.x, y=magnetogram.dimensions.y, z=shape_z)
     range_x, range_y = self._calculate_range(magnetogram)
     range_z = u.Quantity([0*u.cm, width_z])
     self.range = SpatialPair(x=range_x.to(u.cm), y=range_y.to(u.cm), z=range_z.to(u.cm))
     width_x = np.diff(range_x)[0]
     width_y = np.diff(range_y)[0]
     self.width = SpatialPair(x=width_x.to(u.cm), y=width_y.to(u.cm), z=width_z.to(u.cm))
     self.delta = SpatialPair(x=self.width.x/self.shape.x, y=self.width.y/self.shape.y,
                              z=self.width.z/self.shape.z)
Exemplo n.º 2
0
 def __init__(self, observing_time, observer_coordinate, apply_psf=True):
     self.fits_template['telescop'] = 'SDO/AIA'
     self.fits_template['detector'] = 'AIA'
     self.fits_template['waveunit'] = 'angstrom'
     self.name = 'SDO_AIA'
     self.channels = [{
         'wavelength': 94 * u.angstrom,
         'telescope_number': 4,
         'gaussian_width': {
             'x': 0.951 * u.pixel,
             'y': 0.951 * u.pixel
         }
     }, {
         'wavelength': 131 * u.angstrom,
         'telescope_number': 1,
         'gaussian_width': {
             'x': 1.033 * u.pixel,
             'y': 1.033 * u.pixel
         }
     }, {
         'wavelength': 171 * u.angstrom,
         'telescope_number': 3,
         'gaussian_width': {
             'x': 0.962 * u.pixel,
             'y': 0.962 * u.pixel
         }
     }, {
         'wavelength': 193 * u.angstrom,
         'telescope_number': 2,
         'gaussian_width': {
             'x': 1.512 * u.pixel,
             'y': 1.512 * u.pixel
         }
     }, {
         'wavelength': 211 * u.angstrom,
         'telescope_number': 2,
         'gaussian_width': {
             'x': 1.199 * u.pixel,
             'y': 1.199 * u.pixel
         }
     }, {
         'wavelength': 335 * u.angstrom,
         'telescope_number': 1,
         'gaussian_width': {
             'x': 0.962 * u.pixel,
             'y': 0.962 * u.pixel
         }
     }]
     self.cadence = 10.0 * u.s
     self.resolution = SpatialPair(x=0.600698 * u.arcsec / u.pixel,
                                   y=0.600698 * u.arcsec / u.pixel,
                                   z=None)
     self.apply_psf = apply_psf
     super().__init__(observing_time, observer_coordinate)
     self._setup_channels()
Exemplo n.º 3
0
 def __init__(self, observing_time, observer_coordinate, apply_psf=True):
     self.name = 'Hinode_XRT'
     self.cadence = 20*u.s
     self.resolution = SpatialPair(x=2.05719995499*u.arcsec/u.pixel,
                                   y=2.05719995499*u.arcsec/u.pixel, z=None)
     self.fits_template['telescop'] = 'Hinode'
     self.fits_template['instrume'] = 'XRT'
     self.fits_template['waveunit'] = 'keV'
     self.apply_psf = apply_psf
     super().__init__(observing_time, observer_coordinate)
     self._setup_channels()
Exemplo n.º 4
0
    def make_detector_array(self, field):
        """
        Construct bins based on desired observing area.
        """
        # Get field of view
        min_x, max_x, min_y, max_y = self._get_fov(field.magnetogram)
        min_z = self.total_coordinates.distance.min()
        max_z = self.total_coordinates.distance.max()
        delta_x = max_x - min_x
        delta_y = max_y - min_y
        bins_x = np.ceil(delta_x / self.resolution.x)
        bins_y = np.ceil(delta_y / self.resolution.y)
        bins_z = max(bins_x, bins_y)

        # NOTE: the z-quantities are used to determine the integration step along the LOS
        bins = SpatialPair(x=bins_x, y=bins_y, z=bins_z)
        bin_range = SpatialPair(x=u.Quantity([min_x, max_x]),
                                y=u.Quantity([min_y, max_y]),
                                z=u.Quantity([min_z, max_z]))

        return bins, bin_range
Exemplo n.º 5
0
 def __init__(self, observing_time, observer_coordinate, window=None, apply_psf=True):
     self.name = 'Hinode_EIS'
     self.cadence = 10.0*u.s
     self.resolution = SpatialPair(x=1.0*u.arcsec/u.pixel, y=2.0*u.arcsec/u.pixel, z=None)
     self.fits_template['telescop'] = 'Hinode'
     self.fits_template['instrume'] = 'EIS'
     self.fits_template['detector'] = 'EIS'
     self.fits_template['waveunit'] = 'angstrom'
     self.apply_psf = apply_psf
     self.window = 0.5*u.angstrom if window is None else window
     super().__init__(observing_time, observer_coordinate=observer_coordinate)
     self._setup_channels()
Exemplo n.º 6
0
 def calculate_phi(self):
     """
     Calculate potential
     """
     # Set up grid
     y_grid, x_grid = np.indices((int(self.shape.x.value), int(self.shape.y.value)))
     x_grid = x_grid*self.delta.x.value
     y_grid = y_grid*self.delta.y.value
     z_depth = -self.delta.z.value/np.sqrt(2.*np.pi)
     # Project lower boundary
     boundary = self.project_boundary(self.range.x, self.range.y).value
     # Normalized LOS vector
     l_hat = (self.line_of_sight/np.sqrt((self.line_of_sight**2).sum())).value
     # Calculate phi
     delta = SpatialPair(x=self.delta.x.value, y=self.delta.y.value, z=self.delta.z.value)
     shape = SpatialPair(x=int(self.shape.x.value),
                         y=int(self.shape.y.value),
                         z=int(self.shape.z.value))
     phi = np.zeros((shape.x, shape.y, shape.z))
     phi = _calculate_phi_numba(phi, boundary, delta, shape, z_depth, l_hat)
     return phi * u.Unit(self.magnetogram.meta['bunit']) * self.delta.x.unit * (1. * u.pixel)
Exemplo n.º 7
0
 def __init__(self, observing_time, observer_coordinate, fov={}, **kwargs):
     self._fov = fov
     self.fits_template['telescop'] = 'HiC'
     self.fits_template['detector'] = 'HiC'
     self.fits_template['waveunit'] = 'angstrom'
     self.name = 'Hi_C'
     self.channels = [{'wavelength': 171*u.angstrom, 'name': '171', 'intstrument_label': 'HiC',
                       'gaussian_width': {'x': 0.962*u.pixel, 'y': 0.962*u.pixel}},]
     self.cadence = 6.0*u.s
     self.resolution = kwargs.get('resolution',
                                  SpatialPair(x=0.1*u.arcsec/u.pixel, y=0.1*u.arcsec/u.pixel, z=None))
     super().__init__(observing_time, observer_coordinate)
     self._setup_channels()
Exemplo n.º 8
0
    def calculate_field(self, phi: u.G * u.cm):
        """
        Compute vector magnetic field.

        Calculate the vector magnetic field using the current-free approximation,

        .. math::
            \\vec{B} = -\\nabla\phi

        The gradient is computed numerically using a five-point stencil,

        .. math::
            \\frac{\partial B}{\partial x_i} \\approx -\left(\\frac{-B_{x_i}(x_i + 2\Delta x_i) + 8B_{x_i}(x_i + \Delta x_i) - 8B_{x_i}(x_i - \Delta x_i) + B_{x_i}(x_i - 2\Delta x_i)}{12\Delta x_i}\\right)

        Parameters
        ----------
        phi : `~astropy.units.Quantity`

        Returns
        -------
        B_field : `~synthesizAR.util.SpatialPair`
            x, y, and z components of the vector magnetic field in 3D
        """
        Bx = u.Quantity(np.zeros(phi.shape), self.magnetogram.meta['bunit'])
        By = u.Quantity(np.zeros(phi.shape), self.magnetogram.meta['bunit'])
        Bz = u.Quantity(np.zeros(phi.shape), self.magnetogram.meta['bunit'])
        # Take gradient using a five-point stencil
        Bx[2:-2, 2:-2, 2:-2] = -(phi[2:-2, :-4, 2:-2] - 8.*phi[2:-2, 1:-3, 2:-2]
                                 + 8.*phi[2:-2, 3:-1, 2:-2]
                                 - phi[2:-2, 4:, 2:-2])/12./(self.delta.x * 1. * u.pixel)
        By[2:-2, 2:-2, 2:-2] = -(phi[:-4, 2:-2, 2:-2] - 8.*phi[1:-3, 2:-2, 2:-2]
                                 + 8.*phi[3:-1, 2:-2, 2:-2]
                                 - phi[4:, 2:-2, 2:-2])/12./(self.delta.y * 1. * u.pixel)
        Bz[2:-2, 2:-2, 2:-2] = -(phi[2:-2, 2:-2, :-4] - 8.*phi[2:-2, 2:-2, 1:-3]
                                 + 8.*phi[2:-2, 2:-2, 3:-1]
                                 - phi[2:-2, 2:-2, 4:])/12./(self.delta.z * 1. * u.pixel)
        # Set boundary conditions such that the last two cells in either direction in each dimension
        # are the same as the preceding cell.
        for Bfield in (Bx, By, Bz):
            for j in [0, 1]:
                Bfield[j, :, :] = Bfield[2, :, :]
                Bfield[:, j, :] = Bfield[:, 2, :]
                Bfield[:, :, j] = Bfield[:, :, 2]
            for j in [-2, -1]:
                Bfield[j, :, :] = Bfield[-3, :, :]
                Bfield[:, j, :] = Bfield[:, -3, :]
                Bfield[:, :, j] = Bfield[:, :, -3]

        return SpatialPair(x=Bx, y=By, z=Bz)
Exemplo n.º 9
0
    def calculate_field(self, phi: u.G * u.cm):
        """
        Compute vector magnetic field.

        Calculate the vector magnetic field using the current-free approximation,

        .. math::
            \\vec{B} = -\\nabla\phi

        The gradient is computed numerically using a five-point stencil,

        .. math::
            \\frac{\partial B}{\partial x_i} \\approx -\left(\\frac{-B_{x_i}(x_i + 2\Delta x_i) + 8B_{x_i}(x_i + \Delta x_i) - 8B_{x_i}(x_i - \Delta x_i) + B_{x_i}(x_i - 2\Delta x_i)}{12\Delta x_i}\\right)

        Parameters
        ----------
        phi : `~astropy.units.Quantity`

        Returns
        -------
        B_field : `~synthesizAR.util.SpatialPair`
            x, y, and z components of the vector magnetic field in 3D
        """
        Bfield = u.Quantity(np.zeros(phi.shape + (3,)), self.magnetogram.meta['bunit'])
        # Take gradient--indexed as x,y,z in 4th dimension
        Bfield[2:-2, 2:-2, 2:-2, 0] = -(phi[:-4, 2:-2, 2:-2] - 8.*phi[1:-3, 2:-2, 2:-2] 
                                        + 8.*phi[3:-1, 2:-2, 2:-2]
                                        - phi[4:, 2:-2, 2:-2])/12./(self.delta.x * 1. * u.pixel)
        Bfield[2:-2, 2:-2, 2:-2, 1] = -(phi[2:-2, :-4, 2:-2] - 8.*phi[2:-2, 1:-3, 2:-2]
                                        + 8.*phi[2:-2, 3:-1, 2:-2] 
                                        - phi[2:-2, 4:, 2:-2])/12./(self.delta.y * 1. * u.pixel)
        Bfield[2:-2, 2:-2, 2:-2, 2] = -(phi[2:-2, 2:-2, :-4] - 8.*phi[2:-2, 2:-2, 1:-3]
                                        + 8.*phi[2:-2, 2:-2, 3:-1]
                                        - phi[2:-2, 2:-2, 4:])/12./(self.delta.z * 1. * u.pixel)
        # Set boundary conditions
        for i in range(3):
            for j in [0, 1]:
                Bfield[j, :, :, i] = Bfield[2, :, :, i]
                Bfield[:, j, :, i] = Bfield[:, 2, :, i]
                Bfield[:, :, j, i] = Bfield[:, :, 2, i]
            for j in [-2, -1]:
                Bfield[j, :, :, i] = Bfield[-3, :, :, i]
                Bfield[:, j, :, i] = Bfield[:, -3, :, i]
                Bfield[:, :, j, i] = Bfield[:, :, -3, i]
                
        return SpatialPair(x=Bfield[:, :, :, 1], y=Bfield[:, :, :, 0], z=Bfield[:, :, :, 2])