def _create_spectra(self): """ Use trident to create the absorption spectrum of the ray in velocity space for use in fitting. Returns -------- velocity: YT array Array of velocity values of the generated spectra (in km/s) flux: YT array Array of the normalized flux values of the generated spectra """ #set which ions to add to spectra wav = int(np.round(self.wavelength_center)) line = f"{self.ion_name} {wav}" ion_list = [line] #use auto feature to capture full line spect_gen = trident.SpectrumGenerator(lambda_min="auto", lambda_max="auto", dlambda=self.velocity_res, bin_space="velocity") spect_gen.make_spectrum(self.data, lines=ion_list) #get fields from spectra and give correct units flux = spect_gen.flux_field velocity = spect_gen.lambda_field return velocity, flux
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 plot_lambda_space(self, ax=None): """ Use trident to plot the absorption spectrum of the ray. Plot in wavelegnth (lambda) space. Not formatted to be used in spectacle fitting Parameters ----------- ax : matplotlib axis axis in which to draw the spectra plot Returns -------- wavelength: YT array Array of wavelength values of the generated spectra (in km/s) flux: YT array Array of the normalized flux values of the generated spectra """ #set which ions to add to spectra ion_list = self.ion_list #adjust wavelegnth_center for redshift rest_wavelength = self.wavelength_center wave_min = rest_wavelength - self.wavelength_width / 2 wave_max = rest_wavelength + self.wavelength_width / 2 #use wavelength_width to set the range spect_gen = trident.SpectrumGenerator(lambda_min=wave_min, lambda_max=wave_max, dlambda=self.wavelegnth_res) spect_gen.make_spectrum(self.data, lines=ion_list, observing_redshift=self.ds.current_redshift) #get fields from spectra and give correct units rest_wavelength = rest_wavelength * u.Unit('angstrom') wavelength = spect_gen.lambda_field * u.Unit('angstrom') flux = spect_gen.flux_field if ax is not None: #plot values for spectra ax.plot(wavelength[:-1], flux[:-1]) ax.set_ylim(0, 1.05) ax.set_xlim(wave_min, wave_max) ax.xaxis.set_minor_locator(AutoMinorLocator(2)) ax.set_title(f"Spectrum {self.ion_name}", loc='right') ax.set_xlabel("Wavelength $\AA$") ax.set_ylabel("Flux") ax.grid(zorder=0, which='both') return wavelength, flux
def quick_spectrum(ds, triray, filename, **kwargs): line_list = kwargs.get("line_list", ['H I 1216', 'Si II 1260', 'Mg II 2796', 'C III 977', 'C IV 1548', 'O VI 1032']) redshift = ds.get_parameter('CosmologyCurrentRedshift') ldb = trident.LineDatabase('atom_wave_gamma_f.dat') sg = trident.SpectrumGenerator(lambda_min=1000., lambda_max=4000., dlambda=0.01, line_database='atom_wave_gamma_f.dat') sg.make_spectrum(triray, line_list, min_tau=1.e-5,store_observables=True) restwave = sg.lambda_field / (1. + redshift) out_spectrum = Table([sg.lambda_field, restwave, sg.flux_field]) out_spectrum.write(filename+'.fits')
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 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)
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 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_line(ray, line, zsnap=0.0, write=False, use_spectacle=True, hdulist=None, **kwargs): ''' input: a lightray and a line; writes info to extension of hdulist ''' resample = kwargs.get('resample', False) if write and type(hdulist) != fits.hdu.hdulist.HDUList: raise ValueError( 'Must pass HDUList in order to write. Call write_header first.') if not isinstance(line, trident.Line): ldb = trident.LineDatabase('lines.txt') # ldb = trident.LineDatabase('atom_wave_gamma_f.dat') line_out = ldb.parse_subset(line) print(line, line_out) line_out = line_out[0] ar = ray.all_data() lambda_rest = line_out.wavelength if line_out.name == "H I 1216": padding = 5. else: padding = 5. lambda_min = lambda_rest * (1 + min(ar['redshift_eff'])) - padding lambda_max = lambda_rest * (1 + max(ar['redshift_eff'])) + padding sg = trident.SpectrumGenerator(lambda_min=lambda_min.value, lambda_max=lambda_max.value, dlambda=0.0001, line_database='lines.txt' # line_database='atom_wave_gamma_f.dat' ) sg.make_spectrum(ray, lines=line_out.name, min_tau=1.e-5, store_observables=True) if write and str(line_out) in sg.line_observables_dict: tau = sg.tau_field flux = sg.flux_field disp = sg.lambda_field redshift = (sg.lambda_field.value / lambda_rest - 1) z_col = fits.Column(name='redshift', format='E', array=redshift) wavelength = fits.Column(name='wavelength', format='E', array=disp, unit='Angstrom') tau_col = fits.Column(name='tau', format='E', array=tau) flux_col = fits.Column(name='flux', format='E', array=flux) col_list = [z_col, wavelength, tau_col, flux_col] for key in sg.line_observables_dict[str(line_out)].keys(): col = fits.Column( name='sim_' + key, format='E', array=sg.line_observables_dict[str(line_out)][key]) col_list = np.append(col_list, col) cols = fits.ColDefs(col_list) sghdr = fits.Header() sghdr['LINENAME'] = line_out.name print("----->>>>using ", line_out.name, "as LINENAME, whereas ", line, " was passed. Change?") sghdr['RESTWAVE'] = (line_out.wavelength, "Angstroms") sghdr['F_VALUE'] = line_out.f_value sghdr['GAMMA'] = line_out.gamma print("f = ", line_out.f_value) # want to leave blank spaces now for values that we're expecting to generate for MAST # first let's add some spaces for the simulated, tau-weighted values! sghdr['SIM_TAU_HDENS'] = -9999. sghdr['SIM_TAU_TEMP'] = -9999. sghdr['SIM_TAU_METAL'] = -9999. sghdr['TOT_COLUMN'] = (np.log10( np.sum(sg.line_observables_dict[line_out.identifier] ['column_density'].value)), "log cm^-2") # we're also going to want data from spectacle if use_spectacle: print(sg.line_list[0]) lines_properties = get_line_info(disp, flux, \ tau=sg.tau_field, redshift=zsnap, \ lambda_0=sg.line_list[0]['wavelength'].value, \ f_value=sg.line_list[0]['f_value'], \ gamma=sg.line_list[0]['gamma'], \ ion_name=line_out.name) for key in lines_properties: sghdr[key] = lines_properties[key] sghdu = fits.BinTableHDU.from_columns(cols, header=sghdr, name=line_out.name) hdulist.append(sghdu) return sg
## want separate sg's with different lines --> need different rays ray = trident.make_simple_ray(ds, start_position=ray_start, end_position=ray_end, data_filename="ray.h5", lines=line_list, ftype='gas') ar = ray.all_data() for line in ll: lambda_rest = line.wavelength lambda_min = lambda_rest * (1 + min(ar['redshift_eff'])) - 1 lambda_max = lambda_rest * (1 + max(ar['redshift_eff'])) + 1 print lambda_min, lambda_max sg = trident.SpectrumGenerator(lambda_min=lambda_min.value, lambda_max=lambda_max.value, dlambda=0.01) sg.make_spectrum(ray, lines=line.name) # let's plot it! filespecout = 'spectrum_' + ds.basename + '_' + line.identifier.replace( " ", "_") + '.png' sg.plot_spectrum(filespecout, flux_limits=(0.0, 1.0)) # make this sg an hdu col1 = fits.Column(name='wavelength', format='E', array=sg.lambda_field) col2 = fits.Column(name='tau', format='E', array=sg.tau_field) col3 = fits.Column(name='flux', format='E', array=sg.flux_field) col_list = [col1, col2, col3] for key in sg.line_observables[line.identifier].keys():
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()
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+".h5") print("Saved Spectrum image as "+savefolder+"spec_raw"+chk_num+".png")
startSpec = time.time() if dataLoc == "comet": rFile = "%s/lin_rays/ray_%d.h5" % (workdir, i) sFile = "%s/lin_spectra/spectra_%d.h5" % (workdir, i) else: rFile = '%s/rayData/%s/RD%04d/lin_rays/ray_%d.h5'\ %(workdir,simname, d,i) sFile ='%s/rayData/%s/RD%04d/lin_spectra/spectrum_%d.h5'\ %(workdir, simname, d, i) if not os.path.exists(rFile): continue if os.path.exists(sFile): count += 1 continue try: sg = trident.SpectrumGenerator(\ lambda_min=lambda_min, \ lambda_max=lambda_max, \ dlambda=(lambda_max-lambda_min)/(4*dim)) sg.make_spectrum(rFile, lines=['H I 1216']) sg.save_spectrum(sFile) count += 1 print ('[%d] %0.3f seconds to generate'\ %(rank, time.time()-startSpec)) del (sg, startSpec) except: continue if (rank == 0) & (count % 50 == 0) & (dataLoc == "comet"): os.system("cd %s; tar -cvf lin_spectra.tar lin_spectra"\ %(workdir)) os.system("cd %s; cp lin_spectra.tar %s/rayData/%s/RD%04d/"\ %(workdir, scriptsdir, simname, d)) counts = comm.gather(count, root=0)
def plot_vel_space(self, ax=None, annotate_column_density=True): """ Use trident to plot the absorption spectrum of the ray in velocity space. Compute column densities with spectacle fits. Parameters ----------- ax: matplotlib axis object, optional an axis in which to draw the velocity plot. If None, no plot is not drawn. Default: None annotate_column_density: bool, optional if True, add a textbox reporting the calculated col densities by each method to the plot. Default: True Returns ---------- velocity: YT array Array of velocity values of the generated spectra (in km/s) flux: YT array Array of the normalized flux values of the generated spectra """ # add wav center first so it is set as zero point velocity by trident wav = int(np.round(self.wavelength_center)) line = f"{self.ion_name} {wav}" ion_list = [line] + self.ion_list #set up spectra vel_min = -self.velocity_width / 2 vel_max = self.velocity_width / 2 spect_gen = trident.SpectrumGenerator(lambda_min=vel_min, lambda_max=vel_max, dlambda=self.velocity_res, bin_space="velocity") #generate spectra and return fields spect_gen.make_spectrum(self.data, lines=ion_list) flux = spect_gen.flux_field velocity = spect_gen.lambda_field.in_units('km/s') if ax is not None: #plot values for velocity plot ax.plot(velocity[:-1], flux[:-1]) ax.set_ylim(0, 1.05) ax.set_xlim(vel_min, vel_max) ax.xaxis.set_minor_locator(AutoMinorLocator(2)) ax.set_title(f"Rel. to line {self.wavelength_center:.1f} $\AA$", loc='right') ax.set_xlabel("Delta v (km/s)") ax.set_ylabel("Flux") ax.grid(zorder=0, which='both') if self.use_spectacle: line_txt, line_models = self._get_vel_plot_annotations() box_props = dict(boxstyle='square', facecolor='white') if annotate_column_density: #annotate plot with column densities ax.text(0.8, 0.05, line_txt, transform=ax.transAxes, bbox=box_props) #annotate number of lines ax.text(0.9, 0.85, f"{self.num_spectacle} lines", transform=ax.transAxes, bbox=box_props) colors = ['tab:purple', 'tab:orange', 'tab:green'] vel = np.linspace(vel_min, vel_max, 1000) * u.Unit('km/s') #plot individual column lines if line_models is not None: for mod, color in zip(line_models, colors): #plot centroids of largest lines dv = mod.lines[0].delta_v.value cd = mod.lines[0].column_density.value ax.scatter(dv, 1, c=color, marker='v', zorder=5, label="logN={:04.1f}".format(cd)) #plott the largest lines if self.plot_spectacle: ax.step(vel, mod(vel), linestyle='--', color=color, alpha=0.75) ax.legend(loc='lower left') return velocity, flux
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 generate_spectra(index_start, index_end, output, sn_list = [10]): ds = yt.load('/nobackupp2/ibutsky/simulations/romulusC/romulusC.%06d'%(output)) ion_list = ['H I', 'C II', 'C III', 'C 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_z = center[2] print(center_x, center_z) ray_id, x_list, z_list = np.loadtxt('/nobackupp2/ibutsky/data/YalePaper/spectra/coordinate_list.dat',\ skiprows = 1, unpack=True) outfile = open('/nobackup/ibutsky/data/YalePaper/spectra/romulusC_sightline_%i_extra_data.dat'%(output), 'a') # outfile.write('# ray_id N_{HI}, N_{CII}, N_{CIII}, N_{CIV}, N_{OVI}, T_ave, nH_ave, M_tot(Msun) \n'); for i in range(index_start, index_end): x = ((x_list[i] + center_x) / ds.length_unit).d # note: the plus is important. x_list, z_list counted from center z = ((z_list[i] + center_z) / ds.length_unit).d print(x_list[i], z_list[i], ds.length_unit) ray_start = [x, -0.5, z] ray_end = [x, 0.5, z] print(ray_start, ray_end) ray = trident.make_simple_ray(ds, start_position = ray_start, end_position = ray_end, lines='all', ftype='gas', data_filename='/nobackup/ibutsky/data/YalePaper/spectra/ray_%i_%i.h5'%(output, i)) ad = ray.all_data() for sn in sn_list: for choice in[130, 160]: instrument = 'COS-G'+str(choice)+'M' sg = trident.SpectrumGenerator(instrument) sg.make_spectrum(ray, lines= 'all') sg.apply_lsf() sg.add_gaussian_noise(sn) sg.save_spectrum('/nobackup/ibutsky/data/YalePaper/spectra/romulusC_sightline_%i_%s_sn%i_%i.fits'%(output, choice, sn, i), format = 'FITS') H_col = (ad[('gas', 'dl')] * ad[('gas', 'H_number_density')]).sum() CII_col = (ad[('gas', 'dl')] * ad[('gas', 'C_p1_number_density')]).sum() CIII_col = (ad[('gas', 'dl')] * ad[('gas', 'C_p2_number_density')]).sum() CIV_col = (ad[('gas', 'dl')] * ad[('gas', 'C_p3_number_density')]).sum() O_col = (ad[('gas', 'dl')] * ad[('gas', 'O_p5_number_density')]).sum() ray = ds.ray(ray_start, ray_end) weight = ('gas', 'mass') T_ave = ray.quantities.weighted_average_quantity(('gas', 'temperature'), weight) rho_ave = ray.quantities.weighted_average_quantity(('gas', 'particle_H_nuclei_density'), weight) M_tot = ray.quantities.total_quantity(('gas', 'mass')).in_units('Msun') outfile.write('%i %e %e %e %e %e %e %e %e %e %e \n'%(i, H_col, CII_col, CIII_col, CIV_col, O_col, T_ave, rho_ave, M_tot, x, z)) outfile.flush()