Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
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')
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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')
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
## 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():
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
    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")
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
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
Ejemplo n.º 16
0
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') 
Ejemplo n.º 17
0
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()