def setUp(self): super(VelocitySpaceTest, self).setUp() ds = load(COSMO_PLUS_SINGLE) line_list = ['H I 1216', 'H I 1026'] make_simple_ray(ds, start_position=ds.domain_left_edge, end_position=ds.domain_right_edge, data_filename='ray.h5', lines=line_list, ftype='gas') self.line_list = line_list
def test_light_ray_redshift_coverage_grid(self): """ Tests to assure a light ray covers the full redshift range appropriate for that comoving line of sight distance. Was not always so! """ ds = load(COSMO_PLUS_SINGLE) ray = make_simple_ray(ds, start_position=ds.domain_left_edge, end_position=ds.domain_right_edge, lines=['H']) assert_almost_equal(ray.r['redshift'][0], 6.99900695e-03, decimal=8) assert_almost_equal(ray.r['redshift'][-1], -1.08961751e-02, decimal=8)
def test_light_ray_redshift_coverage(self): """ Tests to assure a light ray covers the full redshift range appropriate for that comoving line of sight distance. Was not always so! """ ds = load(GIZMO_COSMO_SINGLE) ray = make_simple_ray(ds, start_position=ds.domain_left_edge, end_position=ds.domain_right_edge, lines=['H']) assert_almost_equal(ray.r['redshift'][0], 0.00489571, decimal=8) assert_almost_equal(ray.r['redshift'][-1], -0.00416831, decimal=8)
def test_light_ray_redshift_monotonic(self): """ Tests to assure a light ray redshift decreases monotonically when ray extends outside the domain. """ ds = load(COSMO_PLUS_SINGLE) ray = make_simple_ray(ds, start_position=ds.domain_center, end_position=ds.domain_center+ds.domain_width) assert((np.diff(ray.data['redshift']) < 0).all())
def generate_spectrum_plot_data(index_start, index_end, output): ds = yt.load('/nobackupp2/ibutsky/simulations/romulusC/romulusC.%06d'%(output)) ion_list = ['H I', 'C II', 'C III', 'C IV', 'Si II', 'Si III', 'Si IV', 'O VI'] trident.add_ion_fields(ds, ions=ion_list) ds.add_field(("gas", "particle_H_nuclei_density"), function = ytf._H_nuc, \ particle_type = True, force_override = True, units = "cm**(-3)") y_start = ds.domain_left_edge[2] y_end = ds.domain_right_edge[2] center = rom.get_romulusC_center(output) center_x = center[0] center_y = center[1] center_z = center[2] print(center_x, center_y, center_z) ray_id, x_list, z_list = np.loadtxt('/nobackupp2/ibutsky/data/YalePaper/spectra/coordinate_list.dat',\ skiprows = 1, unpack=True) for i in range(index_start, index_end): h5file = h5.File('/nobackup/ibutsky/data/YalePaper/romulusC.%06d_sightline_%i_plot_data.h5'%(output, i), 'w') # note: the plus is important. x_list, z_list counted from center x = ((x_list[i] + center_x) / ds.length_unit).d z = ((z_list[i] + center_z) / ds.length_unit).d print(x_list[i], z_list[i], ds.length_unit) ycen = (center_y / ds.length_unit).d # y from -2.5 mpc of center to 2.5 mpc from center ylen = (2500. / ds.length_unit).d ray_start = [x, ycen-ylen , z] ray_end = [x, ycen+ylen, z] ad = ds.r[ray_start:ray_end] ray = trident.make_simple_ray(ds, start_position = ray_start, end_position = ray_end, lines=ion_list) ad_ray = ray.all_data() field_list = ['y', 'temperature', 'density', 'metallicity', 'dl'] source_list = [ad, ad, ad, ad, ad_ray] unit_list = ['kpc', 'K', 'g/cm**3', 'Zsun', 'cm'] yt_ion_list = ipd.generate_ion_field_list(ion_list, 'number_density', full_name = False) yt_ion_list[0] = 'H_number_density' field_list = np.append(field_list, yt_ion_list) for j in range(len(yt_ion_list)): unit_list.append('cm**-3') source_list.append(ad_ray) for field,source,unit in zip(field_list, source_list, unit_list): if field not in h5file.keys(): h5file.create_dataset(field, data = source[('gas', field)].in_units(unit)) h5file.flush() h5file.create_dataset('y_lr', data = ad_ray['y'].in_units('kpc')) h5file.flush() print("saved sightline data %i\n"%(i))
def generate_trident_spectrum(ds, line_list, ray_start, ray_end, spec_name, lambda_rest, vpos): import trident print("Generating trident spectrum...") # Generate ray through box TINIT = time.time() ray = trident.make_simple_ray(ds, start_position=ray_start, end_position=ray_end, data_filename="ray.h5", lines=line_list, ftype='PartType0') print('Trident spectrum done [t=%g s]'%(np.round(time.time()-TINIT,2))) #sg = trident.SpectrumGenerator(lambda_min=lambda_min.value, lambda_max=lambda_max, n_lambda=Nbins) sg = trident.SpectrumGenerator('COS-G130M') # convolves with COS line spread fcn, gives COS resolution with h5py.File('./spectra/{}.h5'.format(spec_name), 'w') as hf: for i in range(len(line_list)): line = line_list[i] l_rest = lambda_rest[i] print('Saving data for line ' + line) name = line.replace(' ', '_') sg.make_spectrum(ray, lines=[line]) # Get fields and convert wavelengths to velocities. Note that the velocities are negative compared to pygad! taus = np.array(sg.tau_field) fluxes = np.array(sg.flux_field) wavelengths = np.array(sg.lambda_field) velocities = wave_to_vel(wavelengths, l_rest, c, ds.current_redshift) plt.plot(velocities, fluxes) plt.axvline(vpos, linewidth=1, c='k') plt.xlabel('Velocity (km/s)') plt.ylabel('Flux') plt.savefig('./plots/'+spec_name+'_'+name+'.png') plt.clf() #Save spectrum to hdf5 format hf.create_dataset(name+'_flux', data=np.array(fluxes)) hf.create_dataset(name+'_tau', data=np.array(taus)) sigma_noise = 1.0/snr noise = np.random.normal(0.0, sigma_noise, len(wavelengths)) #Save spectrum to hdf5 format hf.create_dataset('velocity', data=np.array(velocities)) hf.create_dataset('wavelength', data=np.array(wavelengths)) hf.create_dataset('noise', data=np.array(noise)) del ray; gc.collect() return
def generate_random_rays(ds, halo_center, **kwargs): ''' generate some random rays ''' low_impact = kwargs.get("low_impact", 10.) high_impact = kwargs.get("high_impact", 200.) Nrays = kwargs.get("Nrays",50) haloname = kwargs.get("haloname","somehalo") # line_list = kwargs.get("line_list", ['H I 1216', 'Si II 1260', 'C II 1334', 'Mg II 2796', 'C III 977', 'Si III 1207','C IV 1548', 'O VI 1032']) line_list = kwargs.get("line_list", ['H I 1216', 'Si II 1260', 'C II 1335', 'C III 977', 'Si III 1207','C IV 1548', 'O VI 1032']) ## for now, assume all are z-axis axis = "z" np.random.seed(17) impacts = np.random.uniform(low=low_impact, high=high_impact, size=Nrays) angles = np.random.uniform(low=0, high=2*pi, size=Nrays) out_ray_basename = ds.basename + "_ray_" + axis for i in range(Nrays): this_out_ray_basename = out_ray_basename + "_imp"+"{:05.1f}".format(impacts[i]) + \ "_ang"+"{:4.2f}".format(angles[i]) out_ray_name = this_out_ray_basename + ".h5" out_fits_name = "hlsp_misty_foggie_"+haloname+"_"+ds.basename.lower()+"_i"+"{:05.1f}".format(impacts[i]) + \ "-a"+"{:4.2f}".format(angles[i])+"_v2_los.fits" rs, re = get_ray_endpoints(ds, halo_center, impact=impacts[i], angle=angles[i], axis=axis) rs = ds.arr(rs, "code_length") re = ds.arr(re, "code_length") ray = ds.ray(rs, re) ray.save_as_dataset(out_ray_name) out_tri_name = this_out_ray_basename + "_tri.h5" triray = trident.make_simple_ray(ds, start_position=rs.copy(), end_position=re.copy(), data_filename=out_tri_name, lines=line_list, ftype='gas') ray_start = triray.light_ray_solution[0]['start'] ray_end = triray.light_ray_solution[0]['end'] filespecout_base = this_out_ray_basename + '_spec' print ray_start, ray_end, filespecout_base hdulist = MISTY.write_header(triray,start_pos=ray_start,end_pos=ray_end, lines=line_list, impact=impacts[i], angle=angles[i]) tmp = MISTY.write_parameter_file(ds,hdulist=hdulist) for line in line_list: sg = MISTY.generate_line(triray,line,write=True,hdulist=hdulist) filespecout = filespecout_base+'_'+line.replace(" ", "_")+'.png' ## if we write our own plotting routine, we can overplot the spectacle fits sg.plot_spectrum(filespecout,flux_limits=(0.0,1.0)) MISTY.write_out(hdulist,filename=out_fits_name)
def get_spec(ds, halo_center, rho_ray): proper_box_size = get_proper_box_size(ds) line_list = ['H', 'O', 'C', 'N', 'Si'] # big rectangle box ray_start = [ halo_center[0] - 250. / proper_box_size, halo_center[1] + 71. / proper_box_size, halo_center[2] - 71. / proper_box_size ] ray_end = [ halo_center[0] + 250. / proper_box_size, halo_center[1] + 71. / proper_box_size, halo_center[2] - 71. / proper_box_size ] ray = trident.make_simple_ray(ds, start_position=ray_start, end_position=ray_end, data_filename="ray.h5", lines=line_list, ftype='gas') sg = trident.SpectrumGenerator(lambda_min=1020, lambda_max=1045, dlambda=0.002) trident.add_ion_fields(ds, ions=['C IV', 'O VI', 'H I', 'Si III']) sg.make_spectrum(ray, lines=line_list) sg.plot_spectrum('spec_final.png') sg.save_spectrum('spec_final.txt') # this makes for convenient field extraction from the ray ad = ray.all_data() dl = ad["dl"] # line element length out_dict = { 'nhi': np.sum(ad['H_number_density'] * dl), 'no6': np.sum(ad['O_p5_number_density'] * dl), 'nsi3': np.sum(ad['Si_p2_number_density'] * dl) } print np.sum(ad['H_number_density'] * dl) print np.sum(ad['O_p5_number_density'] * dl) print np.sum(ad['Si_p2_number_density'] * dl) return ray, out_dict
def calculateSpectra(runName, savefolder, file_list): filePrefix = '../Files/' + runName + '/KH_hdf5_chk_' for chk_num in file_list: file_name = filePrefix + chk_num dataset = yt.load(file_name) dataset.add_field(('gas', 'metallicity'), function=_metallicity, display_name="Metallicity", units='Zsun') #make a ray object ray = tri.make_simple_ray(dataset, redshift=0.0, start_position=ray_start, end_position=ray_end, lines=line_list, ftype='gas') #plot and save density projection to look at the path of the ray p = yt.ProjectionPlot(dataset, 'z', 'density', origin='native') p.annotate_ray(ray) p.save(savefolder + 'projection' + chk_num + '.png') print("Saved Projection images as " + savefolder + "/projection" + chk_num + ".png") #create a spectrumGenerator; you may make your own spectrograph settings sg = tri.SpectrumGenerator( lambda_min=500, lambda_max=1600, dlambda=0.01 ) #uses default spectrograph settings for "Cosmic Origins Spectrograph" sg.make_spectrum(ray, lines=line_list) #save and plot the spectrum sg.save_spectrum(savefolder + 'spec_raw' + chk_num + '.h5') sg.plot_spectrum(savefolder + 'spec_raw' + chk_num + '.png', features=line_features, title=title + chk_num, flux_limits=(0, 1.5)) print("Saved Spectrum as " + savefolder + "spec_raw" + chk_num + "_NV.h5") print("Saved Spectrum image as " + savefolder + "spec_raw" + chk_num + "_NV.png") print("Finished with " + runName)
def _get_coldens_helper(dsparamsvectorions): try: ds = dsparamsvectorions[0] scanparams = dsparamsvectorions[1] vector = dsparamsvectorions[2] ions = dsparamsvectorions[3] print(str(current_process())) ident = str(current_process()).split(",")[0] if ident[-2:] == "ss": ident = "" else: ident = ident.split("-")[1] start = vector[5:8] end = vector[8:11] ray = trident.make_simple_ray(ds, start_position=start, end_position=end, data_filename="ray"+ident+".h5", fields = [('gas',"metallicity")], ftype='gas') trident.add_ion_fields(ray,ions) field_data = ray.all_data() for i in range(len(ions)): ion = ions[i] cdens = np.sum(field_data[("gas",ion_to_field_name(ion))] * field_data['dl']) #outcdens = np.sum((field_data['radial_velocity']>0)*field_data[ion_to_field_name(ion)]*field_data['dl']) #incdens = np.sum((field_data['radial_velocity']<0)*field_data[ion_to_field_name(ion)]*field_data['dl']) vector[11+i] = cdens #vector[12+3*i+1] = outcdens #vector[12+3*i+2] = incdens Z = np.average(field_data[('gas',"metallicity")],weights=field_data['dl']) vector[-1] = Z if _platform == 'darwin': foldername = "/Users/claytonstrawn/Desktop/astroresearch/code/ready_for_pleiades/quasarlines" else: foldername = "/u/cstrawn/quasarlines/galaxy_catalogs/" except Exception: logging.exception("failed") try: os.remove(foldername+"/"+"ray"+ident+".h5") except: pass print("vector = "+str(vector)) return vector
def test_create_simple_grid_ray_with_lines(): """ Test to create a simple ray from a grid dataset using the lines kwargs Then generate a spectrum from it with those lines included. """ dirpath = tempfile.mkdtemp() filename = os.path.join(dirpath, 'ray.h5') ds = tri.make_onezone_dataset() ray_start = ds.arr([0., 0., 0.], 'unitary') ray_end = ds.arr([1., 1., 1.], 'unitary') ray = tri.make_simple_ray(ds, start_position=ray_start, end_position=ray_end, data_filename=filename, lines=['H', 'C IV'], ftype='gas') sg = tri.SpectrumGenerator(lambda_min=1000, lambda_max=1400., dlambda=0.1) sg.make_spectrum(ray, lines=['H', 'C IV']) sg.plot_spectrum(os.path.join(dirpath, 'spec.png')) shutil.rmtree(dirpath)
def test_absorption_spectrum_with_continuum(self): """ This test generates an absorption spectrum then does a default fit. Uses the example in the docs as a template: https://trident.readthedocs.io/en/latest/absorption_spectrum_fit.html """ ds = load(ISO_GALAXY) line_list = ['O VI'] ray = make_simple_ray(ds, start_position=ds.domain_left_edge, end_position=ds.domain_right_edge, data_filename='ray.h5', lines=line_list, ftype='gas') sg = SpectrumGenerator('COS') sg.make_spectrum(ray, lines=line_list) wavelength = sg.lambda_field flux = sg.flux_field OVI_parameters = { 'name': 'OVI', 'f': [.1325, .06580], 'Gamma': [4.148E8, 4.076E8], 'wavelength': [1031.9261, 1037.6167], 'numLines': 2, 'maxN': 1E17, 'minN': 1E11, 'maxb': 300, 'minb': 1, 'maxz': 6, 'minz': 0, 'init_b': 20, 'init_N': 1E12 } speciesDicts = {'OVI': OVI_parameters} orderFits = ['OVI'] fitted_lines, fitted_flux = generate_total_fit(wavelength, flux, orderFits, speciesDicts)
def create_misty_spectrum(): my_line_list = ['H I 1216', 'C II 1335', 'C IV 1548', 'O VI 1032'] if len(args.ray) == 0: ## read in example data ds = yt.load(args.sim) print "ray start and end are hardcoded and should be passed in !!!!!!" ## create ray start and end ray_start = [1, 0, 1] ray_end = [1, 2, 1] ray = trident.make_simple_ray(ds, start_position=ray_start, end_position=ray_end, lines=my_line_list, ftype='gas') filespecout_base = 'spectrum_' + ds.basename else: ray = yt.load(args.ray) ray_start = ray.light_ray_solution[0]['start'] ray_end = ray.light_ray_solution[0]['end'] filespecout_base = 'spectrum_' + ray.light_ray_solution[0]['filename'] print ray_start, ray_end, filespecout_base hdulist = MISTY.write_header(ray, start_pos=ray_start, end_pos=ray_end, lines=my_line_list, author=args.author) ## put parameter file into the fits file MISTY.write_parameter_file(args.paramfile, hdulist=hdulist) for line in my_line_list: sg = MISTY.generate_line(ray, line, write=True, hdulist=hdulist) filespecout = filespecout_base + '_' + line.replace(" ", "_") + '.png' sg.plot_spectrum(filespecout, flux_limits=(0.0, 1.0)) MISTY.write_out(hdulist, filename='lauren_advance_spectrum.fits')
def extract_spectra(ds, impact, read=False): out_fits_name = "temp.fits" if read: hdulist = fits.open(out_fits_name) return hdulist, fits[0].header['RAYSTART'], fits[0].header['RAYEND'] else: proper_box_size = ds.get_parameter('CosmologyComovingBoxSize') / ds.get_parameter('CosmologyHubbleConstantNow') * 1000. # in kpc line_list = ['H I 1216', 'Si II 1260', 'C IV 1548', 'O VI 1032'] ray_start = np.zeros(3) ray_end = np.zeros(3) ray_start[0] = xmin ray_end[0] = xmax ray_start[1] = halo_center[1] - (impact/proper_box_size) ray_end[1] = ray_start[1] ray_start[2] = halo_center[2] ray_end[2] = ray_start[2] rs, re = np.array(ray_start), np.array(ray_end) # out_fits_name = "hlsp_misty_foggie_"+haloname+"_"+ds.basename.lower()+"_i"+"{:05.1f}".format(impacts[i]) + \ # "_dx"+"{:4.2f}".format(dx[i])+"_v2_los.fits" rs = ds.arr(rs, "code_length") re = ds.arr(re, "code_length") ray = ds.ray(rs, re) triray = trident.make_simple_ray(ds, start_position=rs.copy(), end_position=re.copy(), data_filename="test.h5", lines=line_list, ftype='gas') hdulist = MISTY.write_header(triray,start_pos=ray_start,end_pos=ray_end, lines=line_list, impact=impact) tmp = MISTY.write_parameter_file(ds,hdulist=hdulist) for line in line_list: sg = MISTY.generate_line(triray,line,write=True,use_spectacle=False,hdulist=hdulist) MISTY.write_out(hdulist,filename=out_fits_name) return hdulist, ray_start, ray_end
trident.add_ion_fields(ds, ['C', "O", "O IV", "O VI", "C IV"], ftype='gas') for field in ds.derived_field_list: print (field) pos = ad['particle_position'][ad['particle_mass'] \ == ad['particle_mass'].max()][0].to('unitary') r = 4.0*ad['virial_radius'][ad['particle_mass'] \ == ad['particle_mass'].max()][0].to('unitary') sp = ds.sphere(pos, r) fields = ['H_p1_density','O_p4_density','C_p0_density', 'H_density'] labels = ['HI', "OIV", "C", "H"] ## make a ray that intersects this most massive halo ## ray = trident.make_simple_ray(ds, start_position=[pos[0], pos[1],0], end_position=[pos[0], pos[1], 1],\ lines='H') width = ds.domain_width[0] lbase = 1215.67 dz = ds.cosmology.z_from_t(ds.current_time-width/ds.quan(2.998*10**8, 'm/s')) lmin = lbase*(z-dz+1) lmax = lbase*(z+1) sg = trident.SpectrumGenerator(lambda_min = lmin, lambda_max = lmax, dlambda=0.01) sg.make_spectrum(ray, lines='H') sg.save_spectrum('/home/azton/simulations/analysis/%s/spectrum_%0.3f.png'%(simname, ds.current_redshift) for field in range(len(fields)): prj = yt.ProfilePlot(sp, "radius",fields[field], label=labels[field]\ , weight_field='density', n_bins=100) prj.annotate_ray(ray, arrow=True) prj.save('/home/azton/simulations/analysis/%s/radialProfile'%simname)
def test_enzo_small_simple(self): """ This is an answer test, which compares the results of this test against answers generated from a previous version of the code. This test generates a COS spectrum from a single Enzo dataset using a simple ray and compare the ray and spectral output data against a known answer. """ # Set the dataset filename, load it into yt and define the trajectory # of the LightRay to cross the box from one corner to the other. ds = load(os.path.join(enzo_small, 'RD0009/RD0009')) ray_start = ds.domain_left_edge ray_end = ds.domain_right_edge # Make a LightRay object including all necessary fields so you can add # all H, C, N, O, and Mg fields to the resulting spectrum from your dataset. # Save LightRay to ray.h5 and use it locally as ray object. ray_fn = 'enzo_small_simple_ray.h5' ray = make_simple_ray(ds, start_position=ray_start, end_position=ray_end, data_filename=ray_fn, lines=['H', 'C', 'N', 'O', 'Mg'], ftype='gas') # Now use the ray object to actually generate an absorption spectrum # Use the settings (spectral range, LSF, and spectral resolution) for COS # And save it as an output hdf5 file and plot it to an image. sg = SpectrumGenerator('COS') sg.make_spectrum(ray, lines=['H', 'C', 'N', 'O', 'Mg']) raw_file = 'enzo_small_simple_spec_raw.h5' raw_file_compare = os.path.join(test_results_dir, raw_file) sg.save_spectrum(raw_file) sg.plot_spectrum('enzo_small_simple_spec_raw.png') # "Final" spectrum with added quasar, MW background, applied line-spread # function, and added gaussian noise (SNR=30) # Save as a text file and plot it to an image. sg.add_qso_spectrum() sg.add_milky_way_foreground() sg.apply_lsf() sg.add_gaussian_noise(30, seed=1) final_file = 'enzo_small_simple_spec_final.h5' final_file_compare = os.path.join(test_results_dir, final_file) sg.save_spectrum(final_file) sg.plot_spectrum('enzo_small_simple_spec_final.png') if generate_results: os.rename(raw_file, raw_file_compare) os.rename(final_file, final_file_compare) else: old_spec = h5py.File(raw_file_compare, 'r') new_spec = h5py.File(raw_file, 'r') for key in old_spec.keys(): assert_almost_equal(new_spec[key].value, old_spec[key].value, \ decimal=err_precision, err_msg='Raw spectrum array does not match '+\ 'for enzo_small_simple answer test') old_spec.close() new_spec.close() old_spec = h5py.File(final_file_compare, 'r') new_spec = h5py.File(final_file, 'r') for key in old_spec.keys(): assert_almost_equal(new_spec[key].value, old_spec[key].value, \ decimal=err_precision, err_msg='Final spectrum array does not match '+\ 'for enzo_small_simple answer test') old_spec.close() new_spec.close()
def make_light_ray_plots(filename, plotting=False, ray_start=[0, 0, 0], ray_direction=[1, 0, 0]): ''' This function computes the dispersion measure along a light ray going through a simulated galaxy. ---------Arguments------------ plotting: If Galaxy plots should be made ray_start: The position of the start of the ray with respect to the center of the Halo ray_direction: The position of the end of the ray with respect to the start of the ray ''' ds, center_Halo, sp, ray_direction_conv, ray_start_conv =\ load_data(ray_start, ray_direction) # RAY CREATION ray_end = list(center_Halo + ray_start_conv + ray_direction_conv) ray = trident.make_simple_ray(ds, start_position=ray_start_conv + center_Halo, end_position=ray_end, fields=['_ElectronDensity', 'density'], data_filename="{}.h5".format(filename)) # GALAXY PLOTS if plotting: # Creates three on-axis projection plots axes = ['x', 'y', 'z'] for axis in axes: prj_x = yt.ProjectionPlot(ds, axis, 'density', width=10 * kpc, data_source=sp, center=center_Halo) prj_x.annotate_ray(ray) prj_x.save(filename + '_galaxy_{}.pdf'.format(str(axis))) # COMPUTING THE DM length = np.linalg.norm(np.array(ray_end)-np.array(center_Halo)-\ np.array(ray_start_conv)) int_elec_dens = [] int_total = 0 # Finding the entry where arc_length>1kpc: for i in range(len(ray.data['_ElectronDensity'])): # Convert in pc/cm^-3 from kpc/h int_total += ray.data['_ElectronDensity'][i]*\ ray.data['dl'][i]*60000*1000/0.7 int_elec_dens.append(float(int_total)) # LIGHT RAY DATA PLOTS fig, axs = pl.subplots(3) axs[0].plot(np.linspace(0, length, len(ray.data['density'])), np.log10(ray.data['density'])) axs[0].set_xlabel('Arc Length (kpc/h)') axs[0].set_ylabel('Density ' + r'$\log\left(\frac{g}{cm^3}\right)$') axs[1].plot(np.linspace(0, length, len(ray.data['_ElectronDensity'])), np.log10(ray.data['_ElectronDensity'])) axs[1].set_xlabel('Arc Length (kpc/h)') axs[1].set_ylabel('Electron Density ' + r'$\log(cm^{-3})$') axs[2].title.set_text('DM = {}'.format(round(int_elec_dens[-1], 2))) axs[2].plot(np.linspace(0, length, len(int_elec_dens)), np.log10(int_elec_dens)) axs[2].set_xlabel('Arc Length (kpc/h)') axs[2].set_ylabel('DM ' + r'$\log(cm^{-2})$') pl.subplots_adjust(left=0.20, right=0.9, bottom=0.2, top=0.9, wspace=0.4, hspace=1.5) fig.savefig(filename + '_subplots.pdf') return int_elec_dens[-1], ray.data['dl']
def generate_random_rays(ds, halo_center, **kwargs): ''' generate some random rays ''' low_impact = kwargs.get("low_impact", 10.) high_impact = kwargs.get("high_impact", 45.) track = kwargs.get("track", "halo_track") Nrays = kwargs.get("Nrays", 2) seed = kwargs.get("seed", 17) axis = kwargs.get("axis", 'x') output_dir = kwargs.get("output_dir", ".") haloname = kwargs.get("haloname", "somehalo") line_list = kwargs.get("line_list", ['H I 1216', 'Si II 1260', 'O VI 1032']) proper_box_size = get_proper_box_size(ds) zsnap = ds.get_parameter('CosmologyCurrentRedshift') refine_box, refine_box_center, x_width = get_refine_box(ds, zsnap, track) proper_x_width = x_width * proper_box_size np.random.seed(seed) high_impact = 0.45 * proper_x_width impacts = np.random.uniform(low=low_impact, high=high_impact, size=Nrays) print('impacts = ', impacts) angles = np.random.uniform(low=0, high=2 * pi, size=Nrays) out_ray_basename = ds.basename + "_ray_" + axis for i in range(Nrays): os.chdir(output_dir) this_out_ray_basename = out_ray_basename + "_i"+"{:05.1f}".format(impacts[i]) + \ "-a"+"{:4.2f}".format(angles[i]) out_ray_name = this_out_ray_basename + ".h5" rs, re = get_refined_ray_endpoints(ds, halo_center, track, impact=impacts[i]) out_name_base = "hlsp_misty_foggie_"+haloname+"_"+ds.basename.lower()+"_ax"+axis+"_i"+"{:05.1f}".format(impacts[i]) + \ "-a"+"{:4.2f}".format(angles[i])+"_v4_los" out_fits_name = out_name_base + ".fits.gz" out_plot_name = out_name_base + ".png" rs = ds.arr(rs, "code_length") re = ds.arr(re, "code_length") if args.velocities: trident.add_ion_fields(ds, ions=[ 'Si II', 'Si III', 'Si IV', 'C II', 'C III', 'C IV', 'O VI', 'Mg II', 'Ne VIII' ]) ray = ds.ray(rs, re) ray["x-velocity"] = ray["x-velocity"].in_units('km / s') ray.save_as_dataset(out_ray_name, fields=["density", "temperature", "metallicity"]) ray["x-velocity"] = ray["x-velocity"].in_units('km / s') if args.velocities: ray['x-velocity'] = ray['x-velocity'].convert_to_units('km/s') ray['y-velocity'] = ray['y-velocity'].convert_to_units('km/s') ray['z-velocity'] = ray['z-velocity'].convert_to_units('km/s') ray['cell_mass'] = ray['cell_mass'].convert_to_units('Msun') ray_df = ray.to_dataframe([ "x", "y", "z", "density", "temperature", "metallicity", "HI_Density", "cell_mass", "x-velocity", "y-velocity", "z-velocity", "C_p2_number_density", "C_p3_number_density", "H_p0_number_density", "Mg_p1_number_density", "O_p5_number_density", "Si_p2_number_density", "Si_p1_number_density", "Si_p3_number_density", "Ne_p7_number_density" ]) out_tri_name = this_out_ray_basename + "_tri.h5" triray = trident.make_simple_ray(ds, start_position=rs.copy(), end_position=re.copy(), data_filename=out_tri_name, lines=line_list, ftype='gas') ray_start = triray.light_ray_solution[0]['start'] ray_end = triray.light_ray_solution[0]['end'] print("final start, end = ", ray_start, ray_end) filespecout_base = this_out_ray_basename + '_spec' print(ray_start, ray_end, filespecout_base) hdulist = MISTY.write_header(triray, start_pos=ray_start, end_pos=ray_end, lines=line_list, impact=impacts[i], redshift=ds.current_redshift) tmp = MISTY.write_parameter_file(ds, hdulist=hdulist) for line in line_list: sg = MISTY.generate_line(triray, line, zsnap=ds.current_redshift, write=True, hdulist=hdulist, use_spectacle=False, resample=True) MISTY.write_out(hdulist, filename=out_fits_name) if args.velocities: print('making the velphase plot....') sv.show_velphase(ds, ray_df, rs, re, hdulist, out_name_base) if args.plot: plot_misty_spectra(hdulist, outname=out_plot_name) print("done with generate_random_rays")
def extract_spectra(ds, impact, **kwargs): read_fits_file = kwargs.get('read_fits_file', False) out_fits_name = kwargs.get('out_fits_name', "temp.fits") xmin = kwargs.get("xmin", 0) xmax = kwargs.get("xmax", 1) halo_center = kwargs.get("halo_center", [0.5, 0.5, 0.5]) refine_box_center = kwargs.get("refine_box_center", halo_center) if read_fits_file: print "opening ", out_fits_name hdulist = fits.open(out_fits_name) ray_start_str, ray_end_str = hdulist[0].header['RAYSTART'], hdulist[ 0].header['RAYEND'] ray_start = [float(ray_start_str.split(",")[0]), \ float(ray_start_str.split(",")[1]), \ float(ray_start_str.split(",")[2])] ray_end = [float(ray_end_str.split(",")[0]), \ float(ray_end_str.split(",")[1]), \ float(ray_end_str.split(",")[2])] return hdulist, ray_start, ray_end else: proper_box_size = get_proper_box_size(ds) # line_list = ['H I 1216', 'Ly b', 'Ly c', 'Ly d', 'Ly 10', 'Si II 1260', 'C IV 1548', 'O VI 1032'] line_list = [ 'H I 1216', 'H I 1026', 'H I 973', 'H I 950', 'H I 919', 'Si II 1260', 'Si III 1207', 'C II 1335', 'C IV 1548', 'O VI 1032' ] ray_start = np.zeros(3) ray_end = np.zeros(3) ray_start[0] = xmin ray_end[0] = xmax ray_start[1] = halo_center[1] + (impact / proper_box_size) ray_end[1] = halo_center[1] + (impact / proper_box_size) ray_start[2] = halo_center[2] ray_end[2] = halo_center[2] rs, re = np.array(ray_start), np.array(ray_end) # out_fits_name = "hlsp_misty_foggie_"+haloname+"_"+ds.basename.lower()+"_i"+"{:05.1f}".format(impacts[i]) + \ # "_dx"+"{:4.2f}".format(dx[i])+"_v2_los.fits" rs = ds.arr(rs, "code_length") re = ds.arr(re, "code_length") ray = ds.ray(rs, re) triray = trident.make_simple_ray(ds, start_position=rs.copy(), end_position=re.copy(), data_filename="test.h5", lines=line_list, ftype='gas') hdulist = MISTY.write_header(triray, start_pos=ray_start, end_pos=ray_end, lines=line_list, impact=impact) tmp = MISTY.write_parameter_file(ds, hdulist=hdulist) for line in line_list: sg = MISTY.generate_line(triray, line, write=True, use_spectacle=True, hdulist=hdulist) MISTY.write_out(hdulist, filename=out_fits_name) return hdulist, ray_start, ray_end
def make_ray(dataset_file, ray_start, ray_end, line_list=["H I", "H II"], field_list=None, filename="ray.h5", return_ray=False, **kwargs): """ A wrapper for the trident.make_simple_ray function to generate rays in SPH simulations. Parameters ---------- dataset_file : string or YT Dataset object Either a YT dataset object or the filename of a dataset on disk. ray_start, ray_end : list of floats The coordinates of the starting and end positions of the ray. The coordinates are assumed to be in code length units. line_list : list of strings, optional The list that will determine which fields that will be added to output ray. The format of these is important, they can include elements (e.g. "C" for Carbon), ions (e.g. "He II" for specifically the Helium II line) or wavelengths (e.g. "Mg II #####" where # is the integer wavelength of the line). These fields will appear in the output ray dataset in the form of "H_p0_number_density" (H plus 0 = H I). Default: ["H I", "H II"] field_list : list of string, optional The list of which additional fields to add to the output light ray. Default: None filename : string, optional The output file name for the ray data stored as a HDF5 file. The ray must be saved. Default: "ray.h5" return_ray : boolean, optional If true, make_ray will return the generated YTDataLightRayDataset, If false, make_ray will return None. Default: False Returns ------- ray return_ray = True: Returns the generated YTDataLightRayDataset None return_ray = False: Returns None """ # If supplied a path name, load the snapshot first if isinstance(dataset_file, str): ds = yt.load(dataset_file) else: ds = dataset_file if field_list is None: field_list = [] field_list.extend([('PartType0', 'SmoothingLength'), ('PartType0', 'ParticleIDs')]) trident.add_ion_fields(ds, ions=line_list) ray = trident.make_simple_ray(ds, start_position=ray_start, end_position=ray_end, lines=line_list, ftype='PartType0', fields=field_list, data_filename=filename, **kwargs) if return_ray: return ray else: return None
def run_sightlines(outputfilename,save_after_num,parallel,\ simulation_dest = None,run = 'default',throwerrors = 'warn'): if run not in ['default', 'test']: print('unknown option for "run" %s.'%run+\ ' Please restart with "run = default"'+\ ' or "run = test".') #do not print out anything from yt (it prints plenty) yt.funcs.mylog.setLevel(50) if parallel: yt.enable_parallelism() readvalsoutput = simulation_quasar_sphere.read_values(outputfilename) #by creating a QuasarSphere, it knows all its metadata and other #information from simparams and scanparams (first lines of file at #'filename') q = simulation_quasar_sphere.SimQuasarSphere( start_up_info_packet=readvalsoutput) if q.simparams[6] is None: if simulation_dest: q.simparams[6] = simulation_dest else: raise NoSimulationError('Simulation file location unknown, '+\ 'run with "simulation_dest" to process') else: simulation_dest = q.simparams[6] ds,fields_to_keep = code_specific_setup.load_and_setup(simulation_dest,\ q.fullname,ions = q.ions,\ redshift = q.redshift) set_up_general(ds, q.code, q.center, q.bulk_velocity, q.Rvir) code_specific_setup.check_redshift(ds, outputfilename=outputfilename) num_bin_vars = q.gasbins.get_length() #Can start at a position further than 0 if reached starting_point = q.length_reached bins = np.append(np.arange(starting_point, q.length, save_after_num), q.length) #first for loop is non-parallel. If 32 processors available, it will break up #into bins of size 32 at a time for example. At end, saves data from all 32. #this is (~12 bins) in usual circumstances for i in range(0, len(bins) - 1): current_info = q.info[bins[i]:bins[i + 1]] if yt.is_root(): tprint("%s-%s /%s" % (bins[i], bins[i + 1], len(q.info))) my_storage = {} #2nd for loop is parallel. Each vector goes to a different processor, and creates #a separate trident sightline (~32 sightlines [in a bin]). #the longest processing step is ray = trident.make_simple_ray, and it's #the only step which actually takes any time (below two for loops go by fast) for sto, in_vec in yt.parallel_objects(current_info, storage=my_storage): vector = np.copy(in_vec) index = vector[0] toprint = "line %s, (r = %.0f) densities " % (str( int(index)), vector[3]) tprint("<line %d, starting process> " % index) ident = str(index) start = ds.arr(tuple(vector[5:8]), 'unitary') end = ds.arr(tuple(vector[8:11]), 'unitary') try: ray = trident.make_simple_ray(ds, start_position=start, end_position=end, data_filename="ray" + ident + ".h5", fields=fields_to_keep, ftype='gas') except KeyboardInterrupt: print('skipping sightline %s ...' % index) print('Interrupt again within 5 seconds to *actually* end') time.sleep(5) continue except ValueError as e: throw_errors_if_allowed( e, throwerrors, 'ray has shape %s - %s, but size 0' % (start, end)) except Exception as e: throw_errors_if_allowed(e, throwerrors, 'problem with making ray') continue trident.add_ion_fields(ray, q.ions) field_data = ray.all_data() dl = field_data['gas', 'dl'] #3rd for loop is for processing each piece of info about each ion #including how much that ion is in each bin according to gasbinning #here just process topline data (column densities and ion fractions) #(~10 ions) for j in range(len(q.ions)): ion = q.ions[j] ionfield = field_data["gas", ion_to_field_name(ion)] cdens = np.sum((ionfield * dl).in_units('cm**-2')).value vector[11 + j * (num_bin_vars + 2)] = cdens total_nucleus = np.sum(ionfield[ionfield>0]/\ field_data["gas",ion_to_field_name(ion,'ion_fraction')][ionfield>0]\ * dl[ionfield>0]) vector[11 + j * (num_bin_vars + 2) + 1] = cdens / total_nucleus #4th for loop is processing each gasbin for the current ion #(~20 bins) for k in range(num_bin_vars): try: variable_name, edges, units = q.gasbins.get_field_binedges_for_num( k, ion) if variable_name is None: vector[11 + j * (num_bin_vars + 2) + k + 2] = np.nan elif variable_name in ray.derived_field_list: if units: data = field_data[variable_name].in_units( units) else: data = field_data[variable_name] abovelowerbound = data > edges[0] belowupperbound = data < edges[1] withinbounds = np.logical_and( abovelowerbound, belowupperbound) coldens_in_line = (ionfield[withinbounds]) * ( dl[withinbounds]) coldens_in_bin = np.sum(coldens_in_line) vector[11 + j * (num_bin_vars + 2) + k + 2] = coldens_in_bin / cdens else: print( str(variable_name) + " not in ray.derived_field_list") except Exception as e: throw_errors_if_allowed( e, throwerrors, 'Could not bin into %s with edges %s' % (variable_name, edges)) toprint += "%s:%e " % (ion, cdens) #gets some more information from the general sightline. #metallicity, average density (over the whole sightline) #mass-weighted temperature try: if ('gas', "H_nuclei_density") in ray.derived_field_list: Z = np.sum(field_data['gas',"metal_density"]*dl)/ \ np.sum(field_data['gas',"H_nuclei_density"]*mh*dl) else: Z = np.sum(field_data['gas',"metal_density"]*dl)/ \ np.sum(field_data['gas',"number_density"]*mh*dl) vector[-1] = Z except Exception as e: throw_errors_if_allowed(e, throwerrors, 'problem with average metallicity') try: n = np.sum( field_data['gas', 'number_density'] * dl) / np.sum(dl) vector[-2] = n except Exception as e: throw_errors_if_allowed(e, throwerrors, 'problem with average density') try: T = np.average(field_data['gas','temperature'],\ weights=field_data['gas','density']*dl) vector[-3] = T except Exception as e: throw_errors_if_allowed(e, throwerrors, 'problem with average temperature') try: os.remove("ray" + ident + ".h5") except: pass tprint(toprint) #'vector' now contains real data, not just '-1's sto.result_id = index sto.result = vector #save all parallel sightlines after they finish (every 32 lines are saved at once) if yt.is_root(): keys = my_storage.keys() for key in keys: q.info[int(key)] = my_storage[key] q.scanparams[6] += (bins[i + 1] - bins[i]) q.length_reached = q.scanparams[6] if run != 'test': outputfilename = q.save_values(oldfilename=outputfilename) tprint("file saved to " + outputfilename + ".")
datafile = sys.argv[1] start_position = sys.argv[2] end_position = sys.argv[3] savename = sys.argv[4] line_list = ['C','N','O'] ds = yt.load(datafile) # Loading the dataset if start_position == 'left_edge': start_position = ds.domain_left_edge if end_position == 'right_edge': end_position = ds.domain_right_edge trident.add_ion_fields(ds,ions=line_list) actual_ray = trident.make_simple_ray(ds,start_position = np.array([0.,0.,0.]),end_position = np.array([128.,128.,128.]),data_filename="mray.h5",lines=line_list,ftype='gas') #lr = trident.LightRay(ds) #lr.make_light_ray(ds,start_position = start_position,end_position = end_position,data_filename="mray.h5",fields=['temperature','density']) sg = trident.SpectrumGenerator('COS') #sg = trident.SpectrumGenerator(lambda_min='auto', lambda_max='auto',dlambda=0.01) sg.make_spectrum(actual_ray, lines=line_list) sg.save_spectrum(savename + '.txt') sg.plot_spectrum(savename + '.png')
def construct_rays(ds_file, start_points, end_points, fld_params=None, line_list=None, other_fields=None, ftype='gas', out_dir='./'): """ Construct rays given a set of starting points and end points. Parameters ---------- ds_file : str or YT dataset path to dataset to be used to create rays start_points : numpy array 1d array of starting points for each ray (code_length) end_points : numpy array 1d array of end points for each ray (code_length) fld_params: dict, optional Dictionary of parameters that will be passed to the lightrays. (ie `center`, `bulk_velocity`). Default: None line_list : list list of ions to add to light rays. None defaults to H I, C IV, and O VI other_fields : list other yt fields to add to light rays. None defaults to density, metallicity, and temperature ftype : str The field to be passed to trident that ion fields will be added to, i.e. ('gas', 'H_p0_number_density'). 'gas' should work for most grid-based simulations. For particle-based simulations this will not work and needs to be changed. 'PartType0' often works though it varies. See trident.make_simple_ray() for more information out_dir : str/path where to save all of the lightrays """ comm = MPI.COMM_WORLD #set defaults if line_list is None: line_list = ['H I', 'C IV', 'O VI'] if other_fields is None: other_fields = ['density', 'metallicity', 'temperature'] n_rays = start_points.shape[0] #set padding for filenames pad = np.floor(np.log10(n_rays)) pad = int(pad) + 1 # distribute rays to proccesors my_ray_nums = np.arange(n_rays) #split ray numbers then take a portion based on rank split_ray_nums = np.array_split(my_ray_nums, comm.size) my_ray_nums = split_ray_nums[comm.rank] for i in my_ray_nums: #construct ray ray_filename = f"{out_dir}/ray{i:0{pad}d}.h5" trident.make_simple_ray(ds_file, start_points[i], end_points[i], lines=line_list, fields=other_fields, ftype=ftype, field_parameters=fld_params, data_filename=ray_filename) comm.Barrier()
def make_random_spectrum(model, output, num_spectra = 1, spectrum_directory = '.', \ ion_list = 'all', rmin = 10, rmax = 100, ray_len = 500, redshift = None): # load data set with yt, galaxy center, and the bulk velocity of the halo ds, gcenter, bulk_velocity = spg.load_simulation_properties(model, output) ad = ds.all_data() # set field parameters so that trident knows to subtract off bulk velocity ad.set_field_parameter('bulk_velocity', bulk_velocity) ad.set_field_parameter('center', gcenter) # either specify redshift manually, or determine redshift from the redshift of the simulation if redshift is None: redshift = round(ds.current_redshift, 2) print(gcenter, gcenter[0], bulk_velocity) gcenter = np.array(gcenter.d) kpc_unit = (ds.domain_right_edge[0].d - ds.domain_left_edge[0].d) \ / (ds.domain_right_edge.in_units('kpc')[0].d - ds.domain_left_edge.in_units('kpc')[0].d) ikpc_unit = 1.0 / kpc_unit for i in range(num_spectra): # generate the coordinates of the random sightline impact_parameter, ray_start, ray_end = spg.generate_random_ray_coordinates(gcenter*kpc_unit, rmin*kpc_unit, rmax*kpc_unit, ray_len*kpc_unit) ray_id, ray_fn = spg.get_next_ray_id(model, redshift, spectrum_directory = spectrum_directory) # write ray id, impact parameter, bulk velocity, and start/end coordinates out to file ray_outfile = open(ray_fn, 'a') ray_outfile.write('%i %.2f %.2f %.2f %.2f %e %e %e %e %e %e %e %e %e\n'%(ray_id, impact_parameter*ikpc_unit, \ bulk_velocity[0].in_units('km/s').d, bulk_velocity[1].in_units('km/s').d, bulk_velocity[2].in_units('km/s').d,\ ray_start[0]*ikpc_unit, ray_start[1]*ikpc_unit, ray_start[2]*ikpc_unit, \ ray_end[0]*ikpc_unit, ray_end[1]*ikpc_unit, ray_end[2]*ikpc_unit,\ gcenter[0].astype(float), gcenter[1].astype(float), gcenter[2].astype(float))) ray_outfile.close() # generate sightline using Trident ray = trident.make_simple_ray(ds, start_position = ray_start, end_position = ray_end, lines=ion_list, ftype='gas', field_parameters=ad.field_parameters, # the current redshift of the simulation, calculated above, rounded to two decimal places redshift=redshift, data_filename='%s/ray_%s_%s_%i.h5'%(spectrum_directory, model, output, ray_id)) # create spectrum from sightline for both G130M and G160M instruments, # for now, save these two spectra as temporary separate files for instrument in ['COS-G130M', 'COS-G160M']: sg = trident.SpectrumGenerator(instrument, line_database = 'pyigm_line_list.txt') sg.make_spectrum(ray, lines = ion_list) sg.apply_lsf() sg.add_gaussian_noise(10) temp_name = '%s.fits'%(instrument) sg.save_spectrum(temp_name, format = 'FITS') # stitch the spectra together in the format you'll need for veeper spec_name = '%s/COS-FUV_%s_z%.2f_%i.fits'%(spectrum_directory, model, redshift, int(ray_id)) spg.stitch_g130m_g160m_spectra('COS-G130M.fits', 'COS-G160M.fits', spec_name) os.remove('COS-G130M.fits') os.remove('COS-G160M.fits')
def generate_ray_data(model, output, ray_data_file, data_loc = '.', \ ion_list = 'all', redshift = None): # load data set with yt, galaxy center, and the bulk velocity of the halo if model == 'P0': ds = yt.load('/nobackup/ibutsky/tmp/pioneer.%06d' % (output)) trident.add_ion_fields(ds, ions=ion_list) # for annoying reasons... need to convert ray positions to "code units" code_unit_conversion = ds.domain_right_edge.d / ds.domain_right_edge.in_units( 'kpc').d ray_id_list, impact, bvx, bvy, bvz, xi, yi, zi, xf, yf, zf, cx, cy, cz =\ np.loadtxt('../../data/P0_z0.25_ray_data.dat', skiprows = 1, unpack = True) gcenter_kpc = [cx[0], cy[0], cz[0] ] # assuming galaxy center is the same for all sightlines gcenter = gcenter_kpc * code_unit_conversion bulk_velocity = YTArray([bvx[0], bvy[0], bvz[0]], 'km/s') # set field parameters so that trident knows to subtract off bulk velocity ad = ds.all_data() ad.set_field_parameter('bulk_velocity', bulk_velocity) ad.set_field_parameter('center', gcenter) ray_start_list = np.ndarray(shape=(0, 3)) ray_end_list = np.ndarray(shape=(0, 3)) for i in range(len(xi)): ray_start_list = np.vstack( (ray_start_list, [xi[i], yi[i], zi[i]] * code_unit_conversion)) ray_end_list = np.vstack( (ray_end_list, [xf[i], yf[i], zf[i]] * code_unit_conversion)) # either specify redshift manually, or determine redshift from the redshift of the simulation if redshift is None: redshift = round(ds.current_redshift, 2) print(gcenter, gcenter[0], bulk_velocity) for i in range(1, 150): # generate the coordinates of the random sightline # write ray id, impact parameter, bulk velocity, and start/end coordinates out to file h5file = h5.File( '%s/ray_%s_%i_%i.h5' % (data_loc, model, output, ray_id_list[i]), 'a') # generate sightline using Trident ray = trident.make_simple_ray( ds, start_position=ray_start_list[i], end_position=ray_end_list[i], lines=ion_list, ftype='gas', field_parameters=ad.field_parameters, # the current redshift of the simulation, calculated above, rounded to two decimal places redshift=redshift) ad_ray = ray.all_data() # generating the list of all of the field_list = ['y', 'temperature', 'density', 'metallicity', 'dl'] source_list = [ad, ad, ad, ad, ad_ray] unit_list = ['kpc', 'K', 'g/cm**3', 'Zsun', 'cm'] yt_ion_list = ipd.generate_ion_field_list(ion_list, 'number_density', full_name=False) yt_ion_list[0] = 'H_number_density' field_list = np.append(field_list, yt_ion_list) for j in range(len(yt_ion_list)): unit_list.append('cm**-3') source_list.append(ad_ray) for field, source, unit in zip(field_list, source_list, unit_list): if field not in h5file.keys(): h5file.create_dataset(field, data=source[('gas', field)].in_units(unit)) h5file.flush() h5file.create_dataset('y_lr', data=ad_ray['y'].in_units('kpc')) h5file.flush() h5file.close() print("saved sightline data %i\n" % (i))
# Set the dataset filename, load it into yt and define the trajectory # of the LightRay. Define desired spectral features to include # all H, C, N, O, and Mg lines. fn = 'enzo_cosmology_plus/RD0009/RD0009' ds = yt.load(fn) ray_start = ds.domain_left_edge ray_end = ds.domain_right_edge line_list = ['H', 'C', 'N', 'O', 'Mg'] # Make a LightRay object including all necessary fields so you can add # all H, C, N, O, and Mg fields to the resulting spectrum from your dataset. # Save LightRay to ray.h5 and use it locally as ray object. ray = trident.make_simple_ray(ds, start_position=ray_start, end_position=ray_end, data_filename='ray.h5', lines=line_list, ftype='gas') # Create a projection of the dataset in density along the x axis, # overplot the trajectory of the ray, and save it. p = yt.ProjectionPlot(ds, 'x', 'density') p.annotate_ray(ray, arrow=True) p.save('projection.png') # Now use the ray object to actually generate an absorption spectrum # Use the settings (spectral range, LSF, and spectral resolution) for COS # And save it as an output text file and plot it to an image. sg = trident.SpectrumGenerator('COS') sg.make_spectrum(ray, lines=line_list) sg.save_spectrum('spec_raw.txt')
savefolder = '../Spectra/'+runName+savefolderEnd filePrefix = '../Files/'+runName+'/KH_hdf5_chk_' #cdfile_list = ['0006'] for chk_num in file_list: file_name = filePrefix+chk_num dataset = yt.load(file_name) dataset.add_field(('gas', 'metallicity'), function=_metallicity, display_name="Metallicity", units='Zsun') #make a ray object ray = tri.make_simple_ray(dataset, redshift=0.0, start_position=ray_start, end_position=ray_end, lines=line_list, ftype = 'gas') #plot and save density projection to look at the path of the ray p = yt.ProjectionPlot(dataset, 'z', 'density', origin='native') p.annotate_ray(ray) p.save(savefolder+'projection'+chk_num+'.png') print("Saved Projection images as "+savefolder+"/projection"+chk_num+".png") #create a spectrumGenerator; you may make your own spectrograph settings sg = tri.SpectrumGenerator(lambda_min= 500, lambda_max=1600, dlambda=0.01) #uses default spectrograph settings for "Cosmic Origins Spectrograph" sg.make_spectrum(ray, lines=line_list) #save and plot the spectrum sg.save_spectrum(savefolder+'spec_raw'+chk_num+'.h5')
theta = x[i] phi = y[i] dx = R * np.cos(theta) * np.sin(phi) dy = R * np.sin(theta) * np.sin(phi) dz = R * np.cos(phi) dv = YTArray([dx, dy, dz], 'kpc') ray_end = ray_start + dv rayfile = 'ray_files/ray' + str(ds) + '_' + str(i) + '_' + '.h5' ray = trident.make_simple_ray(ds, start_position=ray_start, end_position=ray_end, data_filename=rayfile, fields=field_list, ftype='gas') ray_data = ray.all_data() path_length = ray_data['dl'].convert_to_units('kpc').d # Remove the first 5 kpc from the ray data path = np.zeros(len(path_length)) for h in range(len(path_length) - 1): dl = path_length[h] p = path[h] path[h + 1] = dl + p
def make_random_spectrum(model, output = 3195, spectrum_directory = '../../data/unanalyzed_spectra', \ ion_list = 'all', redshift = None, write_spectra = True): ds, gcenter, bulk_velocity = spg.load_simulation_properties(model) ad = ds.all_data() ad.set_field_parameter('bulk_velocity', bulk_velocity) ad.set_field_parameter('center', gcenter) if redshift is None: redshift = round(ds.current_redshift, 2) print(gcenter, gcenter[0], bulk_velocity) field_list = ['temperature', 'density', 'metallicity', 'velocity_x', 'velocity_y', 'velocity_z', 'pressure'] if model == 'P0_agncr': field_list.append('cr_pressure') ray_id_list, impact_list, xs, ys, zs, xe, ye, ze = np.loadtxt('../../data/random_sightlines.dat', skiprows=1, unpack = True) spectrum_data_filename = '%s/%s_z%0.2f_ray_data.dat'%(spectrum_directory, model, redshift) total_column_filename = '%s/%s_total_column.dat'%(spectrum_directory, model) if not os.path.isfile(spectrum_data_filename): spectrum_data_outfile = open(spectrum_data_filename, 'w') spectrum_data_outfile.write('ray_id, impact_parameter(kpc), bulk velocity(km/s)[vx, vy, vz], ray_start(kpc)[x, y, z], \ ray_end(kpc)[x, y, z], sim_center(kpc)[x,y,z] \n') else: spectrum_data_outfile = open(spectrum_data_filename, 'a') if not os.path.isfile(total_column_filename): col_outfile = open(total_column_filename, 'w') col_outfile.write('#ray_id, impact_parameter(kpc), OVI col, SiIII col, HI col\n') else: col_outfile = open(total_column_filename, 'a') for i, ray_id in enumerate(ray_id_list): spec_name = '%s/COS-FUV_%s_z%.2f_%04d.fits'%(spectrum_directory, model, redshift, int(ray_id)) ray_name = '%s/ray_%s_%s_%i.h5'%(spectrum_directory, model, output, ray_id) if not os.path.isfile(ray_name): ray_start = ds.arr(gcenter.in_units('kpc').d + np.array([xs[i], ys[i], zs[i]]), 'kpc') ray_end = ds.arr(gcenter.in_units('kpc').d + np.array([xe[i], ye[i], ze[i]]), 'kpc') spectrum_data_outfile.write('%i %.2f %.2f %.2f %.2f %e %e %e %e %e %e %e %e %e\n'%(ray_id, impact_list[i], bulk_velocity[0], bulk_velocity[1], bulk_velocity[2], ray_start[0], ray_start[1], ray_start[2], ray_end[0], ray_end[1], ray_end[2], gcenter[0].astype(float), gcenter[1].astype(float), gcenter[2].astype(float))) spectrum_data_outfile.flush() ray = trident.make_simple_ray(ds, start_position = ray_start, end_position = ray_end, lines=ion_list, ftype='gas', fields = field_list, field_parameters=ad.field_parameters, # the current redshift of the simulation, calculated above, rounded to two decimal places redshift=redshift, data_filename=ray_name) if write_spectra: rd = ray.all_data() dl = rd['dl'] ocol = np.cumsum(rd['O_p5_number_density']*dl)[-1] sicol = np.cumsum(rd['Si_p2_number_density']*dl)[-1] hcol = np.cumsum(rd['H_p0_number_density']*dl)[-1] col_outfile.write("%i %.2f %.2f %.2f %.2f\n"%(ray_id, impact_list[i], np.log10(ocol), np.log10(sicol), np.log10(hcol))) col_outfile.flush() for instrument in ['COS-G130M', 'COS-G160M']: sg = trident.SpectrumGenerator(instrument, line_database = 'pyigm_line_list.txt') sg.make_spectrum(ray, lines = ion_list) sg.apply_lsf() sg.add_gaussian_noise(10) temp_name = '%s_%s.fits'%(instrument, model) sg.save_spectrum(temp_name, format = 'FITS') # stitch the spectra together in the format you'll need for veeper spg.stitch_g130m_g160m_spectra('COS-G130M_%s.fits'%model, 'COS-G160M_%s.fits'%model, spec_name) os.remove('COS-G130M_%s.fits'%model) os.remove('COS-G160M_%s.fits'%model) spectrum_data_outfile.close() col_outfile.close()
comm.Barrier() for i in locals: startTime = time.time() if dataLoc == "comet": rFile = "%s/lin_rays/ray_%d.h5" % (dataRepo, i) else: rFile = '%s/rayData/%s/RD%04d/lin_rays/ray_%d.h5'\ %(dataRepo,simname, d, i) row = (i // dim) col = (i % dim) xstart = (row + 0.5) * dx ystart = (col + 0.5) * dx start = np.array([xstart, ystart, 0.0]) end = start + np.array([5 * dx, 5 * dx, 1.0]) ray = trident.make_simple_ray(ds, start_position=start,\ end_position=end, data_filename=rFile,\ lines=['H I 1216'], ftype='gas',\ fields = ['density','metallicity','temperature','H_p0_number_density']) count += 1 counts = comm.gather(count, root=0) if rank == 0: if count % 50 == 0: counts = sum(counts) print('%d light-ray objects created!'%(counts)\ +'\nIntermediate pipelinefile being created') f = open('lin_%s_RD%04d_pipeline.info' % (simname, d), 'w') f.write('%s\n%d\n%d\n%s\n%d\n%d\n'\ %(simname,d,dim,sys.argv[4], size, counts )) f.close() os.system('cd %s; tar -cvf lin_rays.tar lin_rays;'%(dataRepo)\ +' mv lin_rays.tar %s/rayData/%s/RD%04d/'\