Ejemplo n.º 1
0
    def update_model(self):
        '''Update absorption model '''
        from linetools.analysis import voigt as lav

        if len(self.abssys_widg.all_abssys) == 0:
            self.lls_model = None
            self.spec_widg.model = None
            return
        '''
        # Regenerate (in case we have switched between multiple spectra)
        if self.spec_widg.spec.nspec > 1:
            self.full_model = XSpectrum1D.from_tuple((
                self.spec_widg.spec.wavelength,np.ones(len(self.spec_widg.spec.wavelength))))
        '''
        # use finer wavelength array to resolve absorption features.
        wa = self.full_model.wavelength
        # Angstroms
        # should really make this a constant velocity width array instead.
        if not self.skip_wveval:
            wa1 = np.arange(wa[0].value, wa[-1].value, self.dw) * wa.unit
        else:
            wa1 = wa
        all_tau_model = igmlls.tau_multi_lls(wa1,
                                             self.abssys_widg.all_abssys,
                                             skip_wveval=self.skip_wveval)

        # Loop on forest lines
        for forest in self.all_forest:
            tau_Lyman = lav.voigt_from_abslines(wa1,
                                                forest.lines,
                                                ret='tau',
                                                skip_wveval=self.skip_wveval)
            all_tau_model += tau_Lyman

        # Flux and smooth
        flux = np.exp(-1. * all_tau_model)
        if self.smooth > 0:
            if not self.skip_wveval:
                mult = np.median(np.diff(wa.value)) / self.dw
                flux = lsc.convolve_psf(flux, self.smooth * mult)
            else:
                flux = lsc.convolve_psf(flux, self.smooth)
        if not self.skip_wveval:
            self.lls_model = np.interp(wa.value, wa1.value, flux)
        else:
            self.lls_model = flux

        # Finish
        self.full_model.flux = self.lls_model * self.continuum.flux
        # Over-absorbed
        try:
            self.spec_widg.bad_model = np.where((self.lls_model < 0.7) & (
                self.full_model.flux <
                (self.spec_widg.spec.flux - self.spec_widg.spec.sig * 1.5)))[0]
        except:
            pass
        # Model
        self.spec_widg.model = self.full_model
Ejemplo n.º 2
0
    def update_model(self):
        '''Update absorption model '''
        from linetools.analysis import voigt as lav

        if len(self.abssys_widg.all_abssys) == 0:
            self.lls_model = None
            self.spec_widg.model = None
            return
        # use finer wavelength array to resolve absorption features.
        wa = self.full_model.dispersion
        # Angstroms
        # should really make this a constant velocity width array instead.
        if not self.skip_wveval:
            wa1 = np.arange(wa[0].value, wa[-1].value, self.dw) * wa.unit
        else:
            wa1 = wa
        all_tau_model = igmlls.tau_multi_lls(wa1,
                                             self.abssys_widg.all_abssys,
                                             skip_wveval=self.skip_wveval)
        #QtCore.pyqtRemoveInputHook()
        #import pdb; pdb.set_trace()
        #QtCore.pyqtRestoreInputHook()

        # Loop on forest lines
        for forest in self.all_forest:
            tau_Lyman = lav.voigt_from_abslines(wa1,
                                                forest.lines,
                                                ret='tau',
                                                skip_wveval=self.skip_wveval)
            all_tau_model += tau_Lyman

        # Flux and smooth
        flux = np.exp(-1. * all_tau_model)
        if self.smooth > 0:
            if not self.skip_wveval:
                mult = np.median(np.diff(wa.value)) / self.dw
                flux = lsc.convolve_psf(flux, self.smooth * mult)
            else:
                flux = lsc.convolve_psf(flux, self.smooth)
        if not self.skip_wveval:
            self.lls_model = np.interp(wa.value, wa1.value, flux)
        else:
            self.lls_model = flux

        # Finish
        self.full_model.flux = self.lls_model * self.continuum.flux
        # Over-absorbed
        self.spec_widg.bad_model = np.where((self.lls_model < 0.7) & (
            self.full_model.flux <
            (self.spec_widg.spec.flux - self.spec_widg.spec.sig * 1.5)))[0]
        # Model
        self.spec_widg.model = self.full_model
Ejemplo n.º 3
0
    def update_model(self):
        '''Update absorption model '''
        from linetools.analysis import voigt as lav

        if len(self.abssys_widg.all_abssys) == 0:
            self.lls_model = None
            self.spec_widg.model = None
            return
        # use finer wavelength array to resolve absorption features.
        wa = self.full_model.dispersion
        # Angstroms
        # should really make this a constant velocity width array instead.
        if not self.skip_wveval:
            wa1 = np.arange(wa[0].value, wa[-1].value, self.dw) * wa.unit
        else:
            wa1 = wa
        all_tau_model = igmlls.tau_multi_lls(wa1,
           self.abssys_widg.all_abssys, skip_wveval=self.skip_wveval)
        #QtCore.pyqtRemoveInputHook()
        #import pdb; pdb.set_trace()
        #QtCore.pyqtRestoreInputHook()

        # Loop on forest lines
        for forest in self.all_forest:
            tau_Lyman = lav.voigt_from_abslines(wa1, forest.lines,
                ret='tau', skip_wveval=self.skip_wveval)
            all_tau_model += tau_Lyman

        # Flux and smooth
        flux = np.exp(-1. * all_tau_model)
        if self.smooth > 0:
            if not self.skip_wveval:
                mult = np.median(np.diff(wa.value)) / self.dw
                flux = lsc.convolve_psf(flux, self.smooth * mult)
            else:
                flux = lsc.convolve_psf(flux, self.smooth)
        if not self.skip_wveval:
            self.lls_model = np.interp(wa.value, wa1.value, flux)
        else:
            self.lls_model = flux

        # Finish
        self.full_model.flux = self.lls_model * self.continuum.flux
        # Over-absorbed
        self.spec_widg.bad_model = np.where( (self.lls_model < 0.7) &
            (self.full_model.flux < (self.spec_widg.spec.flux-
                self.spec_widg.spec.sig*1.5)))[0]
        # Model
        self.spec_widg.model = self.full_model
Ejemplo n.º 4
0
    def auto_plls(self,x,y):
        '''Automatically fit a pLLS
        Parameters:
        ----------
        x,y: floats
          x,y values in the GUI
        '''
        spec = self.spec_widg.spec # For convenience
        if len(self.abssys_widg.all_abssys) > 0:
            conti= self.full_model
        else:
            conti= self.continuum
        # Generate toy LLS from click
        ximn = np.argmin(np.abs(spec.dispersion.value-x))
        NHI = 17.29 + np.log10(-1.*np.log(y/conti.flux.value[ximn]))
        #QtCore.pyqtRemoveInputHook()
        #xdb.set_trace()
        #QtCore.pyqtRestoreInputHook()

        #print('NHI={:g}'.format(NHI))
        z = x/(911.7)-1
        plls = LLSSystem((0*u.deg,0*u.deg),z,[-300.,300]*u.km/u.s,NHI=NHI)
        plls.bval = 20*u.km/u.s
        plls.fill_lls_lines(bval=20*u.km/u.s, do_analysis=0)

        # wrest, Tau model, flux
        wrest = spec.dispersion/(1+plls.zabs)
        tau = igmlls.tau_multi_lls(spec.dispersion,[plls])
        emtau = np.exp(-1. * tau)
        lls_flux = lsc.convolve_psf(emtau, 3.)
#xdb.xplot(wrest, lls_flux)

        # zmin (next highest LLS or zem)
        if len(self.abssys_widg.all_abssys) != 0:
            zlls = [lls.zabs for lls in self.abssys_widg.all_abssys if lls.zabs > plls.zabs]
            if len(zlls) == 0:
                zmin = self.zqso+0.01
            else:
                zmin = np.min(np.array(zlls)) - 0.01
        else:
            zmin = self.zqso+0.01

        # Pixels for analysis and rolling
        # NEED TO CUT ON X-Shooter ARM
        apix = np.where( (wrest > 914*u.AA) & #(spec.dispersion<5600*u.AA) &
                        (spec.dispersion<(1+zmin)*1026.*u.AA))[0] # Might go to Lyb
        nroll = (np.argmin(np.abs(spec.dispersion-(911.7*u.AA*(1+zmin))))- # Extra 0.01 for bad z
                   np.argmin(np.abs(spec.dispersion-(911.7*u.AA*(1+plls.zabs)))))
        # Require nroll does not exceed length of spectrum
        if np.max(apix)+nroll > len(spec.dispersion):
            nroll = len(spec.dispersion) - np.max(apix) - 1
        gdpix = np.arange(np.min(apix)-nroll,np.max(apix)+nroll+1)
        roll_flux = np.concatenate([np.ones(nroll),lls_flux[apix], np.ones(nroll)])
        roll_msk = roll_flux < 0.7

        # Generate data arrays
        wave_pad = spec.dispersion[gdpix]
            #QtCore.pyqtRemoveInputHook()
            #xdb.set_trace()
            #QtCore.pyqtRestoreInputHook()
        flux_pad = spec.flux[gdpix]
        sig_pad = spec.sig[gdpix]
        if len(self.abssys_widg.all_abssys) > 0:
            conti_pad = conti.flux[gdpix]
        else:
            conti_pad = conti.flux[gdpix]

        # Generate matricies
        flux_matrix = np.zeros((len(roll_flux),nroll))
        sig_matrix = np.zeros((len(roll_flux),nroll))
        conti_matrix = np.zeros((len(roll_flux),nroll))

        roll_matrix = np.zeros((len(roll_flux),nroll))
        mask_matrix = np.zeros((len(roll_flux),nroll))
        for kk in range(nroll):
            roll_matrix[:,kk] = np.roll(roll_flux,kk)
            mask_matrix[:,kk] = np.roll(roll_msk,kk)
            flux_matrix[:,kk] = flux_pad
            conti_matrix[:,kk] = conti_pad
            sig_matrix[:,kk] = sig_pad

        # Model -- Multiply by continuum
        model = roll_matrix * conti_matrix

        # Condition
        idx = np.where( (model < (flux_matrix-sig_matrix*1.5)) & (mask_matrix==True))
        bad_matrix = np.zeros((len(roll_flux),nroll))
        bad_matrix[idx] = 1

        # Sum on offsets and get redshift
        bad = np.sum(bad_matrix,0)
        ibest = np.argmin(bad)
        zbest = spec.dispersion[ibest+ximn]/(911.7*u.AA)-1 # Quantity

        # Add pLLS?
        if bad[ibest] < 10:
            #QtCore.pyqtRemoveInputHook()
            #xdb.set_trace()
            #QtCore.pyqtRestoreInputHook()
            self.add_LLS(zbest.value, bval=20.*u.km/u.s, NHI=NHI)
        else:
            print('No viable pLLS found with our criteria!')
Ejemplo n.º 5
0
    def auto_plls(self, x, y):
        """Automatically fit a pLLS

        Parameters:
        ----------
        x,y: floats
          x,y values in the GUI
        """
        spec = self.spec_widg.spec  # For convenience
        if len(self.abssys_widg.all_abssys) > 0:
            conti = self.full_model
        else:
            conti = self.continuum
        # Generate toy LLS from click
        ximn = np.argmin(np.abs(spec.wavelength.value - x))
        if y > conti.flux.value[ximn]:
            print("Type F below the continuum fool!")
            return
        NHI = 17.29 + np.log10(-1. * np.log(y / conti.flux.value[ximn]))
        #QtCore.pyqtRemoveInputHook()
        #pdb.set_trace()
        #QtCore.pyqtRestoreInputHook()

        #print('NHI={:g}'.format(NHI))
        z = x / (911.7) - 1
        plls = LLSSystem((0 * u.deg, 0 * u.deg),
                         z, [-300., 300] * u.km / u.s,
                         NHI=NHI)
        plls.bval = 20 * u.km / u.s
        plls.fill_lls_lines(bval=20 * u.km / u.s, do_analysis=0)

        # wrest, Tau model, flux
        wrest = spec.wavelength / (1 + plls.zabs)

        tau = igmlls.tau_multi_lls(spec.wavelength, [plls])
        emtau = np.exp(-1. * tau)
        lls_flux = lsc.convolve_psf(emtau, 3.)
        #xdb.xplot(wrest, lls_flux)

        # zmin (next highest LLS or zem)
        if len(self.abssys_widg.all_abssys) != 0:
            zlls = [
                lls.zabs for lls in self.abssys_widg.all_abssys
                if lls.zabs > plls.zabs
            ]
            if len(zlls) == 0:
                zmin = self.zqso + 0.05
            else:
                zmin = np.min(np.array(zlls)) - 0.01
        else:
            zmin = self.zqso + 0.05

        # Pixels for analysis and rolling
        # NEED TO CUT ON X-Shooter ARM
        apix = np.where((wrest > 914 * u.AA) &  #(spec.wavelength<5600*u.AA) &
                        (spec.wavelength < (1 + zmin) * 1026. * u.AA))[
                            0]  # Might go to Lyb
        nroll = (
            np.argmin(np.abs(spec.wavelength -
                             (911.7 * u.AA *
                              (1 + zmin)))) -  # Extra 0.01 for bad z
            np.argmin(
                np.abs(spec.wavelength - (911.7 * u.AA * (1 + plls.zabs)))))
        # Require nroll does not exceed length of spectrum
        if np.max(apix) + nroll > len(spec.wavelength):
            nroll = len(spec.wavelength) - np.max(apix) - 1
        gdpix = np.arange(np.min(apix) - nroll, np.max(apix) + nroll + 1)
        roll_flux = np.concatenate(
            [np.ones(nroll), lls_flux[apix],
             np.ones(nroll)])
        roll_msk = roll_flux < 0.7

        # Generate data arrays
        wave_pad = spec.wavelength[gdpix]
        #QtCore.pyqtRemoveInputHook()
        #xdb.set_trace()
        #QtCore.pyqtRestoreInputHook()
        flux_pad = spec.flux[gdpix]
        sig_pad = spec.sig[gdpix]
        if len(self.abssys_widg.all_abssys) > 0:
            conti_pad = conti.flux[gdpix]
        else:
            conti_pad = conti.flux[gdpix]

        # Generate matricies
        flux_matrix = np.zeros((len(roll_flux), nroll))
        sig_matrix = np.zeros((len(roll_flux), nroll))
        conti_matrix = np.zeros((len(roll_flux), nroll))

        roll_matrix = np.zeros((len(roll_flux), nroll))
        mask_matrix = np.zeros((len(roll_flux), nroll))
        for kk in range(nroll):
            roll_matrix[:, kk] = np.roll(roll_flux, kk)
            mask_matrix[:, kk] = np.roll(roll_msk, kk)
            flux_matrix[:, kk] = flux_pad
            conti_matrix[:, kk] = conti_pad
            sig_matrix[:, kk] = sig_pad

        # Model -- Multiply by continuum
        model = roll_matrix * conti_matrix

        # Condition
        idx = np.where((model < (flux_matrix - sig_matrix * 1.5))
                       & (mask_matrix == True))
        bad_matrix = np.zeros((len(roll_flux), nroll))
        bad_matrix[idx] = 1

        # Sum on offsets and get redshift
        bad = np.sum(bad_matrix, 0)
        ibest = np.argmin(bad)
        zbest = spec.wavelength[ibest + ximn] / (911.7 * u.AA) - 1  # Quantity

        # Add pLLS?
        if bad[ibest] < 10:
            #QtCore.pyqtRemoveInputHook()
            #xdb.set_trace()
            #QtCore.pyqtRestoreInputHook()
            self.add_LLS(zbest.value, bval=20. * u.km / u.s, NHI=NHI)
        else:
            print('No viable pLLS found with our criteria!')