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
Beispiel #2
0
def test_project(filename):
    """
    Checks that gas projection 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

    unrotated = project_gas(data,
                            resolution=1024,
                            project="masses",
                            parallel=True)

    rotated = project_gas(
        data,
        resolution=1024,
        project="masses",
        rotation_center=centre,
        rotation_matrix=matrix,
        parallel=True,
    )

    assert array_equal(rotated, unrotated)

    remove(output_filename)
from swiftsimio import load
from swiftsimio.visualisation.projection import project_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^2
mass_map = project_gas(data, resolution=1024, project="masses", parallel=True)
# Map in msun * K / mpc^2
mass_weighted_temp_map = project_gas(data,
                                     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
imsave("/cosma5/data/durham/dc-murr1/temp_map.png",
       LogNorm()(temp_map.value),
       cmap="hot")
Beispiel #4
0
import argparse
from matplotlib.pyplot import imsave
from matplotlib.colors import LogNorm

parser = argparse.ArgumentParser()
parser.add_argument('-i', '--ic-file', type=str, required=True)
parser.add_argument('-t', '--top-cells-per-tile', type=int, default=3, required=False)
parser.add_argument('-o', '--outdir', type=str, default='.', required=False)
args = parser.parse_args()


mask = sw.mask(args.ic_file)
boxsize = mask.metadata.boxsize
load_region = [
    [0. * boxsize[0], 1. * boxsize[0]],
    [0. * boxsize[1], 1. * boxsize[1]],
    [0. * boxsize[2], 0.1 * boxsize[2]],
]

mask.constrain_spatial(load_region)
data = sw.load(args.ic_file, mask=mask)

mass_map = project_gas(
    data,
    resolution=1024,
    project="densities",
    parallel=True,
    backend="subsampled"
)

imsave("gas_slice_map.png", LogNorm()(mass_map), cmap="viridis")
Beispiel #5
0
from swiftsimio import load
from swiftsimio.visualisation.projection import project_gas

data = load("/cosma6/data/dp004/dc-borr1/swift-test-data/eagle_0037.hdf5")


# This creates a grid that has units msun / Mpc^2, and can be transformed like
# any other unyt quantity
mass_map = project_gas(data, resolution=1024, project="masses", parallel=True)


# Let's say we wish to save it as msun / kpc^2,
#from unyt import msun, kpc
#mass_map.convert_to_units(msun / kpc**2)

from matplotlib.pyplot import imsave
from matplotlib.colors import LogNorm

# Normalize and save
imsave("/cosma5/data/durham/dc-murr1/gas_density_projection.pdf", LogNorm()(mass_map.value), cmap="copper")
Beispiel #6
0
    def process_single_halo(
            self,
            zoom_obj: Zoom = None,
            path_to_snap: str = None,
            path_to_catalogue: str = None,
            mask_radius_r500: float = 6,
            map_centre: Union[str, list,
                              np.ndarray] = 'vr_centre_of_potential',
            temperature_range: Optional[tuple] = None,
            depth: Optional[float] = None,
            return_type: Union[type, str] = 'class'):
        sw_data, vr_data = self.get_handles_from_zoom(
            zoom_obj,
            path_to_snap,
            path_to_catalogue,
            mask_radius_r500=mask_radius_r500,
        )

        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 = vr_data.positions.xcminpot[0].to('Mpc') / vr_data.a
            _yCen = vr_data.positions.ycminpot[0].to('Mpc') / vr_data.a
            _zCen = vr_data.positions.zcminpot[0].to('Mpc') / vr_data.a

        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"
            )

        _r500 = vr_data.spherical_overdensities.r_500_rhocrit[0].to(
            'Mpc') / vr_data.a

        region = [
            _xCen - mask_radius_r500 / np.sqrt(3) * _r500,
            _xCen + mask_radius_r500 / np.sqrt(3) * _r500,
            _yCen - mask_radius_r500 / np.sqrt(3) * _r500,
            _yCen + mask_radius_r500 / np.sqrt(3) * _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]

        if depth is not None:

            depth = min(depth * Mpc, mask_radius_r500 * np.sqrt(3) * _r500)

            depth_filter = np.where(
                (sw_data.gas.coordinates[:, -1] > _zCen - depth / 2)
                & (sw_data.gas.coordinates[:, -1] < _zCen + depth / 2))[0]

            if xlargs.debug:
                percent = f"{len(depth_filter) / len(sw_data.gas.temperatures) * 100:.1f}"
                print((
                    f"Filtering particles by depth: +/- {depth:.2f}/2  Mpc.\n"
                    f"Total particles: {len(sw_data.gas.temperatures)}\n"
                    f"Particles within bounds: {len(depth_filter)} = {percent} %"
                ))

            sw_data.gas.coordinates = sw_data.gas.coordinates[depth_filter]
            sw_data.gas.smoothing_lengths = sw_data.gas.smoothing_lengths[
                depth_filter]
            sw_data.gas.masses = sw_data.gas.masses[depth_filter]
            sw_data.gas.densities = sw_data.gas.densities[depth_filter]
            sw_data.gas.temperatures = sw_data.gas.temperatures[depth_filter]

        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 = project_gas(project='entropies_physical',
                                  data=sw_data,
                                  resolution=self.resolution,
                                  parallel=self.parallel,
                                  region=region,
                                  backend=self.backend).to('keV*cm**2/Mpc**2')

        elif self._project_quantity == 'temperatures':
            sw_data.gas.mwtemps = sw_data.gas.masses * sw_data.gas.temperatures

            mass_weighted_temp_map = project_gas(project='mwtemps',
                                                 data=sw_data,
                                                 resolution=self.resolution,
                                                 parallel=self.parallel,
                                                 region=region,
                                                 backend=self.backend)
            mass_map = project_gas(project='masses',
                                   data=sw_data,
                                   resolution=self.resolution,
                                   parallel=self.parallel,
                                   region=region,
                                   backend=self.backend)

            with np.errstate(divide='ignore', invalid='ignore'):
                gas_map = mass_weighted_temp_map / mass_map

            gas_map = gas_map.to('K')

        else:
            gas_map = project_gas(project=self._project_quantity,
                                  data=sw_data,
                                  resolution=self.resolution,
                                  parallel=self.parallel,
                                  region=region,
                                  backend=self.backend)

        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