Example #1
0
def read_spec(ispec, second_file=None):
    '''Parse spectrum out of the input
    Parameters:
    -----------
    ispec: Spectrum1D, str, or tuple

    Returns:
    -----------
    spec: XSpectrum1D 
    spec_file: str
    '''
    from specutils import Spectrum1D
    from linetools.spectra.utils import XSpectrum1D
    #
    if isinstance(ispec,basestring):
        spec_fil = ispec
        spec = lsi.readspec(spec_fil)
        # Second file?
        if not second_file is None:
            spec2 = lsi.readspec(second_file)
            if spec2.sig is None:
                spec2.sig = np.zeros(spec.flux.size)
            # Scale for convenience of plotting
            xper1 = xstats.basic.perc(spec.flux, per=0.9)
            xper2 = xstats.basic.perc(spec2.flux, per=0.9)
            scl = xper1[1]/xper2[1]
            # Stitch together
            wave3 = np.append(spec.dispersion, spec2.dispersion)
            flux3 = np.append(spec.flux, spec2.flux*scl)
            sig3 = np.append(spec.sig, spec2.sig*scl)
            spec3 = Spectrum1D.from_array(wave3, flux3, uncertainty=StdDevUncertainty(sig3))
            # Overwrite
            spec = spec3
            spec.filename = spec_fil
    elif isinstance(ispec,Spectrum1D):
        spec = ispec # Assuming Spectrum1D
        spec_fil = spec.filename # Grab from Spectrum1D 
    elif isinstance(ispec,tuple):
        # Units
        try:
            wv_unit = ispec[0].unit
        except AttributeError:
            wv_unit = u.AA
        uwave = u.Quantity(ispec[0], unit=wv_unit)
        # Generate
        if len(ispec) == 2: # wave, flux
            spec = XSpectrum1D.from_array(uwave, u.Quantity(ispec[1])) 
        else:
            spec = XSpectrum1D.from_array(uwave, u.Quantity(ispec[1]), 
                uncertainty=StdDevUncertainty(ispec[2]))
        #
        spec_fil = 'none'
        spec.filename = spec_fil
    else:
        raise ValueError('Bad input to read_spec')

    # Return
    return spec, spec_fil
Example #2
0
def voigt_model(spec, line, Npix=None, flg_ret=1):
    """Generates a Voigt model from a line or list of lines

    Parameters:
    ------------
        spec: wave array or Spectrum
        line: Abs_Line, List of Abs_line, or array of parameters
        flg_ret : int (1)  Byte-wise Flag for return
          1: vmodel
          2: tau

    ToDo:
        1.  May need to more finely sample the wavelength array

    JXP 01 Nov 2014
    """
    # Imports
    import copy
    from linetools.spectra.utils import XSpectrum1D
    from astropy.nddata import StdDevUncertainty
    from xastropy.spec.lines_utils import AbsLine

    # Spectrum input
    if isinstance(spec,np.ndarray):  # Standard wavelength array
        vmodel = XSpectrum1D.from_array(spec, np.ones(len(spec)), 
        	uncertainty=StdDevUncertainty(np.zeros(len(spec))))
    elif isinstance(spec,Spectrum1D):
        vmodel = copy.deepcopy(spec)
    else:
        raise ValueError('voigt_model: Unknown input')
    #xdb.set_trace()
        
    # Line input
    if isinstance(line,AbsLine):  # Single line as a Abs_Line Class
        par = [0*i for i in range(6)] # Dummy list
        par[0] = line.attrib['N']
        par[1] = line.z
        par[2] = line.attrib['b']
        par[3] = line.wrest
        par[4] = line.atomic['fval']
        par[5] = line.atomic['gamma']
    elif isinstance(line,list):
        if isinstance(line[0],AbsLine):  # List of Abs_Line
            tau = np.zeros(len(vmodel.flux))
            for iline in line:
                tau += voigt_model(vmodel.dispersion, iline, Npix=None, flg_ret=2) 
        else:
            par = line  # Single line as a vector
    else: 
        raise ValueError('voigt: Unknown type for voigt line')

    # tau
    if 'tau' not in locals():
        #xdb.set_trace()
        cold = 10.0**par[0] / u.cm / u.cm
        zp1=par[1]+1.0

        wv=par[3].to(u.cm) #*1.0e-8
        nujk = (const.c / wv).to(u.Hz)
        dnu = ((par[2]*u.km/u.s) / wv).to('Hz')
        avoigt = ((par[5]/u.s)/( 4 * np.pi * dnu)).to(u.dimensionless_unscaled)

        uvoigt = ( ((const.c / (vmodel.dispersion/zp1)) - nujk) / dnu).to(u.dimensionless_unscaled)
        '''
        wv=par[3].to(u.cm) #*1.0e-8
        bl=((par[2]*u.km/u.s)*wv/const.c).to(u.cm) # 2.99792458E5
        a= ((par[5]/u.s)*wv*wv/( 4 * np.pi * const.c.to('cm/s') * bl)).to(u.dimensionless_unscaled)
        cns=wv*wv*par[4]/(bl*2.002134602291006E12) * u.cm

        # Converting to Voigt units
        cne=cold*cns
        ww=(vmodel.dispersion.to('cm'))/zp1
        v=wv*ww*((1.0/ww)-(1.0/wv))/bl
        '''

        # Voigt
        cne = 0.01497 * cold * par[4] * u.cm * u.cm * u.Hz
        tau = cne * voigtking(uvoigt,avoigt) / (np.sqrt(np.pi) * dnu)

    # Flux
    if vmodel.unit is None:
        try:
            vmodel.flux = (np.exp(-1.0*tau)).value
        except AttributeError:
            vmodel.flux = np.exp(-1.0*tau)
    else:
        vmodel.flux = np.exp(-1.0*tau).to(vmodel.unit)

    # Convolve
    if Npix is not None:
        vmodel.gauss_smooth(npix=Npix)
    
    # Return
    ret_val = []
    if flg_ret % 2 == 1: ret_val.append(vmodel)
    if flg_ret % 4 >= 2: ret_val.append(tau)
    #xdb.set_trace()
    if len(ret_val) == 1: ret_val = ret_val[0]
    return ret_val