def process_single_halo(self, zoom_obj: Zoom = None, path_to_snap: str = None, path_to_catalogue: str = None, **kwargs): sw_data, vr_data = self.get_handles_from_zoom(zoom_obj, path_to_snap, path_to_catalogue, **kwargs) r500 = vr_data.spherical_overdensities.r_500_rhocrit[0].to('Mpc') r2500 = vr_data.spherical_overdensities.r_2500_rhocrit[0].to('Mpc') sw_data.gas.radial_distances.convert_to_physical() sw_data.gas.temperatures.convert_to_physical() sw_data.gas.masses.convert_to_physical() # Compute hydrogen number density and the log10 # of the temperature to provide to the xray interpolator. data_nH = np.log10(sw_data.gas.element_mass_fractions.hydrogen * sw_data.gas.densities.to('g*cm**-3') / mp) data_T = np.log10(sw_data.gas.temperatures.value) # Interpolate the Cloudy table to get emissivities emissivities = cloudy.interpolate_X_Ray( data_nH, data_T, sw_data.gas.element_mass_fractions) # Select hot gas within sphere mask = np.where((sw_data.gas.radial_distances <= r500) & (sw_data.gas.temperatures > Tcut_halogas) & (sw_data.gas.fofgroup_ids == 1))[0] LX500 = self.get_emissivities(sw_data, emissivities, mask) mask = np.where((sw_data.gas.radial_distances <= r2500) & (sw_data.gas.temperatures > Tcut_halogas) & (sw_data.gas.fofgroup_ids == 1))[0] LX2500 = self.get_emissivities(sw_data, emissivities, mask) # Select hot gas within spherical shell (no core) mask = np.where((sw_data.gas.radial_distances >= 0.15 * r500) & (sw_data.gas.radial_distances <= r500) & (sw_data.gas.temperatures > Tcut_halogas) & (sw_data.gas.fofgroup_ids == 1))[0] LX500_nocore = self.get_emissivities(sw_data, emissivities, mask) mask = np.where((sw_data.gas.radial_distances >= 0.15 * r500) & (sw_data.gas.radial_distances <= r2500) & (sw_data.gas.temperatures > Tcut_halogas) & (sw_data.gas.fofgroup_ids == 1))[0] LX2500_nocore = self.get_emissivities(sw_data, emissivities, mask) return LX500, LX2500, LX500_nocore, LX2500_nocore
def process_single_halo( self, zoom_obj: Zoom = None, path_to_snap: str = None, path_to_catalogue: str = None ): sw_data, vr_data = self.get_handles_from_zoom( zoom_obj, path_to_snap, path_to_catalogue, mask_radius_r500=self.max_radius_r500 ) fb = Cosmology().fb0 critical_density = unyt_quantity( sw_data.metadata.cosmology.critical_density(sw_data.metadata.z).value, 'g/cm**3' ).to('Msun/Mpc**3') sw_data.gas.radial_distances.convert_to_physical() sw_data.gas.masses.convert_to_physical() sw_data.gas.densities.convert_to_physical() sw_data.gas.entropies.convert_to_physical() try: m500 = vr_data.spherical_overdensities.mass_500_rhocrit[0].to('Msun') r500 = vr_data.spherical_overdensities.r_500_rhocrit[0].to('Mpc') except AttributeError as err: print(f'[{self.__class__.__name__}] {err}') spherical_overdensity = SODelta500( path_to_snap=path_to_snap, path_to_catalogue=path_to_catalogue, ) m500 = spherical_overdensity.get_m500() r500 = spherical_overdensity.get_r500() if xlargs.mass_estimator == 'hse': true_hse = HydrostaticEstimator( path_to_catalogue=path_to_catalogue, path_to_snap=path_to_snap, profile_type='true', diagnostics_on=False ) true_hse.interpolate_hse(density_contrast=500.) r500 = true_hse.r500hse m500 = true_hse.m500hse try: _ = sw_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.") sw_data.gas.temperatures = sw_data.gas.internal_energies * (gamma - 1) * mean_molecular_weight * mh / kb try: _ = sw_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.") sw_data.gas.fofgroup_ids = np.ones_like(sw_data.gas.densities) index = np.where( (sw_data.gas.radial_distances < self.max_radius_r500 * r500) & (sw_data.gas.fofgroup_ids == 1) & (sw_data.gas.temperatures > Tcut_halogas) )[0] radial_distance = sw_data.gas.radial_distances[index] / r500 # Define radial bins and shell volumes lbins = np.logspace(-2, np.log10(self.max_radius_r500), 51) * radial_distance.units radial_bin_centres = 10 ** (0.5 * np.log10(lbins[1:] * lbins[:-1])) * radial_distance.units if self.weighting == 'xray': # Compute hydrogen number density and the log10 # of the temperature to provide to the xray interpolator. data_nH = np.log10( sw_data.gas.element_mass_fractions.hydrogen * sw_data.gas.densities.to('g*cm**-3') / mp) data_T = np.log10(sw_data.gas.temperatures.value) # Interpolate the Cloudy table to get emissivities emissivities = unyt_array( 10 ** cloudy.interpolate_X_Ray( data_nH, data_T, sw_data.gas.element_mass_fractions, fill_value=-50. ), 'erg/s/cm**3' ) xray_luminosities = emissivities * sw_data.gas.masses / sw_data.gas.densities weighting = xray_luminosities[index] del data_nH, data_T, emissivities, xray_luminosities elif self.weighting == 'mass': weighting = sw_data.gas.masses[index] elif self.weighting == 'volume': volume_proxy = sw_data.gas.masses[index] / sw_data.gas.densities[index] weighting = volume_proxy del volume_proxy gas_mass = sw_data.gas.masses[index] gas_mass_profile = histogram_unyt( radial_distance, bins=lbins, weights=gas_mass, ) gas_mass_profile = np.nancumsum(gas_mass_profile.value) * gas_mass_profile.units gas_mass_profile.convert_to_units(Solar_Mass) return radial_bin_centres, gas_mass_profile, m500