def align_with_O2(spectra, O2_spectra, R=5000): # Convert to ispec structures spectra = ispec.create_spectrum_structure(spectra.T[0], spectra.T[1], spectra.T[2]) O2_spectra = ispec.create_spectrum_structure(O2_spectra.T[0], O2_spectra.T[1], O2_spectra.T[2]) # Now normalise normed_spectra, spectra_continuum_model = normalize_whole_spectrum(spectra) #wfilter = ispec.create_wavelength_filter(normed_spectra, wave_base=np.min(O2_spectra['waveobs']) - 3, wave_top=np.max(O2_spectra['waveobs']) + 3) wfilter = ispec.create_wavelength_filter(normed_spectra, wave_base=684, wave_top=690) normed_spectra = normed_spectra[wfilter] params = Parameters() params.add('rv', value=0, min=-100, max=100) params.add('strength', value=1, min=0.7, max=1.3) params.add('zp', value=1., min=0.9, max=1.1, vary=False) mini = Minimizer(lmfit_func, params, fcn_args=(np.copy(normed_spectra), np.copy(O2_spectra), False)) lmfit_minimize_result = mini.minimize() printfuncs.report_fit(lmfit_minimize_result, min_correl=0.5) corrected_spectra, o2_model = lmfit_func(lmfit_minimize_result.params, normed_spectra, O2_spectra, return_model=True) f = plt.figure() plt.plot(normed_spectra['waveobs'], normed_spectra['flux'], 'k', alpha=0.3) plt.plot(corrected_spectra['waveobs'], corrected_spectra['flux'], 'k', label='Corrected solution') plt.plot(O2_spectra['waveobs'], O2_spectra['flux'], 'r', alpha=0.3) plt.plot(O2_spectra['waveobs'], o2_model, 'r', label='O2 model') plt.gca().set(title='RV = {:.3f} +- {:.3f}'.format( lmfit_minimize_result.params['rv'].value, lmfit_minimize_result.params['rv'].stderr), xlabel='Wavelength [nm]', ylabel='Normalized flux') plt.legend() plt.xlim(685, 690) corrected = ispec.correct_velocity( np.copy(spectra), lmfit_minimize_result.params['rv'].value) return f, np.array( [corrected['waveobs'], corrected['flux'], corrected['err']]).T, lmfit_minimize_result.params[ 'rv'].value, lmfit_minimize_result.params['rv'].stderr
def loadtemplatespectrum(filename, resolution, telluric_linelist, ccf_mask, velocity_step, wavemask): spc = Spectrum(filename) if wavemask : spc.applyMask(wavemask) barycentricTime = spc.barycentricTime() barycentric_vel = barycentric_velocity(spc) spc.continuumOrderByOrder(binsize = 30, overlap = 10) spc.normalizeByContinuum(constant=10.0) spc.binningOrderByOrder(rvsampling_kps=2.4, median=False) spc.sortByWavelength() ispectrum = ispec.create_spectrum_structure(spc.wl,spc.flux) smoothed_spectrum = ispec.convolve_spectrum(ispectrum, resolution) tel_models, tel_ccf = ispec.cross_correlate_with_mask(smoothed_spectrum, telluric_linelist, \ lower_velocity_limit=-10, upper_velocity_limit=10, \ velocity_step=0.1, mask_depth=0.01, \ fourier = False, only_one_peak = True) tel_rv = tel_models[0].mu() min_vel = -30.0 max_vel = +30.0 # Only the 25% of the deepest ones: dfilter = telluric_linelist['depth'] > np.percentile(telluric_linelist['depth'], 75) tfilter = ispec.create_filter_for_regions_affected_by_tellurics(smoothed_spectrum['waveobs'], \ telluric_linelist[dfilter], min_velocity=-tel_rv+min_vel, \ max_velocity=-tel_rv+max_vel) clean_spectrum = smoothed_spectrum[~tfilter] corrected_spectrum = ispec.correct_velocity(clean_spectrum, tel_rv - barycentric_vel) models, ccf = ispec.cross_correlate_with_mask(clean_spectrum, ccf_mask, \ lower_velocity_limit=-100, upper_velocity_limit=100, \ velocity_step=velocity_step, mask_depth=0.01, \ fourier=False) rv = models[0].mu() clean_corrected_spectrum = ispec.correct_velocity(corrected_spectrum, rv) return clean_corrected_spectrum
def synthesize_spectrum(theta): teff, logg, MH = theta # alpha = ispec.determine_abundance_enchancements(MH) # microturbulence_vel = ispec.estimate_vmic(teff, logg, MH) # macroturbulence = ispec.estimate_vmac(teff, logg, MH) microturbulence_vel = 1.23 macroturbulence = 3.70 alpha = 0 limb_darkening_coeff = 0.6 resolution = 47000 vsini = 2.4 code = "grid" precomputed_grid_dir = ispec_dir + "/input/grid/SPECTRUM_MARCS.GES_GESv6_atom_hfs_iso.480_680nm/" grid = ispec.load_spectral_grid(precomputed_grid_dir) atomic_linelist = None isotopes = None modeled_layers_pack = None solar_abundances = None fixed_abundances = None abundances = None atmosphere_layers = None if not ispec.valid_interpolated_spectrum_target( grid, { 'teff': teff, 'logg': logg, 'MH': MH, 'alpha': alpha, 'vmic': microturbulence_vel }): msg = "The specified effective temperature, gravity (log g) and metallicity [M/H] \ fall out of the spectral grid limits." print(msg) regions = None # Interpolation synth_spectrum = ispec.create_spectrum_structure(x) # interpolated_spectrum = ispec.create_spectrum_structure(np.arange(wave_base, wave_top, wave_step)) synth_spectrum['flux'] = ispec.generate_spectrum(synth_spectrum['waveobs'], \ atmosphere_layers, teff, logg, MH, alpha, atomic_linelist, isotopes, abundances, \ fixed_abundances, microturbulence_vel = microturbulence_vel, \ macroturbulence=macroturbulence, vsini=vsini, limb_darkening_coeff=limb_darkening_coeff, \ R=resolution, regions=regions, verbose=1, code=code, grid=grid) return synth_spectrum
print "Error: check usage with App_iSpecTest.py -h "; sys.exit(1); if options.verbose: print 'Input spectrum: ', options.input print 'Output wavelength range: ', options.wlrange print 'Spectrum type: ', options.spectype print 'Polar option: ', options.polar print 'Telluric correction: ', options.telluric print 'Heliocentric correction: ', options.helio spc = Spectrum(options.input, options.spectype, options.polar, options.telluric, options.helio) spc.continuumOrderByOrder(binsize = 30, overlap = 10) spc.normalizeByContinuum(constant=10.0) spc.binningOrderByOrder(rvsampling_kps=2.5, median=False) spc.sortByWavelength() ispectrum = ispec.create_spectrum_structure(spc.wl,spc.flux) resolution = 80000 smoothed_star_spectrum = ispec.convolve_spectrum(ispectrum, resolution) mask_file = ispec_dir + "input/linelists/CCF/Narval.Sun.370_1048nm/mask.lst" ccf_mask = ispec.read_cross_correlation_mask(mask_file) models, ccf = ispec.cross_correlate_with_mask(smoothed_star_spectrum, ccf_mask, \ lower_velocity_limit=-50, upper_velocity_limit=50, \ velocity_step=0.05, mask_depth=0.01, \ fourier=False) components = len(models) rv = np.round(models[0].mu(), 3) # km/s
def _synthesize_spectrum(self, code): #--- Synthesizing spectrum ----------------------------------------------------- # Parameters teff = 5771.0 logg = 4.44 MH = 0.00 alpha = ispec.determine_abundance_enchancements(MH) microturbulence_vel = ispec.estimate_vmic(teff, logg, MH) # 1.07 macroturbulence = ispec.estimate_vmac(teff, logg, MH) # 4.21 vsini = 1.60 # Sun limb_darkening_coeff = 0.6 resolution = 300000 wave_step = 0.001 # Wavelengths to synthesis #regions = ispec.read_segment_regions(ispec_dir + "/input/regions/fe_lines_segments.txt") regions = None wave_base = 515.0 # Magnesium triplet region wave_top = 525.0 # Selected model amtosphere, linelist and solar abundances #model = ispec_dir + "/input/atmospheres/MARCS/" model = ispec_dir + "/input/atmospheres/MARCS.GES/" #model = ispec_dir + "/input/atmospheres/MARCS.APOGEE/" #model = ispec_dir + "/input/atmospheres/ATLAS9.APOGEE/" #model = ispec_dir + "/input/atmospheres/ATLAS9.Castelli/" #model = ispec_dir + "/input/atmospheres/ATLAS9.Kurucz/" #model = ispec_dir + "/input/atmospheres/ATLAS9.Kirby/" #atomic_linelist_file = ispec_dir + "/input/linelists/transitions/VALD.300_1100nm/atomic_lines.tsv" #atomic_linelist_file = ispec_dir + "/input/linelists/transitions/VALD.1100_2400nm/atomic_lines.tsv" atomic_linelist_file = ispec_dir + "/input/linelists/transitions/GESv6_atom_hfs_iso.420_920nm/atomic_lines.tsv" #atomic_linelist_file = ispec_dir + "/input/linelists/transitions/GESv6_atom_nohfs_noiso.420_920nm/atomic_lines.tsv" isotope_file = ispec_dir + "/input/isotopes/SPECTRUM.lst" # Load chemical information and linelist atomic_linelist = ispec.read_atomic_linelist(atomic_linelist_file, wave_base=wave_base, wave_top=wave_top) atomic_linelist = atomic_linelist[ atomic_linelist['theoretical_depth'] >= 0.01] # Select lines that have some minimal contribution in the sun isotopes = ispec.read_isotope_data(isotope_file) if "ATLAS" in model: solar_abundances_file = ispec_dir + "/input/abundances/Grevesse.1998/stdatom.dat" else: # MARCS solar_abundances_file = ispec_dir + "/input/abundances/Grevesse.2007/stdatom.dat" #solar_abundances_file = ispec_dir + "/input/abundances/Asplund.2005/stdatom.dat" #solar_abundances_file = ispec_dir + "/input/abundances/Asplund.2009/stdatom.dat" #solar_abundances_file = ispec_dir + "/input/abundances/Anders.1989/stdatom.dat" # Load model atmospheres modeled_layers_pack = ispec.load_modeled_layers_pack(model) # Load SPECTRUM abundances solar_abundances = ispec.read_solar_abundances(solar_abundances_file) ## Custom fixed abundances #fixed_abundances = ispec.create_free_abundances_structure(["C", "N", "O"], chemical_elements, solar_abundances) #fixed_abundances['Abund'] = [-3.49, -3.71, -3.54] # Abundances in SPECTRUM scale (i.e., x - 12.0 - 0.036) and in the same order ["C", "N", "O"] ## No fixed abundances fixed_abundances = None # Validate parameters if not ispec.valid_atmosphere_target(modeled_layers_pack, { 'teff': teff, 'logg': logg, 'MH': MH, 'alpha': alpha }): msg = "The specified effective temperature, gravity (log g) and metallicity [M/H] \ fall out of theatmospheric models." print(msg) # Prepare atmosphere model atmosphere_layers = ispec.interpolate_atmosphere_layers( modeled_layers_pack, { 'teff': teff, 'logg': logg, 'MH': MH, 'alpha': alpha }, code=code) # Synthesis synth_spectrum = ispec.create_spectrum_structure( np.arange(wave_base, wave_top, wave_step)) synth_spectrum['flux'] = ispec.generate_spectrum(synth_spectrum['waveobs'], \ atmosphere_layers, teff, logg, MH, alpha, atomic_linelist, isotopes, solar_abundances, \ fixed_abundances, microturbulence_vel = microturbulence_vel, \ macroturbulence=macroturbulence, vsini=vsini, limb_darkening_coeff=limb_darkening_coeff, \ R=resolution, regions=regions, verbose=1, code=code) return synth_spectrum
def test_interpolate_spectrum(self): #--- Synthesizing spectrum ----------------------------------------------------- # Parameters #teff = 5771.0 teff = 4025.0 logg = 4.44 MH = 0.00 alpha = ispec.determine_abundance_enchancements(MH) microturbulence_vel = ispec.estimate_vmic(teff, logg, MH) # 1.07 macroturbulence = ispec.estimate_vmac(teff, logg, MH) # 4.21 vsini = 1.60 # Sun limb_darkening_coeff = 0.6 resolution = 300000 wave_step = 0.001 # Wavelengths to synthesis wave_base = 515.0 # Magnesium triplet region wave_top = 525.0 code = "grid" precomputed_grid_dir = ispec_dir + "/input/grid/SPECTRUM_MARCS.GES_GESv6_atom_hfs_iso.480_680nm_light/" grid = ispec.load_spectral_grid(precomputed_grid_dir) atomic_linelist = None isotopes = None modeled_layers_pack = None solar_abundances = None fixed_abundances = None abundances = None atmosphere_layers = None regions = None # Validate parameters if not ispec.valid_interpolated_spectrum_target( grid, { 'teff': teff, 'logg': logg, 'MH': MH, 'alpha': alpha, 'vmic': microturbulence_vel }): msg = "The specified effective temperature, gravity (log g) and metallicity [M/H] \ fall out of the spectral grid limits." print(msg) # Interpolation interpolated_spectrum = ispec.create_spectrum_structure( np.arange(wave_base, wave_top, wave_step)) interpolated_spectrum['flux'] = ispec.generate_spectrum(interpolated_spectrum['waveobs'], \ atmosphere_layers, teff, logg, MH, alpha, atomic_linelist, isotopes, abundances, \ fixed_abundances, microturbulence_vel = microturbulence_vel, \ macroturbulence=macroturbulence, vsini=vsini, limb_darkening_coeff=limb_darkening_coeff, \ R=resolution, regions=regions, verbose=1, code=code, grid=grid) np.testing.assert_almost_equal( interpolated_spectrum['flux'][:10], np.array([ 1.0000000e-10, 9.3509103e-01, 9.2898036e-01, 9.2100053e-01, 9.1271230e-01, 9.0331793e-01, 8.9166097e-01, 8.7667336e-01, 8.5752275e-01, 8.3368807e-01 ])) np.testing.assert_almost_equal( interpolated_spectrum['waveobs'][:10], np.array([ 515., 515.001, 515.002, 515.003, 515.004, 515.005, 515.006, 515.007, 515.008, 515.009 ]))
def run_synspec(starname, teff, logg, feh, alpha, outdir, mode = "MR", \ arms = ['blue','red','nir']): ## Custom abundance e.g., to change C, N, O abundances to the desired values solar_abundances_file = ispec_dir + "/input/abundances/Asplund.2009/stdatom.dat" solar_abundances = ispec.read_solar_abundances(solar_abundances_file) chemical_elements_file = ispec_dir + "/input/abundances/chemical_elements_symbols.dat" chemical_elements = ispec.read_chemical_elements(chemical_elements_file) #fixed_abundances = ispec.create_free_abundances_structure(["C", "N", "O"], chemical_elements, solar_abundances) #fixed_abundances['Abund'] = [-3.49, -3.71, -3.54] # Abundances in SPECTRUM scale (i.e., x - 12.0 - 0.036) and in the same order ["C", "N", "O"] fixed_abundances = None ## Synthesize a spectrum with the code "turbospectrum" spectrum_wave = [] spectrum_flux = [] ## - Wavelength coverage defined at ## https://pfs.ipmu.jp/research/parameters.html ## - Mergins of 10nm are applied if possible. ## - Overlaps in wavelength between neighboring arms are removed. for arm in arms: if arm != 'nir': if arm == 'blue': wmin = 370. wmax = 650. R = 2300 elif arm == 'red': if mode == 'MR': wmin = 700. wmax = 895. R = 5000. else: wmin = 650. wmax = 970. R = 3000. synthesize_spectrum(code = "turbospectrum", teff = teff, logg = logg, MH = feh, \ vsini = 0.0, wave_base = wmin, wave_top = wmax, R=R, fixed_abundances = fixed_abundances) spectrum_tmp = ispec.read_spectrum('outflux.txt') spectrum_wave = np.hstack((spectrum_wave, spectrum_tmp['waveobs'])) spectrum_flux = np.hstack((spectrum_flux, spectrum_tmp['flux'])) elif arm == 'nir': for i in range(0, 2): if i==0: if mode == "MR": wmin_tmp = 930. else: wmin_tmp = 970. wmax_tmp = 1100. else: wmin_tmp = 1100. wmax_tmp = 1270. R = 4300. synthesize_spectrum(code = "turbospectrum", teff = teff, logg = logg, MH = feh, \ vsini = 0.0, wave_base = wmin_tmp, wave_top = wmax_tmp, R=R, fixed_abundances = fixed_abundances) spectrum_tmp = ispec.read_spectrum('outflux.txt') spectrum_wave = np.hstack((spectrum_wave, spectrum_tmp['waveobs'])) spectrum_flux = np.hstack((spectrum_flux, spectrum_tmp['flux'])) synth_spectrum = ispec.create_spectrum_structure(spectrum_wave) synth_spectrum['flux'] = spectrum_flux ispec.write_spectrum(synth_spectrum, outdir + '/' + starname + '.txt') return()
def synthesize_spectrum(theta, code="moog"): teff, logg, MH, vsini = theta resolution = 48000 microturbulence_vel = ispec.estimate_vmic(teff, logg, MH) macroturbulence = ispec.estimate_vmac(teff, logg, MH) limb_darkening_coeff = 0.6 regions = None wave_base = 609.0 wave_top = 620.0 model = ispec_dir + "/input/atmospheres/ATLAS9.Castelli/" atomic_linelist_file = ispec_dir + "/input/linelists/transitions/VALD.300_1100nm/atomic_lines.tsv" #atomic_linelist_file = ispec_dir + "/input/linelists/transitions/GESv5_atom_hfs_iso.420_920nm/atomic_lines.tsv" isotope_file = ispec_dir + "/input/isotopes/SPECTRUM.lst" alpha = ispec.determine_abundance_enchancements(MH) atomic_linelist = ispec.read_atomic_linelist(atomic_linelist_file, wave_base=wave_base, wave_top=wave_top) atomic_linelist = atomic_linelist[ atomic_linelist['theoretical_depth'] >= 0.01] isotopes = ispec.read_isotope_data(isotope_file) solar_abundances_file = ispec_dir + "/input/abundances/Asplund.2009/stdatom.dat" solar_abundances = ispec.read_solar_abundances(solar_abundances_file) fixed_abundances = None modeled_layers_pack = ispec.load_modeled_layers_pack(model) atmosphere_layers = ispec.interpolate_atmosphere_layers( modeled_layers_pack, { 'teff': teff, 'logg': logg, 'MH': MH, 'alpha': alpha }, code=code) synth_spectrum = ispec.create_spectrum_structure(x) synth_spectrum['flux'] = ispec.generate_spectrum( synth_spectrum['waveobs'], atmosphere_layers, teff, logg, MH, alpha, atomic_linelist, isotopes, solar_abundances, fixed_abundances, microturbulence_vel=microturbulence_vel, macroturbulence=macroturbulence, vsini=vsini, limb_darkening_coeff=limb_darkening_coeff, R=resolution, regions=regions, verbose=0, code=code) return synth_spectrum