def test_normalize_spectrum_in_segments(self): """ Fit continuum in each segment independently, strategy 'median+max' """ star_spectrum = ispec.read_spectrum( ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz") #--- Continuum fit ------------------------------------------------------------- model = "Splines" # "Polynomy" degree = 2 nknots = 1 from_resolution = 80000 # Strategy: Filter first median values and secondly MAXIMUMs in order to find the continuum order = 'median+max' median_wave_range = 0.05 max_wave_range = 1.0 segments = ispec.read_segment_regions( ispec_dir + "/input/regions/fe_lines_segments.txt") star_continuum_model = ispec.fit_continuum(star_spectrum, from_resolution=from_resolution, \ independent_regions=segments, nknots=nknots, degree=degree,\ median_wave_range=median_wave_range, \ max_wave_range=max_wave_range, \ model=model, order=order, \ automatic_strong_line_detection=True, \ strong_line_probability=0.5, \ use_errors_for_fitting=True) #--- Continuum normalization --------------------------------------------------- normalized_star_spectrum = ispec.normalize_spectrum( star_spectrum, star_continuum_model, consider_continuum_errors=False) # Use a fixed value because the spectrum is already normalized star_continuum_model = ispec.fit_continuum(star_spectrum, fixed_value=1.0, model="Fixed value") np.testing.assert_equal(star_spectrum['waveobs'], normalized_star_spectrum['waveobs']) self.assertAlmostEqual(star_spectrum['flux'][0], 0.67077) self.assertAlmostEqual(star_spectrum['flux'][-1], 2.2169) self.assertAlmostEqual(star_spectrum['err'][0], 0.0021259) self.assertAlmostEqual(star_spectrum['err'][-1], 0.0043878) self.assertAlmostEqual(normalized_star_spectrum['flux'][0], 1.0) self.assertAlmostEqual(normalized_star_spectrum['flux'][-1], 1.0) self.assertAlmostEqual(normalized_star_spectrum['err'][0], 0.0) self.assertAlmostEqual(normalized_star_spectrum['err'][-1], 0.0) self.assertAlmostEqual(normalized_star_spectrum['flux'][11], 0.9928764307623508) self.assertAlmostEqual(normalized_star_spectrum['flux'][58288], 0.960387654522309) self.assertAlmostEqual(normalized_star_spectrum['err'][11], 0.0028468129511384785) self.assertAlmostEqual(normalized_star_spectrum['err'][58288], 0.0019771951824093786) self.assertEqual( len(np.where(normalized_star_spectrum['flux'] != 1.)[0]), 33722) self.assertTrue( np.all(star_continuum_model(star_spectrum['waveobs']) == 1))
def test_cut_spectrum_from_segments(self): star_spectrum = ispec.read_spectrum( ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz") #--- Cut ----------------------------------------------------------------------- # Keep only points inside a list of segments segments = ispec.read_segment_regions( ispec_dir + "/input/regions/fe_lines_segments.txt") wfilter = ispec.create_wavelength_filter(star_spectrum, regions=segments) cutted_star_spectrum = star_spectrum[wfilter] self.assertEqual(len(segments), 132) self.assertAlmostEqual(segments['wave_base'][0], 480.01937) self.assertAlmostEqual(segments['wave_top'][0], 481.08295) self.assertEqual(len(cutted_star_spectrum), 33722) self.assertAlmostEqual(cutted_star_spectrum['waveobs'][0], 480.02156956) self.assertAlmostEqual(cutted_star_spectrum['flux'][0], 0.81984) self.assertAlmostEqual(cutted_star_spectrum['err'][0], 0.0023458)
def test_find_continuum_regions_in_segments(self): star_spectrum = ispec.read_spectrum( ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz") #--- Continuum fit ------------------------------------------------------------- model = "Splines" # "Polynomy" degree = 2 nknots = None # Automatic: 1 spline every 5 nm from_resolution = 80000 # Strategy: Filter first median values and secondly MAXIMUMs in order to find the continuum order = 'median+max' median_wave_range = 0.05 max_wave_range = 1.0 star_continuum_model = ispec.fit_continuum(star_spectrum, from_resolution=from_resolution, \ nknots=nknots, degree=degree, \ median_wave_range=median_wave_range, \ max_wave_range=max_wave_range, \ model=model, order=order, \ automatic_strong_line_detection=True, \ strong_line_probability=0.5, \ use_errors_for_fitting=True) #--- Find continuum regions in segments ---------------------------------------- resolution = 80000 sigma = 0.005 max_continuum_diff = 1.0 fixed_wave_step = 0.05 # Limit the search to given segments segments = ispec.read_segment_regions( ispec_dir + "/input/regions/fe_lines_segments.txt") limited_star_continuum_regions = ispec.find_continuum(star_spectrum, resolution, \ segments=segments, max_std_continuum = sigma, \ continuum_model = star_continuum_model, \ max_continuum_diff=max_continuum_diff, \ fixed_wave_step=fixed_wave_step) #ispec.write_continuum_regions(limited_star_continuum_regions, \ #"example_limited_star_continuum_region.txt") self.assertEqual(len(limited_star_continuum_regions), 504)
raise Exception("Lines: wave_top cannot be smaller than wave_base") if np.any((lines['wave_top'] - lines['wave_peak']) < 0): raise Exception("Lines: wave_top cannot be smaller than wave_peak") if np.any((lines['wave_peak'] - lines['wave_base']) < 0): raise Exception( "Lines: wave_peak cannot be smaller than wave_base") else: lines = np.zeros((0, ), dtype=[('wave_peak', '<f8'), ('wave_base', '<f8'), ('wave_top', '<f8')]) if filenames['segments'] != None: try: segments = ispec.read_segment_regions(filenames['segments']) except Exception as e: print "Segments file", filenames[ 'segments'], "has an incompatible format!" sys.exit(2) ## Validations if np.any((segments['wave_top'] - segments['wave_base']) < 0): raise Exception( "Segments: wave_top cannot be smaller than wave_base") else: segments = np.zeros((0, ), dtype=[('wave_base', '<f8'), ('wave_top', '<f8')]) regions = {} regions['continuum'] = continuum
def test_determine_astrophysical_parameters_using_grid(self): star_spectrum = ispec.read_spectrum( ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz") #star_spectrum = ispec.read_spectrum(ispec_dir + "/input/spectra/examples/NARVAL_Arcturus.txt.gz") #star_spectrum = ispec.read_spectrum(ispec_dir + "/input/spectra/examples/NARVAL_muCas.txt.gz") #star_spectrum = ispec.read_spectrum(ispec_dir + "/input/spectra/examples/NARVAL_muLeo.txt.gz") #star_spectrum = ispec.read_spectrum(ispec_dir + "/input/spectra/examples/HARPS.GBOG_Procyon.txt.gz") #--- Radial Velocity determination with template ------------------------------- # - Read synthetic template #template = ispec.read_spectrum(ispec_dir + "/input/spectra/templates/Atlas.Arcturus.372_926nm/template.txt.gz") #template = ispec.read_spectrum(ispec_dir + "/input/spectra/templates/Atlas.Sun.372_926nm/template.txt.gz") template = ispec.read_spectrum( ispec_dir + "/input/spectra/templates/NARVAL.Sun.370_1048nm/template.txt.gz") #template = ispec.read_spectrum(ispec_dir + "/input/spectra/templates/Synth.Sun.300_1100nm/template.txt.gz") models, ccf = ispec.cross_correlate_with_template(star_spectrum, template, \ lower_velocity_limit=-200, upper_velocity_limit=200, \ velocity_step=1.0, fourier=False) # Number of models represent the number of components components = len(models) # First component: rv = np.round(models[0].mu(), 2) # km/s rv_err = np.round(models[0].emu(), 2) # km/s #--- Radial Velocity correction ------------------------------------------------ star_spectrum = ispec.correct_velocity(star_spectrum, rv) #--- Resolution degradation ---------------------------------------------------- # NOTE: The line selection was built based on a solar spectrum with R ~ 47,000 and GES/VALD atomic linelist. from_resolution = 80000 to_resolution = 47000 star_spectrum = ispec.convolve_spectrum(star_spectrum, to_resolution, from_resolution) #--- Continuum fit ------------------------------------------------------------- model = "Splines" # "Polynomy" degree = 2 nknots = None # Automatic: 1 spline every 5 nm from_resolution = to_resolution # Strategy: Filter first median values and secondly MAXIMUMs in order to find the continuum order = 'median+max' median_wave_range = 0.05 max_wave_range = 1.0 star_continuum_model = ispec.fit_continuum(star_spectrum, from_resolution=from_resolution, \ nknots=nknots, degree=degree, \ median_wave_range=median_wave_range, \ max_wave_range=max_wave_range, \ model=model, order=order, \ automatic_strong_line_detection=True, \ strong_line_probability=0.5, \ use_errors_for_fitting=True) #--- Normalize ------------------------------------------------------------- normalized_star_spectrum = ispec.normalize_spectrum( star_spectrum, star_continuum_model, consider_continuum_errors=False) # Use a fixed value because the spectrum is already normalized star_continuum_model = ispec.fit_continuum(star_spectrum, fixed_value=1.0, model="Fixed value") #--- Model spectra ---------------------------------------------------------- # Parameters initial_teff = 5750.0 initial_logg = 4.5 initial_MH = 0.00 initial_alpha = 0.00 initial_vmic = ispec.estimate_vmic(initial_teff, initial_logg, initial_MH) initial_vmac = ispec.estimate_vmac(initial_teff, initial_logg, initial_MH) initial_vsini = 2.0 initial_limb_darkening_coeff = 0.6 initial_R = to_resolution initial_vrad = 0 max_iterations = 20 code = "grid" precomputed_grid_dir = ispec_dir + "/input/grid/SPECTRUM_MARCS.GES_GESv6_atom_hfs_iso.480_680nm_light/" atomic_linelist = None isotopes = None modeled_layers_pack = None solar_abundances = None free_abundances = None linelist_free_loggf = None # Free parameters (vmic cannot be used as a free parameter when using a spectral grid) #free_params = ["teff", "logg", "MH", "alpha", "vmic", "vmac", "vsini", "R", "vrad", "limb_darkening_coeff"] free_params = ["teff", "logg", "MH", "alpha", "vmic", "R"] # Line regions line_regions = ispec.read_line_regions( ispec_dir + "/input/regions/47000_GES/{}_synth_good_for_params_all.txt".format( code)) #line_regions = ispec.read_line_regions(ispec_dir + "/input/regions/47000_GES/{}_synth_good_for_params_all_extended.txt".format(code)) #line_regions = ispec.read_line_regions(ispec_dir + "/input/regions/47000_VALD/{}_synth_good_for_params_all.txt".format(code)) #line_regions = ispec.read_line_regions(ispec_dir + "/input/regions/47000_VALD/{}_synth_good_for_params_all_extended.txt".format(code)) ## Select only some lines to speed up the execution (in a real analysis it is better not to do this) #line_regions = line_regions[np.logical_or(line_regions['note'] == 'Ti 1', line_regions['note'] == 'Ti 2')] #line_regions = ispec.adjust_linemasks(normalized_star_spectrum, line_regions, max_margin=0.5) # Read segments if we have them or... #segments = ispec.read_segment_regions(ispec_dir + "/input/regions/fe_lines_segments.txt") # ... or we can create the segments on the fly: segments = ispec.create_segments_around_lines(line_regions, margin=0.25) ## Add also regions from the wings of strong lines: # H beta hbeta_lines = ispec.read_line_regions(ispec_dir + "input/regions/wings_Hbeta.txt") hbeta_segments = ispec.read_segment_regions( ispec_dir + "input/regions/wings_Hbeta_segments.txt") line_regions = np.hstack((line_regions, hbeta_lines)) segments = np.hstack((segments, hbeta_segments)) # H alpha halpha_lines = ispec.read_line_regions( ispec_dir + "input/regions/wings_Halpha.txt") halpha_segments = ispec.read_segment_regions( ispec_dir + "input/regions/wings_Halpha_segments.txt") line_regions = np.hstack((line_regions, halpha_lines)) segments = np.hstack((segments, halpha_segments)) # Magnesium triplet mgtriplet_lines = ispec.read_line_regions( ispec_dir + "input/regions/wings_MgTriplet.txt") mgtriplet_segments = ispec.read_segment_regions( ispec_dir + "input/regions/wings_MgTriplet_segments.txt") line_regions = np.hstack((line_regions, mgtriplet_lines)) segments = np.hstack((segments, mgtriplet_segments)) obs_spec, modeled_synth_spectrum, params, errors, abundances_found, loggf_found, status, stats_linemasks = \ ispec.model_spectrum(normalized_star_spectrum, star_continuum_model, \ modeled_layers_pack, atomic_linelist, isotopes, solar_abundances, free_abundances, linelist_free_loggf, initial_teff, \ initial_logg, initial_MH, initial_alpha, initial_vmic, initial_vmac, initial_vsini, \ initial_limb_darkening_coeff, initial_R, initial_vrad, free_params, segments=segments, \ linemasks=line_regions, \ enhance_abundances=False, \ use_errors = True, \ vmic_from_empirical_relation = False, \ vmac_from_empirical_relation = True, \ max_iterations=max_iterations, \ tmp_dir = None, \ code=code, precomputed_grid_dir=precomputed_grid_dir) expected_params = { 'teff': 5848.516352941799, 'logg': 4.47140586507073, 'MH': 0.021745200217247945, 'alpha': 0.0, 'vmic': 0.5617098008018283, 'vmac': 4.5, 'vsini': 2.0, 'limb_darkening_coeff': 0.6, 'R': 78395.52968455742 } for k, v in list(expected_params.items()): self.assertAlmostEqual(params[k], v) expected_errors = { 'teff': 16.061649602869444, 'logg': 0.028408456932473077, 'MH': 0.007324730574204324, 'alpha': 0.007733907152934892, 'vmic': 0.043996803165640905, 'vmac': 0.0, 'vsini': 0.0, 'limb_darkening_coeff': 0.0, 'R': 3898.724894322937 } for k, v in list(expected_errors.items()): self.assertAlmostEqual(errors[k], v) self.assertEqual(len(stats_linemasks), 337)
def param_using_grid(normalized_star_spectrum, star_continuum_model, object_id,\ resolution=80000, p0 = [5750.0, 4.5, 0, 0, 2, 0.6, 0], max_iter = 10): ''' Derive spectroscopic parameters using grid model p0 are initial values list: teff, logg, MH, alpha, vsini, limb_darkening coef, vrad Returns params, errors and ispec_pectrum object with spectra form best fit ''' #--- Model spectra -------------------------------------------------------- # Parameters initiall values initial_teff = p0[0] initial_logg = p0[1] initial_MH = p0[2] initial_alpha = p0[3] initial_vmic = ispec.estimate_vmic(initial_teff, initial_logg, initial_MH) initial_vmac = ispec.estimate_vmac(initial_teff, initial_logg, initial_MH) initial_vsini = p0[4] initial_limb_darkening_coeff = p0[5] initial_R = resolution initial_vrad = p0[6] max_iterations = max_iter #load grid code = "grid" precomputed_grid_dir = ispec_dir + "/input/grid/SPECTRUM_MARCS.GES_GESv5_atom_hfs_iso.480_680nm_light/" atomic_linelist = None isotopes = None modeled_layers_pack = None solar_abundances = None free_abundances = None linelist_free_loggf = None # Free parameters (vmic cannot be used as a free parameter when using a spectral grid) free_params = ["teff", "logg", "MH", "alpha", "R"] # Line regions line_regions = ispec.read_line_regions( ispec_dir + "/input/regions/47000_GES/{}_synth_good_for_params_all.txt".format( code)) #line_regions = ispec.read_line_regions(ispec_dir + "/input/regions/47000_GES/{}_synth_good_for_params_all_extended.txt".format(code)) #line_regions = ispec.read_line_regions(ispec_dir + "/input/regions/47000_VALD/{}_synth_good_for_params_all.txt".format(code)) #line_regions = ispec.read_line_regions(ispec_dir + "/input/regions/47000_VALD/{}_synth_good_for_params_all_extended.txt".format(code)) ## Select only some lines to speed up the execution (in a real analysis it is better not to do this) #line_regions = line_regions[np.logical_or(line_regions['note'] == 'Ti 1', line_regions['note'] == 'Ti 2')] #line_regions = ispec.adjust_linemasks(normalized_star_spectrum, line_regions, max_margin=0.5) # Read segments if we have them or... #segments = ispec.read_segment_regions(ispec_dir + "/input/regions/fe_lines_segments.txt") # ... or we can create the segments on the fly: segments = ispec.create_segments_around_lines(line_regions, margin=0.25) ## Add also regions from the wings of strong lines: # H beta hbeta_lines = ispec.read_line_regions(ispec_dir + "/input/regions/wings_Hbeta.txt") hbeta_segments = ispec.read_segment_regions( ispec_dir + "/input/regions/wings_Hbeta_segments.txt") line_regions = np.hstack((line_regions, hbeta_lines)) segments = np.hstack((segments, hbeta_segments)) # H alpha halpha_lines = ispec.read_line_regions(ispec_dir + "/input/regions/wings_Halpha.txt") halpha_segments = ispec.read_segment_regions( ispec_dir + "/input/regions/wings_Halpha_segments.txt") line_regions = np.hstack((line_regions, halpha_lines)) segments = np.hstack((segments, halpha_segments)) # Magnesium triplet mgtriplet_lines = ispec.read_line_regions( ispec_dir + "/input/regions/wings_MgTriplet.txt") mgtriplet_segments = ispec.read_segment_regions( ispec_dir + "/input/regions/wings_MgTriplet_segments.txt") line_regions = np.hstack((line_regions, mgtriplet_lines)) segments = np.hstack((segments, mgtriplet_segments)) # run model spectra from grid! obs_spec, modeled_synth_spectrum, params, errors, abundances_found,\ loggf_found, status, stats_linemasks = \ ispec.model_spectrum(normalized_star_spectrum, star_continuum_model,\ modeled_layers_pack, atomic_linelist, isotopes, solar_abundances,\ free_abundances, linelist_free_loggf, initial_teff, initial_logg,\ initial_MH, initial_alpha, initial_vmic, initial_vmac, initial_vsini,\ initial_limb_darkening_coeff, initial_R, initial_vrad, free_params,\ segments=segments, linemasks=line_regions, enhance_abundances=False,\ use_errors = True, vmic_from_empirical_relation = False,\ vmac_from_empirical_relation = True, max_iterations=max_iterations,\ tmp_dir = None, code=code, precomputed_grid_dir=precomputed_grid_dir) ##--- Save results --------------------------------------------------------- #logging.info("Saving results...") dump_file = "example_results_synth_grid_%s.dump" % (object_id) #logging.info("Saving results...") ispec.save_results(dump_file, (params, errors, abundances_found, loggf_found, status, stats_linemasks)) # If we need to restore the results from another script: # params, errors, abundances_found, loggf_found, status, stats_linemasks = ispec.restore_results(dump_file) #logging.info("Saving synthetic spectrum...") synth_filename = "example_modeled_synth_grid_%s.fits" % (object_id) ispec.write_spectrum(modeled_synth_spectrum, synth_filename) return params, errors, modeled_synth_spectrum