Exemple #1
0
    def invert(self, domain=None, coeff=None, deg=None):
        """
        Utility to return a traceset modeling x vs. y instead of y vs. x
        """
        if domain is None:
            domain = [self.wmin, self.wmax]
        ispec = np.arange(self.nspec)  # Doing for all spectra
        if coeff is None:
            coeff = self.ycoeff  # doing y-wavelength map
        ytmp = list()
        for ii in ispec:
            fit_dict = dufits.mk_fit_dict(coeff[ii, :], coeff.shape[1],
                                          'legendre', domain[0], domain[1])
            xtmp = np.array((domain[0], domain[1]))
            yfit = dufits.func_val(xtmp, fit_dict)
            ytmp.append(yfit)

        ymin = np.min(ytmp)
        ymax = np.max(ytmp)
        x = np.linspace(domain[0], domain[1], 1000)
        if deg is None:
            deg = self.ncoeff + 2

        #- Now get the coefficients for inverse mapping
        c = np.zeros((coeff.shape[0], deg + 1))
        for ii in ispec:
            fit_dict = dufits.mk_fit_dict(coeff[ii, :], coeff.shape,
                                          'legendre', domain[0], domain[1])
            y = dufits.func_val(x, fit_dict)
            yy = 2.0 * (y - ymin) / (ymax - ymin) - 1.0
            c[ii] = legfit(yy, x, deg)

        return c, ymin, ymax
Exemple #2
0
    def invert(self, domain=None, coeff=None, deg=None):
        """
        Utility to return a traceset modeling x vs. y instead of y vs. x
        """
        if domain is None:
            domain=[self.wmin,self.wmax]
        ispec=np.arange(self.nspec) # Doing for all spectra
        if coeff is None:
            coeff=self.ycoeff # doing y-wavelength map
        ytmp=list()
        for ii in ispec:
                
            fit_dict=dufits.mk_fit_dict(coeff[ii,:],coeff.shape[1],'legendre',domain[0],domain[1])
            xtmp=np.array((domain[0],domain[1]))
            yfit = dufits.func_val(xtmp, fit_dict)
            ytmp.append(yfit)

        ymin = np.min(ytmp)
        ymax = np.max(ytmp)
        x = np.linspace(domain[0], domain[1], 1000)
        if deg is None:
            deg = self.ncoeff+2

        #- Now get the coefficients for inverse mapping    
        c = np.zeros((coeff.shape[0], deg+1))
        for ii in ispec:
            fit_dict=dufits.mk_fit_dict(coeff[ii,:],coeff.shape,'legendre',domain[0],domain[1])
            y = dufits.func_val(x,fit_dict)
            yy = 2.0 * (y-ymin) / (ymax-ymin) - 1.0
            c[ii] = legfit(yy, x, deg)
            
        return c,ymin,ymax
Exemple #3
0
    def y(self,ispec=None,wavelength=None):
        """
        returns CCD y centroids for the spectra
        ispec can be None, scalar or a vector
        wavelength can be a vector but not allowing None #- similar as in specter.psf.PSF.y
        """
        if wavelength is None:
            raise ValueError, "PSF.y requires wavelength 1D vector"
            
        wavelength = np.asarray(wavelength)
        if ispec is None:
            ispec=np.arange(self.nspec)
            y=list()
            for ii in ispec:
                fit_dicty=dufits.mk_fit_dict(self.ycoeff[ii],self.ncoeff,'legendre',self.wmin,self.wmax)
                yfit=dufits.func_val(wavelength,fit_dicty)
                y.append(yfit) 
            return np.array(y)

        if isinstance(ispec,(np.ndarray,list,tuple)):
            y=list()
            for ii in ispec:
                fit_dicty=dufits.mk_fit_dict(self.ycoeff[ii],self.ncoeff,'legendre',self.wmin,self.wmax)
                yfit=dufits.func_val(wavelength,fit_dicty)
                y.append(yfit)
            return np.array(y)
    
        if isinstance(ispec,int): # int ispec
            fit_dicty=dufits.mk_fit_dict(self.ycoeff[ispec],self.ncoeff,'legendre',self.wmin,self.wmax)
            y=dufits.func_val(wavelength,fit_dicty)
            return np.array(y)
Exemple #4
0
    def wavelength(self, ispec=None, y=None):
        """
        returns wavelength evaluated at y
        """
        if y is None:
            y = np.arange(0, self.npix_y)
        if ispec is None:
            ispec = np.arange(self.nspec)
        c = self.icoeff
        ymin = self.ymin
        ymax = self.ymax

        if isinstance(ispec, numbers.Integral):
            new_dict = dufits.mk_fit_dict(c[ispec, :], c[ispec, :].shape,
                                          'legendre', ymin, ymax)
            wfit = dufits.func_val(y, new_dict)
            return wfit
        else:
            ww = list()
            for ii in ispec:
                new_dict = dufits.mk_fit_dict(c[ii, :], c[ii, :].shape,
                                              'legendre', ymin, ymax)
                wfit = dufits.func_val(y, new_dict)
                ww.append(wfit)
        return np.array(ww)
Exemple #5
0
    def y(self,ispec=None,wavelength=None):
        """
        returns CCD y centroids for the spectra
        ispec can be None, scalar or a vector
        wavelength can be a vector but not allowing None #- similar as in specter.psf.PSF.y
        """
        if wavelength is None:
            raise ValueError("PSF.y requires wavelength 1D vector")
            
        wavelength = np.asarray(wavelength)
        if ispec is None:
            ispec=np.arange(self.nspec)
            y=list()
            for ii in ispec:
                fit_dicty=dufits.mk_fit_dict(self.ycoeff[ii],self.ncoeff,'legendre',self.wmin,self.wmax)
                yfit=dufits.func_val(wavelength,fit_dicty)
                y.append(yfit) 
            return np.array(y)

        if isinstance(ispec,(np.ndarray,list,tuple)):
            y=list()
            for ii in ispec:
                fit_dicty=dufits.mk_fit_dict(self.ycoeff[ii],self.ncoeff,'legendre',self.wmin,self.wmax)
                yfit=dufits.func_val(wavelength,fit_dicty)
                y.append(yfit)
            return np.array(y)

        if isinstance(ispec, numbers.Integral): # int ispec
            fit_dicty=dufits.mk_fit_dict(self.ycoeff[ispec],self.ncoeff,'legendre',self.wmin,self.wmax)
            y=dufits.func_val(wavelength,fit_dicty)
            return np.array(y)
Exemple #6
0
    def test_wavelengths(self):
        if self.data_unavailable:
            self.skipTest("Failed to download test data.")
        # Read flat
        flat_hdu = fits.open(self.testflat)
        header = flat_hdu[0].header
        flat = flat_hdu[0].data
        ny = flat.shape[0]
        # Find fibers (necessary)
        xpk, ypos, cut = desiboot.find_fiber_peaks(flat)
        # Trace
        xset, xerr = desiboot.trace_crude_init(flat, xpk, ypos)
        xfit, fdicts = desiboot.fit_traces(xset, xerr)
        # Test fiber_gauss_old for coverage
        gauss = desiboot.fiber_gauss_old(flat, xfit, xerr)
        # Gaussian
        gauss = desiboot.fiber_gauss(flat, xfit, xerr)
        # Read arc
        arc_hdu = fits.open(self.testarc)
        arc = arc_hdu[0].data
        arc_ivar = np.ones(arc.shape)
        # Extract arc spectra (one per fiber)
        all_spec = desiboot.extract_sngfibers_gaussianpsf(arc, arc_ivar, xfit, gauss)
        # Line list
        camera = header['CAMERA']
        llist = desiboot.load_arcline_list(camera)
        dlamb, gd_lines = desiboot.load_gdarc_lines(camera,llist)
        #
        all_wv_soln = []
        for ii in range(1):
            spec = all_spec[:,ii]
            # Find Lines
            pixpk, flux = desiboot.find_arc_lines(spec)
            id_dict = {"pixpk":pixpk,"flux":flux}
            # Match a set of 5 gd_lines to detected lines
            desiboot.id_arc_lines_using_triplets(id_dict,gd_lines,dlamb)
            # Now the rest
            desiboot.id_remainder(id_dict, llist, deg=3)
            # Final fit wave vs. pix too
            final_fit, mask = dufits.iter_fit(np.array(id_dict['id_wave']),
                                              np.array(id_dict['id_pix']),
                                              'polynomial', 3, xmin=0., xmax=1.)
            rms = np.sqrt(np.mean((dufits.func_val(
                np.array(id_dict['id_wave'])[mask==0], final_fit)-
                                   np.array(id_dict['id_pix'])[mask==0])**2))
            final_fit_pix,mask2 = dufits.iter_fit(np.array(id_dict['id_pix']),
                                                  np.array(id_dict['id_wave']),
                                                  'legendre',4, niter=5)
            # Save
            id_dict['final_fit'] = final_fit
            id_dict['rms'] = rms
            id_dict['final_fit_pix'] = final_fit_pix
            id_dict['wave_min'] = dufits.func_val(0, final_fit_pix)
            id_dict['wave_max'] = dufits.func_val(ny-1, final_fit_pix)
            id_dict['mask'] = mask
            all_wv_soln.append(id_dict)

        self.assertLess(all_wv_soln[0]['rms'], 0.25)
Exemple #7
0
    def x(self, ispec=None, wavelength=None):
        """
        returns CCD x centroids for the spectra
        ispec can be None, scalar or a vector
        wavelength can be None or a vector
        """
        if wavelength is None:
            #- ispec = None -> all the spectra
            if ispec is None:
                ispec = np.arange(self.nspec)
                x = list()
                #x=np.array((len(ispec),len(wavelength)))
                for ii in ispec:
                    wave = self.wavelength(ii)
                    fit_dictx = dufits.mk_fit_dict(self.xcoeff[ii],
                                                   self.ncoeff, 'legendre',
                                                   self.wmin, self.wmax)
                    xfit = dufits.func_val(wave, fit_dictx)
                    x.append(xfit)
                return np.array(x)

            if isinstance(ispec, (np.ndarray, list, tuple)):
                x = list()
                for ii in ispec:
                    wave = self.wavelength(ii)
                    fit_dictx = dufits.mk_fit_dict(self.xcoeff[ii],
                                                   self.ncoeff, 'legendre',
                                                   self.wmin, self.wmax)
                    xfit = dufits.func_val(wave, fit_dictx)
                    x.append(xfit)
                return np.array(x)

            else:  # int ispec
                wave = self.wavelength(ispec)
                fit_dictx = dufits.mk_fit_dict(self.xcoeff[ispec], self.ncoeff,
                                               'legendre', self.wmin,
                                               self.wmax)
                x = dufits.func_val(wave, fit_dictx)
                return np.array(x)

        #- wavelength not None but a scalar or 1D-vector here and below
        wavelength = np.asarray(wavelength)
        if isinstance(ispec, numbers.Integral):
            fit_dictx = dufits.mk_fit_dict(self.xcoeff[ispec], self.ncoeff,
                                           'legendre', self.wmin, self.wmax)
            x = dufits.func_val(wavelength, fit_dictx)
            return np.array(x)
        if ispec is None:
            ispec = np.arange(self.nspec)
        x = list()
        for ii in ispec:  #- for a None or a np.ndarray or anything that can be iterated case
            fit_dictx = dufits.mk_fit_dict(self.xcoeff[ii], self.ncoeff,
                                           'legendre', self.wmin, self.wmax)
            xfit = dufits.func_val(wavelength, fit_dictx)
            x.append(xfit)
        return np.array(x)
Exemple #8
0
    def x(self,ispec=None,wavelength=None):
        """
        returns CCD x centroids for the spectra
        ispec can be None, scalar or a vector
        wavelength can be None or a vector
        """
        if wavelength is None:
            #- ispec = None -> all the spectra
            if ispec is None:
                ispec=np.arange(self.nspec)
                wavelength=self.wavelength
                x=list()
                for ii in ispec:
                    wave=self.wavelength(ii)
                    fit_dictx=dufits.mk_fit_dict(self.xcoeff[ii],self.ncoeff,'legendre',self.wmin,self.wmax)
                    xfit=dufits.func_val(wave,fit_dictx)
                    x.append(xfit)
                return np.array(x)

            if isinstance(ispec,(np.ndarray,list,tuple)):
                x=list()
                for ii in ispec:
                    wave=self.wavelength(ii)
                    fit_dictx=dufits.mk_fit_dict(self.xcoeff[ii],self.ncoeff,'legendre',self.wmin,self.wmax)
                    xfit=dufits.func_val(wave,fit_dictx)
                    x.append(xfit)
                return np.array(x)
    
            else: # int ispec
                wave=self.wavelength(ispec)
                fit_dictx=dufits.mk_fit_dict(self.xcoeff[ispec],self.ncoeff,'legendre',self.wmin,self.wmax)
                x=dufits.func_val(wave,fit_dictx)
                return np.array(x)
        
        #- wavelength not None but a scalar or 1D-vector here and below
        wavelength = np.asarray(wavelength)
        if isinstance(ispec,int):
            fit_dictx=dufits.mk_fit_dict(self.xcoeff[ispec],self.ncoeff,'legendre',self.wmin,self.wmax)
            x=dufits.func_val(wavelength,fit_dictx)
            return np.array(x)
        if ispec is None:
            ispec=np.arange(self.nspec) 
        x=list()
        for ii in ispec: #- for a None or a np.ndarray or anything that can be iterated case
            fit_dictx=dufits.mk_fit_dict(self.xcoeff[ii],self.ncoeff,'legendre',self.wmin,self.wmax)
            xfit=dufits.func_val(wavelength,fit_dictx)
            x.append(xfit)
        return np.array(x)
Exemple #9
0
    def wavelength(self,ispec=None,y=None):
        """
        returns wavelength evaluated at y
        """
        if y is None:
            y=np.arange(0,self.npix_y)
        if ispec is None:
            ispec=np.arange(self.nspec)
        #- First get the inversion map y --> wavelength dictionary
        c,ymin,ymax=self.invert(coeff=self.ycoeff) 

 
        if isinstance(ispec,int):
            new_dict=dufits.mk_fit_dict(c[ispec,:],c[ispec,:].shape,'legendre',ymin,ymax)
            wfit=dufits.func_val(y,new_dict)
            return wfit
        else:
            ww=list()
            for ii in ispec:
                new_dict=dufits.mk_fit_dict(c[ii,:],c[ii,:].shape,'legendre',ymin,ymax)
                wfit=dufits.func_val(y,new_dict)
                ww.append(wfit)
            
        return np.array(ww)
Exemple #10
0
    def __init__(self, mu=None, sigma=None, wdict=None, waves=None, ndiag=9):
        self.__ndiag = ndiag
        if ndiag & 0x1 == 0:
            raise ValueError("Need odd numbered diagonals, got %d" % ndiag)

        def _binIntegral(x, mu=None, sigma=None):
            """
            x: bin boundaries vector (self.__ndiag,)
            mu: means vector of shape[nwave,1]
            sigma: sigmas of shape[nwave,1]
            """
            nvecs = 1
            if sigma is not None:
                nvecs = sigma.shape[0]
            if mu is None:
                mu = np.zeros((nvecs, 1))
            if sigma is None:
                sigma = np.ones(mu.shape) * 0.5
            sx = (np.tile(x, (mu.shape[0], 1)) - mu) / (sigma * np.sqrt(2))
            return 0.5 * (np.abs(np.diff(scipy.special.erf(sx))))

        mnone = mu is None
        snone = sigma is None
        dnone = wdict is None
        wnone = waves is None
        if snone:
            if wnone or dnone:
                raise ValueError(
                    'Cannot initialize Resolution data need sigma or wdict and waves'
                )
            else:
                from desiutil import funcfits as dufits
                sigma = dufits.func_val(waves, wdict)
        nwave = len(sigma)
        s = sigma.reshape((nwave, 1))
        bins = np.arange(ndiag, 0, -1)
        bins = bins - (bins[0] + bins[-1]) / 2.0
        x = np.concatenate([bins + 0.5, bins[-1:] - 0.5])
        self.offsets = bins
        rdata = _binIntegral(x, mu=mu, sigma=s).T

        scipy.sparse.dia_matrix.__init__(self, (rdata, self.offsets),
                                         (nwave, nwave))
Exemple #11
0
    def test_wavelengths(self):
        if self.data_unavailable:
            self.skipTest("Failed to download test data.")
        # Read flat
        flat_hdu = fits.open(self.testflat)
        header = flat_hdu[0].header
        flat = flat_hdu[0].data
        ny = flat.shape[0]
        # Find fibers (necessary)
        xpk, ypos, cut = desiboot.find_fiber_peaks(flat)
        # Trace
        xset, xerr = desiboot.trace_crude_init(flat, xpk, ypos)
        xfit, fdicts = desiboot.fit_traces(xset, xerr)
        # Test fiber_gauss_old for coverage
        gauss = desiboot.fiber_gauss_old(flat, xfit, xerr)
        # Gaussian
        gauss = desiboot.fiber_gauss(flat, xfit, xerr)
        # Read arc
        arc_hdu = fits.open(self.testarc)
        arc = arc_hdu[0].data
        arc_ivar = np.ones(arc.shape)
        # Extract arc spectra (one per fiber)
        all_spec = desiboot.extract_sngfibers_gaussianpsf(
            arc, arc_ivar, xfit, gauss)
        # Line list
        camera = header['CAMERA']
        llist = desiboot.load_arcline_list(camera)
        dlamb, gd_lines = desiboot.load_gdarc_lines(camera, llist)
        #
        all_wv_soln = []
        for ii in range(1):
            spec = all_spec[:, ii]
            # Find Lines
            pixpk, flux = desiboot.find_arc_lines(spec)
            id_dict = {"pixpk": pixpk, "flux": flux}
            # Match a set of 5 gd_lines to detected lines
            desiboot.id_arc_lines_using_triplets(id_dict, gd_lines, dlamb)
            # Now the rest
            desiboot.id_remainder(id_dict, llist, deg=3)
            # Final fit wave vs. pix too
            final_fit, mask = dufits.iter_fit(np.array(id_dict['id_wave']),
                                              np.array(id_dict['id_pix']),
                                              'polynomial',
                                              3,
                                              xmin=0.,
                                              xmax=1.)
            rms = np.sqrt(
                np.mean((dufits.func_val(
                    np.array(id_dict['id_wave'])[mask == 0], final_fit) -
                         np.array(id_dict['id_pix'])[mask == 0])**2))
            final_fit_pix, mask2 = dufits.iter_fit(np.array(id_dict['id_pix']),
                                                   np.array(
                                                       id_dict['id_wave']),
                                                   'legendre',
                                                   4,
                                                   niter=5)
            # Save
            id_dict['final_fit'] = final_fit
            id_dict['rms'] = rms
            id_dict['final_fit_pix'] = final_fit_pix
            id_dict['wave_min'] = dufits.func_val(0, final_fit_pix)
            id_dict['wave_max'] = dufits.func_val(ny - 1, final_fit_pix)
            id_dict['mask'] = mask
            all_wv_soln.append(id_dict)

        self.assertLess(all_wv_soln[0]['rms'], 0.25)
Exemple #12
0
def main(args):

    log=get_logger()

    log.info("Starting")

    if args.triplet_matching :
        log.warning("triplet_matching option deprecated, this algorithm is now used for all cases")


    lamps=None
    if args.lamps :
        lamps=np.array(args.lamps.split(","))
        log.info("Using lamps = %s"%str(lamps))
    else :
        log.info("Using default set of lamps")

    if args.fiberflat is not None and args.contfile is None :
        args.contfile=args.fiberflat
        log.warning("Please use --contfile instead of --fiberflat")
    

    if (args.psffile is None) and (args.contfile is None):
        raise IOError("Must provide either a PSF file or a contfile")

    # Start QA
    try:
        pp = PdfPages(args.qafile)
    except ValueError:
        QA = False
    else:
        QA = True

    contfile_header = None

    if args.psffile is None:
        ###########
        # Read continuum
        cont_hdu = fits.open(args.contfile)
        contfile_header = cont_hdu[0].header
        header = cont_hdu[0].header
        if len(cont_hdu)>=3 :
            cont = cont_hdu[0].data*(cont_hdu[1].data>0)*(cont_hdu[2].data==0)
        else :
            cont = cont_hdu[0].data
            log.warning("found only %d HDU in cont, do not use ivar"%len(cont_hdu))
        ny = cont.shape[0]

        ###########
        # Find fibers
        log.info("Finding the fibers")
        xpk, ypos, cut = desiboot.find_fiber_peaks(cont)
        if QA:
            desiboot.qa_fiber_peaks(xpk, cut, pp)

        # Test?
        if args.test:
            log.warning("cutting down fibers for testing..")
            #xpk = xpk[0:100]
            xpk = xpk[0:50]
            #xpk = xpk[0:5]

        ###########
        # Trace the fiber cont spectra
        log.info("Tracing the continuum spectra")
        # Crude first
        log.info("Crudely..")
        xset, xerr = desiboot.trace_crude_init(cont,xpk,ypos)
        # Polynomial fits
        log.info("Fitting the traces")
        xfit, fdicts = desiboot.fit_traces(xset,xerr)
        # QA
        if QA:
            desiboot.qa_fiber_Dx(xfit, fdicts, pp)

        ###########
        # Model the PSF with Gaussian
        log.info("Modeling the PSF with a Gaussian, be patient..")
        gauss = desiboot.fiber_gauss(cont,xfit,xerr)
        if QA:
            desiboot.qa_fiber_gauss(gauss, pp)
        XCOEFF = None
    else: # Load PSF file and generate trace info
        log.warning("Not tracing the continuum.  Using the PSF file.")
        psf_hdu = fits.open(args.psffile)
        psf_head = psf_hdu[0].header
        # Gaussians
        gauss = psf_hdu[2].data
        # Traces
        WAVEMIN = psf_head['WAVEMIN']
        WAVEMAX = psf_head['WAVEMAX']
        XCOEFF = psf_hdu[0].data
        xfit = None
        fdicts = None

    arc_header = None

    # ARCS
    if not args.trace_only:

        ###########
        # Read arc
        log.info("Reading arc")
        arc_hdu = fits.open(args.arcfile)
        arc_header = arc_hdu[0].header
        if len(arc_hdu)>=3 :
            # set to zero ivar of masked pixels, force positive or null ivar
            arc_ivar = arc_hdu[1].data*(arc_hdu[2].data==0)*(arc_hdu[1].data>0)
            # and mask pixels below -5 sigma (cures unmasked dead columns in sims.)
            arc_ivar *= (arc_hdu[0].data*np.sqrt(arc_hdu[1].data)>-5.)
            # set to zero pixel values with null ivar
            arc = arc_hdu[0].data*(arc_ivar>0)
        else :
            arc = arc_hdu[0].data
            arc_ivar = np.ones(arc.shape)
            log.warning("found only %d HDU in arc, do not use ivar"%len(arc_hdu))

        header = arc_hdu[0].header
        ny = arc.shape[0]

        #####################################
        # Extract arc spectra (one per fiber)
        log.info("Extracting arcs")
        if xfit is None:
            wv_array = np.linspace(WAVEMIN, WAVEMAX, num=arc.shape[0])
            nfiber = XCOEFF.shape[0]
            ncoeff = XCOEFF.shape[1]
            xfit = np.zeros((arc.shape[0], nfiber))
            # Generate a fit_dict
            fit_dict = dufits.mk_fit_dict(XCOEFF[:,0], ncoeff, 'legendre', WAVEMIN, WAVEMAX)
            for ii in range(nfiber):
                fit_dict['coeff'] = XCOEFF[ii,:]
                xfit[:,ii] = dufits.func_val(wv_array, fit_dict)

        all_spec = desiboot.extract_sngfibers_gaussianpsf(arc, arc_ivar, xfit, gauss)

        ############################
        # Line list
        camera = header['CAMERA'].lower()
        log.info("Loading line list")
        llist = desiboot.load_arcline_list(camera,vacuum=True,lamps=lamps)
        dlamb, gd_lines = desiboot.load_gdarc_lines(camera,llist,vacuum=True,lamps=lamps,good_lines_filename=args.good_lines)

        #####################################
        # Loop to solve for wavelengths
        all_wv_soln = []
        all_dlamb = []
        debug=False

        id_dict_of_fibers=[]
        # first loop to find arc lines and do a first matching
        for ii in range(all_spec.shape[1]):
            spec = all_spec[:,ii]

            id_dict={}
            id_dict["fiber"]  = ii
            id_dict["status"] = "none"
            id_dict['id_pix'] = []
            id_dict['id_idx'] = []
            id_dict['id_wave'] = []

            pixpk, flux = desiboot.find_arc_lines(spec)

            id_dict["pixpk"] =  pixpk
            id_dict["flux"]  =  flux

            try:
                desiboot.id_arc_lines_using_triplets(id_dict, gd_lines, dlamb,ntrack=args.ntrack,nmax=args.nmax,toler=args.toler)
            except :
                log.warning(sys.exc_info())
                log.warning("fiber {:d} ID_ARC failed".format(ii))
                id_dict['status'] = "failed"
                id_dict_of_fibers.append(id_dict)
                continue

            # Add lines
            if len(id_dict['pixpk'])>len(id_dict['id_pix']) :
                desiboot.id_remainder(id_dict, llist, deg=args.legendre_degree)
            log.info("Fiber #{:d} n_match={:d} n_detec={:d}".format(ii,len(id_dict['id_pix']),len(id_dict['pixpk'])))
            # Save
            id_dict_of_fibers.append(id_dict)




        # now record the list of waves identified in several fibers
        matched_lines=np.array([])
        for ii in range(all_spec.shape[1]):
            matched_lines = np.append(matched_lines,id_dict_of_fibers[ii]['id_wave'])
        matched_lines = np.unique(matched_lines)
        number_of_detections = []
        for line in matched_lines :
            ndet=0
            for ii in range(all_spec.shape[1]):
                if np.sum(id_dict_of_fibers[ii]['id_wave']==line) >0 :
                    ndet += 1
            print(line,"ndet=",ndet)
            number_of_detections.append(ndet)

        # choose which lines are ok and
        # ok if 5 detections (coincidental error very low)
        min_number_of_detections=min(5,all_spec.shape[1])
        number_of_detections=np.array(number_of_detections)
        good_matched_lines = matched_lines[number_of_detections>=min_number_of_detections]
        bad_matched_lines  = matched_lines[number_of_detections<min_number_of_detections]

        log.info("good matched lines = {:s}".format(str(good_matched_lines)))
        log.info("bad matched lines  = {:s}".format(str(bad_matched_lines)))


        # loop again on all fibers
        for ii in range(all_spec.shape[1]):
            spec = all_spec[:,ii]

            id_dict = id_dict_of_fibers[ii]
            n_matched_lines=len(id_dict['id_wave'])
            n_detected_lines=len(id_dict['pixpk'])

            # did we find any bad line for this fiber?
            n_bad = np.intersect1d(id_dict['id_wave'],bad_matched_lines).size
            # how many good lines did we find
            n_good = np.intersect1d(id_dict['id_wave'],good_matched_lines).size


            if id_dict['status']=="ok" and ( n_bad>0 or (n_good < good_matched_lines.size-1 and n_good<30) ) and  n_good<40 :

                log.info("Try to refit fiber {:d} with n_bad={:d} and n_good={:d} when n_good_all={:d} n_detec={:d}".format(ii,n_bad,n_good,good_matched_lines.size,n_detected_lines))

                try:
                    desiboot.id_arc_lines_using_triplets(id_dict,  good_matched_lines, dlamb,ntrack=args.ntrack,nmax=args.nmax)
                except:
                    log.warning(sys.exc_info())
                    log.warning("ID_ARC failed on fiber {:d}".format(ii))
                    id_dict["status"]="failed"

                if id_dict['status']=="ok" and  len(id_dict['pixpk'])>len(id_dict['id_pix']) :
                    desiboot.id_remainder(id_dict, llist, deg=args.legendre_degree)
            else :
                log.info("Do not refit fiber {:d} with n_bad={:d} and n_good={:d} when n_good_all={:d} n_detec={:d}".format(ii,n_bad,n_good,good_matched_lines.size,n_detected_lines))

            if id_dict['status'] != 'ok':
                all_wv_soln.append(id_dict)
                all_dlamb.append(0.)
                log.warning("Fiber #{:d} failed, no final fit".format(ii))
                continue



            # Final fit wave vs. pix too
            id_wave=np.array(id_dict['id_wave'])
            id_pix=np.array(id_dict['id_pix'])

            deg=max(1,min(args.legendre_degree,id_wave.size-2))

            final_fit, mask = dufits.iter_fit(id_wave,id_pix, 'polynomial', deg, xmin=0., xmax=1., sig_rej=3.)
            rms = np.sqrt(np.mean((dufits.func_val(id_wave[mask==0], final_fit)-id_pix[mask==0])**2))
            final_fit_pix,mask2 = dufits.iter_fit(id_pix[mask==0],id_wave[mask==0],'legendre',deg , sig_rej=100000000.)
            rms_pix = np.sqrt(np.mean((dufits.func_val(id_pix[mask==0], final_fit_pix)-id_wave[mask==0])**2))

            # Append
            wave = dufits.func_val(np.arange(spec.size),final_fit_pix)
            idlamb = np.median(np.abs(wave-np.roll(wave,1)))
            all_dlamb.append(idlamb)
            # Save
            id_dict['final_fit'] = final_fit
            id_dict['rms'] = rms
            id_dict['final_fit_pix'] = final_fit_pix
            id_dict['wave_min'] = dufits.func_val(0,final_fit_pix)
            id_dict['wave_max'] = dufits.func_val(ny-1,final_fit_pix)
            id_dict['mask'] = mask

            log.info("Fiber #{:d} final fit rms(y->wave) = {:g} A ; rms(wave->y) = {:g} pix ; nlines = {:d}".format(ii,rms,rms_pix,id_pix.size))

            all_wv_soln.append(id_dict)

        if QA:
            desiboot.qa_arc_spec(all_spec, all_wv_soln, pp)
            desiboot.qa_fiber_arcrms(all_wv_soln, pp)
            desiboot.qa_fiber_dlamb(all_spec, all_wv_soln, pp)
    else:
        all_wv_soln = None

    ###########
    # Write PSF file
    log.info("Writing PSF file")
    desiboot.write_psf(args.outfile, xfit, fdicts, gauss, all_wv_soln, legendre_deg=args.legendre_degree , without_arc=args.trace_only,
                       XCOEFF=XCOEFF,fiberflat_header=contfile_header,arc_header=arc_header)
    log.info("Successfully wrote {:s}".format(args.outfile))

    if ( not args.trace_only ) and args.out_line_list :
         log.info("Writing list of lines found in {:s}".format(args.out_line_list))
         desiboot.write_line_list(args.out_line_list,all_wv_soln,llist)
         log.info("Successfully wrote {:s}".format(args.out_line_list))

    ###########
    # All done
    if QA:
        log.info("Successfully wrote {:s}".format(args.qafile))
        pp.close()
    log.info("end")

    return
Exemple #13
0
 def wdisp(self,ispec,wave):
     #- wave: scalar or vector, ispec: scalar integer TODO: make useful for other permutations
     if hasattr(self,'wcoeff'):
         new_dict=dufits.mk_fit_dict(self.wcoeff[ispec],self.wcoeff.shape[1],'legendre',self.wmin,self.wmax)
         wsigma=dufits.func_val(wave,new_dict)
         return wsigma