def test_selection_render(filename): data = load(filename) bs = data.metadata.boxsize[0] # Projection render_full = project_gas(data, 256, parallel=True) render_partial = project_gas(data, 256, parallel=True, region=[0.25 * bs, 0.75 * bs] * 2) render_tiny = project_gas(data, 256, parallel=True, region=[0 * bs, 0.001 * bs] * 2) # Slicing render_full = slice_gas(data, 256, slice=0.5, parallel=True) render_partial = slice_gas(data, 256, slice=0.5, parallel=True, region=[0.25 * bs, 0.75 * bs] * 2) render_tiny = slice_gas(data, 256, slice=0.5, parallel=True, region=[0 * bs, 0.001 * bs] * 2) # If they don't crash we're happy! return
def test_slice(filename): """ Checks that a slice of a single particle snapshot is invariant under rotations around the particle Parameters ---------- filename: str name of file providing metadata to copy """ # Start from the beginning, open the file output_filename = "single_particle.hdf5" create_single_particle_dataset(filename, output_filename) data = load(output_filename) # Compute rotation matrix for rotating around particle centre = data.gas.coordinates[0] rotate_vec = [0.5, 0.5, 0.5] matrix = rotation_matrix_from_vector(rotate_vec, axis="z") boxsize = data.metadata.boxsize z_range = boxsize[2] slice_z = centre[2] / z_range unrotated = slice_gas(data, resolution=1024, slice=slice_z, project="masses", parallel=True) rotated = slice_gas( data, resolution=1024, slice=slice_z, project="masses", rotation_center=centre, rotation_matrix=matrix, parallel=True, ) # Check that we didn't miss the particle assert unrotated.any() assert rotated.any() assert array_equal(rotated, unrotated) remove(output_filename)
from swiftsimio import load from swiftsimio.visualisation.slice import slice_gas data = load("/cosma6/data/dp004/dc-borr1/swift-test-data/eagle_0037.hdf5") # First create a mass-weighted temperature dataset data.gas.mass_weighted_temps = data.gas.masses * data.gas.temperatures # Map in msun / mpc^3 mass_map = slice_gas(data, slice=0.5, resolution=1024, project="masses", parallel=True) # Map in msun * K / mpc^3 mass_weighted_temp_map = slice_gas(data, slice=0.5, resolution=1024, project="mass_weighted_temps", parallel=True) temp_map = mass_weighted_temp_map / mass_map from unyt import K temp_map.convert_to_units(K) from matplotlib.pyplot import imsave from matplotlib.colors import LogNorm # Normalize and save
def plot_result(filename): """ Create and save the plot """ print("working on", filename) data = swiftsimio.load(filename) meta = data.metadata global imshow_kwargs imshow_kwargs["extent"] = [ 0.0 * meta.boxsize[0].v, 0.9 * meta.boxsize[0].v, 0.0 * meta.boxsize[1].v, 0.9 * meta.boxsize[1].v, ] cutoff = int(0.05 * slice_kwargs["resolution"]) mass_map = slice_gas(data, project="masses", **slice_kwargs) gamma = meta.hydro_scheme["Adiabatic index"][0] data.gas.mXHI = data.gas.ion_mass_fractions.HI * data.gas.masses data.gas.mXHII = data.gas.ion_mass_fractions.HII * data.gas.masses data.gas.mP = data.gas.pressures * data.gas.masses data.gas.mrho = data.gas.densities * data.gas.masses imf = data.gas.ion_mass_fractions mu = mean_molecular_weight(imf.HI, imf.HII, imf.HeI, imf.HeII, imf.HeIII) data.gas.mT = (gas_temperature(data.gas.internal_energies, mu, gamma) * data.gas.masses) mass_weighted_hydrogen_map = slice_gas(data, project="mXHI", **slice_kwargs) mass_weighted_pressure_map = slice_gas(data, project="mP", **slice_kwargs) mass_weighted_density_map = slice_gas(data, project="mrho", **slice_kwargs) mass_weighted_temperature_map = slice_gas(data, project="mT", **slice_kwargs) hydrogen_map = mass_weighted_hydrogen_map / mass_map hydrogen_map = hydrogen_map[cutoff:-cutoff, cutoff:-cutoff] pressure_map = mass_weighted_pressure_map / mass_map pressure_map = pressure_map[cutoff:-cutoff, cutoff:-cutoff] pressure_map = pressure_map.to("g/cm/s**2") density_map = mass_weighted_density_map / mass_map density_map = density_map[cutoff:-cutoff, cutoff:-cutoff] density_map = density_map.to("kg/cm**3") density_map = density_map / unyt.proton_mass temperature_map = mass_weighted_temperature_map / mass_map temperature_map = temperature_map[cutoff:-cutoff, cutoff:-cutoff] temperature_map = temperature_map.to("K") fig = plt.figure(figsize=(12, 12), dpi=200) figname = filename[:-5] + ".png" ax1 = fig.add_subplot(221) ax2 = fig.add_subplot(222) ax3 = fig.add_subplot(223) ax4 = fig.add_subplot(224) try: im1 = ax1.imshow( density_map.T, **imshow_kwargs, norm=LogNorm(vmin=1e-4, vmax=1e-1), cmap="bone", ) set_colorbar(ax1, im1) ax1.set_title(r"Hydrogen Number Density [cm$^{-3}$]") except ValueError: print( filename, "densities wrong? min", data.gas.densities.min(), "max", data.gas.densities.max(), ) return try: im2 = ax2.imshow( hydrogen_map.T, **imshow_kwargs, norm=LogNorm(vmin=1e-3, vmax=1.0), cmap="cividis", ) set_colorbar(ax2, im2) ax2.set_title("Hydrogen Mass Fraction [1]") except ValueError: print( filename, "mass fraction wrong? min", data.gas.ion_mass_fractions.HI.min(), "max", data.gas.ion_mass_fractions.HI.max(), ) return try: im3 = ax3.imshow( pressure_map.T, **imshow_kwargs, norm=LogNorm(vmin=1e-15, vmax=1e-12), cmap="viridis", ) set_colorbar(ax3, im3) ax3.set_title(r"Pressure [g/cm/s$^2$]") except ValueError: print( filename, "pressures wrong? min", data.gas.pressures.min(), "max", data.gas.pressures.max(), ) return try: im4 = ax4.imshow( temperature_map.T, **imshow_kwargs, norm=LogNorm(vmin=1e2, vmax=4e4), cmap="inferno", ) set_colorbar(ax4, im4) ax4.set_title(r"Temperature [K]") except ValueError: print( filename, "temperatures wrong? min", temperature_map.min(), "max", temperature_map.max(), ) return for ax in [ax1, ax2, ax3, ax4]: ax.set_xlabel("[kpc]") ax.set_ylabel("[kpc]") title = filename.replace("_", "\_") # exception handle underscore for latex if meta.cosmology is not None: title += ", $z$ = {0:.2e}".format(meta.z) title += ", $t$ = {0:.2e}".format(meta.time.to("Myr")) fig.suptitle(title) plt.tight_layout() plt.savefig(figname) plt.close() gc.collect() return
def process_single_halo( self, zoom_obj: Zoom = None, path_to_snap: str = None, path_to_catalogue: str = None, mask_radius: Tuple[float, str] = (6, 'r500'), map_centre: Union[str, list, np.ndarray] = 'vr_centre_of_potential', temperature_range: Optional[tuple] = None, depth_offset: Optional[float] = None, return_type: Union[type, str] = 'class', inscribe_mask: bool = False, ): sw_data, vr_data = self.get_handles_from_zoom( zoom_obj, path_to_snap, path_to_catalogue, mask_radius_r500=15, ) map_centres_allowed = [ 'vr_centre_of_potential' ] if type(map_centre) is str and map_centre.lower() not in map_centres_allowed: raise AttributeError(( f"String-commands for `map_centre` only support " f"`vr_centre_of_potential`. Got {map_centre} instead." )) elif (type(map_centre) is list or type(map_centre) is np.ndarray) and len(map_centre) != 3: raise AttributeError(( f"List-commands for `map_centre` only support " f"length-3 lists. Got {map_centre} " f"(length {len(map_centre)}) instead." )) self.map_centre = map_centre centre_of_potential = [ vr_data.positions.xcminpot[0].to('Mpc') / vr_data.a, vr_data.positions.ycminpot[0].to('Mpc') / vr_data.a, vr_data.positions.zcminpot[0].to('Mpc') / vr_data.a ] if self.map_centre == 'vr_centre_of_potential': _xCen = centre_of_potential[0] _yCen = centre_of_potential[1] _zCen = centre_of_potential[2] elif type(self.map_centre) is list or type(self.map_centre) is np.ndarray: _xCen = self.map_centre[0] * Mpc / vr_data.a _yCen = self.map_centre[1] * Mpc / vr_data.a _zCen = self.map_centre[2] * Mpc / vr_data.a if xlargs.debug: print(f"Centre of potential: {[float(f'{i.v:.3f}') for i in centre_of_potential]} Mpc") print(f"Map centre: {[float(f'{i.v:.3f}') for i in [_xCen, _yCen, _zCen]]} Mpc") self.depth = _zCen / sw_data.metadata.boxsize[0] if depth_offset is not None: self.depth += depth_offset * Mpc / sw_data.metadata.boxsize[0] if xlargs.debug: percent = f"{depth_offset * Mpc / _zCen * 100:.1f}" print(( f"Imposing offset in slicing depth: {depth_offset:.2f} Mpc.\n" f"Percentage shift compared to centre: {percent} %" )) _r500 = vr_data.spherical_overdensities.r_500_rhocrit[0].to('Mpc') / vr_data.a if mask_radius[1] == 'r500': mask_radius_r500 = mask_radius[0] * _r500 else: mask_radius_r500 = unyt_quantity(mask_radius[0], units=mask_radius[1]) if inscribe_mask: mask_radius_r500 /= np.sqrt(3) region = [ _xCen - mask_radius_r500, _xCen + mask_radius_r500, _yCen - mask_radius_r500, _yCen + mask_radius_r500 ] if temperature_range is not None: temp_filter = np.where( (sw_data.gas.temperatures > temperature_range[0]) & (sw_data.gas.temperatures < temperature_range[1]) )[0] if xlargs.debug: percent = f"{len(temp_filter) / len(sw_data.gas.temperatures) * 100:.1f}" print(( f"Filtering particles by temperature: {temperature_range} K.\n" f"Total particles: {len(sw_data.gas.temperatures)}\n" f"Particles within bounds: {len(temp_filter)} = {percent} %" )) sw_data.gas.coordinates = sw_data.gas.coordinates[temp_filter] sw_data.gas.smoothing_lengths = sw_data.gas.smoothing_lengths[temp_filter] sw_data.gas.masses = sw_data.gas.masses[temp_filter] sw_data.gas.densities = sw_data.gas.densities[temp_filter] sw_data.gas.temperatures = sw_data.gas.temperatures[temp_filter] # Rotate about CoP if required center = [_xCen, _yCen, _zCen] rotate_vec = [0, 0, 1] matrix = rotation_matrix_from_vector(rotate_vec, axis='z') common_kwargs = dict( rotation_matrix=matrix, rotation_center=center, data=sw_data, resolution=self.resolution, parallel=self.parallel, region=region, slice=self.depth ) if self._project_quantity == 'entropies': number_density = (sw_data.gas.densities / mh).to('cm**-3') / mean_molecular_weight entropy = kb * sw_data.gas.temperatures / number_density ** (2 / 3) sw_data.gas.entropies_physical = entropy.to('keV*cm**2') gas_map = slice_gas(project='entropies_physical', **common_kwargs).to('keV*cm**2/Mpc**3') elif self._project_quantity == 'temperatures': sw_data.gas.mwtemps = sw_data.gas.masses * sw_data.gas.temperatures mass_weighted_temp_map = slice_gas(project='mwtemps', **common_kwargs) mass_map = slice_gas(project='masses', **common_kwargs) with np.errstate(divide='ignore', invalid='ignore'): gas_map = mass_weighted_temp_map / mass_map gas_map = gas_map.to('K') else: gas_map = slice_gas(project=self._project_quantity, **common_kwargs) units = gas_map.units gas_map = gas_map.value gas_map = np.ma.array( gas_map, mask=(gas_map <= 0.), fill_value=np.nan, copy=True, dtype=np.float64 ) output_values = [ gas_map, region, units, [_xCen, _yCen, _zCen], _r500, sw_data.metadata.z ] output_names = [ 'map', 'region', 'units', 'centre', 'r500', 'z' ] if return_type is tuple: output = tuple(output_values) elif return_type is dict: output = dict(zip(output_names, output_values)) elif return_type == 'class': OutputClass = namedtuple('OutputClass', output_names) output = OutputClass(*output_values) else: raise TypeError(f"Return type {return_type} not recognised.") return output