def process_sim(isim, args): """Process one simulation.""" if args.have_full_sim_dir: args.wdir = isim else: args.wdir = xl.get_sim_dir(args.base_dir, isim) args.dmo_dir = xl.get_sim_dir(args.base_dir, args.dmo_sim) print(f"Matching simulation {args.wdir} to DMO sim {args.dmo_dir}...") for isnap in args.snapshots: process_snapshot(isim, isnap, args)
def main(): """Main loop over simulations and snapshots.""" if args.sims[0].lower() == 'all': args.sims = xl.get_all_sims(args.base_dir) have_full_sim_dir = True else: have_full_sim_dir = False for isim in args.sims: if have_full_sim_dir: wdir = isim else: wdir = xl.get_sim_dir(args.base_dir, isim) print("") print( "====================================================================" ) print(f"=== Processing {wdir} ===") print( "====================================================================" ) print("") for iisnap, isnap in enumerate(args.snaps): # Account for possibly different VR numbering than (desired) output if args.vr_snaps is None: ivsnap = isnap else: ivsnap = args.vr_snaps[iisnap] process_snap(wdir, args.out_file, isnap, ivsnap)
def process_sim(args, isim, have_full_sim_dir): """Process one individual simulation.""" if have_full_sim_dir: wdir = isim else: wdir = xl.get_sim_dir(args.base_dir, isim) print(f"Processing simulation {wdir}...") # Check if output directory exists, create if needed if not os.path.isdir(os.path.dirname(f'{wdir}{args.link_names}')): os.makedirs(os.path.dirname(f'{wdir}{args.link_names}')) # Load output codes from ASCII file if not os.path.isfile(args.list_file): print(f"It looks like the specified file '{args.list_file}' " f"does not exist...") set_trace() output_table = ascii.read(args.list_file, format='no_header') f = open(args.list_file, "r") line1 = f.readline() f.close() if line1.startswith('# Redshift'): print("Output file in redshift units") else: set_trace() zred = np.array(output_table['col1']) types = np.array(output_table['col2']) ind_snaps = np.nonzero(types == args.snapshot_type)[0] print(f"Found {len(ind_snaps)} snapshots (type {args.snapshot_type})...") for iisnap, isnap in enumerate(ind_snaps): create_link(iisnap, isnap, wdir, args) print(" ...done!")
def main(): print("Parsing input arguments...") parser = argparse.ArgumentParser(description="Parse input parameters.") parser.add_argument('sim', help='Simulation index or name to analyse') parser.add_argument('--base_dir', help=f'Simulation base directory, default: ' f'{local.BASE_DIR}', default=local.BASE_DIR) parser.add_argument('--bh_mmax', type=float, help='Maximum BH mass, for the scaling in the images ' 'in log (M/M_Sun), default: 8.5.', default=8.5) parser.add_argument('--numpix', type=int, help='Size of images in pixels, default: 1000', default=1000) parser.add_argument('--gallery_dir', default='gallery') parser.add_argument('--plot_prefix', default='vr_plots', help='Prefix for plot files (within gallery_dir), ' 'default: vr_plots') parser.add_argument('--snapshots', nargs='+', type=int, help='Snapshots for which to set up websites.') parser.add_argument('--snap_name', default='snapshot', help='Snapshot prefix, default: "snapshot".') parser.add_argument('--mstar_min', type=float, help='Minimum stellar mass of the host galaxy for ' 'a black hole to be included, in M_Sun ' '(default: 3e10)', default=3e10) parser.add_argument('--m200_min', type=float, help='Minimum M200c of the host galaxy for ' 'a black hole to be included, in M_Sun ' '(default: 0, i.e. select on stellar mass only)', default=0.0) parser.add_argument('--bh_data_file', default='black_hole_data.hdf5', help='Name of the file containing the BH data, ' 'default: "black_hole_data.hdf5"') parser.add_argument('--vr_prefix', default='vr', help='Prefix of (combined) VR catalogue, default: vr.') parser.add_argument('--snap_frontpage', type=int, help='Snapshot for images on frontpage (default: 36)', default=36) parser.add_argument('--size_frontpage', type=float, help='Size of image for front page, in pMpc ' '(default: 0.03)', default=0.03) args = parser.parse_args() if len(args.snapshots) == 0: print("No snapshots selected, aborting.") # Adjust selected front page size to closest match in list frontpage_sizeind = np.argmin( np.abs(np.array(ap_list) - args.size_frontpage)) args.size_frontpage = ap_list[frontpage_sizeind] # Construct the full working directory of the simulation args.wdir = xl.get_sim_dir(args.base_dir, args.sim) # Look up the snapshot redshifts get_snapshot_redshifts(args) args.plotdata_file = (f'{args.wdir}{args.gallery_dir}/' f'{args.plot_prefix}.hdf5') if os.path.isfile(args.plotdata_file): bh_list = hd.read_data(args.plotdata_file, 'BlackHoleBIDs') select_list = None print(f"Using pre-created BH list with {len(bh_list)} BHs.") else: # Find BHs we are intereste in, load data select_list = [["Halo_M200c", '>=', args.m200_min], ["Halo_MStar", '>=', args.mstar_min], ["Flag_MostMassiveInHalo", '==', 1], ["HaloTypes", '==', 10]] bh_list = None bh_data, bh_sel = xl.lookup_bh_data(args.wdir + args.bh_data_file, bh_props_list, select_list) if bh_list is None: bh_list = bh_sel if len(bh_list) == 0: print("No black holes selected, aborting.") return # Generate the script to auto-generate all the required images generate_image_script(args, bh_list) # Generate the script to auto-generate all the tracks generate_track_script(args, bh_list) generate_website(args, bh_data, bh_list)
def process_sim(args, isim, have_full_sim_dir): """Generate the images for one particular simulation.""" if have_full_sim_dir: args.wdir = isim else: args.wdir = xl.get_sim_dir(args.base_dir, isim) # Name of the input BH data catalogue args.catloc = f'{args.wdir}{args.bh_file}' # Find BHs we are intereste in, load data (of internal VR match) select_list = [["Halo_MStar", '>=', args.halo_mstar_range[0]], ["Halo_MStar", '<', args.halo_mstar_range[1]], ["DMO_M200c", '>=', args.halo_m200_range[0]], ["DMO_M200c", '<', args.halo_m200_range[1]]] if not args.include_subdominant_bhs: select_list.append(['Flag_MostMassiveInHalo', '==', 1]) if not args.include_satellites: select_list.append(['HaloTypes', '==', 10]) if args.bh_mass_range is not None: zreds = hd.read_data(args.wdir + args.bh_file, 'Redshifts') best_index = np.argmin(np.abs(zreds - args.bh_selection_redshift)) print(f"Best index for redshift {args.bh_selection_redshift} is " f"{best_index}.") # Subgrid masses are in 10^10 M_sun, so need to adjust selection range select_list.append( ['SubgridMasses', '>=', args.bh_mass_range[0] / 1e10, best_index]) select_list.append( ['SubgridMasses', '<=', args.bh_mass_range[1] / 1e10, best_index]) bh_props_list = ['SubgridMasses', 'Redshifts', 'ParticleIDs'] bh_data, bh_list = xl.lookup_bh_data(args.wdir + args.bh_file, bh_props_list, select_list) if len(bh_list) == 0: print("No BHs selected, aborting.") return args.sim_pointdata_loc = args.wdir + args.plot_prefix + '.hdf5' if not os.path.isdir(os.path.dirname(args.sim_pointdata_loc)): os.makedirs(os.path.dirname(args.sim_pointdata_loc)) if os.path.isfile(args.sim_pointdata_loc): shutil.move(args.sim_pointdata_loc, args.sim_pointdata_loc + '.old') hd.write_data(args.sim_pointdata_loc, 'BlackHoleBIDs', bh_list, comment='BIDs of all BHs selected for this simulation.') # Go through snapshots for iisnap, isnap in enumerate(args.snapshots): print("") print(f"Processing snapshot {isnap}...") # Need to explicitly connect BHs to VR catalogue from this snap vr_data = xl.connect_to_galaxies( bh_data['ParticleIDs'][bh_list], f'{args.wdir}{args.vr_file}_{isnap:04d}', extra_props=[('ApertureMeasurements/Projection1/30kpc/' 'Stars/HalfMassRadii', 'StellarHalfMassRad'), ('MatchInDMO/M200crit', 'DMO_M200c')]) # Add subgrid mass of BHs themselves ind_bh_cat = np.argmin( np.abs(bh_data['Redshifts'] - vr_data['Redshift'])) print(f"Using BH masses from index {ind_bh_cat}") vr_data['BH_SubgridMasses'] = ( bh_data['SubgridMasses'][bh_list, ind_bh_cat] * 1e10) n_good_m200 = np.count_nonzero(vr_data['DMO_M200c'] * 0 == 0) print(f"Have {n_good_m200} BHs with DMO_M200c, out of " f"{len(bh_list)}.") # Make plots for each BH, and "general" overview plot print("Overview plot") generate_vr_plots(args, vr_data, isnap) if not args.summary_only: for iibh, ibh in enumerate(bh_list): print(f"Make plot for BH-BID {ibh} ({iibh}/{len(bh_list)})") generate_vr_plots(args, vr_data, isnap, iibh, ibh) print("Done!")
def process_sim(args, isim, have_full_sim_dir): args.first_snap = None args.last_snap = None if have_full_sim_dir: args.wdir = isim else: args.wdir = xl.get_sim_dir(args.base_dir, isim) if args.out_dir is None: args.out_dir = args.wdir # Find total number of black holes and assign their black-IDs bpart_ids, bpart_first_output = find_black_ids(args) if args.first_snap is None: print("Did not find any black holes, aborting.") return # Set up output arrays output_dict, comment_dict = setup_output(args) # For efficiency, create a reverse list of BH IDs (if possible) if max(bpart_ids) < 1e10: bpart_rev_ids = hx.ReverseList(bpart_ids, assume_positive=True) use_rev_list = True else: use_rev_list = False # Retrieve header info from first valid snapshot collect_header_data(args) # Loop through all snapshots and fill output arrays for iisnap, isnap in enumerate(range(args.first_snap, args.last_snap + 1)): if use_rev_list: process_output(iisnap, isnap, output_dict, bpart_ids, args, bpart_rev_ids=bpart_rev_ids) else: process_output(iisnap, isnap, output_dict, bpart_ids, args, bpart_rev_ids=None) # Connect black holes to z = 0 galaxies # For this, exclude BHs that are not BHs at the linking snapshot. if args.vr_snap is not None: get_vr_props(args) bh_vr_snap = np.argmin(np.abs(args.redshifts - args.vr_zred)) print(f"VR snap corresponds to BH output index {bh_vr_snap}.") bpart_ids_mod = np.copy(bpart_ids) ind_nobh = np.nonzero( output_dict['SubgridMasses'][:, bh_vr_snap] * .0 != 0)[0] bpart_ids_mod[ind_nobh] = -1 vr_file = f'{args.wdir}{args.vr_file}_{args.vr_snap:04d}' gal_props = xl.connect_to_galaxies(bpart_ids_mod, vr_file, extra_props=vr_extra_props) # Finish galaxy-based analysis if gal_props is not None: finish_galaxy_analysis(output_dict, gal_props, args) else: gal_props = None # Write output HDF5 file write_output_file(output_dict, comment_dict, bpart_ids, bpart_first_output, gal_props, args)
def main(): print("Parsing input arguments...") parser = argparse.ArgumentParser(description="Parse input parameters.") parser.add_argument('sim', help='Simulation index/name to analyse') parser.add_argument('--bh_bid', type=int, help='BID of the black hole to highlight.') parser.add_argument('--base_dir', default=local.BASE_DIR, help='Base directory of the simulation, default: ' f'{local.BASE_DIR}') parser.add_argument('--bh_file', default='black_hole_data.hdf5', help='Name of the file containing the BH data, ' 'default: "black_hole_data.hdf5"') parser.add_argument('--plot_prefix', default='gallery/bh_growth_tracks', help='Prefix of output files, default: ' '"gallery/bh_growth_tracks') parser.add_argument('--vrplot_prefix', default='gallery/vr_plots', help='Prefix of VR plots, default: ' '"gallery/vr_plots".') parser.add_argument('--plot_mass_range', type=float, nargs='+', help='Min and max mass of plot range, default: ' '5.0 8.5', default=[5.0, 8.5]) parser.add_argument('--bh_mass_range', type=float, nargs='+', help='Min and max BH mass for selection, at target z ' '[M_Sun], default: no selection.') parser.add_argument('--bh_selection_redshift', type=float, default=0.0, help='Redshift at which to make BH mass selection ' '(default: 0.0)') parser.add_argument('--include_subdominant_bhs', action='store_true', help='Only show black holes that are the most massive ' 'in their galaxy, at the linked snapshot.') parser.add_argument('--halo_mstar_range', default=[3e10, 4e11], type=float, help='Min and max stellar mass of host galaxy ' '[M_Sun], default: 3e10, 4e11.', nargs='+') parser.add_argument('--halo_m200_range', default=[0, 1e16], type=float, help='Min and max M200 mass of host galaxy ' '[M_Sun], default: 0, 1e16.', nargs='+') parser.add_argument('--include_satellites', action='store_true', help='Only show BHs in central haloes, not satellites.') parser.add_argument('--show_target_only', action='store_true', help='Show only the target BH, not possible others ' 'that also match the selection criteria.') parser.add_argument('--show_median', action='store_true', help='Add the median for all selected BHs.') parser.add_argument('--summary_only', action='store_true', help='Only generate summary plot, not ones for ' 'individual BHs.') parser.add_argument('--alpha_others', type=float, default=0.25, help='Alpha value for non-target BHs, default: 0.25') args = parser.parse_args() args.wdir = xl.get_sim_dir(args.base_dir, args.sim) # Name of the input catalogue, containing all the data to plot args.catloc = f'{args.wdir}{args.bh_file}' args.plotdata_file = f'{args.wdir}{args.vrplot_prefix}.hdf5' if os.path.isfile(args.plotdata_file): bh_list = hd.read_data(args.plotdata_file, 'BlackHoleBIDs') select_list = None else: # Find BHs we are intereste in, load data select_list = [ ["Halo_MStar", '>=', args.halo_mstar_range[0]], ["Halo_MStar", '<', args.halo_mstar_range[1]], ["Halo_M200c", '>=', args.halo_m200_range[0]], ["Halo_M200c", '<', args.halo_m200_range[1]] ] if not args.include_subdominant_bhs: select_list.append(['Flag_MostMassiveInHalo', '==', 1]) if not args.include_satellites: select_list.append(['HaloTypes', '==', 10]) if args.bh_mass_range is not None: zreds = hd.read_data(args.wdir + args.bh_file, 'Redshifts') best_index = np.argmin(np.abs(zreds - args.bh_selection_redshift)) print(f"Best index for redshift {args.bh_selection_redshift} is " f"{best_index}.") # Subgrid masses are in 10^10 M_sun, so need to adjust selection range select_list.append( ['SubgridMasses', '>=', args.bh_mass_range[0]/1e10, best_index]) select_list.append( ['SubgridMasses', '<=', args.bh_mass_range[1]/1e10, best_index]) bh_list = None bh_data, bh_sel = xl.lookup_bh_data(args.wdir + args.bh_file, bh_props_list, select_list) if bh_list is None: bh_list = bh_sel generate_track_image(args, bh_data, bh_list) if args.bh_bid is None: # No target specified: process all selected BHs for iibh, ibh in enumerate(bh_list): generate_track_image(args, bh_data, bh_list, iibh) else: # Only plot the selected BH. iibh = np.nonzero(bh_list == args.bh_bid)[0] if len(iibh) == 1: generate_track_image(args, bh_data, bh_list, iibh[0]) else: print(f"Could not (unambiguously) find BH-BID {args.bh_bid} " f"in BH list.") print("Done!")
def process_sim(isim, args): """Process one individual simulation.""" if args.have_full_sim_dir: args.wdir = isim else: args.wdir = xl.get_sim_dir(args.base_dir, isim) print(f"Analysing simulation {args.wdir}...") # Name of the input catalogue, containing all the data to plot args.catloc = f'{args.wdir}{args.bh_file}' bh_props_list = ['ParticleIDs'] # Select BHs in this sim args.plotdata_file = f'{args.wdir}{args.vrplot_prefix}.hdf5' if os.path.isfile(args.plotdata_file): bh_list = hd.read_data(args.plotdata_file, 'BlackHoleBIDs') select_list = None elif args.bh_bid is None: # Find BHs we are intereste in, load data select_list = [ ["Halo_MStar", '>=', args.halo_mstar_range[0]], ["Halo_MStar", '<', args.halo_mstar_range[1]], ["Halo_M200c", '>=', args.halo_m200_range[0]], ["Halo_M200c", '<', args.halo_m200_range[1]] ] if not args.include_subdominant_bhs: select_list.append(['Flag_MostMassiveInHalo', '==', 1]) if not args.include_satellites: select_list.append(['HaloTypes', '==', 10]) if args.bh_mass_range is not None: zreds = hd.read_data(args.wdir + args.bh_file, 'Redshifts') best_index = np.argmin(np.abs(zreds - args.bh_selection_redshift)) print(f"Best index for redshift {args.bh_selection_redshift} is " f"{best_index}.") # Subgrid masses are in 10^10 M_sun, so need to adjust selection # range select_list.append( ['SubgridMasses', '>=', args.bh_mass_range[0]/1e10, best_index]) select_list.append( ['SubgridMasses', '<=', args.bh_mass_range[1]/1e10, best_index]) bh_list = None else: bh_list = args.bh_bid select_list = None bh_file = args.wdir + args.bh_file bh_data, bh_sel = xl.lookup_bh_data(bh_file, bh_props_list, select_list) if bh_list is None: bh_list = bh_sel if len(bh_list) == 0: print("No black holes selected, aborting.") return # Overwrite selection with input, if specific BID(s) provided if args.bh_bid is not None: bh_list = args.bh_bid for isnap in args.snapshots: process_snapshot(args, bh_list, bh_data, isim, isnap)
def process_sim(isim, args): """Process one specific simulation.""" if args.have_full_sim_dir: args.wdir = isim else: args.wdir = xl.get_sim_dir(args.base_dir, isim) print(f"Analysing simulation {args.wdir}...") # Name of the input catalogue, containing all the data to plot args.catloc = f'{args.wdir}{args.bh_file}' # Select BHs in this sim args.plotdata_file = f'{args.wdir}{args.vrplot_prefix}.hdf5' if os.path.isfile(args.plotdata_file): bh_list = hd.read_data(args.plotdata_file, 'BlackHoleBIDs') select_list = None elif args.bh_bid is not None: select_list = None bh_list = args.bh_bid else: # Find BHs we are intereste in, load data select_list = [["Halo_MStar", '>=', args.halo_mstar_range[0]], ["Halo_MStar", '<', args.halo_mstar_range[1]], ["Halo_M200c", '>=', args.halo_m200_range[0]], ["Halo_M200c", '<', args.halo_m200_range[1]]] if not args.include_subdominant_bhs: select_list.append(['Flag_MostMassiveInHalo', '==', 1]) if not args.include_satellites: select_list.append(['HaloTypes', '==', 10]) if args.bh_mass_range is not None: zreds = hd.read_data(args.wdir + args.bh_file, 'Redshifts') best_index = np.argmin(np.abs(zreds - args.bh_selection_redshift)) print(f"Best index for redshift {args.bh_selection_redshift} is " f"{best_index}.") # Subgrid masses are in 10^10 M_sun, so need to adjust selection # range select_list.append([ 'SubgridMasses', '>=', args.bh_mass_range[0] / 1e10, best_index ]) select_list.append([ 'SubgridMasses', '<=', args.bh_mass_range[1] / 1e10, best_index ]) bh_list = None bh_file = args.wdir + args.bh_file bh_data, bh_list = xl.lookup_bh_data(bh_file, bh_props_list, select_list, bh_list) args.nsnap = len(bh_data['Times']) # Extract meta-data from Header bh_data['CodeBranch'] = hd.read_attribute(bh_file, 'Code', 'Git Branch') bh_data['CodeDate'] = hd.read_attribute(bh_file, 'Code', 'Git Date') bh_data['CodeRev'] = hd.read_attribute(bh_file, 'Code', 'Git Revision') bh_data['SimName'] = hd.read_attribute(bh_file, 'Header', 'RunName') # Look up stars data stars = Stars(args) for ibh in bh_list: process_bh(args, stars, bh_data, ibh, isim)