Example #1
0
def load_spectrum(spec_fil):
    '''Load X-Shooter spectra'''
    # Load Spectrum
    uvb_spec = XSpectrum1D.from_file(spec_fil)
    vis_specfil = spec_fil.replace('uvb', 'vis')
    vis_spec = XSpectrum1D.from_file(vis_specfil)
    comb_spec = uvb_spec.splice(vis_spec)
    comb_spec.filename = spec_fil
    # Return
    return comb_spec
Example #2
0
def load_1dspec(fname, exten=None, extract='OPT', objname=None, flux=False):
    """
    Parameters
    ----------
    fname : str
      Name of the file
    exten : int, optional
      Extension of the spectrum
      If not given, all spectra in the file are loaded
    extract : str, optional
      Extraction type ('opt', 'box')
    objname : str, optional
      Identify extension based on input object name
    flux : bool, optional
      Return fluxed spectra?

    Returns
    -------
    spec : XSpectrum1D

    """

    # Identify extension from objname?
    if objname is not None:
        hdulist = fits.open(fname)
        hdu_names = [hdu.name for hdu in hdulist]
        exten = hdu_names.index(objname)
        if exten < 0:
            msgs.error("Bad input object name: {:s}".format(objname))

    # Keywords for Table
    rsp_kwargs = {}
    if flux:
        rsp_kwargs['flux_tag'] = '{:s}_FLAM'.format(extract)
        rsp_kwargs['sig_tag'] = '{:s}_FLAM_SIG'.format(extract)
    else:
        rsp_kwargs['flux_tag'] = '{:s}_COUNTS'.format(extract)
        rsp_kwargs['sig_tag'] = '{:s}_COUNTS_SIG'.format(extract)

    # Use the WAVE_GRID (for 2d coadds) if it exists, otherwise use WAVE
    rsp_kwargs['wave_tag'] = '{:s}_WAVE_GRID'.format(extract)
    # Load
    try:
        spec = XSpectrum1D.from_file(fname, exten=exten, **rsp_kwargs)
    except ValueError:
        rsp_kwargs['wave_tag'] = '{:s}_WAVE'.format(extract)
        spec = XSpectrum1D.from_file(fname, exten=exten, **rsp_kwargs)

    # Return
    return spec
Example #3
0
def test_get_local_s2n():
    spec = XSpectrum1D.from_file(data_path('UM184_nF.fits'))
    wv0 = 4000 * u.AA
    s2n, sig_s2n = spec.get_local_s2n(wv0, 20, flux_th=0.9)
    np.testing.assert_allclose(s2n, 9.30119800567627, rtol=1e-5)
    np.testing.assert_allclose(sig_s2n, 1.0349911451339722, rtol=1e-5)
    # test with continuum
    spec.co = np.ones_like(spec.flux)
    s2n, sig_s2n = spec.get_local_s2n(wv0, 20, flux_th=0.9)
    np.testing.assert_allclose(s2n, 10.330545425415039, rtol=1e-5)
    np.testing.assert_allclose(sig_s2n, 0.4250050187110901, rtol=1e-5)
    # test errors
    # out of range
    with pytest.raises(IOError):
        spec.get_local_s2n(1215 * u.AA, 20)
    # sig not defined
    spec = XSpectrum1D.from_tuple((spec.wavelength, spec.flux))
    with pytest.raises(ValueError):
        spec.get_local_s2n(wv0, 20)
    # bad shape for flux_th
    with pytest.raises(ValueError):
        spec.get_local_s2n(wv0, 20, flux_th=np.array([1, 2, 3, 4, 5]))
    # npix too big
    with pytest.raises(ValueError):
        spec.get_local_s2n(wv0, 1 + len(spec.wavelength))
Example #4
0
def test_get_local_s2n():
    spec = XSpectrum1D.from_file(data_path('UM184_nF.fits'))
    wv0 = 4000 * u.AA
    s2n, sig_s2n = spec.get_local_s2n(wv0, 20, flux_th=0.9)
    np.testing.assert_allclose(s2n, 9.30119800567627, rtol=1e-5)
    np.testing.assert_allclose(sig_s2n, 1.0349911451339722, rtol=1e-5)
    # test with continuum
    spec.co = np.ones_like(spec.flux)
    s2n, sig_s2n = spec.get_local_s2n(wv0, 20, flux_th=0.9)
    np.testing.assert_allclose(s2n, 10.330545425415039, rtol=1e-5)
    np.testing.assert_allclose(sig_s2n, 0.4250050187110901, rtol=1e-5)
    # test errors
    # out of range
    with pytest.raises(IOError):
        spec.get_local_s2n(1215*u.AA, 20)
    # sig not defined
    spec = XSpectrum1D.from_tuple((spec.wavelength, spec.flux))
    with pytest.raises(ValueError):
        spec.get_local_s2n(wv0, 20)
    # bad shape for flux_th
    with pytest.raises(ValueError):
        spec.get_local_s2n(wv0, 20, flux_th=np.array([1,2,3,4,5]))
    # npix too big
    with pytest.raises(ValueError):
        spec.get_local_s2n(wv0, 1 + len(spec.wavelength))
Example #5
0
def fit_cont(filename):

    from linetools.spectra.xspectrum1d import XSpectrum1D
    import re
    from astropy.coordinates import SkyCoord
    from linetools.isgm import abssystem as lt_absys
    from linetools.spectralline import AbsLine
    from linetools.isgm.abscomponent import AbsComponent
    from linetools import line_utils as ltlu
    from linetools.spectralline import AbsLine, SpectralLine
    import numpy
    from astropy.io import fits
    from glob import glob
    from astropy import units as u
    from linetools.lists.linelist import LineList
    import warnings
    warnings.filterwarnings('ignore')

    # Create a spectrum class object from the fits file
    sp = XSpectrum1D.from_file(filename)

    data, radec = get_prop(filename)

    # Call the GUI to interactively fit the continuum
    sp.fit_continuum(kind='QSO', redshift=data['zq'])

    # Normalize the Continuum
    sp.normalize(co=sp.co)

    # Write the Normalized Continuum to a new fits file
    sp.write_to_fits('n_' + filename)

    return print(filename + ' has been normalized and written to ' + 'n_' +
                 filename)
Example #6
0
    def __init__(self):
        super().__init__()

        self.setWindowTitle('My simple dialog app')

        button = QPushButton('Press me for a dialog!')
        button.clicked.connect(self.button_clicked)

        self.setCentralWidget(button)

        #Add your flux extraction code in here

        sp = XSpectrum1D.from_file('./example-data/test.fits')

        wave = sp.wavelength.value
        flux = sp.flux.value
        error = sp.sig.value
        q = np.where((wave > 1330) & (wave < 1340))
        self.wave = wave[q]
        self.flux = flux[q]
        self.error = error[q]

        sizeObj = QDesktopWidget().screenGeometry(-1)
        print('Screen size:' + str(sizeObj.height()) + 'x' +
              str(sizeObj.width()))
        availObj = QDesktopWidget().availableGeometry(-1)
        print('Availble size:' + str(availObj.height()) + 'x' +
              str(availObj.width()))
        self.move(sizeObj.width() // 2, sizeObj.height() // 2)
Example #7
0
def test_from_file():
    spec = XSpectrum1D.from_file(data_path('UM184_nF.fits'))
    idl = ascii.read(data_path('UM184.dat.gz'), names=['wave', 'flux', 'sig'])

    np.testing.assert_allclose(spec.dispersion.value, idl['wave'])
    np.testing.assert_allclose(spec.sig, idl['sig'], atol=2e-3, rtol=0)

    assert spec.dispersion.unit == u.Unit('AA')
Example #8
0
    def __init__(self, filepath=''):
        self.fitsobj = FitsObj(wave=[])
        self.filepath = filepath
        self.warning = ''

        try:
            self.sp = XSpectrum1D.from_file(self.filepath)
        except (OSError, KeyError, AttributeError):
            self.warning += 'XSpectrum1D cannot read this file.'
Example #9
0
 def load_spec(self):
     '''Input the Spectrum
     '''
     from linetools.spectra.xspectrum1d import XSpectrum1D
     if self._specfil is None:
         self.get_specfil()
     #
     if self.verbose:
         print('SdssQso: Loading spectrum from {:s}'.format(self._specfil))
     self.spec = XSpectrum1D.from_file(self._specfil)
Example #10
0
	def __init__(self, filepath=''):
		self.fitsobj = FitsObj(wave=[])
		self.filepath = filepath
		self.warning = ''

		# try if XSpectrum1D can read current file
		try:
			self.sp = XSpectrum1D.from_file(self.filepath)
		except (OSError, KeyError, AttributeError):
			# give warning without GUI crashing
			self.warning += 'XSpectrum1D cannot read this file.'
Example #11
0
def test_addmask():
    spec = XSpectrum1D.from_file(data_path('UM184_nF.fits'))
    assert not spec.data['flux'][0].mask[100]
    mask = spec.data['flux'][0].mask.copy()
    mask[100:110] = True
    spec.add_to_mask(mask)
    assert spec.data['flux'][0].mask[100]
    # Compressed
    badp = spec.flux < 0.1
    spec.add_to_mask(badp, compressed=True)
    assert np.sum(spec.data['flux'][0].mask) > 3000
Example #12
0
def test_addmask():
    spec = XSpectrum1D.from_file(data_path('UM184_nF.fits'))
    assert not spec.data['flux'][0].mask[100]
    mask = spec.data['flux'][0].mask.copy()
    mask[100:110] = True
    spec.add_to_mask(mask)
    assert spec.data['flux'][0].mask[100]
    # Compressed
    badp = spec.flux < 0.1
    spec.add_to_mask(badp, compressed=True)
    assert np.sum(spec.data['flux'][0].mask) > 3000
Example #13
0
def test_from_file():
    spec = XSpectrum1D.from_file(data_path('UM184_nF.fits'))
    idl = ascii.read(data_path('UM184.dat.gz'), names=['wave', 'flux', 'sig'])

    np.testing.assert_allclose(spec.data['wave'][spec.select].data,
                               idl['wave'])
    np.testing.assert_allclose(spec.data['sig'][spec.select].data,
                               idl['sig'],
                               atol=2e-3,
                               rtol=0)

    assert spec.wavelength.unit == u.Unit('AA')
Example #14
0
def measure_sodium_EW(filename):
    from linetools.lists.linelist import LineList
    from astropy import units as u
    from linetools.spectralline import AbsLine
    from linetools.spectra.xspectrum1d import XSpectrum1D
    import matplotlib.pyplot as plt

    sp = XSpectrum1D.from_file('RF_' + filename)
    sp.normalize(co=sp.co)

    wvlim = [5880, 6030] * u.AA
    strong = LineList('Strong')
    transitions = strong.available_transitions(wvlim,
                                               n_max_tuple=None,
                                               min_strength=0.0)
    line1 = transitions['wrest'][0]
    line2 = transitions['wrest'][1]
    avg_line = (line1 + line2) / 2.0

    # Plot the spectrum to get limits for EW
    fig = plt.figure()
    plt.axvline(x=line1, color='k', linestyle='--')
    plt.axhline(y=1.0, color='r', linestyle='--')
    plt.axvline(x=line2, color='k', linestyle='--')
    sp.plot(xlim=(avg_line - 30, avg_line + 30))

    S1 = AbsLine(transitions['wrest'][0] * u.AA, z=0.0)
    S1.analy['spec'] = sp
    S2 = AbsLine(transitions['wrest'][1] * u.AA, z=0.0)
    S2.analy['spec'] = sp

    #x = float(input("Enter a lower lim: "))
    #y = float(input("Enter a higher lim: "))

    x = 5888
    y = 5896

    S1.limits.set([x, y] * u.AA)
    S1.measure_ew(flg=1)  # Measure the EW of the first line
    EW1 = S1.attrib['EW'], S1.attrib['sig_EW']

    #x = float(input("Enter a lower lim: "))
    #y = float(input("Enter a higher lim: "))

    x = 5895
    y = 5905
    S2.limits.set([x, y] * u.AA)
    S2.measure_ew()  # Measure the EW of the second line
    EW2 = S2.attrib['EW'], S2.attrib['sig_EW']
    return EW1, EW2
Example #15
0
def fig_lya_forest(zoom_in=False, redshift=False):

    outfile = 'fig_lya_forest.png'
    xmnx = (3950., 4363)

    if zoom_in:
        xmnx = (4130., 4183)
        outfile = 'fig_lya_forest_zoom.png'

    if redshift:
        outfile = 'fig_lya_forest_z.png'
        xmnx = np.array(xmnx) / 1215.6701 - 1.

    # Read spectrum
    spec_file = os.getenv(
        'DROPBOX_DIR') + 'Keck/HIRES/RedData/Q1759+75/Q1759+75T_f.fits'
    xspec = XSpectrum1D.from_file(spec_file)

    plt.figure(figsize=(9, 5))
    plt.clf()
    gs = gridspec.GridSpec(1, 1)
    ax = plt.subplot(gs[:, :])

    # Plot
    if redshift:
        xplt = xspec.wavelength.value / 1215.6701 - 1.
    else:
        xplt = xspec.wavelength.value
    ax.plot(xplt, xspec.flux, 'k')
    ax.plot([0., 5000], [0., 0.], 'g--')
    ax.set_xlim(xmnx)
    ax.set_ylim(-0.05, 1.1)
    ax.set_ylabel('Normalized Flux')
    if redshift:
        ax.set_xlabel('Redshift (z)')
    else:
        ax.set_xlabel('Wavelength (A)')

    set_fontsize(ax, 15.)

    # Write
    plt.tight_layout(pad=0.2, h_pad=0., w_pad=0.1)
    plt.savefig(outfile, dpi=500)
    plt.close()
    print("Wrote: {:s}".format(outfile))
Example #16
0
def measure_ew_lim(filename):
    from linetools.lists.linelist import LineList
    import numpy
    from astropy import units as u
    from linetools.spectralline import AbsLine
    from linetools.spectra.xspectrum1d import XSpectrum1D

    sp = XSpectrum1D.from_file('RF_' + filename)
    sp.normalize(co=sp.co)

    wv0 = 5891.5833 * u.AA
    R = 4013.0 / .3
    d_lambda_pix = 0.13333317282580992
    d_lambda_res = 5891.5833 / R
    N_pix = d_lambda_res / d_lambda_pix
    s_2_n = sp.get_local_s2n(wv0, npix=100)[0]  #/100 S_2_N per pixel
    EW_lim = 3.0 * numpy.sqrt(N_pix) * d_lamba_pix / s_2_n  # 1 sigma limit
    return EW_lim
Example #17
0
def load_1dspec(fname, exten=None, extract='opt', objname=None, flux=False):
    """
    Parameters
    ----------
    fname : str
      Name of the file
    exten : int, optional
      Extension of the spectrum
      If not given, all spectra in the file are loaded
    extract : str, optional
      Extraction type ('opt', 'box')
    objname : str, optional
      Identify extension based on input object name
    flux : bool, optional
      Return fluxed spectra?

    Returns
    -------
    spec : XSpectrum1D

    """
    from astropy.io import fits
    from linetools.spectra.xspectrum1d import XSpectrum1D

    # Keywords for Table
    rsp_kwargs = {}
    rsp_kwargs['wave_tag'] = '{:s}_wave'.format(extract)
    if flux:
        rsp_kwargs['flux_tag'] = '{:s}_flam'.format(extract)
        rsp_kwargs['var_tag'] = '{:s}_flam_var'.format(extract)
    else:
        rsp_kwargs['flux_tag'] = '{:s}_counts'.format(extract)
        rsp_kwargs['var_tag'] = '{:s}_var'.format(extract)
    # Identify extension from objname?
    if objname is not None:
        hdulist = fits.open(fname)
        hdu_names = [hdu.name for hdu in hdulist]
        exten = hdu_names.index(objname)
        if exten < 0:
            msgs.error("Bad input object name: {:s}".format(objname))
    # Load
    spec = XSpectrum1D.from_file(fname, exten=exten, **rsp_kwargs)
    # Return
    return spec
Example #18
0
def spec_dered(filename):
    from linetools.lists.linelist import LineList
    from astropy import units as u
    from linetools.spectra.xspectrum1d import XSpectrum1D

    # Create a json file and centroid the lines
    spec_inspect(filename)

    # Read in the json file
    data = read_json(filename[:-5] + '.json')
    z_new = data['zabs']

    # Create a spectrum object, and normalize it, using the
    # already fitted continuum.

    sp = XSpectrum1D.from_file('n_' + filename)
    sp.normalize(co=sp.co)

    # Transform the spectra into the rest frame
    sp.wavelength = de_redshift(sp, z_new)
    sp.write_to_fits('RF_' + filename)
    sp.plot()

    return print('The Spectrum has been transformed into the Lab Frame')
Example #19
0
    def from_file(cls, filename, filetype=False, efil=None, **kwargs):

        if filetype == False:
            #Take File Extention and try
            if filename == False:
                if 'wave' in kwargs:
                    wave = kwargs['wave']
                else:
                    raise IOError("Input wavelength array")
                if 'flux' in kwargs:
                    flux = kwargs['flux']
                else:
                    raise IOError("Input flux array")
                if 'error' in kwargs:
                    error = kwargs['error']
                else:
                    raise IOError("Input error array")

            else:
                tt = os.path.splitext(filename)[1]
                if (tt == 'txt') | (tt == 'dat'):
                    filetype = 'ascii'
                else:
                    filetype = tt[1:len(tt)]

        # Read in Files in differet formats
        if filetype == 'ascii':
            from astropy.io import ascii
            dat = ascii.read(filename)
            tab = dat.keys()
            wave = np.array(dat[tab[0]])
            flux = np.array(dat[tab[1]])
            if (len(dat.keys()) >= 3):
                error = dat[tab[2]]
            else:
                error = 0. * flux

        elif filetype == 'fits':
            from astropy.io import fits
            file = fits.open(filename)  #(cwd+'/'+filename)
            dat = file[1].data
            tab = dat.names
            wave = np.array(dat['wave'][0])
            flux = np.array(dat['flux'][0])
            if (len(tab) >= 3):
                error = np.array(dat['error'][0])
            else:
                error = 0. * flux
        elif filetype == 'HSLA':
            from astropy.io import fits
            file = fits.open(filename)  #(cwd+'/'+filename)
            dat = file[1].data
            tab = dat.names
            wave = np.array(dat['WAVE'])
            flux = np.array(dat['FLUX'])  #/np.median(np.array(dat['FLUX']))
            if (len(tab) >= 3):
                error = np.array(
                    dat['ERROR'])  #/np.median(np.array(dat['FLUX']))
            else:
                error = 0. * flux

        if filetype == 'xfits':
            from linetools.spectra.xspectrum1d import XSpectrum1D
            sp = XSpectrum1D.from_file(filename)

            wave = sp.wavelength.value
            flux = sp.flux.value
            error = sp.sig.value

            if sp.co_is_set == True:
                print('Normalizing spectrum using given continuum...')
                flux = sp.flux.value / sp.co.value
                error = sp.sig.value / sp.co.value

        elif filetype == 'p':
            import pickle
            dat = pickle.load(open(filename, "rb"))
            #tab=dat.keys()
            wave = np.array(dat['wave'])
            flux = np.array(dat['flux'])
            if (len(tab) >= 3):
                error = np.array(dat['error'])
            else:
                error = 0. * flux
        elif filetype == 'temp':
            from astropy.io import fits
            file = fits.open(filename)  #(cwd+'/'+filename)
            #a=fits.open(path+'spec_knotA.fits')

            wave = file[2].data
            flux = file[0].data
            error = file[1].data
        #Use linetools.io.readspec to read file
        elif filetype == 'linetools':
            from linetools.spectra import io as tio
            sp = tio.readspec(filename, inflg=None, efil=efil, **kwargs)
            wave = sp.wavelength.value
            flux = sp.flux.value

            if sp.sig_is_set == False:
                print('Assuiming arbiarbitrary 10% error on flux')
                error = 0.1 * flux
            else:
                error = sp.sig.value

        return cls(wave, flux, error, filename=filename)
Example #20
0
def test_co_kludges():
    spec = XSpectrum1D.from_file(data_path('SDSSJ220248.31+123656.3.fits'),
                                 masking='edges')
    assert spec.co.size == 4599
Example #21
0
def simple_coadd(uves_table=None, outputbase=None, airtovac=True):
    """simple_coadd(uves_table=None, outputbase=None,airtovac=True):

    Combine multiple UVES exposures obtained with the same set-up into a single spectrum, weighting by the inverse variance of the input data.

    For multiple set-ups, outputs an individual file for each unique wavelength range.
    """

    import numpy as np
    from astropy.table import Table
    from linetools.spectra.xspectrum1d import XSpectrum1D

    if uves_table == None:
        #   There is no input table; let's create one.
        uves_table = uves_log()

    # Select unique wavelengths to identify the setups
    # Table should be the output from UVES log or at least contain wavelengths and filenames.
    uniq_setup, uniq_indeces, uniq_inverse = np.unique(np.around(
        uves_table['WAVELMIN'], 1),
                                                       return_index=True,
                                                       return_inverse=True)

    num_setups = np.size(uniq_indeces)

    # Loop over the setups.
    for j in np.arange(num_setups):
        # Work out the setups that are to be coadded
        setup_obs = (np.where(uniq_inverse == j))[0]
        num_setup_obs = np.size(setup_obs)

        # Hold object name
        setup_obj = uves_table[uniq_indeces[j]]['OBJECT']

        # Loop over the files in this setup
        for k in np.arange(num_setup_obs):
            # inspec = fits.getdata(uves_table[setup_obs[k]]['fitsName'])
            specfile = uves_table[setup_obs[k]]['fitsName']
            inspec = Table.read(specfile)

            # Load the spectrum with XSpectrum1D:
            inspec = XSpectrum1D.from_file(specfile)
            inspec.meta['airvac'] = 'air'

            # Unless user requests, we transform to vacuum.
            if airtovac == True:
                inspec.airtovac()

            # Check for sig = 0:
            badErrors = (inspec.sig == 0)
            inspec.flux[badErrors] = np.nan
            inspec.sig[badErrors] = np.nan
            inspec.ivar[badErrors] = np.nan

            # Set up the arrays if it's the first spectrum.
            if k == 0:
                out_file_list = specfile
                out_wave = inspec.wavelength.value
                # Do weighted average; calculate the inverse variance and the inv var-weighted flux.
                out_inv_variance = inspec.ivar.value
                out_flux_weighted = \
                    inspec.flux.value*inspec.ivar.value
            # For subsequent spectra:
            else:
                #Test for same array length:
                new_length = np.min(
                    [np.size(inspec.flux.value),
                     np.size(out_flux_weighted)])

                out_file_list += ', ' + specfile
                out_inv_variance[:new_length] += \
                    inspec.ivar.value[:new_length]
                out_flux_weighted[:new_length] += \
                    inspec.flux.value[:new_length]*inspec.ivar.value[:new_length]

        # Calculate the output weighted mean flux and error.
        out_flux = out_flux_weighted / out_inv_variance
        out_err = np.sqrt(1. / out_inv_variance)

        # Book-keeping: set up filename
        if outputbase == None:
            # If there is no base for the filenames, use the object name.
            outputfilename = uves_table[setup_obs[k]]['OBJECT']
        else:
            outputfilename = outputbase

        outputfilename = "{0}.uves.{1:0.0f}.{2:0.0f}.fits".format(
            outputfilename, uves_table[setup_obs[k]]['WAVELMIN'] * 10.,
            uves_table[setup_obs[k]]['WAVELMAX'] * 10.)
        # Set up the output table
        outputtable = Table([out_wave, out_flux, out_err],
                            names=['wave', 'flux', 'err'])
        # Load the spectrum in the standard way to get the units right:
        inspec = Table.read(uves_table[0]['fitsName'])
        # Assign units
        outputtable['wave'].unit = inspec['WAVE'].unit
        outputtable['flux'].unit = inspec['FLUX'].unit
        outputtable['err'].unit = inspec['ERR'].unit

        outputtable.meta = inspec.meta
        outputtable.meta['COMMENT'] = 'Simple coadd of ' + out_file_list

        outputtable.write(outputfilename, overwrite=True)
        print('Wrote ' + outputfilename + '.')
Example #22
0
def xspec(z_bin, plot=False):
    """
    :param z_bin: (list) min and max redshift values of the desired bin ex:[2.0,2.5]

    :return:
        (numpy array) XSpectrum1D objects, corresponding redshifts and coordinates
    """

    import numpy as np
    import matplotlib.pyplot as plt
    from astropy.table import Table
    import astropy.units as u
    from linetools.spectra.xspectrum1d import XSpectrum1D

    path_16 = "../../spectra/2016/"
    path_17 = "../../spectra/2017/"

    spec_atr_16 = Table.read(path_16 + "spec_atr.txt", format='ascii')
    spec_atr_17 = Table.read(path_17 + "spec_atr.txt", format='ascii')

    # read in

    spec_16 = []
    z_16 = []
    coord_16 = []

    for entry in spec_atr_16:  # from the CLAMATO 2016 survey

        if np.min(z_bin) <= entry["zspec"] <= np.max(
                z_bin):  # creating the bin size

            if entry["Conf"] < 10.0:  # excluding any QSOs

                temp = XSpectrum1D.from_file(path_16 + entry["Filename"])

                if temp.wvmin < (1216 * u.AA) * (1 +
                                                 entry["zspec"]) < temp.wvmax:

                    coord_16.append([entry["RA"],
                                     entry["Dec"]])  # coordinates in deg

                    z_16.append(entry["zspec"])

                    spec_16.append(
                        XSpectrum1D.from_file(path_16 + entry["Filename"]))

    spec_17 = []
    z_17 = []
    coord_17 = []

    for entry in spec_atr_17:

        if np.min(z_bin) <= entry["col5"] <= np.max(z_bin):

            if entry["col4"] < 10.0:

                temp = XSpectrum1D.from_file(path_17 + entry["col1"])

                if temp.wvmin < (1216 * u.AA) * (1 +
                                                 entry["col5"]) < temp.wvmax:

                    coord_17.append([entry["col7"], entry["col8"]])

                    z_17.append(entry["col5"])

                    spec_17.append(
                        XSpectrum1D.from_file(path_17 + entry["col1"]))

    # array creation

    spec = np.asarray(spec_16 + spec_17)
    red = np.asarray(z_16 + z_17)
    coord = np.asarray(coord_16 + coord_17)

    print("Number of spectra in the redshift bin:", len(spec))

    z_16_tot = [entry["zspec"]
                for entry in spec_atr_16]  # from the CLAMATO 2016 survey
    z_17_tot = [entry["col5"]
                for entry in spec_atr_17]  # from the CLAMATO 2017 survey
    z_tot = z_16_tot + z_17_tot

    # a histogram to illustrate the sample selected

    if plot == True:

        plt.figure(figsize=(8, 8))

        plt.hist(z_tot,
                 bins=70,
                 edgecolor='white',
                 linewidth=1.2,
                 label="Full Sample",
                 color="grey")
        plt.hist(red,
                 bins=12,
                 edgecolor='black',
                 linewidth=1.2,
                 label="Reduced Sample",
                 color="#fd8d3c")

        plt.ylabel("Number of Galaxies", fontsize=15)
        plt.xlabel("$z$", fontsize=15)

        plt.xlim(1.5, 3.5)

        plt.legend(fontsize=12)
        plt.xticks(fontsize=12)
        plt.yticks(fontsize=12)
        plt.show()

    return spec, red, coord
Example #23
0
def test_unmask():
    spec = XSpectrum1D.from_file(data_path('UM184_nF.fits'), masking='edges')
    assert np.sum(spec.data['wave'].mask) > 0
    spec.unmask()
    assert np.sum(spec.data['wave'].mask) == 0
Example #24
0
def fit_lines(spec_file,
              z_init=0.,
              do_plot=True,
              file_out=None,
              no_tie_5008=False):
    # from astropy.modeling import models, fitting
    from linetools.spectra.xspectrum1d import XSpectrum1D
    import matplotlib.pyplot as plt

    # Redshift scale:
    scale_factor = (1. + z_init)

    # Read in the spectrum. **ASSUME VACUUM WAVELENGTHS?**
    mods_spec = XSpectrum1D.from_file(spec_file)
    # mods_spec = Table.read(spec_file)

    # Set up a convenient wavelength, flux, error arrays
    wave = mods_spec.wavelength.value
    flux = mods_spec.flux.value
    err = mods_spec.sig.value
    # wave = mods_spec['wave']
    # flux = mods_spec['flux']
    # err = mods_spec['err']

    # Load the data for the lines to be fit. Starts with MANGA line list, modified for MODS.
    line_data = get_linelist()
    # Exclude lines outside of the wavelength coverage.
    keep_lines = np.where(
        (line_data['lambda'] <= np.max(wave) / scale_factor)
        & (line_data['lambda'] >= np.min(wave) / scale_factor))[0]
    keep_line_index = line_data['indx'][keep_lines]

    ##########
    # MODEL DEFINITION
    # Define a joint model as the sums of Gaussians for each line

    # Initial parameters
    amplitude_init = 0.1 * np.max(flux)
    stddev_init = 1.5

    # Constraint parameters:
    amplitude_bounds, stddev_bounds, velocity_range = _define_bounds()

    # Start up the constraints on the mean wavelength  [separate bounds for each lambda0]
    mean_bounds_scale = (velocity_range / c.c.to('km/s').value) * np.array(
        [-1., 1.]) + 1.
    mean_bounds = []

    ##### DEFINE THE MODEL:
    #  Initial Gaussian:
    j = 0
    wave0 = line_data['lambda'][j]
    line_center = wave0 * scale_factor
    model_name = np.str(line_data['name'][j])

    # Traditional astropy 1D Gaussian model:
    joint_model = models.Gaussian1D(amplitude=amplitude_init,
                                    mean=line_center,
                                    stddev=stddev_init,
                                    name=model_name)
    # Set constraints on how much the central value can vary
    mean_bounds.append([
        line_center * mean_bounds_scale[0], line_center * mean_bounds_scale[1]
    ])

    #  Loop through the remaining lines to create their Gaussian model:
    for j in np.arange(1, np.size(line_data)):
        wave0 = line_data['lambda'][j]
        line_center = wave0 * scale_factor
        model_name = np.str(line_data['name'][j])

        # Traditional astropy 1D Gaussian fit:
        joint_model += models.Gaussian1D(amplitude=amplitude_init,
                                         mean=line_center,
                                         stddev=stddev_init,
                                         name=model_name)
        # Set constraints on how much the central value can vary
        mean_bounds.append([
            line_center * mean_bounds_scale[0],
            line_center * mean_bounds_scale[1]
        ])

    # Extract the model names:
    model_names = joint_model.submodel_names

    # Now we have to loop through the same models, applying the
    #  remaining bounds. This includes tying parameters:
    for k in np.arange(0, np.size(line_data)):
        mdlnm = model_names[k]
        joint_model[mdlnm].bounds['amplitude'] = amplitude_bounds
        joint_model[mdlnm].bounds['mean'] = (mean_bounds[k][0],
                                             mean_bounds[k][1])
        joint_model[mdlnm].bounds['stddev'] = stddev_bounds

        # Tie some parameters together, checking that reference lines
        #  are actually covered by the spectrum:
        if (line_data['mode'][k] == 't33') & (np.in1d(33, keep_line_index)):
            joint_model[mdlnm].stddev.tied = _tie_sigma_4862
        elif (line_data['mode'][k] == 't35') & (np.in1d(35, keep_line_index)):
            #joint_model[mdlnm].stddev.tied = _tie_sigma_4862
            joint_model[mdlnm].stddev.tied = _tie_sigma_5008
        elif (line_data['mode'][k] == 't45') & (np.in1d(45, keep_line_index)):
            joint_model[mdlnm].stddev.tied = _tie_sigma_6585

        # Tie amplitudes of doublets
        if (line_data['line'][k] == 'd35') & (np.in1d(35, keep_line_index)):
            joint_model[mdlnm].amplitude.tied = _tie_ampl_5008  # 4959/5008
        if (line_data['line'][k] == 'd45') & (np.in1d(45, keep_line_index)):
            joint_model[mdlnm].amplitude.tied = _tie_ampl_6585  # 6549/6585

        # Finally, tie redshifts of OII 3727, 3729, OIII 4364, 4960 to 5008
        if not no_tie_5008:
            if (line_data['indx'][k] == '16') & (np.in1d(35, keep_line_index)):
                joint_model[mdlnm].redshift.tied = _tie_mean_3727_5008
            if (line_data['indx'][k] == '17') & (np.in1d(35, keep_line_index)):
                joint_model[mdlnm].redshift.tied = _tie_mean_3729_5008
            if (line_data['indx'][k] == '29') & (np.in1d(35, keep_line_index)):
                joint_model[mdlnm].redshift.tied = _tie_mean_4364_5008
            if (line_data['indx'][k] == '34') & (np.in1d(35, keep_line_index)):
                joint_model[mdlnm].redshift.tied = _tie_mean_4960_5008

    # TODO Assess quality of emission line fits.
    # Standard astropy fit:
    fitter = fitting.LevMarLSQFitter()
    fitted_model = fitter(joint_model,
                          wave,
                          flux,
                          weights=1. / err**2,
                          maxiter=500)
    fitted_flux = fitted_model(wave)
    # Print the reason the fitter stops:
    fitter.fit_info['message']

    # Plot the results
    if do_plot:
        plt.clf()
        plt.plot(wave, flux, drawstyle='steps-mid', linewidth=2)
        plt.plot(wave, fitted_flux, color='orange', linewidth=2)

    ##### Create integrated fluxes and errors
    # The integration range is over +/-stddev * int_delta_factor
    int_delta_factor = _define_integration_delta()

    # Test whether we've constructed output or not:
    output_construct = 0

    # Loop through the list of lines:
    #  --One could imagine only looping over lines covered by the spectrum,
    #     but this screws up the way we tie parameters.
    for j in np.arange(np.size(line_data)):
        # Only fit those lines that are covered by the spectrum
        if np.in1d(j, keep_lines):
            # Calculate integrated fluxes, errors; deal with the blended O II 3727/3729 doublet
            if line_data[j]['name'] == '[OII]3727':
                # Calculate the integrated fluxes and errors
                iflux, ierr = integrate_line_flux(wave,
                                                  flux,
                                                  err,
                                                  fitted_model[j].mean.value,
                                                  fitted_model[j].stddev *
                                                  int_delta_factor,
                                                  line3727=True)
            elif line_data[j]['name'] == '[OII]3729':
                # pdb.set_trace()
                # For 3729, use the flux derived for 3726
                iflux = output_table['int_flux'][j - 1]
                #iflux = 0.
                # For 3729, use its own error. This is appropriate for the fitted errors of both liness
                crap, ierr = integrate_line_flux(
                    wave, flux, err, fitted_model[j].mean.value,
                    fitted_model[j].stddev * int_delta_factor)
            else:
                # Calculate the integrated fluxes and errors
                iflux, ierr = integrate_line_flux(
                    wave, flux, err, fitted_model[j].mean.value,
                    fitted_model[j].stddev * int_delta_factor)

            redshift_out = (fitted_model[j].mean / line_data[j]['lambda'] - 1.)
            fitted_flux_out = np.sqrt(
                2. *
                np.pi) * fitted_model[j].amplitude * fitted_model[j].stddev

            if output_construct == 0:
                # Define and construct the initial table to hold the results
                output_col_names, output_format, output_dtype = _define_output_table(
                )

                output_data = [[line_data[j]['name']], [line_data[j]['ion']],
                               [line_data[j]['lambda']],
                               [line_data[j]['indx']], [line_data[j]['mode']],
                               [fitted_model[j].mean.value],
                               [fitted_model[j].amplitude.value],
                               [fitted_model[j].stddev.value], [redshift_out],
                               [fitted_flux_out], [iflux], [ierr],
                               [iflux / ierr]]
                output_table = Table(output_data,
                                     names=output_col_names,
                                     dtype=output_dtype)

                output_construct = 1
            else:
                output_table.add_row([
                    line_data[j]['name'], line_data[j]['ion'],
                    line_data[j]['lambda'], line_data[j]['indx'],
                    line_data[j]['mode'], fitted_model[j].mean.value,
                    fitted_model[j].amplitude.value,
                    fitted_model[j].stddev.value, redshift_out,
                    fitted_flux_out, iflux, ierr, iflux / ierr
                ])

    # Set the output format of the results table:
    colnames = output_table.colnames
    for j in np.arange(np.size(colnames)):
        output_table[colnames[j]].format = output_format[j]

    # Set up the spectral table:
    spec_table = Table([wave, flux, err, fitted_flux],
                       names=['wave', 'flux', 'err', 'spec_fit'])

    # # Excise lines that weren't part of the fitting process:
    # output_table = output_table[keep_lines]

    # Write summary FITS files
    if file_out is None:
        file_base = spec_file.strip('.fits')
    else:
        file_base = file_out

    table_file = file_base + '.HIIFitTable.fits'
    fit_file = file_base + '.HIIFitSpec.fits'

    output_table.write(table_file, overwrite=True)
    spec_table.write(fit_file, overwrite=True)

    return output_table
Example #25
0
    def __init__(self,
                 redrock_file,
                 parent=None,
                 zdict=None,
                 coadd_dict=None,
                 outfile='tmp.json',
                 unit_test=False,
                 screen_scale=1.,
                 **kwargs):
        QMainWindow.__init__(self, parent)
        """
        redrock_file = str
          Input RedRock output FITS file from our redrock script
        parent : Widget parent, optional
        zsys : float, optional
          intial redshift either from a previous vet_rr json or the original
          rr guesses
        screen_scale : float, optional
          Scale the default sizes for the gui size
        """

        # Load up
        self.outfile = outfile
        self.rr_hdul = fits.open(redrock_file)
        if coadd_dict is not None:
            self.slit_info = {}
            for key in coadd_dict.keys():
                if isinstance(coadd_dict[key], dict):
                    if '2D_xval' in coadd_dict[key].keys():
                        name = coadd_dict[key]['outfile'].replace('.fits', '')
                        self.slit_info[name] = {}
                        self.slit_info[name]['xval'] = coadd_dict[key][
                            '2D_xval']
                        self.slit_info[name]['Gslit'] = coadd_dict[key][
                            'Gemini_slit']
        else:
            self.slit_info = None

        # names, spectra, zs = [], [], []
        names, spectra = [], []
        if zdict is None:
            self.zdict = OrderedDict()
            load_z = True
        else:
            self.zdict = OrderedDict()
            load_z = False
        for hdu in self.rr_hdul[1:]:
            # Grab the spectrum
            spec_file = hdu.name
            # tmp = XSpectrum1D.from_file(spec_file.replace('FITS','fits'))
            spectra.append(
                XSpectrum1D.from_file(spec_file.replace('FITS', 'fits'),
                                      masking='edges'))
            names.append(spec_file.replace('.FITS', ''))
            # RedRock
            data = hdu.data
            # Init the dict
            if load_z:
                self.zdict[names[-1]] = {}
                self.zdict[names[-1]]['zRR'] = data['z']
                self.zdict[names[-1]]['ZQ'] = -99
                self.zdict[names[-1]]['Comment'] = ''
                self.zdict[names[-1]]['z'] = data['z'][0]
            else:
                self.zdict[names[-1]] = zdict[names[-1]]
        # Collate
        ispec = lspu.collate(spectra, masking='edges')
        # Fill
        ispec.labels = names
        ispec.stypes = ['galaxy'] * ispec.nspec
        # ispec.z = zs  # DO NOT SET THE REDSHIFT HERE

        self.RRi = 0

        self.scale = screen_scale

        # Needed to avoid crash in large spectral files
        rcParams['agg.path.chunksize'] = 20000
        # avoid scientific notation in axes tick labels
        rcParams['axes.formatter.useoffset'] = False

        # Build a widget combining several others
        self.main_widget = QWidget()

        # Status bar
        self.create_status_bar()

        # ZQ window
        self.ZQ_widg = ltgsm.EditBox(-99, 'ZQ', '{:d}')
        self.ZQ_values = [-99, -1, 0, 1, 3, 4]
        # Comment window
        self.comment_widg = ltgsm.EditBox('', 'Comment', '{:s}')

        # Grab the pieces and tie together
        self.pltline_widg = ltgl.PlotLinesWidget(status=self.statusBar,
                                                 screen_scale=self.scale)
        self.pltline_widg.setMaximumWidth(300 * self.scale)

        # Hook the spec widget to Plot Line
        self.spec_widg = ltgsp.ExamineSpecWidget(ispec,
                                                 status=self.statusBar,
                                                 parent=self,
                                                 llist=self.pltline_widg.llist,
                                                 screen_scale=self.scale,
                                                 **kwargs)
        # Reset redshift from spec
        # Auto set line list if spec has proper object type
        if hasattr(self.spec_widg.spec, 'stypes'):
            if self.spec_widg.spec.stypes[
                    self.spec_widg.select].lower() == 'galaxy':
                self.pltline_widg.llist = ltgu.set_llist(
                    'Galaxy', in_dict=self.pltline_widg.llist)
            elif self.spec_widg.spec.stypes[
                    self.spec_widg.select].lower() == 'absorber':
                self.pltline_widg.llist = ltgu.set_llist(
                    'Strong', in_dict=self.pltline_widg.llist)
            self.pltline_widg.llist['Plot'] = True
            idx = self.pltline_widg.lists.index(
                self.pltline_widg.llist['List'])
            self.pltline_widg.llist_widget.setCurrentRow(idx)
        #
        self.pltline_widg.spec_widg = self.spec_widg
        # Multi spec
        self.mspec_widg = ltgsp.MultiSpecWidget(self.spec_widg,
                                                extra_method=self)

        self.spec_widg.canvas.mpl_connect('key_press_event', self.on_key)
        self.spec_widg.canvas.mpl_connect('button_press_event', self.on_click)

        self.prev_select = 0  # Index of previous spectrum;  starts at 0

        # Legend -- specific to this GUI
        self.legend = {}
        self.wv_dict = {'*': 3727., '(': 3950., ')': 4940., '_': 6564.}
        self.legend['zoom'] = self.wv_dict
        self.legend['&'] = 'Toggle through ZQ'
        self.legend[
            '#'] = 'Toggle through zRR (WARNING: will not necessary start at the first one)'
        self.legend['%'] = 'Set z=0 (for stars)'
        self.legend['9'] = 'Skip to next spectrum with ZQ=-99'
        self.legend['x'] = 'Next spectrum'
        for key, value in self.legend.items():
            print(key, value)

        # Extras
        extras = QWidget()
        extras.setMinimumWidth(180 * self.scale)
        extras.setMaximumWidth(280 * self.scale)
        vbox = QVBoxLayout()
        qbtn = QPushButton(self)
        qbtn.setText('Quit')
        qbtn.clicked.connect(self.quit)
        vbox.addWidget(self.pltline_widg)
        vbox.addWidget(self.ZQ_widg)
        vbox.addWidget(self.comment_widg)
        vbox.addWidget(self.mspec_widg)
        vbox.addWidget(qbtn)
        extras.setLayout(vbox)

        # Main window
        hbox = QHBoxLayout()
        hbox.addWidget(self.spec_widg)
        hbox.addWidget(extras)

        self.main_widget.setLayout(hbox)

        # Point MainWindow
        self.setCentralWidget(self.main_widget)
        if unit_test:
            self.quit()

        # Giddy up
        self.run_with_select(save=False)
Example #26
0
        efil = sys.argv[3]

    # Read in Files in differet formats
    if filetype == 'ascii':
        from astropy.io import ascii
        dat = ascii.read(cwd + '/' + filename)
        tab = dat.keys()
        wave = np.array(dat[tab[0]])
        flux = np.array(dat[tab[1]])
        if (len(dat.keys()) >= 3):
            error = dat[tab[2]]
    elif (filetype == 'fits') | (filetype == 'linetools'):
        #Use linetools.io.readspec to read file
        #from linetools.spectra import io as tio
        if (len(sys.argv) > 3):
            sp = XSpectrum1D.from_file(filename, efil=efil)
        else:
            sp = XSpectrum1D.from_file(filename)

        #sp=tio.readspec(filename,inflg=None, efil=efil,**kwargs)
        wave = sp.wavelength.value
        flux = sp.flux.value

        if sp.sig_is_set == False:
            print('Assuiming arbiarbitrary 10% error on flux')
            error = 0.1 * flux
        else:
            error = sp.sig.value

        #from astropy.io import fits
        #file=fits.open(cwd+'/'+filename)
from linetools.spectralline import AbsLine
from linetools.spectra.xspectrum1d import XSpectrum1D
import imp
import warnings

try:
    import seaborn as sns
    sns.set(context="notebook", font_scale=2)
except:
    pass

warnings.filterwarnings('ignore')

#Background info
lt_path = imp.find_module('linetools')[1]
xspec = XSpectrum1D.from_file(lt_path + '/spectra/tests/files/UM184_nF.fits')
names = ['Mg II 2796', 'Mg II 2803', 'Mg I 2852']

#for loop manipulating background info
abslines = []
for trans in names:
    iline = AbsLine(trans)
    clear_CACHE_LLIST = True
    iline.attrib['z'] = .603
    iline.analy['vlim'] = [-3000., 500.] * u.km / u.s
    iline.analy['spec'] = xspec
    abslines.append(iline)

#Wavelengths of interest
MgII2796wrest = 2796.3542699
MgII2803wrest = 2803.5314853
Example #28
0
def fit_lines_sherpa(spec_file,
                     z_init=0.,
                     file_out=None,
                     do_plot=True,
                     monte_carlo=False):
    """Fit an HII region spectrum using Sherpa package.    """

    # from astropy.modeling.fitting import SherpaFitter
    from saba import SherpaFitter
    import matplotlib.pyplot as plt
    from linetools.spectra.xspectrum1d import XSpectrum1D

    # Redshift scale:
    scale_factor = (1. + z_init)

    # Read in the spectrum. **ASSUME VACUUM WAVELENGTHS?**
    mods_spec = XSpectrum1D.from_file(spec_file)

    # Set up a convenient wavelength, flux, error arrays
    wave = mods_spec.wavelength.value
    flux = mods_spec.flux.value
    err = mods_spec.sig.value

    ###### ------ FOR TESTING!! ------
    ### To test this, let's constrain ourselves to only the wavelengths between ~Hbeta, OIII
    # g = np.where((wave >= 4000) & (wave <= 5400.))
    # wave = wave[g]
    # flux = flux[g]
    # err = err[g]

    # Load the data for the lines to be fit. Starts with MANGA line list, modified for MODS.
    line_data = get_linelist()
    # Exclude lines outside of the wavelength coverage.
    keep_lines = np.where(
        (line_data['lambda'] <= np.max(wave) / scale_factor)
        & (line_data['lambda'] >= np.min(wave) / scale_factor))[0]
    keep_line_index = line_data['indx'][keep_lines]

    # For now...debugging. jch
    keep_lines = np.array(len(line_data))
    keep_line_index = line_data['indx'][keep_lines]

    ##### MODEL DEFINITIONS
    # Define initial parameters
    amplitude_init = 0.1 * np.max(mods_spec.flux)
    stddev_init = 1.5

    amplitude_bounds, stddev_bounds, velocity_range = _define_bounds()

    # Calculate the redshift delta
    z_bounds_scale = (velocity_range / c.c.to('km/s').value) * scale_factor
    z_bounds = (z_init - z_bounds_scale, z_init + z_bounds_scale)

    # Define a joint model as the sums of Gaussians for each line
    #  Gaussian for first line:
    j = 0
    wave0 = line_data['lambda'][j]
    line_center = wave0 * scale_factor
    model_name = np.str(line_data['name'][j])
    # Here we use a custom Gaussian class to  fix redshifts together
    joint_model = GaussianEmission(amplitude=amplitude_init,
                                   redshift=z_init,
                                   stddev=stddev_init,
                                   wave0=wave0,
                                   name=model_name)
    # The rest wavelength is not a free parameter:
    joint_model.wave0.fixed = True

    #  Loop through the remaining lines:
    for j in np.arange(1, np.size(line_data)):
        wave0 = line_data['lambda'][j]
        line_center = wave0 * scale_factor
        model_name = np.str(line_data['name'][j])

        joint_model += GaussianEmission(amplitude=amplitude_init,
                                        redshift=z_init,
                                        stddev=stddev_init,
                                        wave0=wave0,
                                        name=model_name)

    # Extract the model names:
    model_names = joint_model.submodel_names

    # Now we have to loop through the same models, applying the bounds:
    for mdlnms in model_names:
        joint_model[mdlnms].bounds['amplitude'] = amplitude_bounds
        joint_model[mdlnms].bounds['redshift'] = z_bounds
        joint_model[mdlnms].bounds['stddev'] = stddev_bounds
        # The rest wavelength is not a free parameter:
        joint_model[mdlnms].wave0.fixed = True

    # TODO Get tied parameters to work.
    # Tie some parameters together, checking that reference lines
    #  are actually covered by the spectrum:
    for k in np.arange(0, np.size(line_data)):
        mdlnm = model_names[k]
        if (line_data['mode'][k] == 't33') & (np.in1d(33, keep_line_index)):
            joint_model[mdlnm].stddev.tied = _tie_sigma_4862
            joint_model[mdlnm].redshift.tied = _tie_redshift_4862
        elif (line_data['mode'][k] == 't35') & (np.in1d(35, keep_line_index)):
            joint_model[mdlnm].stddev.tied = _tie_sigma_5008
            joint_model[mdlnm].redshift.tied = _tie_redshift_5008
        elif (line_data['mode'][k] == 't45') & (np.in1d(45, keep_line_index)):
            joint_model[mdlnm].stddev.tied = _tie_sigma_6585
            joint_model[mdlnm].redshift.tied = _tie_redshift_6585
        elif (line_data['mode'][k] == 't46') & (np.in1d(46, keep_line_index)):
            joint_model[mdlnm].stddev.tied = _tie_sigma_6718
            joint_model[mdlnm].redshift.tied = _tie_redshift_6718

        # 3727/3729 lines:
        if mdlnm == '[OII]3727':
            import IPython
            IPython.embed()

            joint_model[mdlnm].stddev.tied = _tie_sigma_3729
            joint_model[mdlnm].redshift.tied = _tie_redshift_3729

        # Tie amplitudes of doublets
        if (line_data['line'][k] == 'd35') & (np.in1d(35, keep_line_index)):
            joint_model[mdlnm].amplitude.tied = _tie_ampl_5008  # 4959/5008
        if (line_data['line'][k] == 'd45') & (np.in1d(45, keep_line_index)):
            joint_model[mdlnm].amplitude.tied = _tie_ampl_6585  # 6549/6585

    ##### FITTING
    # Sherpa model fitting from SABA package
    sfit = SherpaFitter(statistic='chi2',
                        optimizer='levmar',
                        estmethod='confidence')
    sfit_lm = SherpaFitter(statistic='chi2',
                           optimizer='neldermead',
                           estmethod='confidence')
    sfit_mc = SherpaFitter(statistic='chi2',
                           optimizer='moncar',
                           estmethod='confidence')
    # Do the fit
    sfitted_model = sfit(joint_model, wave, flux, err=err)
    # Refine with different optimizer
    temp_model = sfitted_model.copy()
    sfitted_model = sfit_lm(temp_model, wave, flux, err=err)

    if monte_carlo:
        # If requested, do a second fit with the very slow Monte Carlo approach
        sfitted_model = sfit_mc(sfitted_model.copy(), wave, flux, err=err)

    # Create the fitted flux array
    sfitted_flux = sfitted_model(wave)

    # TODO Get error estimates from Sherpa
    # Work out the errors...
    #sfit.est_config['maxiters']=200
    #sfitted_err = sfit.est_errors(sigma=3)

    # Plot the results
    if do_plot:
        plt.clf()
        plt.plot(wave, flux, drawstyle='steps-mid', linewidth=2)
        plt.plot(wave, sfitted_flux, color='orange', linewidth=2)

    ##### Create integrated fluxes and errors
    # The integration range is over +/-stddev * int_delta_factor
    int_delta_factor = _define_integration_delta()
    output_construct = 0

    for j in np.arange(np.size(line_data)):
        # Calculate integrated fluxes, errors;
        #  -- First test that the lines are in the range covered by data
        if np.in1d(j, keep_lines):
            mean_lambda = line_data[j]['lambda'] * (1. +
                                                    sfitted_model[j].redshift)

            #    deal with blended O II 3727/3729 doublet
            if line_data[j]['name'] == '[OII]3727':
                # Calculate the integrated fluxes and errors
                iflux, ierr = integrate_line_flux(wave,
                                                  flux,
                                                  err,
                                                  mean_lambda,
                                                  sfitted_model[j].stddev *
                                                  int_delta_factor,
                                                  line3727=True)
            elif line_data[j]['name'] == '[OII]3729':
                # pdb.set_trace()
                # For 3729, use the flux derived for 3726
                iflux = output_table['int_flux'][j - 1]
                #iflux = 0.
                # For 3729, use its own error. This is appropriate for the fitted errors of both lines
                crap, ierr = integrate_line_flux(
                    wave, flux, err, mean_lambda,
                    sfitted_model[j].stddev * int_delta_factor)
            else:
                # Calculate the integrated fluxes and errors
                iflux, ierr = integrate_line_flux(
                    wave, flux, err, mean_lambda,
                    sfitted_model[j].stddev * int_delta_factor)

            redshift_out = (sfitted_model[j].redshift)[0]
            sfitted_flux_out = np.sqrt(
                2. *
                np.pi) * sfitted_model[j].amplitude * sfitted_model[j].stddev

            if output_construct == 0:
                # Define and construct the initial table to hold the results
                output_col_names, output_format, output_dtype = _define_output_table(
                )
                output_data = [[line_data[j]['name']], [line_data[j]['ion']],
                               [line_data[j]['lambda']],
                               [line_data[j]['indx']], [line_data[j]['mode']],
                               [mean_lambda],
                               [sfitted_model[j].amplitude.value],
                               [sfitted_model[j].stddev.value], [redshift_out],
                               [sfitted_flux_out], [iflux], [ierr],
                               [iflux / ierr]]
                output_table = Table(output_data,
                                     names=output_col_names,
                                     dtype=output_dtype)

                output_construct = 1
            else:
                output_table.add_row([
                    line_data[j]['name'], line_data[j]['ion'],
                    line_data[j]['lambda'], line_data[j]['indx'],
                    line_data[j]['mode'], mean_lambda,
                    sfitted_model[j].amplitude.value,
                    sfitted_model[j].stddev.value, redshift_out,
                    sfitted_flux_out, iflux, ierr, iflux / ierr
                ])

    # Set the output format of the results table:
    colnames = output_table.colnames
    for j in np.arange(np.size(colnames)):
        output_table[colnames[j]].format = output_format[j]

    # Set up the spectral table:
    spec_table = Table([wave, flux, err, sfitted_flux],
                       names=['wave', 'flux', 'err', 'spec_fit'])

    # Write summary FITS files
    if file_out is None:
        file_base = spec_file.strip('.fits')
    else:
        file_base = file_out

    table_file = file_base + '.HIIFitTable.fits'
    fit_file = file_base + '.HIIFitSpec.fits'

    output_table.write(table_file, overwrite=True)
    spec_table.write(fit_file, overwrite=True)

    return output_table
Example #29
0
    def __init__(self, filename, filetype=False, efil=None, **kwargs):
        """ creates the spectrum object """
        self.filename = filename

        if filetype == False:
            #Take File Extention and try
            tt = os.path.splitext(filename)[1]
            if (tt == 'txt') | (tt == 'dat'):
                filetype = 'ascii'
            else:
                filetype = tt[1:len(tt)]

        # Read in Files in differet formats
        if filetype == 'ascii':
            from astropy.io import ascii
            dat = ascii.read(filename)
            tab = dat.keys()
            wave = np.array(dat[tab[0]])
            flux = np.array(dat[tab[1]])
            if (len(dat.keys()) >= 3):
                error = dat[tab[2]]
            else:
                error = 0. * flux

        elif filetype == 'fits':
            from astropy.io import fits
            file = fits.open(filename)  #(cwd+'/'+filename)
            dat = file[1].data
            tab = dat.names
            wave = np.array(dat['wave'][0])
            flux = np.array(dat['flux'][0])
            if (len(tab) >= 3):
                error = np.array(dat['error'][0])
            else:
                error = 0. * flux
        elif filetype == 'HSLA':
            from astropy.io import fits
            file = fits.open(filename)  #(cwd+'/'+filename)
            dat = file[1].data
            tab = dat.names
            wave = np.array(dat['WAVE'])
            flux = np.array(dat['FLUX'])  #/np.median(np.array(dat['FLUX']))
            if (len(tab) >= 3):
                error = np.array(
                    dat['ERROR'])  #/np.median(np.array(dat['FLUX']))
            else:
                error = 0. * flux

        if filetype == 'xfits':
            from linetools.spectra.xspectrum1d import XSpectrum1D
            sp = XSpectrum1D.from_file(filename)

            wave = sp.wavelength.value
            flux = sp.flux.value
            error = sp.sig.value

        elif filetype == 'p':
            import pickle
            dat = pickle.load(open(filename, "rb"))
            #tab=dat.keys()
            wave = np.array(dat['wave'])
            flux = np.array(dat['flux'])
            if (len(tab) >= 3):
                error = np.array(dat['error'])
            else:
                error = 0. * flux
        elif filetype == 'temp':
            from astropy.io import fits
            file = fits.open(filename)  #(cwd+'/'+filename)
            #a=fits.open(path+'spec_knotA.fits')

            wave = file[2].data
            flux = file[0].data
            error = file[1].data
        #Use linetools.io.readspec to read file
        elif filetype == 'linetools':
            from linetools.spectra import io as tio
            sp = tio.readspec(filename, inflg=None, efil=efil, **kwargs)
            wave = sp.wavelength.value
            flux = sp.flux.value

            if sp.sig_is_set == False:
                print('Assuiming arbiarbitrary 10% error on flux')
                error = 0.1 * flux
            else:
                error = sp.sig.value

        self.wave = wave
        self.flux = flux
        self.error = error
        self.wrest = wave * (1. + 0.)
        self.zabs = 0.
Example #30
0
def test_co_kludges():
    spec = XSpectrum1D.from_file(data_path('SDSSJ220248.31+123656.3.fits'), masking='edges')
    assert spec.co.size == 4599
    #ax.get_xaxis().get_major_formatter().set_useOffset(False)
    plt.ylim(0., 1.1)
    plt.show()
    plt.close()


ism = LineList('ISM')

abslin = AbsLine(1215.670 * u.AA, z=2.0, linelist=ism)
#abslin = AbsLine(1215.670*u.AA, linelist=ism)

abslin.attrib['N'] = 10**14. / u.cm**2  # log N
abslin.attrib['b'] = 25. * u.km / u.s
abslin.attrib['z'] = 2.0

xspec = XSpectrum1D.from_file(
    resource_filename('linetools', '/spectra/tests/files/UM184_nF.fits'))
#xspec = lsio.readspec(resource_filename('linetools','/spectra/tests/files/UM184_nF.fits'))
#Load
abslin.analy['spec'] = xspec
#lsio.readspec(resource_filename('linetools','/spectra/tests/files/UM184_nF.fits'))#('../../linetools/spectra/tests/files/UM184_nF.fits')

#Generate
vmodel = abslin.generate_voigt()

# Plot
plt_line(vmodel)

abslin.attrib['N'] = 10**17.5 / u.cm**2
abslin.attrib['b'] = 20. * u.km / u.s

wave = np.linspace(3644, 3650, 100) * u.AA
Example #32
0
def test_unmask():
    spec = XSpectrum1D.from_file(data_path('UM184_nF.fits'))
    assert np.sum(spec.data['wave'].mask) > 0
    spec.unmask()
    assert np.sum(spec.data['wave'].mask) == 0
Example #33
0
def full_coadd(uves_table=None,
               outputbase=None,
               wavelength_range=None,
               airtovac=True):
    """full_coadd(uves_table=None, outputbase=None,
                    wavelength_range=None, airtovac=True):

    Combine multiple UVES exposures UVES into a single spectrum, weighting by the inverse variance of the input data. Creates a single spectrum covering the full wavelength range of the individual exposures.

    Note: no guarantee the fluxes will be continuous if there are issues with the flux calibration of individual datasets.
    """

    import numpy as np
    import astropy.units as u
    from astropy.table import Table
    from linetools.spectra.xspectrum1d import XSpectrum1D

    if uves_table == None:
        #   There is no input table; let's create one.
        uves_table = uves_log()

    # Create minmax wavelengths for filename, wavelength array
    wave_minmax = []
    wave_minmax.append(np.min(uves_table['WAVELMIN']) * 10.)
    wave_minmax.append(np.max(uves_table['WAVELMAX']) * 10.)
    wave_minmax = np.around(wave_minmax)

    if wavelength_range == None:
        wavelength_range = wave_minmax

    # Store the string to make the filename:
    file_wave = '{0:0.0f}.{1:0.0f}'.format(wavelength_range[0],
                                           wavelength_range[1])

    # TODO: Allow for linear-space regular array
    # Create the wavelength array. For now uniform in log space
    log_steps = True
    if log_steps:
        wavelength_range = np.log10(wavelength_range)
        wavelength_step = 2.e-6  # log-space step
        out_wave = np.arange(wavelength_range[0],
                             wavelength_range[1],
                             wavelength_step,
                             dtype=np.float64)
        out_wave = 10.**out_wave

    # Create the holder arrays
    out_inv_variance = np.zeros(np.size(out_wave), dtype=np.float32)
    out_weighted_flux = np.zeros(np.size(out_wave), dtype=np.float32)

    # Loop over files:
    for j in np.arange(np.size(uves_table)):
        # Filename:
        specfile = uves_table[j]['fitsName']
        print('{0}: {1}'.format(j, specfile))

        # Load the spectrum with XSpectrum1D:
        inspec = XSpectrum1D.from_file(specfile)
        inspec.meta['airvac'] = 'air'

        # Unless user requests, we transform to vacuum.
        if airtovac == True:
            inspec.airtovac()

        # Check for sig = 0:
        badErrors = (inspec.sig == 0)
        inspec.flux[badErrors] = np.nan
        inspec.sig[badErrors] = np.nan
        inspec.ivar[badErrors] = np.nan

        # Interpolate the UVES fluxes onto the wavelength grid using the XSpectrum1D functionality
        grid_spec = inspec.rebin(out_wave * u.angstrom,
                                 do_sig=True,
                                 grow_bad_sig=True)

        # Add new fluxes, errors into output weighting, flux arrays
        # The inverse variance is stored in the XSpectrum1D class

        out_inv_variance += grid_spec.ivar.value
        out_weighted_flux += grid_spec.flux.value * grid_spec.ivar.value

    #####
    # Calculate the final output weighted mean flux and error by taking out the weighting
    out_flux = out_weighted_flux / out_inv_variance
    out_err = np.sqrt(1. / out_inv_variance)

    # Book-keeping: set up filename
    if outputbase == None:
        # If there is no base for the filenames, use the object name.
        outputbase = uves_table[0]['OBJECT']
    # Create final filename
    outputfilename = "{0}.uves.{1}.fits".format(outputbase, file_wave)

    # Set up the output table
    outputtable = Table([out_wave, out_flux, out_err],
                        names=['wave', 'flux', 'err'])

    # Load the spectrum in the standard way to get the units right:
    inspec = Table.read(uves_table[0]['fitsName'])
    # Assign units
    outputtable['wave'].unit = inspec['WAVE'].unit
    outputtable['flux'].unit = inspec['FLUX'].unit
    outputtable['err'].unit = inspec['ERR'].unit

    # TODO: Get the header information to save
    # The header:
    outputtable.meta = inspec.meta
    outputtable.meta['NCOMBINE'] = np.size(uves_table)
    outputtable.meta['HISTORY'] = 'Coadd of {0}'.format(
        uves_table[0]['fitsName'])
    for j in np.arange(1, np.size(uves_table)):
        outputtable.meta['HISTORY'] += ', {0}'.format(
            uves_table[j]['fitsName'])

    # TODO: Switch back to the XSpectrum1D format?
    # # Put the results into the XSpectrum1D format
    #out_spec = XSpectrum1D.from_tuple((out_wave*u.angstrom,out_flux,out_err),
    #                                   verbose=False)
    #out_spec.write(outputfilename)

    # Write the output
    outputtable.write(outputfilename, overwrite=True)
    print('Wrote ' + outputfilename + '.')
Example #34
0

def get_position(iden):
    targ_ra_hr = name[48:50]
    targ_ra_min = name[50:52]
    targ_dec_hr = name[53:55]
    targ_dec_min = name[55:57]
    targ_RA = targ_ra_hr + ':' + targ_ra_min
    targ_DEC = targ_dec_hr + ':' + targ_dec_min
    return targ_RA, targ_DEC


# Now let's plot all the spectra and save each figure
fname = glob('/Users/ryan/Desktop/keck_spectra/2017mar5/*F.fits')
for name in fname:
    sp = XSpectrum1D.from_file(name)
    targ_coord = get_position(name[42:-5])
    targ_coord = get_position(name)

    dtype = [('RA', 'U5'), ('DEC', 'U5'), ('zq', float), ('z', float),
             ('b', float), ('logM', float), ('QSO_mag', float),
             ('Sod_line', float)]
    prop = numpy.genfromtxt(
        '/Users/ryan/Desktop/keck_spectra/2017mar5/target_list.dat',
        usecols=(0, 1, 2, 3, 4, 5, 6, 7),
        dtype=dtype)

    # Match the target with its properties by using RA and DEC cooords
    w = numpy.logical_and(targ_coord[0] == prop['RA'],
                          targ_coord[1] == prop['DEC'])
    data = prop[w]