def magnetic_field_to_yt_dataset(Bx: u.gauss, By: u.gauss, Bz: u.gauss, range_x: u.cm, range_y: u.cm, range_z: u.cm): """ Reshape vector magnetic field data into a yt dataset Parameters ---------- Bx,By,Bz : `~astropy.units.Quantity` 3D arrays holding the x,y,z components of the extrapolated field range_x, range_y, range_z : `~astropy.units.Quantity` Spatial range in the x,y,z dimensions of the grid """ Bx = Bx.to(u.gauss) By = By.to(u.gauss) Bz = Bz.to(u.gauss) data = dict(Bx=(np.swapaxes(Bx.value, 0, 1), Bx.unit.to_string()), By=(np.swapaxes(By.value, 0, 1), By.unit.to_string()), Bz=(np.swapaxes(Bz.value, 0, 1), Bz.unit.to_string())) # Uniform, rectangular grid bbox = np.array([ range_x.to(u.cm).value, range_y.to(u.cm).value, range_z.to(u.cm).value ]) return yt.load_uniform_grid(data, data['Bx'][0].shape, bbox=bbox, length_unit=yt.units.cm, geometry=('cartesian', ('x', 'y', 'z')))
def refine_loops(self, delta_s: u.cm): """ Interpolate loop coordinates and field strengths to a specified spatial resolution and return a new `Skeleton` object. This can be important in order to ensure that an adequate number of points are used to represent each fieldline when binning intensities onto the instrument grid. """ new_loops = [] for l in self.loops: tck, _ = splprep(l.coordinate.cartesian.xyz.value, u=l.field_aligned_coordinate_norm) new_s = np.arange(0, l.length.to(u.Mm).value, delta_s.to(u.Mm).value) * u.Mm x, y, z = splev((new_s / l.length).decompose(), tck) unit = l.coordinate.cartesian.xyz.unit new_coord = SkyCoord( x=x * unit, y=y * unit, z=z * unit, frame=l.coordinate.frame, representation_type=l.coordinate.representation_type) f_B = interp1d(l.field_aligned_coordinate.to(u.Mm), l.field_strength) new_field_strength = f_B(new_s.to(u.Mm)) * l.field_strength.unit new_loops.append( Loop(l.name, new_coord, new_field_strength, model_results_filename=l.model_results_filename)) return Skeleton(new_loops)
def interpolate_to_uniform_grid(hydrad_root, delta_s: u.cm,): """ Interpolate temperature, density, and velocity to uniform grid """ # Create the strand s = Strand(hydrad_root, read_amr=False) # Create uniform coordinate s_uniform = np.arange(0,s.loop_length.to(u.cm).value, delta_s.to(u.cm).value)*u.cm # Preallocate space for arrays electron_temperature = np.zeros(s.time.shape+s_uniform.shape) ion_temperature = np.zeros(s.time.shape+s_uniform.shape) density = np.zeros(s.time.shape+s_uniform.shape) velocity = np.zeros(s.time.shape+s_uniform.shape) # Interpolate each quantity at each timestep for i,_ in enumerate(s.time): p = s[i] coord = p.coordinate.to(u.cm).value # Temperature tsk = splrep(coord, p.electron_temperature.to(u.K).value,) electron_temperature[i,:] = splev(s_uniform.value, tsk, ext=0) tsk = splrep(coord, p.ion_temperature.to(u.K).value,) ion_temperature[i,:] = splev(s_uniform.value, tsk, ext=0) # Density tsk = splrep(coord, p.electron_density.to(u.cm**(-3)).value) density[i,:] = splev(s_uniform.value,tsk,ext=0) # Velocity tsk = splrep(coord, p.velocity.to(u.cm/u.s).value,) velocity[i,:] = splev(s_uniform.value, tsk, ext=0) return s.time, s_uniform, electron_temperature*u.K, ion_temperature*u.K, density*u.cm**(-3), velocity*u.cm/u.s
def get_uniform_grid(self, delta_s: u.cm): """ Create a spatial grid with uniform spacing `delta_s`. # Parameters: delta_s (`astropy.units.Quantity`): Spacing between each grid point """ return np.arange( 0, self.loop_length.to(u.cm).value, delta_s.to(u.cm).value)*u.cm
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)
def to_constant_grid(self, name, grid: u.cm): """ Interpolate a given quantity onto a spatial grid that is the same at each time step. # Parameters name (`str`): Name of quantity grid (`astropy.units.Quantity`): Spatial grid to interpolate onto """ q_uniform = np.zeros(self.time.shape+grid.shape) grid_cm = grid.to(u.cm).value for i, p in enumerate(self): q = getattr(p, name) tsk = splrep(p.coordinate.to(u.cm).value, q.value,) q_uniform[i, :] = splev(grid_cm, tsk, ext=0) return q_uniform * q.unit
def to_constant_grid(self, name, grid: u.cm, order=1): """ Interpolate a given quantity onto a spatial grid that is the same at each time step. Parameters ---------- name : `str` grid : `~astropy.units.Quantity` Spatial grid to interpolate onto order : `int` Order of the spline interpolation. Defualt is 1. """ q_uniform = np.zeros(self.time.shape + grid.shape) grid_cm = grid.to(u.cm).value for i, p in enumerate(self): q = getattr(p, name) tsk = splrep(p.coordinate.to(u.cm).value, q.value, k=order) q_uniform[i, :] = splev(grid_cm, tsk, ext=0) return q_uniform * q.unit