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 __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
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
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
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")