Example #1
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')
Example #2
0
    def __init__(self,
                 ds_filename,
                 ray_filename,
                 ion_name='H I',
                 cut_region_filters=None,
                 wavelength_center=None,
                 velocity_res=10,
                 spectacle_defaults=None,
                 spectacle_res=None,
                 absorber_min=None,
                 frac=0.8):

        #set file names and ion name
        if isinstance(ds_filename, str):
            self.ds = yt.load(ds_filename)
        elif isinstance(ds_filename, Dataset):
            self.ds = ds_filename

        self.ray_filename = ray_filename
        self.ion_name = ion_name
        self.cut_region_filters = cut_region_filters
        self.frac = frac

        #add ion name to list of all ions to be plotted
        self.ion_list = [ion_name]

        #open up the dataset and ray files
        self.load_ray(self.ray_filename)

        if absorber_min is None:
            if self.ion_name in default_cloud_dict.keys():
                self.absorber_min = default_cloud_dict[self.ion_name]
            else:
                self.absorber_min = 13
        else:
            self.absorber_min = absorber_min

        self.defaults_dict = {
            'bounds': {
                'column_density': (self.absorber_min - 0.5, 23)
            },
            'fixed': {
                'delta_lambda': True,
                'column_density': False
            }
        }

        #add user defined defaults
        if spectacle_defaults is not None:
            self.defaults_dict.update(spectacle_defaults)

        self.velocity_res = velocity_res

        #default spectacle resolution to velocity_res
        if spectacle_res is None:
            self.spectacle_res = velocity_res
        else:
            self.spectacle_res = spectacle_res

        #default set the wavelength center to one of the known spectral lines
        #for ion name. Use tridents line database to search for correct wavelength
        if wavelength_center is None:
            #open up tridents default line database
            lbd = trident.LineDatabase('lines.txt')
            #find all lines that match ion
            lines = lbd.parse_subset(subsets=[self.ion_name])
            #take one with largest f_value
            f_val = 0
            for line in lines:
                if line.f_value >= f_val:
                    f_val = line.f_value
                    self.wavelength_center = line.wavelength
        else:
            self.wavelength_center = wavelength_center
Example #3
0
    def __init__(self,
                 ds_filename,
                 ray_filename,
                 ion_name='H I',
                 ftype='gas',
                 cut_region_filters=None,
                 slice_field=None,
                 absorber_fields=[],
                 north_vector=[0, 0, 1],
                 center_gal=None,
                 wavelength_center=None,
                 wavelength_width=30,
                 velocity_width=3000,
                 wavelength_res=0.1,
                 velocity_res=10,
                 use_spectacle=False,
                 plot_spectacle=False,
                 spectacle_defaults=None,
                 spectacle_res=None,
                 plot_spice=False,
                 absorber_min=None,
                 frac=0.8,
                 num_dense_min=None,
                 num_dense_max=None,
                 markers=True,
                 mark_plot_args=None,
                 figure=None):
        #set file names and ion name
        if isinstance(ds_filename, str):
            self.ds = yt.load(ds_filename)
        elif isinstance(ds_filename, Dataset):
            self.ds = ds_filename
        self.ray_filename = ray_filename
        self.ion_name = ion_name

        self.cut_region_filters = cut_region_filters
        self.frac = frac

        #add ion name to list of all ions to be plotted
        self.ion_list = [ion_name] + absorber_fields

        #add ion fields to dataset if not already there
        trident.add_ion_fields(self.ds, ions=self.ion_list, ftype=ftype)

        #set a value for slice
        self.slice = None
        self.north_vector = north_vector
        self.center_gal = center_gal

        #open up the ray files
        self.load_ray(self.ray_filename)

        #set slice field to ion name if no field is specified
        if (slice_field is None):
            self.slice_field = ion_p_num(self.ion_name)
        else:
            self.slice_field = slice_field

        # whether to use/plot these methods
        self.plot_spice = plot_spice
        self.use_spectacle = use_spectacle
        self.plot_spectacle = plot_spectacle

        if absorber_min is None:

            if self.ion_name in min_absorber_dict.keys():
                self.absorber_min = min_absorber_dict[self.ion_name]
            else:
                self.absorber_min = 13
        else:
            self.absorber_min = absorber_min

        # define defaults for spectacle fit
        self.defaults_dict = {
            'bounds': {
                'column_density': (self.absorber_min - 0.5, 23)
            },
            'fixed': {
                'delta_lambda': True,
                'column_density': False
            }
        }

        #add user defined defaults
        if spectacle_defaults is not None:
            self.defaults_dict.update(spectacle_defaults)

        #parameters for trident
        self.wavelength_width = wavelength_width
        self.wavelegnth_res = wavelength_res
        self.velocity_width = velocity_width
        self.velocity_res = velocity_res

        #default spectacle resolution to velocity_res
        if spectacle_res is None:
            self.spectacle_res = velocity_res
        else:
            self.spectacle_res = spectacle_res

        #default set the wavelength center to one of the known spectral lines
        #for ion name. Use tridents line database to search for correct wavelength
        if wavelength_center is None:
            #open up tridents default line database
            lbd = trident.LineDatabase('lines.txt')
            #find all lines that match ion
            lines = lbd.parse_subset(subsets=[self.ion_name])
            #take one with largest f_value
            f_val = 0
            for line in lines:
                if line.f_value >= f_val:
                    f_val = line.f_value
                    self.wavelength_center = line.wavelength
        else:
            self.wavelength_center = wavelength_center

        #open up a figure if none specified
        if figure is None:
            self.fig = plt.figure(figsize=(10, 10))
        else:
            self.fig = figure

        #set marker plot properties
        self.markers = markers
        if markers:
            self.mark_kwargs = {
                'alpha': 0.45,
                's': 100,
                'edgecolors': 'black',
                'linewidth': 3,
                'spacing': 50,
                'marker_cmap': 'viridis',
                'marker_shape': 's'
            }
            if mark_plot_args != None:
                self.mark_kwargs.update(mark_plot_args)

            self.marker_spacing = self.mark_kwargs.pop('spacing')
            self.marker_cmap = self.mark_kwargs.pop('marker_cmap')
            self.marker_shape = self.mark_kwargs.pop('marker_shape')
        self.mark_dist_arr = None

        #optionally set min/max value for number density plot
        self.num_dense_min = num_dense_min
        self.num_dense_max = num_dense_max
from astropy.io import fits

import time

## read in example data
fn = 'WindTest/DD0010/DD0010'
ds = yt.load(fn)

## create ray start and end
ray_start = [1, 0, 1]
ray_end = [1, 2, 1]

## lines to calculate spectrum fo
## line_list = ['H','C','N','O','Mg','S','Si','Ne']
ldb = trident.LineDatabase('lines.txt')
line_list = ['H I 1216', 'C IV 1548', 'O VI 1032']
ll = ldb.parse_subset(line_list)

## begin making fits header
prihdr = fits.Header()
prihdr['AUTHOR'] = "Molly Peeples"
prihdr['DATE'] = time.strftime("%c")  ## doesn't have time zone
prihdr['RAY_START'] = str(ray_start)
prihdr['RAY_END'] = str(ray_end)
prihdr['SIMULATION_NAME'] = fn
i = 1
for line in ll:
    keyword = 'LINE_' + str(i)
    prihdr[keyword] = line.name
    i += 1
Example #5
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
Example #6
0
from astropy.io import fits
import time
import trident
import spectacle

from spectacle.core.spectra import Spectrum1D
from spectacle.modeling.models import Absorption1D
from spectacle.core.lines import Line
from spectacle.modeling.fitting import DynamicLevMarFitter

import getpass
import datetime
import os.path

## ldb = trident.LineDatabase('lines.txt')
ldb = trident.LineDatabase('atom_wave_gamma_f.dat')

def write_header(ray,start_pos=None,end_pos=None,lines=None,**kwargs):
	## begin making fits header
    prihdr = fits.Header()
    prihdr['AUTHOR'] = kwargs.get("author",getpass.getuser())
    prihdr['DATE'] = datetime.datetime.now().isoformat()
    prihdr['RAYSTART'] = str(start_pos[0]) + "," + str(start_pos[1]) + "," + str(start_pos[2])
    prihdr['RAYEND'] = str(end_pos[0]) + "," + str(end_pos[1]) + "," + str(end_pos[2])
    prihdr['SIM_NAME'] = ray.basename
    prihdr['NLINES'] = str(len(np.array(lines)))
    prihdr['DOI'] = "doi.corlies2017.paper.thisistotesnotmadeup"
    prihdr['PAPER'] = "Corlies et al. (2017) ApJ, ###, ###"
    prihdr['EUVB'] = "HM12" ## probably shouldn't be hardcoded
    prihdr['IMPACT'] = (kwargs.get("impact","undef"), "impact parameter, kpc")
    prihdr['ANGLE'] = (kwargs.get("angle","undef"), "radians")