예제 #1
0
    def test_normalize_whole_spectrum_with_template(self):
        """
        Use a template to normalize the whole spectrum
        """
        star_spectrum = ispec.read_spectrum(
            ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
        synth_spectrum = ispec.read_spectrum(
            ispec_dir +
            "/input/spectra/templates/Synth.Sun.300_1100nm/template.txt.gz")

        #--- Continuum fit -------------------------------------------------------------
        model = "Template"
        nknots = None  # Automatic: 1 spline every 5 nm (in this case, used to apply a gaussian filter)
        from_resolution = 80000
        median_wave_range = 5.0

        #strong_lines = ispec.read_line_regions(ispec_dir + "/input/regions/strong_lines/absorption_lines.txt")
        strong_lines = ispec.read_line_regions(
            ispec_dir + "/input/regions/relevant/relevant_line_masks.txt")
        #strong_lines = None
        star_continuum_model = ispec.fit_continuum(star_spectrum, from_resolution=from_resolution, \
                                    ignore=strong_lines, \
                                    nknots=nknots, \
                                    median_wave_range=median_wave_range, \
                                    model=model, \
                                    template=synth_spectrum)

        #--- 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],
                               0.7964201448878107)
        self.assertAlmostEqual(normalized_star_spectrum['flux'][-1],
                               0.997168332612696)
        self.assertAlmostEqual(normalized_star_spectrum['err'][0],
                               0.002524128368914824)
        self.assertAlmostEqual(normalized_star_spectrum['err'][-1],
                               0.0019736457259407225)
        self.assertTrue(
            np.all(star_continuum_model(star_spectrum['waveobs']) == 1))
예제 #2
0
    def test_determine_radial_velocity_with_mask(self):
        mu_cas_spectrum = ispec.read_spectrum(
            ispec_dir + "/input/spectra/examples/NARVAL_muCas.txt.gz")
        #--- Radial Velocity determination with linelist mask --------------------------
        # - Read atomic data
        mask_file = ispec_dir + "input/linelists/CCF/Narval.Sun.370_1048nm/mask.lst"
        #mask_file = ispec_dir + "input/linelists/CCF/Atlas.Arcturus.372_926nm/mask.lst""
        #mask_file = ispec_dir + "input/linelists/CCF/Atlas.Sun.372_926nm/mask.lst"
        #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.A0.350_1095nm/mask.lst"
        #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.F0.360_698nm/mask.lst"
        #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.G2.375_679nm/mask.lst"
        #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.K0.378_679nm/mask.lst"
        #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.K5.378_680nm/mask.lst"
        #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.M5.400_687nm/mask.lst"
        #mask_file = ispec_dir + "input/linelists/CCF/Synthetic.Sun.350_1100nm/mask.lst"
        #mask_file = ispec_dir + "input/linelists/CCF/VALD.Sun.300_1100nm/mask.lst"
        ccf_mask = ispec.read_cross_correlation_mask(mask_file)

        models, ccf = ispec.cross_correlate_with_mask(mu_cas_spectrum, ccf_mask, \
                                lower_velocity_limit=-200, upper_velocity_limit=200, \
                                velocity_step=1.0, mask_depth=0.01, \
                                fourier=False)

        # Number of models represent the number of components
        components = len(models)
        # First component:
        rv = models[0].mu()  # km/s
        rv_err = models[0].emu()  # km/s
        self.assertEqual(components, 1)
        self.assertAlmostEqual(rv, -96.43)
        self.assertAlmostEqual(rv_err, 0.03736164048308909)
예제 #3
0
def read_write_spectrum(spec_id):
    #--- Reading spectra -----------------------------------------------------------
    logging.info("Reading spectra")
    star_spectrum = ispec.read_spectrum(spec_id + "_datafile.txt")
    ##--- Save spectrum ------------------------------------------------------------
    logging.info("Saving spectrum...")
    ispec.write_spectrum(star_spectrum, spec_id + "_processed.fits")
예제 #4
0
def clean_telluric_regions(spec_id, clean_percent):
    star_spectrum = ispec.read_spectrum(spec_id)
    #--- Telluric velocity shift determination from spectrum --------------------------
    logging.info("Telluric velocity shift determination...")
    # - Telluric
    telluric_linelist_file = ispec_dir + "/input/linelists/CCF/Synth.Tellurics.500_1100nm/mask.lst"
    telluric_linelist = ispec.read_telluric_linelist(telluric_linelist_file, minimum_depth=0.0)

    models, ccf = ispec.cross_correlate_with_mask(star_spectrum, telluric_linelist, \
                            lower_velocity_limit=-100, upper_velocity_limit=100, \
                            velocity_step=0.5, mask_depth=0.01, \
                            fourier = False,
                            only_one_peak = True)

    bv = np.round(models[0].mu(), 2) # km/s
    bv_err = np.round(models[0].emu(), 2) # km/s

    #--- Clean regions that may be affected by tellurics ---------------------------
    logging.info("Cleaning tellurics...")

    telluric_linelist_file = ispec_dir + "/input/linelists/CCF/Synth.Tellurics.500_1100nm/mask.lst"
    telluric_linelist = ispec.read_telluric_linelist(telluric_linelist_file, minimum_depth=0.0)

    # - Filter regions that may be affected by telluric lines
    #bv = 0.0
    min_vel = -30.0
    max_vel = +30.0
    # Only the 25% of the deepest ones:
    dfilter = telluric_linelist['depth'] > np.percentile(telluric_linelist['depth'], clean_percent)
    tfilter = ispec.create_filter_for_regions_affected_by_tellurics(star_spectrum['waveobs'], \
                                telluric_linelist[dfilter], min_velocity=-bv+min_vel, \
                                max_velocity=-bv+max_vel)
    clean_star_spectrum = star_spectrum[~tfilter]
    ispec.write_spectrum(clean_star_spectrum, spec_id)
예제 #5
0
def normalize_whole_spectrum(spec_id, med_wave, max_wave):
    """
    Use the whole spectrum, strategy 'median+max'
    """
    star_spectrum = ispec.read_spectrum(spec_id)

    #--- Continuum fit -------------------------------------------------------------
    model = "Splines" # "Polynomy"
    degree = 2
    nknots = None # Automatic: 1 spline every 5 nm
    from_resolution = 47000

    # Strategy: Filter first median values and secondly MAXIMUMs in order to find the continuum
    order='median+max'
    median_wave_range=med_wave
    max_wave_range=max_wave

    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)

    #--- Continuum normalization ---------------------------------------------------
    logging.info("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")
    ispec.write_spectrum(normalized_star_spectrum, spec_id)
예제 #6
0
    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))
예제 #7
0
def determine_radial_velocity_with_mask(spec_id):
    mu_cas_spectrum = ispec.read_spectrum(spec_id)
    #--- Radial Velocity determination with linelist mask --------------------------
    logging.info("Radial velocity determination with linelist mask...")
    # - Read atomic data
    mask_file = ispec_dir + "input/linelists/CCF/Narval.Sun.370_1048nm/mask.lst"
    #mask_file = ispec_dir + "input/linelists/CCF/Atlas.Arcturus.372_926nm/mask.lst""
    #mask_file = ispec_dir + "input/linelists/CCF/Atlas.Sun.372_926nm/mask.lst"
    #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.A0.350_1095nm/mask.lst"
    #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.F0.360_698nm/mask.lst"
    #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.G2.375_679nm/mask.lst"
    #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.K0.378_679nm/mask.lst"
    #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.K5.378_680nm/mask.lst"
    #mask_file = ispec_dir + "input/linelists/CCF/HARPS_SOPHIE.M5.400_687nm/mask.lst"
    #mask_file = ispec_dir + "input/linelists/CCF/Synthetic.Sun.350_1100nm/mask.lst"
    #mask_file = ispec_dir + "input/linelists/CCF/VALD.Sun.300_1100nm/mask.lst"
    ccf_mask = ispec.read_cross_correlation_mask(mask_file)

    models, ccf = ispec.cross_correlate_with_mask(mu_cas_spectrum, ccf_mask, \
                            lower_velocity_limit=-200, upper_velocity_limit=200, \
                            velocity_step=1.0, mask_depth=0.01, \
                            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
    
    # Applying correction
    logging.info("Applying radial velocity correction...")
    #rv = -96.40 # km/s
    mu_cas_spectrum = ispec.correct_velocity(mu_cas_spectrum, rv)
    ispec.write_spectrum(mu_cas_spectrum, spec_id)
예제 #8
0
    def test_filter_cosmic_rays(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)
        #--- Filtering cosmic rays -----------------------------------------------------
        # Spectrum should be already normalized
        cosmics = ispec.create_filter_cosmic_rays(star_spectrum, star_continuum_model, \
                                                resampling_wave_step=0.001, window_size=15, \
                                                variation_limit=0.01)
        clean_star_spectrum = star_spectrum[~cosmics]
        np.testing.assert_equal(
            np.where(cosmics)[0],
            np.array([
                730, 1472, 2626, 2635, 2703, 2704, 5319, 5773, 5782, 6075,
                6500, 6610, 11814, 11846, 11883, 12050, 12104, 16562, 16862,
                25310, 25311, 25948, 29402, 32355, 34342, 46984, 49469, 57858
            ]))
예제 #9
0
def resample_spectrum(spec_id, min_wl, max_wl):
    star_spectrum = ispec.read_spectrum(spec_id)
    #--- Resampling  --------------------------------------------------------------
    logging.info("Resampling...")
    wavelengths = np.arange(min_wl, max_wl, 0.002)
    #resampled_star_spectrum = ispec.resample_spectrum(star_spectrum, wavelengths, method="bessel", zero_edges=True)
    resampled_star_spectrum = ispec.resample_spectrum(star_spectrum, wavelengths, method="linear", zero_edges=True)
    ispec.write_spectrum(resampled_star_spectrum, spec_id)
예제 #10
0
def degrade_resolution(spec_id, initial_res, final_res):
    star_spectrum = ispec.read_spectrum(spec_id)
    #--- Resolution degradation ----------------------------------------------------
    logging.info("Degrading resolution...")
    from_resolution = initial_res
    to_resolution = final_res
    convolved_star_spectrum = ispec.convolve_spectrum(star_spectrum, to_resolution, \
                                                    from_resolution=from_resolution)
    ispec.write_spectrum(convolved_star_spectrum, spec_id)
예제 #11
0
def estimate_snr_from_flux(spec_id):
    star_spectrum = ispec.read_spectrum(spec_id)
    ## WARNING: To compare SNR estimation between different spectra, they should
    ##          be homogeneously sampled (consider a uniform re-sampling)
    #--- Estimate SNR from flux ----------------------------------------------------
    logging.info("Estimating SNR from fluxes...")
    num_points = 10
    estimated_snr = ispec.estimate_snr(star_spectrum['flux'], num_points=num_points)
    return estimated_snr
예제 #12
0
 def test_correct_radial_velocity(self):
     mu_cas_spectrum = ispec.read_spectrum(
         ispec_dir + "/input/spectra/examples/NARVAL_muCas.txt.gz")
     #--- Radial Velocity correction ------------------------------------------------
     rv = -96.40  # km/s
     mu_cas_spectrum = ispec.correct_velocity(mu_cas_spectrum, rv)
     self.assertAlmostEqual(mu_cas_spectrum['waveobs'][0], 480.15547196)
     self.assertAlmostEqual(mu_cas_spectrum['flux'][0], 0.19076)
     self.assertAlmostEqual(mu_cas_spectrum['err'][0], 0.00095993)
예제 #13
0
def find_linemasks(spec_id, species):
    #code = "synthe"
    code = "spectrum"
    star_spectrum = ispec.read_spectrum(spec_id)
    #--- Continuum fit -------------------------------------------------------------
    logging.info("Fitting fixed continuum...")
    star_continuum_model = ispec.fit_continuum(star_spectrum, fixed_value=1.0, model="Fixed value")

    #--- Find linemasks ------------------------------------------------------------
    logging.info("Finding line masks...")
    #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/GESv5_atom_hfs_iso.420_920nm/atomic_lines.tsv"
    #atomic_linelist_file = ispec_dir + "/input/linelists/transitions/GESv5_atom_nohfs_noiso.420_920nm/atomic_lines.tsv"

    #telluric_linelist_file = ispec_dir + "/input/linelists/CCF/Synth.Tellurics.500_1100nm/mask.lst"

    # Read
    atomic_linelist = ispec.read_atomic_linelist(atomic_linelist_file, wave_base=np.min(star_spectrum['waveobs']), wave_top=np.max(star_spectrum['waveobs']))
    atomic_linelist = atomic_linelist[atomic_linelist['theoretical_depth'] >= 0.01] # Select lines that have some minimal contribution in the sun
    #telluric_linelist = ispec.read_telluric_linelist(telluric_linelist_file, minimum_depth=0.01)
    #vel_telluric = 17.79  # km/s
    telluric_linelist = None
    vel_telluric = None

    resolution = 47000
    smoothed_star_spectrum = ispec.convolve_spectrum(star_spectrum, resolution)
    min_depth = 0.10 #0.05
    max_depth = 1.00
    star_linemasks = ispec.find_linemasks(star_spectrum, star_continuum_model, \
                            atomic_linelist=atomic_linelist, \
                            max_atomic_wave_diff = 0.005, \
                            telluric_linelist=telluric_linelist, \
                            vel_telluric=vel_telluric, \
                            minimum_depth=min_depth, maximum_depth=max_depth, \
                            smoothed_spectrum=star_spectrum, \
                            check_derivatives=False, \
                            discard_gaussian=False, discard_voigt=True, \
                            closest_match=False)
    # Exclude lines that have not been successfully cross matched with the atomic data
    # because we cannot calculate the chemical abundance (it will crash the corresponding routines)
    rejected_by_atomic_line_not_found = (star_linemasks['wave_nm'] == 0)
    star_linemasks = star_linemasks[~rejected_by_atomic_line_not_found]

    # Exclude lines with EW equal to zero
    rejected_by_zero_ew = (star_linemasks['ew'] == 0)
    star_linemasks = star_linemasks[~rejected_by_zero_ew]

    # Select only lines of desired species
    elmt = star_linemasks['element'] == species
    elmt_star_linemasks = star_linemasks[elmt]
    
    file_id = species.replace(" ", "_") + "_linemasks.txt"

    # Write line regions with only masks limits and note:
    ispec.write_line_regions(elmt_star_linemasks, file_id)
예제 #14
0
    def test_determine_tellurics_shift_with_template(self):
        star_spectrum = ispec.read_spectrum(
            ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
        #--- Telluric velocity shift determination from spectrum --------------------------
        # - Read synthetic template
        template = ispec.read_spectrum(
            ispec_dir +
            "/input/spectra/templates/Synth.Tellurics.350_1100nm/template.txt.gz"
        )

        models, ccf = ispec.cross_correlate_with_template(star_spectrum, template, \
                                lower_velocity_limit=-100, upper_velocity_limit=100, \
                                velocity_step=0.5, fourier=False, \
                                only_one_peak = True)

        bv = models[0].mu()  # km/s
        bv_err = models[0].emu()  # km/s
        self.assertAlmostEqual(bv, 8.169999999999954)
        self.assertAlmostEqual(bv_err, 0.6605884013888695)
예제 #15
0
 def test_estimate_snr_from_flux(self):
     star_spectrum = ispec.read_spectrum(
         ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
     ## WARNING: To compare SNR estimation between different spectra, they should
     ##          be homogeneously sampled (consider a uniform re-sampling)
     #--- Estimate SNR from flux ----------------------------------------------------
     num_points = 10
     estimated_snr = ispec.estimate_snr(star_spectrum['flux'],
                                        num_points=num_points)
     self.assertAlmostEqual(estimated_snr, 139.92497450174938)
예제 #16
0
    def test_normalize_whole_spectrum_ignoring_prefixed_strong_lines(self):
        """
        Use the whole spectrum but ignoring some strong lines, 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 = 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

        strong_lines = ispec.read_line_regions(
            ispec_dir + "/input/regions/strong_lines/absorption_lines.txt")
        star_continuum_model = ispec.fit_continuum(star_spectrum, from_resolution=from_resolution, \
                                    ignore=strong_lines, \
                                    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],
                               0.8005567874185445)
        self.assertAlmostEqual(normalized_star_spectrum['flux'][-1],
                               0.9874528805693361)
        self.assertAlmostEqual(normalized_star_spectrum['err'][0],
                               0.0025372388067043607)
        self.assertAlmostEqual(normalized_star_spectrum['err'][-1],
                               0.0019544164145257493)
        self.assertTrue(
            np.all(star_continuum_model(star_spectrum['waveobs']) == 1))
예제 #17
0
    def test_normalize_spectrum_using_continuum_regions(self):
        """
        Consider only continuum regions for the fit, 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 = 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

        continuum_regions = ispec.read_continuum_regions(
            ispec_dir + "/input/regions/fe_lines_continuum.txt")
        star_continuum_model = ispec.fit_continuum(star_spectrum, from_resolution=from_resolution, \
                                continuum_regions=continuum_regions, 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],
                               0.7990890725070141)
        self.assertAlmostEqual(normalized_star_spectrum['flux'][-1],
                               0.9887281323707806)
        self.assertAlmostEqual(normalized_star_spectrum['err'][0],
                               0.0025325871151701197)
        self.assertAlmostEqual(normalized_star_spectrum['err'][-1],
                               0.001956940457042046)
        self.assertTrue(
            np.all(star_continuum_model(star_spectrum['waveobs']) == 1))
예제 #18
0
def estimate_snr_from_err(spec_id):
    star_spectrum = ispec.read_spectrum(spec_id)
    #--- Estimate SNR from errors --------------------------------------------------
    logging.info("Estimating SNR from errors...")
    efilter = star_spectrum['err'] > 0
    filtered_star_spectrum = star_spectrum[efilter]
    if len(filtered_star_spectrum) > 1:
        estimated_snr = np.median(filtered_star_spectrum['flux'] / filtered_star_spectrum['err'])
    else:
        # All the errors are set to zero and we cannot calculate SNR using them
        estimated_snr = 0
    return estimated_snr
예제 #19
0
    def test_normalize_whole_spectrum(self):
        """
        Use the whole spectrum, 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 = 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)

        #--- 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],
                               0.8052457389161867)
        self.assertAlmostEqual(normalized_star_spectrum['flux'][-1],
                               0.9895767577073404)
        self.assertAlmostEqual(normalized_star_spectrum['err'][0],
                               0.0025520997008839415)
        self.assertAlmostEqual(normalized_star_spectrum['err'][-1],
                               0.0019586200989978207)
        self.assertTrue(
            np.all(star_continuum_model(star_spectrum['waveobs']) == 1))
예제 #20
0
    def determine_radial_velocity_with_template(self):
        mu_cas_spectrum = ispec.read_spectrum(
            ispec_dir + "/input/spectra/examples/NARVAL_muCas.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(mu_cas_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 = models[0].mu()  # km/s
        rv_err = models[0].emu()  # km/s
        self.assertEqual(components, 1)
        self.assertAlmostEqual(rv, -96.43)
        self.assertAlmostEqual(rv_err, 0.03736164048308909)
예제 #21
0
 def test_smooth_spectrum(self):
     star_spectrum = ispec.read_spectrum(
         ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
     #--- Smoothing spectrum (resolution will be affected) --------------------------
     resolution = 80000
     smoothed_star_spectrum = ispec.convolve_spectrum(
         star_spectrum, resolution)
     np.testing.assert_equal(star_spectrum['waveobs'],
                             smoothed_star_spectrum['waveobs'])
     self.assertAlmostEqual(smoothed_star_spectrum['flux'][0],
                            0.6973069596669491)
     self.assertAlmostEqual(smoothed_star_spectrum['flux'][-1],
                            2.2207560753191666)
     self.assertAlmostEqual(smoothed_star_spectrum['err'][0],
                            0.002174423029777254)
     self.assertAlmostEqual(smoothed_star_spectrum['err'][-1],
                            0.004451564365118501)
예제 #22
0
 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)
예제 #23
0
 def test_degrade_resolution(self):
     star_spectrum = ispec.read_spectrum(
         ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
     #--- Resolution degradation ----------------------------------------------------
     from_resolution = 80000
     to_resolution = 47000
     convolved_star_spectrum = ispec.convolve_spectrum(star_spectrum, to_resolution, \
                                                     from_resolution=from_resolution)
     np.testing.assert_equal(star_spectrum['waveobs'],
                             convolved_star_spectrum['waveobs'])
     self.assertAlmostEqual(convolved_star_spectrum['flux'][0],
                            0.7109576121207318)
     self.assertAlmostEqual(convolved_star_spectrum['flux'][-1],
                            2.2237382541838007)
     self.assertAlmostEqual(convolved_star_spectrum['err'][0],
                            0.0021974272902411723)
     self.assertAlmostEqual(convolved_star_spectrum['err'][-1],
                            0.004453852796214372)
예제 #24
0
 def test_add_noise_to_spectrum(self):
     """
     Add noise to an spectrum (ideally to a synthetic one) based on a given SNR.
     """
     star_spectrum = ispec.read_spectrum(
         ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
     np.random.seed(42)
     #--- Adding poisson noise -----------------------------------------------------
     snr = 100
     distribution = "poisson"  # "gaussian"
     noisy_star_spectrum = ispec.add_noise(star_spectrum, snr, distribution)
     np.testing.assert_almost_equal(
         noisy_star_spectrum['flux'][:10],
         np.array([
             0.6678, 0.7459, 0.776, 0.7796, 0.802, 0.7953, 0.7383, 0.7164,
             0.7381, 0.7876
         ]))
     np.testing.assert_equal(star_spectrum['waveobs'],
                             noisy_star_spectrum['waveobs'])
예제 #25
0
 def test_convert_air_to_vacuum(self):
     star_spectrum = ispec.read_spectrum(
         ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
     #--- Converting wavelengths from air to vacuum and viceversa -------------------
     star_spectrum_vacuum = ispec.air_to_vacuum(star_spectrum)
     star_spectrum_air = ispec.vacuum_to_air(star_spectrum_vacuum)
     np.testing.assert_equal(star_spectrum['flux'],
                             star_spectrum_vacuum['flux'])
     np.testing.assert_equal(star_spectrum['err'],
                             star_spectrum_vacuum['err'])
     np.testing.assert_equal(star_spectrum['flux'],
                             star_spectrum_air['flux'])
     np.testing.assert_equal(star_spectrum['err'], star_spectrum_air['err'])
     np.testing.assert_almost_equal(star_spectrum['waveobs'],
                                    star_spectrum_air['waveobs'])
     self.assertAlmostEqual(star_spectrum_vacuum['waveobs'][0],
                            480.12574305216896)
     self.assertAlmostEqual(star_spectrum_vacuum['waveobs'][-1],
                            680.175349351457)
예제 #26
0
 def test_adjust_line_masks(self):
     star_spectrum = ispec.read_spectrum(
         ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
     #--- Adjust line masks ---------------------------------------------------------
     resolution = 80000
     smoothed_star_spectrum = ispec.convolve_spectrum(
         star_spectrum, resolution)
     line_regions = ispec.read_line_regions(ispec_dir +
                                            "/input/regions/fe_lines.txt")
     linemasks = ispec.adjust_linemasks(smoothed_star_spectrum,
                                        line_regions,
                                        max_margin=0.5)
     self.assertAlmostEqual(line_regions['wave_base'][0], 480.26937)
     self.assertAlmostEqual(line_regions['wave_top'][0], 480.28771)
     self.assertEqual(len(linemasks), 315)
     np.testing.assert_equal(line_regions['wave_peak'],
                             linemasks['wave_peak'])
     self.assertAlmostEqual(linemasks['wave_base'][0], 480.269365109)
     self.assertAlmostEqual(linemasks['wave_top'][0], 480.319964199)
예제 #27
0
    def test_determine_tellurics_shift_with_mask(self):
        star_spectrum = ispec.read_spectrum(
            ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
        #--- Telluric velocity shift determination from spectrum --------------------------
        # - Telluric
        telluric_linelist_file = ispec_dir + "/input/linelists/CCF/Synth.Tellurics.500_1100nm/mask.lst"
        telluric_linelist = ispec.read_telluric_linelist(
            telluric_linelist_file, minimum_depth=0.0)

        models, ccf = ispec.cross_correlate_with_mask(star_spectrum, telluric_linelist, \
                                lower_velocity_limit=-100, upper_velocity_limit=100, \
                                velocity_step=0.5, mask_depth=0.01, \
                                fourier = False,
                                only_one_peak = True)

        bv = models[0].mu()  # km/s
        bv_err = models[0].emu()  # km/s
        self.assertAlmostEqual(bv, 8.139999999999954)
        self.assertAlmostEqual(bv_err, 0.031123202937016047)
예제 #28
0
    def test_find_continuum_regions(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 ----------------------------------------------------
        resolution = 80000
        sigma = 0.001
        max_continuum_diff = 1.0
        fixed_wave_step = 0.05
        star_continuum_regions = ispec.find_continuum(star_spectrum, resolution, \
                                            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(star_continuum_regions, "example_star_fe_lines_continuum.txt")
        self.assertEqual(len(star_continuum_regions), 2)
        self.assertAlmostEqual(star_continuum_regions['wave_base'][0],
                               528.6665701)
        self.assertAlmostEqual(star_continuum_regions['wave_top'][0],
                               528.6915701)
        self.assertAlmostEqual(star_continuum_regions['wave_base'][1],
                               608.4415701)
        self.assertAlmostEqual(star_continuum_regions['wave_top'][1],
                               608.4665701)
예제 #29
0
 def test_resample_spectrum(self):
     star_spectrum = ispec.read_spectrum(
         ispec_dir + "/input/spectra/examples/NARVAL_Sun_Vesta-1.txt.gz")
     #--- Resampling  --------------------------------------------------------------
     wavelengths = np.arange(480.0, 680.0, 0.001)
     resampled_star_spectrum = ispec.resample_spectrum(star_spectrum,
                                                       wavelengths,
                                                       method="linear",
                                                       zero_edges=True)
     #resampled_star_spectrum = ispec.resample_spectrum(star_spectrum, wavelengths, method="bessel", zero_edges=True)
     self.assertEqual(len(resampled_star_spectrum), 200000)
     self.assertAlmostEqual(resampled_star_spectrum['waveobs'][0], 480.)
     self.assertAlmostEqual(resampled_star_spectrum['waveobs'][-1],
                            680. - 0.001)
     self.assertAlmostEqual(resampled_star_spectrum['flux'][0],
                            0.7957469310344828)
     self.assertAlmostEqual(resampled_star_spectrum['flux'][-1], 0.0)
     self.assertAlmostEqual(resampled_star_spectrum['err'][0],
                            0.002313683448275862)
     self.assertAlmostEqual(resampled_star_spectrum['err'][-1], 0.0)
예제 #30
0
def determine_radial_velocity_with_template(star_spectrum):
    ''' Determine radial velocity of star_spectrum compared with some template
    Chose template wisely; Return Radial velocity and err'''
    logging.info("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)

    # First component:
    rv = np.round(models[0].mu(), 2)  # km/s
    rv_err = np.round(models[0].emu(), 2)  # km/s
    return rv, rv_err
예제 #31
0
            # set up the plots
            if args.plot:
                #fig, ax = plt.subplots(3, 1, figsize=(10, 10))
                #ax[0].set_title('Spectral Analysis - {}'.format(swasp_id))
                plt.ion()
                ax_spec = plt.subplot2grid((6, 4), (0, 0), colspan=4, rowspan=2)
                ax_spec.set_title('{} {}'.format(swasp_id, spectrum))
                ax_mask_rv = plt.subplot2grid((6, 4), (2, 0), colspan=2, rowspan=2)
                ax_mask_rv.set_title('RV wrt {}'.format(mask_type))
                ax_mask_ccf = plt.subplot2grid((6, 4), (4, 0), colspan=2, rowspan=2)
                ax_mask_ccf.set_title('CCF wrt {}'.format(mask_type))
                plt.subplots_adjust(hspace=1.0)
                plt.show()

            # read in the spectrum
            spec = ispec.read_spectrum(spectrum)
            print('{} Loaded...'.format(spectrum))

            # chop out the wavelength range we want to work on
            # accesss the data using column names
            # e.g. s['waveobs' | 'flux' | 'err']
            wave_filter = ispec.create_wavelength_filter(spec, \
                                          wave_base=INSTRUMENT[args.instrument]['WV_LLIM'], \
                                          wave_top=INSTRUMENT[args.instrument]['WV_ULIM'])
            spec = spec[wave_filter]
            print('{} Wavelength range restricted to {}-{}'.format(spectrum, \
                                            INSTRUMENT[args.instrument]['WV_LLIM'], \
                                            INSTRUMENT[args.instrument]['WV_ULIM']))
            if args.plot:
                ax_spec.plot(spec['waveobs'], spec['flux'], 'r-')