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
Example #2
0
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)
Example #3
0
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
Example #4
0
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
Example #5
0
    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