def test_basic_load_catalogue_no_crash(
        filename="/Users/mphf18/Desktop/halo_027_z00p101.properties"):
    catalogue = load(filename)

    import pdb

    pdb.set_trace()

    return
예제 #2
0
def read(snapshot_number):
    _, path_to_catalogue = find_files()

    path_to_catalogue.replace(f'{xlargs.snapshot_number:04d}', f'{snapshot_number:04d}')

    vr_handle = velociraptor.load(path_to_catalogue)
    r500 = vr_handle.spherical_overdensities.r_500_rhocrit[0].to('Mpc').value
    xcminpot = vr_handle.positions.xcminpot[0].to('Mpc').value
    ycminpot = vr_handle.positions.ycminpot[0].to('Mpc').value
    zcminpot = vr_handle.positions.zcminpot[0].to('Mpc').value
    return r500, xcminpot, ycminpot, zcminpot
예제 #3
0
def profile_3d_particles(
    path_to_snap: str,
    path_to_catalogue: str,
) -> tuple:
    # Read in halo properties
    vr_catalogue_handle = vr.load(path_to_catalogue)
    M500 = vr_catalogue_handle.spherical_overdensities.mass_500_rhocrit[0].to(
        'Msun')
    R500 = vr_catalogue_handle.spherical_overdensities.r_500_rhocrit[0].to(
        'Mpc')
    XPotMin = vr_catalogue_handle.positions.xcminpot[0].to('Mpc')
    YPotMin = vr_catalogue_handle.positions.ycminpot[0].to('Mpc')
    ZPotMin = vr_catalogue_handle.positions.zcminpot[0].to('Mpc')

    # Apply spatial mask to particles. SWIFTsimIO needs comoving coordinates
    # to filter particle coordinates, while VR outputs are in physical units.
    # Convert the region bounds to comoving, but keep the CoP and Rcrit in
    # physical units for later use.
    mask = sw.mask(path_to_snap, spatial_only=True)
    region = [[(XPotMin - R500), (XPotMin + R500)],
              [(YPotMin - R500), (YPotMin + R500)],
              [(ZPotMin - R500), (ZPotMin + R500)]]
    mask.constrain_spatial(region)
    data = sw.load(path_to_snap, mask=mask)

    # Select hot gas within sphere
    tempGas = data.gas.temperatures
    deltaX = data.gas.coordinates[:, 0] - XPotMin
    deltaY = data.gas.coordinates[:, 1] - YPotMin
    deltaZ = data.gas.coordinates[:, 2] - ZPotMin
    radial_distance = np.sqrt(deltaX**2 + deltaY**2 + deltaZ**2) / R500
    index = np.where((radial_distance < 2) & (tempGas > 1e5))[0]
    del tempGas, deltaX, deltaY, deltaZ

    mass_weighted_temperatures = (data.gas.temperatures *
                                  unyt.boltzmann_constant).to('keV')
    number_densities = (data.gas.densities.to('g/cm**3') /
                        (unyt.mp * mean_molecular_weight)).to('cm**-3')
    field_value = mass_weighted_temperatures / number_densities**(2 / 3)

    radial_distance = radial_distance[index]
    entropies = field_value[index]
    temperatures = mass_weighted_temperatures[index]

    rho_crit = unyt.unyt_quantity(
        data.metadata.cosmology.critical_density(data.metadata.z).value,
        'g/cm**3').to('Msun/Mpc**3')
    densities = data.gas.densities[index] / rho_crit

    return radial_distance, densities, temperatures, entropies, M500, R500
예제 #4
0
    def get_vr_handle(self, zoom_obj: Zoom = None, path_to_catalogue: str = None):

        if xlargs.debug:
            assert (
                    zoom_obj is not None or
                    (path_to_catalogue is not None and path_to_catalogue is not None)
            ), (
                "Either a `Zoom` object must be specified or the absolute "
                "paths to the snapshot and properties catalogue files."
            )

        catalog_file = path_to_catalogue

        if zoom_obj is not None:
            zoom_at_redshift = zoom_obj.get_redshift(xlargs.redshift_index)
            catalog_file = zoom_at_redshift.catalogue_properties_path

        return velociraptor.load(catalog_file, disregard_units=True)
예제 #5
0
def profile_3d_shells(
    path_to_snap: str,
    path_to_catalogue: str,
) -> tuple:
    # Read in halo properties
    vr_catalogue_handle = vr.load(path_to_catalogue)
    M500 = vr_catalogue_handle.spherical_overdensities.mass_500_rhocrit[0].to(
        'Msun')
    R500 = vr_catalogue_handle.spherical_overdensities.r_500_rhocrit[0].to(
        'Mpc')
    XPotMin = vr_catalogue_handle.positions.xcminpot[0].to('Mpc')
    YPotMin = vr_catalogue_handle.positions.ycminpot[0].to('Mpc')
    ZPotMin = vr_catalogue_handle.positions.zcminpot[0].to('Mpc')

    # Apply spatial mask to particles. SWIFTsimIO needs comoving coordinates
    # to filter particle coordinates, while VR outputs are in physical units.
    # Convert the region bounds to comoving, but keep the CoP and Rcrit in
    # physical units for later use.
    mask = sw.mask(path_to_snap, spatial_only=True)
    region = [[(XPotMin - R500), (XPotMin + R500)],
              [(YPotMin - R500), (YPotMin + R500)],
              [(ZPotMin - R500), (ZPotMin + R500)]]
    mask.constrain_spatial(region)
    data = sw.load(path_to_snap, mask=mask)

    # Select gas within sphere and main FOF halo
    fof_id = data.gas.fofgroup_ids
    tempGas = data.gas.temperatures
    deltaX = data.gas.coordinates[:, 0] - XPotMin
    deltaY = data.gas.coordinates[:, 1] - YPotMin
    deltaZ = data.gas.coordinates[:, 2] - ZPotMin
    radial_distance = np.sqrt(deltaX**2 + deltaY**2 + deltaZ**2) / R500
    index = np.where((radial_distance < 2) & (fof_id == 1)
                     & (tempGas > 1e5))[0]
    del deltaX, deltaY, deltaZ, fof_id, tempGas

    radial_distance = radial_distance[index]
    data.gas.masses = data.gas.masses[index]
    data.gas.temperatures = data.gas.temperatures[index]

    # Define radial bins and shell volumes
    lbins = np.logspace(-3, 2, 40) * radial_distance.units
    radial_bin_centres = 10.0**(
        0.5 * np.log10(lbins[1:] * lbins[:-1])) * radial_distance.units
    volume_shell = (4. * np.pi / 3.) * (R500**3) * ((lbins[1:])**3 -
                                                    (lbins[:-1])**3)

    mass_weights, _ = histogram_unyt(radial_distance,
                                     bins=lbins,
                                     weights=data.gas.masses)
    mass_weights[mass_weights == 0] = np.nan  # Replace zeros with Nans
    density_profile = mass_weights / volume_shell
    number_density_profile = (density_profile.to('g/cm**3') /
                              (unyt.mp * mean_molecular_weight)).to('cm**-3')

    mass_weighted_temperatures = (
        data.gas.temperatures *
        unyt.boltzmann_constant).to('keV') * data.gas.masses
    temperature_weights, _ = histogram_unyt(radial_distance,
                                            bins=lbins,
                                            weights=mass_weighted_temperatures)
    temperature_weights[temperature_weights ==
                        0] = np.nan  # Replace zeros with Nans
    temperature_profile = temperature_weights / mass_weights  # kBT in units of [keV]

    entropy_profile = temperature_profile / number_density_profile**(2 / 3)

    rho_crit = unyt.unyt_quantity(
        data.metadata.cosmology.critical_density(data.metadata.z).value,
        'g/cm**3').to('Msun/Mpc**3')
    density_profile /= rho_crit

    return radial_bin_centres, density_profile, temperature_profile, entropy_profile, M500, R500
예제 #6
0
from velociraptor.particles import load_groups
from velociraptor import load
from velociraptor.swift.swift import to_swiftsimio_dataset
from swiftsimio.visualisation.sphviewer import SPHViewerWrapper
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt
from matplotlib.colors import LogNorm

catalogue = load("/cosma6/data/dp004/dc-borr1/snap7/new_randomness_runs/adiabatic/Run_0/halo_0007.properties")
groups = load_groups("/cosma6/data/dp004/dc-borr1/snap7/new_randomness_runs/adiabatic/Run_0/halo_0007.catalog_groups", catalogue=catalogue)

particles, unbound_particles = groups.extract_halo(halo_id=0)

data, mask = to_swiftsimio_dataset(
    particles,
    "/cosma6/data/dp004/dc-borr1/snap7/new_randomness_runs/adiabatic/Run_0/eagle_0007.hdf5",
    generate_extra_mask=True
)


particle_data = getattr(data, 'dark_matter')
sphviewer = SPHViewerWrapper(particle_data)

x = particles.x / data.metadata.a
y = particles.y / data.metadata.a
z = particles.z / data.metadata.a
r_size = particles.r_size * 0.8 / data.metadata.a

sphviewer.get_camera(x=x, y=y, z=z, r=r_size, zoom=2, xsize=1024, ysize=1024)
sphviewer.get_scene()
예제 #7
0
from velociraptor import load
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot
import numpy
from velociraptor.tools.labels import get_full_label
import unyt
from velociraptor.observations import load_observation

pyplot.rcParams.update({'font.size':40})

data = load('/cosma6/data/dp004/dc-borr1/swift-test-data/halo_0037/halo_0037.properties', disregard_units = True)
obs = numpy.loadtxt('/cosma5/data/durham/dc-murr1/Zahid2014.txt')



mass = data.masses.m_star_30kpc
x = data.metallicity.zmet_gas
mass.convert_to_units('msun')

x_wh = numpy.where(x != 0)[0]
mass = mass[x_wh]
x = x[x_wh]
m_wh = numpy.where(mass != 0)[0]
x = x[m_wh]
mass = mass[m_wh]

xlabel = get_full_label(mass)
ylabel = get_full_label(x)

obs = numpy.loadtxt('/cosma5/data/durham/dc-murr1/Zahid2014.txt')
예제 #8
0
    def get_handles_from_paths(
            self,
            path_to_snap: str,
            path_to_catalogue: str,
            mask_radius_r500: float = 10
    ) -> tuple:
        """
        All quantities in the VR file are physical.
        All quantities in the Swiftsimio file are comoving. Convert them upon use.
        Args:
            path_to_snap:
            path_to_catalogue:
            mask_radius_r500:

        Returns:

        TODO:

        """
        # Read in halo properties
        vr_handle = velociraptor.load(path_to_catalogue, disregard_units=True)

        # Try to import r500 from the catalogue.
        # If not there (and needs to be computed), assume 1 Mpc for the spatial mask.
        try:
            r500 = vr_handle.spherical_overdensities.r_500_rhocrit[0].to('Mpc') / vr_handle.a
        except Exception as err:
            r500 = unyt_quantity(3, 'Mpc') / vr_handle.a
            if xlargs.debug:
                print(err, "Setting r500 = 3. Mpc. / scale_factor", sep='\n')

        xcminpot = vr_handle.positions.xcminpot[0].to('Mpc') / vr_handle.a
        ycminpot = vr_handle.positions.ycminpot[0].to('Mpc') / vr_handle.a
        zcminpot = vr_handle.positions.zcminpot[0].to('Mpc') / vr_handle.a

        # Apply spatial mask to particles. SWIFTsimIO needs comoving coordinates
        # to filter particle coordinates, while VR outputs are in physical units.
        # Convert the region bounds to comoving, but keep the CoP and Rcrit in
        # physical units for later use.
        mask = swiftsimio.mask(path_to_snap)
        mask_radius = mask_radius_r500 * r500
        region = [
            [xcminpot - mask_radius, xcminpot + mask_radius],
            [ycminpot - mask_radius, ycminpot + mask_radius],
            [zcminpot - mask_radius, zcminpot + mask_radius]
        ]
        mask.constrain_spatial(region)
        sw_handle = swiftsimio.load(path_to_snap, mask=mask)

        if len(sw_handle.gas.coordinates) == 0:
            raise ValueError((
                "The spatial masking of the snapshot returned 0 particles. "
                "Check whether an appropriate aperture is selected and if "
                "the physical/comoving units match."
            ))
        elif xlargs.debug:
            print((
                f"[{self.__class__.__name__}] Particles in snap file:\n\t| "
                f"{sw_handle.metadata.n_gas:11d} gas | "
                f"{sw_handle.metadata.n_dark_matter:11d} dark_matter | "
                f"{sw_handle.metadata.n_stars:11d} stars | "
                f"{sw_handle.metadata.n_black_holes:11d} black_holes | "
            ))

        # If the mask overlaps with the box boundaries, wrap coordinates.
        boxsize = sw_handle.metadata.boxsize
        centre_coordinates = unyt_array([xcminpot, ycminpot, zcminpot], xcminpot.units)

        sw_handle.gas.coordinates = self.wrap_coordinates(
            sw_handle.gas.coordinates,
            centre_coordinates,
            boxsize
        )

        sw_handle.dark_matter.coordinates = self.wrap_coordinates(
            sw_handle.dark_matter.coordinates,
            centre_coordinates,
            boxsize
        )

        if sw_handle.metadata.n_stars > 0:
            sw_handle.stars.coordinates = self.wrap_coordinates(
                sw_handle.stars.coordinates,
                centre_coordinates,
                boxsize
            )

        if sw_handle.metadata.n_black_holes > 0:
            sw_handle.black_holes.coordinates = self.wrap_coordinates(
                sw_handle.black_holes.coordinates,
                centre_coordinates,
                boxsize
            )

        # Compute radial distances
        sw_handle.gas.radial_distances = self.get_radial_distance(
            sw_handle.gas.coordinates,
            centre_coordinates
        )

        sw_handle.dark_matter.radial_distances = self.get_radial_distance(
            sw_handle.dark_matter.coordinates,
            centre_coordinates
        )

        if sw_handle.metadata.n_stars > 0:
            sw_handle.stars.radial_distances = self.get_radial_distance(
                sw_handle.stars.coordinates,
                centre_coordinates
            )

        if sw_handle.metadata.n_black_holes > 0:
            sw_handle.black_holes.radial_distances = self.get_radial_distance(
                sw_handle.black_holes.coordinates,
                centre_coordinates
            )

        if xlargs.debug:

            print((
                f"[{self.__class__.__name__}] Particles in mask:\n\t| "
                f"{sw_handle.gas.coordinates.shape[0]:11d} gas | "
                f"{sw_handle.dark_matter.coordinates.shape[0]:11d} dark_matter | "
                f"{sw_handle.stars.coordinates.shape[0] if sw_handle.metadata.n_stars > 0 else 0:11d} stars | "
                f"{sw_handle.black_holes.coordinates.shape[0] if sw_handle.metadata.n_black_holes > 0 else 0:11d} black_holes | "
            ))

        return sw_handle, vr_handle
예제 #9
0
velociraptor_properties = velociraptor_base_name
velociraptor_groups = velociraptor_base_name.replace("properties",
                                                     "catalog_groups")

filenames = {
    "parttypes_filename":
    velociraptor_base_name.replace("properties", "catalog_partypes"),
    "particles_filename":
    velociraptor_base_name.replace("properties", "catalog_particles"),
    "unbound_parttypes_filename":
    velociraptor_base_name.replace("properties", "catalog_partypes.unbound"),
    "unbound_particles_filename":
    velociraptor_base_name.replace("properties", "catalog_particles.unbound"),
}

catalogue = load(velociraptor_properties)
groups = load_groups(velociraptor_groups, catalogue)

# Let's make an image of those particles!
import matplotlib.pyplot as plt
import numpy as np

from swiftsimio.visualisation.sphviewer import SPHViewerWrapper
from matplotlib.colors import LogNorm

particle_type_cmap = {
    "gas": "inferno",
    "stars": "bone",
    "dark_matter": "plasma",
}
예제 #10
0
    def __init__(self, path_to_catalogue: str,
                 galaxy_min_stellar_mass: unyt.array.unyt_quantity):
        """
        Parameters
        ----------
        path_to_catalogue: str
        Path to the catalogue with halo properties

        galaxy_min_stellar_mass: unyt.array.unyt_quantity
        Minimum stellar mass in units of Msun. Objects whose stellar mass is lower than this
        threshold are disregarded
        """

        self.path_to_catalogue = path_to_catalogue

        # Load catalogue using velociraptor python library
        catalogue = load(self.path_to_catalogue)

        # Selecting central galaxies whose stellar mass is larger than
        # 'galaxy_min_stellar_mass'
        mask = np.logical_and(
            catalogue.apertures.mass_star_30_kpc >= galaxy_min_stellar_mass,
            catalogue.structure_type.structuretype == 10,
        )
        # They also need to contain at least one gas particle
        mask = np.logical_and(
            mask, catalogue.apertures.mass_gas_30_kpc > unyt.unyt_quantity(
                0.0, "Msun"))
        # Compute the number of haloes following the selection mask
        self.number_of_haloes = mask.sum()

        # Log10 stellar mass in units of Msun
        self.log10_stellar_mass = np.log10(
            catalogue.apertures.mass_star_30_kpc.to("Msun").value[mask])
        # Log10 gas mass in units of Msun
        self.log10_gas_mass = np.log10(
            catalogue.apertures.mass_gas_30_kpc.to("Msun").value[mask])
        # Log10 halo mass in units of Msun
        self.log10_halo_mass = np.log10(
            catalogue.masses.mass_200crit.to("Msun").value[mask])

        # Half mass radius in units of kpc (stars)
        self.half_mass_radius_star = catalogue.radii.r_halfmass_star.to(
            "kpc").value[mask]
        # Half mass radius in units of kpc (gas)
        self.half_mass_radius_gas = catalogue.radii.r_halfmass_gas.to(
            "kpc").value[mask]

        # Star formation rate in units of Msun/yr
        self.sfr = (catalogue.apertures.sfr_gas_30_kpc.value[mask] *
                    10227144.8879616 / 1e9)

        # Metallicity of star-forming gas
        self.metallicity_gas_sfr = catalogue.apertures.zmet_gas_sf_30_kpc.value[
            mask]

        # Metallicity of all gas
        self.metallicity_gas = catalogue.apertures.zmet_gas_30_kpc.value[mask]

        # Ids of haloes satisfying the selection criterion
        self.halo_ids = np.array(
            [i for i in range(len(mask)) if mask[i] == True])

        self.kappa_co = np.zeros(self.number_of_haloes)
        self.momentum = np.zeros(self.number_of_haloes)
        self.axis_ca = np.zeros(self.number_of_haloes)
        self.axis_cb = np.zeros(self.number_of_haloes)
        self.axis_ba = np.zeros(self.number_of_haloes)

        self.gas_kappa_co = np.zeros(self.number_of_haloes)
        self.gas_momentum = np.zeros(self.number_of_haloes)
        self.gas_axis_ca = np.zeros(self.number_of_haloes)
        self.gas_axis_cb = np.zeros(self.number_of_haloes)
        self.gas_axis_ba = np.zeros(self.number_of_haloes)

        self.sigma_H2 = np.zeros(self.number_of_haloes)
        self.sigma_gas = np.zeros(self.number_of_haloes)
        self.sigma_SFR = np.zeros(self.number_of_haloes)

        self.xminpot = catalogue.positions.xcminpot.to("kpc").value[mask]
        self.yminpot = catalogue.positions.ycminpot.to("kpc").value[mask]
        self.zminpot = catalogue.positions.zcminpot.to("kpc").value[mask]

        self.vxminpot = catalogue.velocities.vxcminpot.to("km/s").value[mask]
        self.vyminpot = catalogue.velocities.vycminpot.to("km/s").value[mask]
        self.vzminpot = catalogue.velocities.vzcminpot.to("km/s").value[mask]
예제 #11
0
    def total_mass_profiles(self):

        # Read in halo properties from catalog
        vr_catalogue_handle = vr.load(self.zoom.catalogue_properties_path)
        a = vr_catalogue_handle.a
        self.r500c = vr_catalogue_handle.spherical_overdensities.r_500_rhocrit[
            0].to('Mpc')
        self.r2500c = vr_catalogue_handle.spherical_overdensities.r_2500_rhocrit[
            0].to('Mpc')
        XPotMin = vr_catalogue_handle.positions.xcminpot[0].to('Mpc')
        YPotMin = vr_catalogue_handle.positions.ycminpot[0].to('Mpc')
        ZPotMin = vr_catalogue_handle.positions.zcminpot[0].to('Mpc')

        # Read in gas particles and parse densities and temperatures
        mask = sw.mask(self.zoom.snapshot_path, spatial_only=False)
        region = [[(XPotMin - 1.5 * self.r500c) / a,
                   (XPotMin + 1.5 * self.r500c) / a],
                  [(YPotMin - 1.5 * self.r500c) / a,
                   (YPotMin + 1.5 * self.r500c) / a],
                  [(ZPotMin - 1.5 * self.r500c) / a,
                   (ZPotMin + 1.5 * self.r500c) / a]]

        mask.constrain_spatial(region)
        mask.constrain_mask("gas", "temperatures",
                            Tcut_halogas * mask.units.temperature,
                            1.e12 * mask.units.temperature)
        data = sw.load(self.zoom.snapshot_path, mask=mask)
        self.fbary = Cosmology().get_baryon_fraction(data.metadata.z)

        # Convert datasets to physical quantities
        # r500c is already in physical units
        data.gas.coordinates.convert_to_physical()
        data.gas.masses.convert_to_physical()
        data.gas.temperatures.convert_to_physical()
        data.gas.densities.convert_to_physical()
        data.dark_matter.coordinates.convert_to_physical()
        data.dark_matter.masses.convert_to_physical()
        data.stars.coordinates.convert_to_physical()
        data.stars.masses.convert_to_physical()

        # Set bounds for the radial profiles
        radius_bounds = [0.15, 1.5]
        lbins = np.logspace(np.log10(radius_bounds[0]),
                            np.log10(radius_bounds[1]),
                            true_data_nbins) * dimensionless

        shell_volume = (4 / 3 * np.pi) * self.r500c**3 * (lbins[1:]**3 -
                                                          lbins[:-1]**3)

        critical_density = unyt_quantity(
            data.metadata.cosmology.critical_density(data.metadata.z).value,
            'g/cm**3').to('Msun/Mpc**3')

        # Select hot gas within sphere and without core
        deltaX = data.gas.coordinates[:, 0] - XPotMin
        deltaY = data.gas.coordinates[:, 1] - YPotMin
        deltaZ = data.gas.coordinates[:, 2] - ZPotMin
        deltaR = np.sqrt(deltaX**2 + deltaY**2 + deltaZ**2) / self.r500c

        # Keep only particles inside 1.5 R500crit
        index = np.where(deltaR < radius_bounds[1])[0]
        central_mass = sum(
            data.gas.masses[np.where(deltaR < radius_bounds[0])[0]])
        mass_weights, _ = histogram_unyt(deltaR[index],
                                         bins=lbins,
                                         weights=data.gas.masses[index])

        self.density_profile_input = mass_weights / shell_volume / critical_density

        # Select DM within sphere and without core
        deltaX = data.dark_matter.coordinates[:, 0] - XPotMin
        deltaY = data.dark_matter.coordinates[:, 1] - YPotMin
        deltaZ = data.dark_matter.coordinates[:, 2] - ZPotMin
        deltaR = np.sqrt(deltaX**2 + deltaY**2 + deltaZ**2) / self.r500c

        # Keep only particles inside 1.5 R500crit
        index = np.where(deltaR < radius_bounds[1])[0]
        central_mass += sum(
            data.dark_matter.masses[np.where(deltaR < radius_bounds[0])[0]])
        _mass_weights, _ = histogram_unyt(
            deltaR[index], bins=lbins, weights=data.dark_matter.masses[index])
        mass_weights += _mass_weights

        # Select stars within sphere and without core
        deltaX = data.stars.coordinates[:, 0] - XPotMin
        deltaY = data.stars.coordinates[:, 1] - YPotMin
        deltaZ = data.stars.coordinates[:, 2] - ZPotMin
        deltaR = np.sqrt(deltaX**2 + deltaY**2 + deltaZ**2) / self.r500c

        # Keep only particles inside 1.5 R500crit
        index = np.where(deltaR < radius_bounds[1])[0]
        central_mass += sum(
            data.stars.masses[np.where(deltaR < radius_bounds[0])[0]])
        _mass_weights, _ = histogram_unyt(deltaR[index],
                                          bins=lbins,
                                          weights=data.stars.masses[index])
        mass_weights += _mass_weights

        # Replace zeros with Nans
        mass_weights[mass_weights == 0] = np.nan
        cumulative_mass = central_mass + cumsum_unyt(mass_weights)

        self.radial_bin_centres_input = 10.0**(
            0.5 * np.log10(lbins[1:] * lbins[:-1])) * dimensionless
        self.cumulative_mass_input = cumulative_mass.to('Msun')
        self.total_density_profile_input = mass_weights / shell_volume / critical_density
예제 #12
0
    def load_xray_profiles(self, spec_fit_data: dict):

        # Read in halo properties from catalog
        vr_catalogue_handle = vr.load(self.catalog_file)
        a = vr_catalogue_handle.a

        with h5.File(self.catalog_file, 'r') as h5file:
            self.r2500c = unyt_quantity(h5file['/SO_R_2500_rhocrit'][0], Mpc)
            self.r500c = unyt_quantity(h5file['/SO_R_500_rhocrit'][0], Mpc)
            XPotMin = unyt_quantity(h5file['/Xcminpot'][0], Mpc)
            YPotMin = unyt_quantity(h5file['/Ycminpot'][0], Mpc)
            ZPotMin = unyt_quantity(h5file['/Zcminpot'][0], Mpc)

        # Read in gas particles and parse densities and temperatures
        mask = sw.mask(self.snapshot_file, spatial_only=False)
        region = [[(XPotMin - 1.5 * self.r500c) * a,
                   (XPotMin + 1.5 * self.r500c) * a],
                  [(YPotMin - 1.5 * self.r500c) * a,
                   (YPotMin + 1.5 * self.r500c) * a],
                  [(ZPotMin - 1.5 * self.r500c) * a,
                   (ZPotMin + 1.5 * self.r500c) * a]]
        mask.constrain_spatial(region)
        mask.constrain_mask("gas", "temperatures",
                            Tcut_halogas * mask.units.temperature,
                            1.e12 * mask.units.temperature)
        data = sw.load(self.snapshot_file, mask=mask)

        # Convert datasets to physical quantities
        # r500c is already in physical units
        data.gas.coordinates.convert_to_physical()
        data.gas.masses.convert_to_physical()
        data.gas.temperatures.convert_to_physical()
        data.gas.densities.convert_to_physical()
        data.dark_matter.coordinates.convert_to_physical()
        data.dark_matter.masses.convert_to_physical()
        data.stars.coordinates.convert_to_physical()
        data.stars.masses.convert_to_physical()

        # Calculate the critical density for the density profile
        self.rho_crit = unyt_quantity(
            data.metadata.cosmology.critical_density(data.metadata.z).value,
            'g/cm**3').to('Msun/Mpc**3')

        # Select hot gas within sphere and without core
        deltaX = data.gas.coordinates[:, 0] - XPotMin
        deltaY = data.gas.coordinates[:, 1] - YPotMin
        deltaZ = data.gas.coordinates[:, 2] - ZPotMin
        deltaR = np.sqrt(deltaX**2 + deltaY**2 + deltaZ**2)

        # Keep only particles inside 5 R500crit
        index = np.where(deltaR < 5 * self.r500c)[0]
        radial_distance_scaled = deltaR[index] / self.r500c
        assert radial_distance_scaled.units == dimensionless
        gas_masses = data.gas.masses[index]

        # Set bounds for the radial profiles
        radius_bounds = [0.15, 5]
        if not self.excise_core:
            # Compute convergence radius and set as inner limit
            gas_convergence_radius = convergence_radius(
                deltaR[index], gas_masses.to('Msun'),
                self.rho_crit.to('Msun/Mpc**3')) / self.r500c
            radius_bounds[0] = gas_convergence_radius.value

        # Create the interpolation objects for the x-ray density and temperature
        for key in ['Rspec', 'RHOspec', 'Tspec']:
            assert key in spec_fit_data, (
                f"{key} key not found in the spec data fitting output: {spec_fit_data}."
            )

        spec_density_interpolate = interp1d(spec_fit_data['Rspec'],
                                            spec_fit_data['RHOspec'],
                                            kind='linear')
        spec_temperature_interpolate = interp1d(spec_fit_data['Rspec'],
                                                spec_fit_data['Tspec'],
                                                kind='linear')

        lbins = np.logspace(np.log10(radius_bounds[0]),
                            np.log10(radius_bounds[1]),
                            true_data_nbins) * radial_distance_scaled.units

        self.radial_bin_centres = 10.0**(
            0.5 * np.log10(lbins[1:] * lbins[:-1])) * dimensionless
        self.radial_bin_edges = lbins

        # Cut ends of the radial bins to interpolate, since they might be
        # outside the spec_fit_data['Rspec'] range
        # Prevents ValueError: A value in x_new is below the interpolation range.
        radial_bins_intersect = np.where(
            (self.radial_bin_centres *
             self.r500c > spec_fit_data['Rspec'].min())
            & (self.radial_bin_centres *
               self.r500c < spec_fit_data['Rspec'].max()))[0]
        self.radial_bin_centres = self.radial_bin_centres[
            radial_bins_intersect]

        # Compute the radial gas density profile
        self.density_profile = spec_density_interpolate(
            self.radial_bin_centres * self.r500c) * dimensionless
        self.temperature_profile = spec_temperature_interpolate(
            self.radial_bin_centres * self.r500c) * keV
예제 #13
0
    def load_zoom_profiles(self):
        # Read in halo properties from catalog
        vr_catalogue_handle = vr.load(self.catalog_file)
        a = vr_catalogue_handle.a

        try:
            self.m200c = vr_catalogue_handle.masses.mass_200crit[0].to('Msun')
            self.r200c = vr_catalogue_handle.radii.r_200crit[0].to('Mpc')
        except AttributeError as err:
            print(f'[{self.__class__.__name__}] {err}')

            spherical_overdensity = SODelta200(
                path_to_snap=self.snapshot_file,
                path_to_catalogue=self.catalog_file,
            )
            self.m200c = spherical_overdensity.get_m200()
            self.r200c = spherical_overdensity.get_r200()

        try:
            self.m500c = vr_catalogue_handle.spherical_overdensities.mass_500_rhocrit[
                0].to('Msun')
            self.r500c = vr_catalogue_handle.spherical_overdensities.r_500_rhocrit[
                0].to('Mpc')
        except AttributeError as err:
            print(f'[{self.__class__.__name__}] {err}')

            spherical_overdensity = SODelta500(
                path_to_snap=self.snapshot_file,
                path_to_catalogue=self.catalog_file,
            )
            self.m500c = spherical_overdensity.get_m500()
            self.r500c = spherical_overdensity.get_r500()

        try:
            self.r2500c = vr_catalogue_handle.spherical_overdensities.r_2500_rhocrit[
                0].to('Mpc')
            self.m2500c = vr_catalogue_handle.spherical_overdensities.mass_2500_rhocrit[
                0].to('Msun')
        except AttributeError as err:
            print(f'[{self.__class__.__name__}] {err}')

            spherical_overdensity = SODelta2500(
                path_to_snap=self.snapshot_file,
                path_to_catalogue=self.catalog_file,
            )
            self.m2500c = spherical_overdensity.get_m2500()
            self.r2500c = spherical_overdensity.get_r2500()

        XPotMin = vr_catalogue_handle.positions.xcminpot[0].to('Mpc')
        YPotMin = vr_catalogue_handle.positions.ycminpot[0].to('Mpc')
        ZPotMin = vr_catalogue_handle.positions.zcminpot[0].to('Mpc')

        # Read in gas particles and parse densities and temperatures
        mask = sw.mask(self.snapshot_file, spatial_only=True)
        region = [[(XPotMin - 1.5 * self.r500c) / a,
                   (XPotMin + 1.5 * self.r500c) / a],
                  [(YPotMin - 1.5 * self.r500c) / a,
                   (YPotMin + 1.5 * self.r500c) / a],
                  [(ZPotMin - 1.5 * self.r500c) / a,
                   (ZPotMin + 1.5 * self.r500c) / a]]
        mask.constrain_spatial(region)
        data = sw.load(self.snapshot_file, mask=mask)

        try:
            _ = data.gas.temperatures
        except AttributeError as err:
            print(f'[{self.__class__.__name__}] {err}')
            if xlargs.debug:
                print(
                    f"[{self.__class__.__name__}] Computing gas temperature from internal energies."
                )
            data.gas.temperatures = data.gas.internal_energies * (
                gamma - 1) * mean_molecular_weight * mh / kb

        try:
            _ = data.gas.fofgroup_ids
        except AttributeError as err:
            print(f'[{self.__class__.__name__}] {err}')
            if xlargs.debug:
                print(
                    f"[{self.__class__.__name__}] Select particles only by radial distance."
                )
            data.gas.fofgroup_ids = np.ones_like(data.gas.densities)

        self.fbary = Cosmology().fb0

        # Convert datasets to physical quantities
        # r500c is already in physical units
        data.gas.coordinates.convert_to_physical()
        data.gas.masses.convert_to_physical()
        data.gas.densities.convert_to_physical()
        data.dark_matter.coordinates.convert_to_physical()
        data.dark_matter.masses.convert_to_physical()
        # data.stars.coordinates.convert_to_physical()
        # data.stars.masses.convert_to_physical()

        # Calculate the critical density for the density profile
        self.rho_crit = unyt_quantity(
            data.metadata.cosmology.critical_density(data.metadata.z).value,
            'g/cm**3').to('Msun/Mpc**3')

        # Select hot gas within sphere and without core
        deltaX = data.gas.coordinates[:, 0] - XPotMin
        deltaY = data.gas.coordinates[:, 1] - YPotMin
        deltaZ = data.gas.coordinates[:, 2] - ZPotMin
        deltaR = np.sqrt(deltaX**2 + deltaY**2 + deltaZ**2)

        # Set bounds for the radial profiles
        radius_bounds = [0.15, 1.5]

        # Keep only particles inside 5 R500crit
        index = np.where(deltaR < radius_bounds[1] * self.r500c)[0]
        radial_distance_scaled = deltaR[index] / self.r500c
        assert radial_distance_scaled.units == dimensionless
        gas_masses = data.gas.masses[index]
        gas_temperatures = data.gas.temperatures[index]
        gas_mass_weighted_temperatures = gas_temperatures * gas_masses

        if not self.excise_core:
            # Compute convergence radius and set as inner limit
            gas_convergence_radius = convergence_radius(
                deltaR[index], gas_masses.to('Msun'),
                self.rho_crit.to('Msun/Mpc**3')) / self.r500c
            radius_bounds[0] = gas_convergence_radius.value

        lbins = np.logspace(np.log10(radius_bounds[0]),
                            np.log10(radius_bounds[1]),
                            true_data_nbins) * radial_distance_scaled.units

        mass_weights, bin_edges = histogram_unyt(radial_distance_scaled,
                                                 bins=lbins,
                                                 weights=gas_masses)

        # Replace zeros with Nans
        mass_weights[mass_weights == 0] = np.nan

        # Set the radial bins as object attribute
        self.radial_bin_centres = 10.0**(
            0.5 * np.log10(lbins[1:] * lbins[:-1])) * dimensionless
        self.radial_bin_edges = lbins

        # Compute the radial gas density profile
        volume_shell = (4. * np.pi / 3.) * (self.r500c**3) * (
            (bin_edges[1:])**3 - (bin_edges[:-1])**3)
        self.density_profile = mass_weights / volume_shell / self.rho_crit
        assert self.density_profile.units == dimensionless

        # Compute the radial mass-weighted temperature profile
        hist, _ = histogram_unyt(radial_distance_scaled,
                                 bins=lbins,
                                 weights=gas_mass_weighted_temperatures)
        hist /= mass_weights
        self.temperature_profile = (hist * kb).to('keV')
예제 #14
0
from velociraptor.particles import load_groups
from velociraptor import load
from velociraptor.swift.swift import to_swiftsimio_dataset
import numpy
import unyt

catalogue = load(
    "/cosma6/data/dp004/dc-borr1/swift-test-data/halo_0037/halo_0037.properties"
)
groups = load_groups(
    "/cosma6/data/dp004/dc-borr1/swift-test-data/halo_0037/halo_0037.catalog_groups",
    catalogue=catalogue)

struc = catalogue.structure_type.structuretype
n = len(struc[struc == 10])
radii = catalogue.apertures.rhalfmass_star_30_kpc
masses = catalogue.apertures.mass_star_30_kpc
radii.convert_to_units(unyt.kpc)
masses.convert_to_units(unyt.msun)

data = numpy.zeros((n, 5))
ids = numpy.where(struc == 10)[0]
data[:, 0] = catalogue.positions.xc[ids]
data[:, 1] = catalogue.positions.yc[ids]
data[:, 2] = catalogue.positions.zc[ids]
data[:, 3] = radii[ids]
data[:, 4] = masses[ids]

numpy.savetxt('/cosma5/data/durham/dc-murr1/halos.txt', data)
예제 #15
0
def profile_3d_single_halo(
        path_to_snap: str,
        path_to_catalogue: str,
        hse_dataset: pd.Series = None,
) -> tuple:
    # Read in halo properties
    vr_catalogue_handle = vr.load(path_to_catalogue)
    a = vr_catalogue_handle.a
    M500 = vr_catalogue_handle.spherical_overdensities.mass_500_rhocrit[0].to('Msun')
    R500 = vr_catalogue_handle.spherical_overdensities.r_500_rhocrit[0].to('Mpc')
    XPotMin = vr_catalogue_handle.positions.xcminpot[0].to('Mpc')
    YPotMin = vr_catalogue_handle.positions.ycminpot[0].to('Mpc')
    ZPotMin = vr_catalogue_handle.positions.zcminpot[0].to('Mpc')

    # If no custom aperture, select r500c as default
    if hse_dataset is not None:
        assert R500.units == hse_dataset["R500hse"].units
        assert M500.units == hse_dataset["M500hse"].units
        R500 = hse_dataset["R500hse"]
        M500 = hse_dataset["M500hse"]

    # Apply spatial mask to particles. SWIFTsimIO needs comoving coordinates
    # to filter particle coordinates, while VR outputs are in physical units.
    # Convert the region bounds to comoving, but keep the CoP and Rcrit in
    # physical units for later use.
    mask = sw.mask(path_to_snap, spatial_only=True)
    region = [
        [(XPotMin - aperture_fraction * R500) / a, (XPotMin + aperture_fraction * R500) / a],
        [(YPotMin - aperture_fraction * R500) / a, (YPotMin + aperture_fraction * R500) / a],
        [(ZPotMin - aperture_fraction * R500) / a, (ZPotMin + aperture_fraction * R500) / a]
    ]
    mask.constrain_spatial(region)
    data = sw.load(path_to_snap, mask=mask)

    # Convert datasets to physical quantities
    # r500c is already in physical units
    data.gas.coordinates.convert_to_physical()
    data.gas.masses.convert_to_physical()
    data.gas.temperatures.convert_to_physical()
    data.gas.densities.convert_to_physical()

    # Select gas within sphere and main FOF halo
    fof_id = data.gas.fofgroup_ids
    deltaX = data.gas.coordinates[:, 0] - XPotMin
    deltaY = data.gas.coordinates[:, 1] - YPotMin
    deltaZ = data.gas.coordinates[:, 2] - ZPotMin
    radial_distance = np.sqrt(deltaX ** 2 + deltaY ** 2 + deltaZ ** 2) / R500
    index = np.where((radial_distance < aperture_fraction) & (fof_id == 1))[0]
    del deltaX, deltaY, deltaZ

    number_density = (data.gas.densities / unyt.mh).to('cm**-3').value[index]
    temperature = (data.gas.temperatures).to('K').value[index]

    agn_flag = data.gas.heated_by_agnfeedback[index]
    snii_flag = data.gas.heated_by_sniifeedback[index]
    agn_flag = agn_flag > 0
    snii_flag = snii_flag > 0

    # Calculate the critical density for the cross-hair marker
    rho_crit = unyt.unyt_quantity(
        data.metadata.cosmology.critical_density(data.metadata.z).value, 'g/cm**3'
    ).to('Msun/Mpc**3')
    nH_500 = (rho_crit * 500 / unyt.mh).to('cm**-3')

    return number_density, temperature, agn_flag, snii_flag, M500, R500, nH_500
"""
Example using the autoplotter library.

See auto_plotter_example.yml for the example
yaml file.
"""

from velociraptor.autoplotter.objects import AutoPlotter
from velociraptor.autoplotter.metadata import AutoPlotterMetadata
from velociraptor import load

catalogue = load("/Users/mphf18/Documents/science/halo_matching/ref/halo_2729.properties")

ap = AutoPlotter("auto_plotter_example.yml")

ap.link_catalogue(catalogue)
ap.create_plots("test_auto_plotter")

metadata = AutoPlotterMetadata(auto_plotter=ap)
metadata.write_metadata("test_auto_plotter/test_metadata.yml")

예제 #17
0
from velociraptor import load
from swiftsimio import load as load_snap
from unyt import unyt_array
from scipy.spatial import cKDTree
import numpy

catalogue = load(
    '/cosma6/data/dp004/dc-borr1/swift-test-data/halo_2730/halo_2730.properties'
)
snap = load_snap('/cosma6/data/dp004/dc-borr1/swift-test-data/eagle_2730.hdf5')

centrals = catalogue.structure_type.structuretype == 10
dm_data = getattr(snap, 'dark_matter', None)
boxsize = snap.metadata.boxsize
tree = cKDTree(dm_data.coordinates.value, boxsize=boxsize.value)

halo_coordinates = (unyt_array([
    getattr(catalogue.positions, f"{x}cmbp")[centrals]
    for x in ["x", "y", "z"]
]).T / catalogue.units.a)

halo_radii = catalogue.radii.r_200mean[centrals] / catalogue.units.a

block_size = 1024
number_of_haloes = halo_radii.size
number_of_blocks = 1 + number_of_haloes // block_size

starting_index = 1 * 1024
ending_index = 2 * 1024

particle_indicies = tree.query_ball_point(x=5, r=4, n_jobs=-1)
예제 #18
0
def profile_3d_single_halo(
    path_to_snap: str,
    path_to_catalogue: str,
    hse_dataset: pd.Series = None,
) -> tuple:
    # Read in halo properties
    vr_catalogue_handle = vr.load(path_to_catalogue)
    a = vr_catalogue_handle.a
    M500 = vr_catalogue_handle.spherical_overdensities.mass_500_rhocrit[0].to(
        'Msun')
    R500 = vr_catalogue_handle.spherical_overdensities.r_500_rhocrit[0].to(
        'Mpc')
    XPotMin = vr_catalogue_handle.positions.xcminpot[0].to('Mpc')
    YPotMin = vr_catalogue_handle.positions.ycminpot[0].to('Mpc')
    ZPotMin = vr_catalogue_handle.positions.zcminpot[0].to('Mpc')

    # If no custom aperture, select r500c as default
    if hse_dataset is not None:
        assert R500.units == hse_dataset["R500hse"].units
        assert M500.units == hse_dataset["M500hse"].units
        R500 = hse_dataset["R500hse"]
        M500 = hse_dataset["M500hse"]

    # Apply spatial mask to particles. SWIFTsimIO needs comoving coordinates
    # to filter particle coordinates, while VR outputs are in physical units.
    # Convert the region bounds to comoving, but keep the CoP and Rcrit in
    # physical units for later use.
    mask = sw.mask(path_to_snap, spatial_only=True)
    region = [[(XPotMin - R500) * a, (XPotMin + R500) * a],
              [(YPotMin - R500) * a, (YPotMin + R500) * a],
              [(ZPotMin - R500) * a, (ZPotMin + R500) * a]]
    mask.constrain_spatial(region)
    data = sw.load(path_to_snap, mask=mask)

    # Convert datasets to physical quantities
    # r500c is already in physical units
    data.gas.coordinates.convert_to_physical()
    data.gas.masses.convert_to_physical()
    data.gas.temperatures.convert_to_physical()
    data.gas.densities.convert_to_physical()

    # Select hot gas within sphere
    tempGas = data.gas.temperatures
    deltaX = data.gas.coordinates[:, 0] - XPotMin
    deltaY = data.gas.coordinates[:, 1] - YPotMin
    deltaZ = data.gas.coordinates[:, 2] - ZPotMin
    radial_distance = np.sqrt(deltaX**2 + deltaY**2 + deltaZ**2) / R500
    index = np.where((radial_distance < 2) & (tempGas > 1e5))[0]
    del tempGas, deltaX, deltaY, deltaZ

    # Calculate particle mass and rho_crit
    rho_crit = unyt.unyt_quantity(
        data.metadata.cosmology.critical_density(data.metadata.z).value,
        'g/cm**3')

    mass_weighted_temperatures = (data.gas.temperatures *
                                  unyt.boltzmann_constant).to('keV')
    number_densities = (data.gas.densities.to('g/cm**3') /
                        (unyt.mp * mean_molecular_weight)).to('cm**-3')
    field_value = mass_weighted_temperatures / number_densities**(2 / 3)

    field_label = r'$K$ [keV cm$^2$]'
    radial_distance = radial_distance[index]
    field_value = field_value[index]
    field_masses = data.gas.temperatures[index]

    return radial_distance, field_value, field_masses, field_label, M500, R500
예제 #19
0
import numpy
from velociraptor import load
from numba import njit

halos = numpy.loadtxt('/cosma5/data/durham/dc-murr1/gas_stellar_nearest_halos.txt')
halos = halos.astype(int)
cat = load('/cosma6/data/dp004/dc-borr1/swift-test-data/halo_0037/halo_0037.properties')
radii = cat.radii.r_200crit
struc = cat.structure_type.structuretype
radii = radii[numpy.where(struc == 10)[0]]
radii = radii[numpy.where(radii > 0)[0]]
radii.convert_to_units('Mpc')


@njit
def find_average_radius(x, r):
    average = numpy.zeros(len(x[:,0]))
    for i in range(len(average)):
        halo_radii = r[halos[i,:]]
        average[i] = numpy.mean(halo_radii)
        if i in range(0, 6400000, 100000):
            print(i)
    return average


average_halo_mass = find_average_radius(halos, radii)
numpy.savetxt('/cosma5/data/durham/dc-murr1/gas_average_stellar_radius.txt', average_halo_mass)
예제 #20
0
"""
Creates as basic galaxy sizes plot using the velociraptor library.

Please pass the path to the catalogue as your first argument.
"""

import velociraptor as vr
import velociraptor.tools as tools

import numpy as np
import matplotlib.pyplot as plt
import unyt

import sys

data = vr.load(sys.argv[1])

# Create local pointers to data and convert them to the units we'd like to plot
stellar_masses = data.apertures.mass_star_30_kpc
stellar_ages = data.stellar_age.tage_star

stellar_masses.convert_to_units(unyt.msun)
stellar_ages.convert_to_units(unyt.Gyr)

stellar_mass_bins = np.logspace(7, 12, 25) * unyt.msun

# constrained_layout is similar to tight_layout() but continuous
fig, ax = plt.subplots(constrained_layout=True)
ax.semilogx()

# Create background scatter plot of galaxy size data