Beispiel #1
0
    def fitsol_fit(self):
        """Perform a fit to the line identifications
        """
        # Calculate the dispersion
        # disp = (ids[-1] - ids[0]) / (tcent[idx_str[-1]] - tcent[idx_str[0]])
        # final_fit = fitting.iterative_fitting(censpec, tcent, idx_str, ids,
        #                                       llist, disp, verbose=False,
        #                                       n_first=2, n_final=self._fitdict["polyorder"])
        ord = self._fitdict["polyorder"]
        gd_det = np.where(
            (self._lineflg == 1) |
            (self._lineflg
             == 2))  # Use the user IDs or acceptable auto IDs only!
        # Check if there are enough points to perform a fit
        if gd_det[0].size < ord + 1:
            msg = "Polynomial order must be >= number of line IDs\n" +\
                  "Polynomial order = {0:d}, Number of line IDs = {1:d}".format(ord, gd_det[0].size)
            self.update_infobox(message=msg, yesno=False)
        else:
            # Start by performing a basic fit
            xpix = self._detns[gd_det] / self._fitdict["scale"]
            ylam = self._lineids[gd_det]
            self._fitdict["coeff"] = np.polyfit(xpix, ylam, ord)
            bdisp = self.fitsol_deriv(
                self.specdata.size /
                2)  # Angstroms/pixel at the centre of the spectrum
            # Then try a detailed fit
            try:
                final_fit = fitting.iterative_fitting(
                    self.specdata,
                    self._detns,
                    gd_det[0],
                    self._lineids[gd_det[0]],
                    self._line_lists,
                    bdisp,
                    verbose=False,
                    n_first=min(2, self._fitdict["polyorder"]),
                    match_toler=self.par['match_toler'],
                    func=self.par['func'],
                    n_final=self._fitdict["polyorder"],
                    sigrej_first=self.par['sigrej_first'],
                    sigrej_final=self.par['sigrej_final'])
                # Update the fitdict
                for key in final_fit:
                    self._fitdict[key] = final_fit[key]

            except TypeError:
                # Just stick use the basic fit
                self._fitdict["fitc"] = None
Beispiel #2
0
    def get_results(self):
        """Perform the final wavelength calibration

        Using the line IDs perform the final fit according
        to the wavelength calibration parameters set by the
        user. This routine must be called after the user has
        manually identified all lines.

        Returns:
            wvcalib (dict): Dict of wavelength calibration solutions
        """
        wvcalib = {}
        # Check that a result exists:
        if self._fitdict['coeff'] is None:
            wvcalib[str(self._slit)] = None
        else:
            # Perform an initial fit to the user IDs
            self.fitsol_fit()
            # Now perform a detailed fit
            gd_det = np.where((self._lineflg == 1) | (self._lineflg == 2))[0]
            bdisp = self.fitsol_deriv(
                self.specdata.size /
                2)  # Angstroms/pixel at the centre of the spectrum
            try:
                n_final = wvutils.parse_param(self.par, 'n_final', self._slit)
                final_fit = fitting.iterative_fitting(
                    self.specdata,
                    self._detns,
                    gd_det,
                    self._lineids[gd_det],
                    self._line_lists,
                    bdisp,
                    verbose=False,
                    n_first=self.par['n_first'],
                    match_toler=self.par['match_toler'],
                    func=self.par['func'],
                    n_final=n_final,
                    sigrej_first=self.par['sigrej_first'],
                    sigrej_final=self.par['sigrej_final'])
            except TypeError:
                wvcalib = None
                #wvcalib[str(self._slit)] = None
            else:
                wvcalib = copy.deepcopy(final_fit)
                #wvcalib[str(self._slit)] = copy.deepcopy(final_fit)
        return wvcalib
Beispiel #3
0
def reid_in_steps(slit, instr, plot_fil=None, IDtol=1., subpix=None):
    if instr == '600':
        wv_dict, template = load_600()
        fwhm = 4.
        n_first = 2
        nsnippet = 2
    elif instr == '300':
        wv_dict, template = load_300()
        fwhm = 8.
        n_first = 3
        nsnippet = 2
    else:
        pdb.set_trace()
    # Template
    nwwv = template['wave'].data
    nwspec = template['flux'].data

    # Full snippet (padded as need be)
    tspec, mspec, mwv, targ_wv, targ_x, targ_y = target_lines(wv_dict,
                                                              slit,
                                                              nwwv,
                                                              nwspec,
                                                              fwhm=fwhm,
                                                              subpix=subpix)
    # Loop on snippets
    nsub = tspec.size // nsnippet
    sv_det, sv_IDs = [], []
    for kk in range(nsnippet):
        # Construct
        i0 = nsub * kk
        i1 = min(nsub * (kk + 1), tspec.size)
        tsnippet = tspec[i0:i1]
        msnippet = mspec[i0:i1]
        mwvsnippet = mwv[i0:i1]
        # Run reidentify
        detections, spec_cont_sub, patt_dict = autoid.reidentify(
            tsnippet,
            msnippet,
            mwvsnippet,
            llist,
            1,
            debug_xcorr=False,
            nonlinear_counts=55000.,
            debug_reid=True,  # verbose=True,
            match_toler=2.5,
            cc_thresh=0.1,
            fwhm=fwhm)
        # Deal with IDs
        sv_det.append(i0 + detections)
        sv_IDs.append(patt_dict['IDs'])

    # Collate and proceed
    dets = np.concatenate(sv_det)
    IDs = np.concatenate(sv_IDs)
    #
    i1 = np.where(mwv > 0.)[0][0]
    dwv = mwv[i1 + 1] - mwv[i1]
    #
    gd_det = np.where(IDs > 0.)[0]
    final_fit = fitting.iterative_fitting(tspec,
                                          dets,
                                          gd_det,
                                          IDs[gd_det],
                                          llist,
                                          dwv,
                                          verbose=True,
                                          plot_fil=plot_fil,
                                          n_first=n_first)
    return final_fit
Beispiel #4
0
def do_it_all(slit, instr, plot_fil=None, IDtol=1., subpix=None):
    if instr == '600':
        wv_dict, template = load_600()
        fwhm = 4.
        n_order = 3
        n_first = 2
    elif instr == '300':
        wv_dict, template = load_300()
        fwhm = 8.
        n_order = 3
        n_first = 3
    else:
        pdb.set_trace()
    nwwv = template['wave'].data
    nwspec = template['flux'].data
    # Snippet
    tspec, mspec, mwv, targ_wv, targ_x, targ_y = target_lines(wv_dict,
                                                              slit,
                                                              nwwv,
                                                              nwspec,
                                                              fwhm=fwhm,
                                                              subpix=subpix)
    # Find new lines
    all_tcent, all_ecent, cut_tcent, icut, arc_cont_sub = wvutils.arc_lines_from_spec(
        tspec, fwhm=fwhm, debug=True)
    # Grab initial guess
    func = 'legendre'
    sigrej_first = 3.
    fmin, fmax = 0., 1.
    xfit = np.arange(mwv.size)
    yfit = mwv
    initial_mask = (mwv > targ_wv.min()) & (mwv < targ_wv.max())
    i1 = np.where(initial_mask)[0][0]
    disp = mwv[i1 + 1] - mwv[i1]
    #
    mask, fit = utils.robust_polyfit(xfit,
                                     yfit,
                                     n_order,
                                     function=func,
                                     sigma=sigrej_first,
                                     initialmask=~initial_mask,
                                     minx=fmin,
                                     maxx=fmax,
                                     verbose=True)  # , weights=wfit)
    rms_ang = utils.calc_fit_rms(xfit[mask == 0],
                                 yfit[mask == 0],
                                 fit,
                                 func,
                                 minx=fmin,
                                 maxx=fmax)
    #                                     weights=wfit[mask == 0])
    rms_pix = rms_ang / disp
    print("Initial fit: {};  RMS = {}".format(fit, rms_pix))
    # Target grid
    targ_grid = np.outer(targ_wv, np.ones(all_tcent.size))
    # Check the loss
    loss = loss_func(fit[0:2], all_tcent, targ_grid, targ_y, fit, 2)
    # Bounds
    bounds = [[fit[0] - 50., fit[0] + 50], [fit[1] * 0.9, fit[1] * 1.1]]
    #for ifit in fit[2:]:
    #    bounds.append([np.abs(ifit)*-2, np.abs(ifit)*2])
    # Differential evolution
    #diff_result = fitme(bounds, all_tcent, targ_grid, targ_y)
    diff_result = fitme(bounds, all_tcent, targ_grid, targ_y, fit.copy())
    new_fit = fit.copy()
    new_fit[:len(bounds)] = diff_result.x
    loss = loss_func(new_fit[0:len(bounds)],
                     all_tcent,
                     targ_grid,
                     targ_y,
                     fit,
                     len(bounds),
                     verbose=True)
    print("Refined fit: {}".format(diff_result.x))
    # Now cut on saturation
    all_tcent, all_ecent, cut_tcent, icut, arc_cont_sub = wvutils.arc_lines_from_spec(
        tspec, fwhm=fwhm, nonlinear_counts=55000)
    #debug=True)
    final_guess = utils.func_val(new_fit,
                                 all_tcent,
                                 func,
                                 minx=fmin,
                                 maxx=fmax)
    # Match to line list
    IDs = []
    dwv = mwv[i1 + 1] - mwv[i1]
    lmask = np.zeros(final_guess.size, dtype=bool)
    for kk, iwv in enumerate(final_guess):
        imin = np.argmin(np.abs(iwv - llist['wave']))
        if np.abs(iwv - llist['wave'][imin]) < dwv * IDtol:
            lmask[kk] = True
            IDs.append(llist['wave'][imin])
    print("IDs: {}".format(IDs))
    # Final fit
    final_fit = fitting.iterative_fitting(tspec,
                                          all_tcent,
                                          np.where(lmask)[0],
                                          np.array(IDs),
                                          llist,
                                          dwv,
                                          verbose=True,
                                          plot_fil=plot_fil,
                                          n_first=n_first)
    # Return
    return final_fit