def make_map(self, particle_type: int, weights: unyt.array, tilt: str = 'z') -> np.ndarray: cop = self.data.subfind_tab.FOF.GroupCentreOfPotential R500c = self.data.subfind_tab.FOF.Group_R_Crit500 coord = self.data.subfind_particles[f'PartType{particle_type}'][ 'Coordinates'] coord_rot = self.rotate_coordinates(particle_type, tilt=tilt) smoothing_lengths = self.data.subfind_particles[ f'PartType{particle_type}']['SmoothingLength'] aperture = unyt.unyt_quantity(5 * R500c / np.sqrt(3), coord.units) if particle_type == 0: temperature = self.data.subfind_particles['PartType0'][ 'Temperature'] spatial_filter = np.where( (np.abs(coord_rot[:, 0]) < aperture) & (np.abs(coord_rot[:, 1]) < aperture) & (np.abs(coord_rot[:, 2]) < aperture) & (temperature.value > self.hot_gas_temperature_threshold))[0] else: spatial_filter = np.where((np.abs(coord_rot[:, 0]) < aperture) & (np.abs(coord_rot[:, 1]) < aperture) & (np.abs(coord_rot[:, 2]) < aperture))[0] read.pprint(coord_rot, cop, spatial_filter, sep='\n') x_max = np.max(coord_rot[spatial_filter, 0]) x_min = np.min(coord_rot[spatial_filter, 0]) y_max = np.max(coord_rot[spatial_filter, 1]) y_min = np.min(coord_rot[spatial_filter, 1]) x_range = x_max - x_min y_range = y_max - y_min x = (coord_rot[spatial_filter, 0] - x_min) / x_range y = (coord_rot[spatial_filter, 1] - y_min) / y_range h = smoothing_lengths[spatial_filter] / (2 * aperture) # Gather and handle coordinates to be processed x = np.asarray(x.value, dtype=np.float64) y = np.asarray(y.value, dtype=np.float64) m = np.asarray(weights[spatial_filter].value, dtype=np.float32) h = np.asarray(h.value, dtype=np.float32) smoothed_map = scatter(x=x, y=y, m=m, h=h, res=self.resolution).T smoothed_map = np.ma.masked_where( np.abs(smoothed_map) < 1.e-9, smoothed_map) surface_element = x_range * y_range / self.resolution**2 setattr(Mapping, f'surface_element{particle_type}', surface_element) return smoothed_map # * weights.units / coord.units ** 2
def set_hot_gas(self) -> None: temperature = self.data.subfind_particles['PartType0']['Temperature'] temperature_cut = np.where( temperature.value > self.hot_gas_temperature_threshold)[0] coord = self.data.subfind_particles['PartType0']['Coordinates'][ temperature_cut] vel = self.data.subfind_particles['PartType0']['Velocity'][ temperature_cut] masses = self.data.subfind_particles['PartType0']['Mass'][ temperature_cut] peculiar_velocity = np.sum(vel * masses[:, None], axis=0) / np.sum(masses) setattr(self, 'peculiar_velocity_hot_gas', peculiar_velocity) read.pprint(self.peculiar_velocity_hot_gas) angular_momentum = np.sum(np.cross(coord, vel * masses[:, None]), axis=0) setattr(self, 'angular_momentum_hot_gas', angular_momentum * coord.units * vel.units * masses.units) read.pprint(self.angular_momentum_hot_gas) return
x_min = np.min(snapshot['PartType0']['Coordinates'][depth_mask, 0]) y_max = np.max(snapshot['PartType0']['Coordinates'][depth_mask, 1]) y_min = np.min(snapshot['PartType0']['Coordinates'][depth_mask, 1]) x_range = x_max - x_min y_range = y_max - y_min x = (snapshot['PartType0']['Coordinates'][depth_mask, 0] - x_min) / x_range y = (snapshot['PartType0']['Coordinates'][depth_mask, 1] - y_min) / y_range h = snapshot['PartType0']['SmoothingLength'][depth_mask] / x_range # Gather and handle coordinates to be processed x = np.asarray(x.value, dtype=np.float64) y = np.asarray(y.value, dtype=np.float64) m = np.asarray(snapshot['PartType0']['Density'][depth_mask].value, dtype=np.float32) h = np.asarray(h.value, dtype=np.float32) read.pprint(f'Computing map ({resolution} x {resolution})') smoothed_map = scatter(x=x, y=y, m=m, h=h, res=resolution).T smoothed_map = np.ma.masked_where( np.abs(smoothed_map) < 1.e-9, smoothed_map) fig, axes = plt.subplots() cmap = copy.copy(plt.get_cmap('twilight')) cmap.set_under('black') axes.axis("off") axes.set_aspect("equal") axes.imshow(smoothed_map.T, norm=LogNorm(), cmap=cmap, origin="lower", extent=[x_min, x_max, y_min, y_max]) fig.savefig('box.png')
def view_all(self): fig, axarr = plt.subplots(nrows=5, ncols=15, sharex=False, sharey=False, figsize=(30, 10)) viewpoints = ['z', 'y', 'x', 'faceon', 'edgeon'] for i_plot, viewpoint in enumerate(viewpoints): read.pprint(f"Rendering veiwpoint {i_plot + 1:d}/{len(viewpoints):d}: {viewpoint:s}.") for ax in axarr[i_plot, :]: ax.set_aspect('equal') ax.axis("off") axarr[i_plot, 0].imshow( self.map_mass(0, tilt=viewpoint), norm=LogNorm(), cmap="PuOr", origin="lower", ) axarr[i_plot, 0].text(.5, .9, 'Gas mass', horizontalalignment='center', transform=axarr[i_plot, 0].transAxes) axarr[i_plot, 1].imshow( self.map_density(0, tilt=viewpoint), norm=LogNorm(), cmap="inferno", origin="lower", ) axarr[i_plot, 1].text(.5, .9, 'Gas density', horizontalalignment='center', transform=axarr[i_plot, 1].transAxes) coord_x, coord_y = self.map_particle_dot(0, tilt=viewpoint) axarr[i_plot, 2].plot(coord_x, coord_y, ',', c="C0", alpha=1) axarr[i_plot, 2].set_xlim([np.min(coord_x), np.max(coord_x)]) axarr[i_plot, 2].set_ylim([np.min(coord_y), np.max(coord_y)]) axarr[i_plot, 2].text(.5, .9, 'Gas dot', horizontalalignment='center', transform=axarr[i_plot, 2].transAxes) axarr[i_plot, 3].imshow( self.map_particle_number(0, tilt=viewpoint), norm=LogNorm(), cmap="cividis", origin="lower", ) axarr[i_plot, 3].text(.5, .9, 'Gas particle number', horizontalalignment='center', transform=axarr[i_plot, 3].transAxes) axarr[i_plot, 4].imshow( self.map_mass_weighted_temperature(0, tilt=viewpoint), norm=LogNorm(), cmap="inferno", origin="lower", ) axarr[i_plot, 4].text(.5, .9, 'Gas temperature', horizontalalignment='center', transform=axarr[i_plot, 4].transAxes) axarr[i_plot, 5].imshow( self.map_tSZ(0, tilt=viewpoint), norm=LogNorm(), cmap="inferno", origin="lower", ) axarr[i_plot, 5].text(.5, .9, 'Gas tSZ', horizontalalignment='center', transform=axarr[i_plot, 5].transAxes) ksz = self.map_kSZ(0, tilt=viewpoint) vlim = np.abs(ksz).max() read.pprint(vlim) axarr[i_plot, 6].imshow( ksz, norm=SymLogNorm(linthresh=1e-5, linscale=0.5, vmin=-vlim, vmax=vlim, base=10), cmap="PuOr", origin="lower", ) axarr[i_plot, 6].text(.5, .9, 'Gas kSZ', horizontalalignment='center', transform=axarr[i_plot, 6].transAxes) rksz = self.map_rkSZ(0, tilt=viewpoint) vlim = np.abs(rksz).max() read.pprint(vlim) axarr[i_plot, 7].imshow( rksz, norm=SymLogNorm(linthresh=1e-5, linscale=0.5, vmin=-vlim, vmax=vlim, base=10), cmap="PuOr", origin="lower", ) axarr[i_plot, 7].text(.5, .9, 'Gas rkSZ', horizontalalignment='center', transform=axarr[i_plot, 7].transAxes) axarr[i_plot, 8].imshow( self.map_mass(1, tilt=viewpoint), norm=LogNorm(), cmap="PuOr", origin="lower", ) axarr[i_plot, 8].text(.5, .9, 'DM mass', horizontalalignment='center', transform=axarr[i_plot, 8].transAxes) coord_x, coord_y = self.map_particle_dot(1, tilt=viewpoint) axarr[i_plot, 9].plot(coord_x, coord_y, ',', c="C0", alpha=1) axarr[i_plot, 9].set_xlim([np.min(coord_x), np.max(coord_x)]) axarr[i_plot, 9].set_ylim([np.min(coord_y), np.max(coord_y)]) axarr[i_plot, 9].text(.5, .9, 'DM dot', horizontalalignment='center', transform=axarr[i_plot, 9].transAxes) axarr[i_plot, 10].imshow( self.map_particle_number(1, tilt=viewpoint), norm=LogNorm(), cmap="cividis", origin="lower", ) axarr[i_plot, 10].text(.5, .9, 'DM particle number', horizontalalignment='center', transform=axarr[i_plot, 10].transAxes) axarr[i_plot, 11].imshow( self.map_mass(4, tilt=viewpoint), norm=LogNorm(), cmap="inferno", origin="lower", ) axarr[i_plot, 11].text(.5, .9, 'Star mass', horizontalalignment='center', transform=axarr[i_plot, 11].transAxes) axarr[i_plot, 12].imshow( self.map_density(4, tilt=viewpoint), norm=LogNorm(), cmap="PuOr", origin="lower", ) axarr[i_plot, 12].text(.5, .9, 'Star density', horizontalalignment='center', transform=axarr[i_plot, 12].transAxes) coord_x, coord_y = self.map_particle_dot(4, tilt=viewpoint) axarr[i_plot, 13].plot(coord_x, coord_y, ',', c="C0", alpha=1) axarr[i_plot, 13].set_xlim([np.min(coord_x), np.max(coord_x)]) axarr[i_plot, 13].set_ylim([np.min(coord_y), np.max(coord_y)]) axarr[i_plot, 13].text(.5, .9, 'Star dot', horizontalalignment='center', transform=axarr[i_plot, 13].transAxes) axarr[i_plot, 14].imshow( self.map_particle_number(4, tilt=viewpoint), norm=LogNorm(), cmap="cividis", origin="lower", ) axarr[i_plot, 14].text(.5, .9, 'Star particle number', horizontalalignment='center', transform=axarr[i_plot, 14].transAxes) plt.subplots_adjust(wspace=0., hspace=0.) plt.tight_layout() return fig, axarr
for job_id, n in enumerate(cluster_ids): # Parallelize across ranks # If image not allocated to specific rank, skip iteration if job_id % read.nproc != read.rank: continue try: if not os.path.isfile(f'{output_directory}/test_cluster_data.{redshift}_{n}.pickle'): fof = read.fof_group(n, fofs) cluster_dict = read.fof_particles(fof, csrm) with open(f'{output_directory}/test_cluster_data.{redshift}_{n}.pickle', 'wb') as handle: pickle.dump(cluster_dict, handle, protocol=pickle.HIGHEST_PROTOCOL) if not os.path.isfile(f'{output_directory}/test.{redshift}_{n}.png'): with open(f'{output_directory}/test_cluster_data.{redshift}_{n}.pickle', 'rb') as handle: cluster_dict = pickle.load(handle) cluster_data = read.class_wrap(cluster_dict).data maps = Mapping(cluster_data) fig, _ = maps.view_all() maps.savefig(fig, f'{output_directory}/test.{redshift}_{n}.png', dpi=(maps.resolution * 15) // 30) except IndexError as e: # Some high-index halos may not have sufficient mass to be picked up at high # redshifts. Catch that exception and continue with other halos. read.pprint(e) continue
import read simulation_type = 'hydro' redshift = 'z003p000' cluster_id = 1 # -------------------------------------------------------------------- # files = read.find_files(simulation_type, redshift) halo_catalogue = read.fof_groups(files) csrm = read.csr_index_matrix(halo_catalogue) fof = read.fof_group(cluster_id, halo_catalogue) cluster_dict = read.fof_particles(fof, csrm) # cluster_dict = read.snapshot_data(files) read.pprint("Dark matter particle mass:", cluster_dict['mass_DMpart']) for key in cluster_dict['subfind_tab']['FOF']: read.pprint(f"subfind_tab.FOF.{key:<30s}", cluster_dict['subfind_tab']['FOF'][key]) for key in cluster_dict['subfind_tab']['Subhalo']: read.pprint(f"subfind_tab.Subhalo.{key:<30s}", cluster_dict['subfind_tab']['Subhalo'][key]) for key in cluster_dict['group_tab']['FOF']: read.pprint(f"group_tab.FOF.{key:<30s}", cluster_dict['group_tab']['FOF'][key]) for pt in ['0', '1', '4']: for key in cluster_dict['subfind_particles'][f'PartType{pt}']:
def density_map(particle_type: int, cluster_data) -> None: z = cluster_data.header.subfind_particles.Redshift CoP = cluster_data.subfind_tab.FOF.GroupCentreOfPotential M200c = cluster_data.subfind_tab.FOF.Group_M_Crit200 R200c = cluster_data.subfind_tab.FOF.Group_R_Crit200 R500c = cluster_data.subfind_tab.FOF.Group_R_Crit500 M500c = cluster_data.subfind_tab.FOF.Group_M_Crit500 coord = cluster_data.subfind_particles[f'PartType{particle_type}'][ 'Coordinates'] boxsize = cluster_data.boxsize DM_part_mass = cluster_data.mass_DMpart if particle_type == 1: masses = np.ones_like(coord[:, 0].value, dtype=np.float32) * DM_part_mass # Generate DM particle smoothing lengths smoothing_lengths = generate_smoothing_lengths( coord, boxsize, kernel_gamma=1.8, neighbours=57, speedup_fac=3, dimension=3, ) else: masses = cluster_data.subfind_particles[f'PartType{particle_type}'][ 'Mass'] smoothing_lengths = cluster_data.subfind_particles[ f'PartType{particle_type}']['SmoothingLength'] # Run aperture filter read.pprint('[Check] Particle max x: ', np.max(np.abs(coord[:, 0] - CoP[0])), '6 x R500c: ', 6 * R500c) read.pprint('[Check] Particle max y: ', np.max(np.abs(coord[:, 1] - CoP[1])), '6 x R500c: ', 6 * R500c) read.pprint('[Check] Particle max z: ', np.max(np.abs(coord[:, 2] - CoP[2])), '6 x R500c: ', 6 * R500c) # Rotate particles # coord_rot = rotation_align_with_vector(coord.value, CoP, np.array([0, 0, 1])) coord_rot = coord # After derotation create a cubic aperture filter inscribed within a sphere of radius 5xR500c and # Centred in the CoP. Each semi-side of the aperture has length 5 * R500c / sqrt(3). aperture = 5 * R500c / np.sqrt(3) mask = np.where((np.abs(coord_rot[:, 0] - CoP[0]) <= aperture) & (np.abs(coord_rot[:, 1] - CoP[1]) <= aperture) & (np.abs(coord_rot[:, 2] - CoP[2]) <= aperture))[0] # Gather and handle coordinates to be plotted x = coord_rot[mask, 0].value y = coord_rot[mask, 1].value x_max = np.max(x) x_min = np.min(x) y_max = np.max(y) y_min = np.min(y) x_range = x_max - x_min y_range = y_max - y_min # Test that we've got a square box read.pprint(x_range, y_range) map_input_m = np.asarray(masses.value, dtype=np.float32) map_input_h = np.asarray(smoothing_lengths.value, dtype=np.float32) mass_map = scatter(x=(x - x_min) / x_range, y=(y - y_min) / y_range, m=map_input_m[mask], h=map_input_h[mask] / x_range, res=map_resolution) mass_map_units = masses.units / coord.units**2 # Mask zero values in the map with black mass_map = np.ma.masked_where(mass_map < 0.05, mass_map) read.pprint(mass_map) # Make figure fig, ax = plt.subplots(figsize=(6, 6), dpi=map_resolution // 6) ax.set_aspect('equal') fig.subplots_adjust(0, 0, 1, 1) ax.axis("off") ax.imshow(mass_map.T, norm=LogNorm(), cmap="inferno", origin="lower", extent=[x_min, x_max, y_min, y_max]) t = ax.text( 0.025, 0.025, (f"Halo {cluster_id:d} {simulation_type}\n" f"Particles: {partType_atlas[str(particle_type)]}\n" f"$z={z:3.3f}$\n" f"$M_{{500c}}={latex_float(M500c.value)}$ M$_\odot$\n" f"$R_{{500c}}={latex_float(R500c.value)}$ Mpc\n" f"$M_{{200c}}={latex_float(M200c.value)}$ M$_\odot$\n" f"$R_{{200c}}={latex_float(R200c.value)}$ Mpc"), color="white", ha="left", va="bottom", transform=ax.transAxes, ) t.set_bbox(dict(facecolor='black', alpha=0.2, edgecolor='none')) ax.text(CoP[0], CoP[1] + 1.02 * R500c, r"$R_{500c}$", color="white", ha="center", va="bottom") circle_r500 = plt.Circle((CoP[0], CoP[1]), R500c, color="white", fill=False, linestyle='-') ax.add_artist(circle_r500) plt.tight_layout() fig.savefig( f"{output_directory}/halo{cluster_id}_{redshift}_densitymap_type{particle_type}.png" ) plt.close(fig)
parser.add_argument('--dark_matter', default=False, action='store_true') parser.add_argument('--stars', default=False, action='store_true') args = parser.parse_args() # -------------------------------------------------------------------- # # Edit these parameters simulation_type = 'hydro' redshift = 'z000p000' cluster_id = 0 size_R200c = 1 output_directory = '/local/scratch/altamura/bahamas/maps' # -------------------------------------------------------------------- # # Boot up the BAHAMAS data files = read.find_files(simulation_type, redshift) fofs = read.fof_groups(files) csrm = read.csr_index_matrix(fofs) fof = read.fof_group(cluster_id, fofs) cluster_data = read.class_wrap(read.fof_particles(fof, csrm)).data # Execute tasks if args.gas: read.pprint("Generating gas density map") density_map(0, cluster_data) if args.dark_matter: read.pprint("Generating dark_matter density map") density_map(1, cluster_data) if args.stars: read.pprint("Generating stars density map") density_map(4, cluster_data) read.pprint("Job done.")
metadata[f'PartType{part_type}']['offset'] = metadata[f'PartType{part_type}']['offset'][master_unique_indices] metadata[f'PartType{part_type}']['unique'] = metadata[f'PartType{part_type}']['unique'][master_unique_indices] assert ~np.all(master_unique - metadata[f'PartType{part_type}']['unique']) # Sort the elements in the array from cluster 0 upwards sort_key = np.argsort(metadata[f'PartType{part_type}']['unique']) metadata[f'PartType{part_type}']['length'] = metadata[f'PartType{part_type}']['length'][sort_key] metadata[f'PartType{part_type}']['offset'] = metadata[f'PartType{part_type}']['offset'][sort_key] metadata[f'PartType{part_type}']['unique'] = metadata[f'PartType{part_type}']['unique'][sort_key] # Truncate out halos with index larger than 0.5e6 metadata[f'PartType{part_type}']['length'] = metadata[f'PartType{part_type}']['length'][:500000] metadata[f'PartType{part_type}']['offset'] = metadata[f'PartType{part_type}']['offset'][:500000] metadata[f'PartType{part_type}']['unique'] = metadata[f'PartType{part_type}']['unique'][:500000] pprint(f'PartType{part_type} unique', len(metadata[f'PartType{part_type}']['unique']), metadata[f'PartType{part_type}']['unique']) pprint(f'PartType{part_type} length', len(metadata[f'PartType{part_type}']['length']), metadata[f'PartType{part_type}']['length']) pprint(f'PartType{part_type} offset', len(metadata[f'PartType{part_type}']['offset']), metadata[f'PartType{part_type}']['offset']) comm.Barrier() if rank == 0: # Convert into arrays similar to the Subfind ones null_array = np.zeros_like(metadata[f'PartType{part_type}']['offset'], dtype=np.int) GroupLengthType = np.vstack(( metadata['PartType0']['length'],#null_array, metadata['PartType1']['length'], null_array, null_array, metadata['PartType4']['length'],#null_array, null_array