def FitWavelength(self, data_original, telluric, tol=0.05, linestrength=0.98, oversampling=4, fitorder=3,
                      numiters=10):
        """
        Function to fine-tune the wavelength solution of a generated model
          It does so by looking for telluric lines in both the
          data and the telluric model. For each line, it finds the shift needed
          to make them line up, and then fits a function to that fit over the
          full wavelength range of the data. Wavelength calibration MUST already
          be very close for this algorithm to succeed! NOT MEANT TO BE CALLED
          DIRECTLY BY THE USER!
        """
        logging.debug("Fitting Wavelength")
        old = []
        new = []
        #Find lines in the telluric model
        linelist = FittingUtilities.FindLines(telluric, debug=self.debug, tol=linestrength)
        if len(linelist) < fitorder:
            fit = lambda x: x
            mean = 0.0
            return fit, mean
        linelist = telluric.x[linelist]

        if self.debug and self.debug_level >= 5:
            logfilename = "FitWavelength.log"
            logging.debug("Outputting data and telluric model to %s" % logfilename)
            np.savetxt(logfilename,
                       np.transpose((data_original.x, data_original.y, data_original.cont, data_original.err)),
                       fmt="%.8f")
            infile = open(logfilename, "a")
            infile.write("\n\n\n\n\n")
            np.savetxt(infile, np.transpose((telluric.x, telluric.y)), fmt="%.8f")
            infile.close()

        #Interpolate to finer spacing
        xgrid = np.linspace(data_original.x[0], data_original.x[-1], data_original.x.size * oversampling)
        data = FittingUtilities.RebinData(data_original, xgrid)
        model = FittingUtilities.RebinData(telluric, xgrid)

        #Begin loop over the lines
        numlines = 0
        model_lines = []
        dx = []
        for line in linelist:
            if line - tol > data.x[0] and line + tol < data.x[-1]:
                numlines += 1

                #Find line center in the model
                left = np.searchsorted(model.x, line - tol)
                right = np.searchsorted(model.x, line + tol)

                #Don't use lines that are saturated
                if min(model.y[left:right]) < 0.05:
                    continue

                pars, model_success = self.FitGaussian(model[left:right])
                if model_success < 5 and pars[1] > 0 and pars[1] < 1:
                    model_lines.append(pars[2])
                else:
                    continue

                #Do the same for the data
                left = np.searchsorted(data.x, line - tol)
                right = np.searchsorted(data.x, line + tol)

                if min(data.y[left:right] / data.cont[left:right]) < 0.05:
                    model_lines.pop()
                    continue

                pars, data_success = self.FitGaussian(data[left:right])
                if data_success < 5 and pars[1] > 0 and pars[1] < 1:
                    dx.append(pars[2] - model_lines[-1])
                else:
                    model_lines.pop()

        #Convert the lists to np arrays
        model_lines = np.array(model_lines)
        dx = np.array(dx)

        #Remove any points with very large shifts:
        badindices = np.where(np.abs(dx) > 0.015)[0]
        model_lines = np.delete(model_lines, badindices)
        dx = np.delete(dx, badindices)

        if self.debug and self.debug_level >= 5:
            plt.figure(2)
            plt.plot(model_lines, dx, 'ro')
            plt.title("Fitted Line shifts")
            plt.xlabel("Old Wavelength")
            plt.ylabel("New Wavelength")

        numlines = len(model_lines)
        logging.info("Found %i lines in this order" % numlines)
        fit = lambda x: 0
        mean = 0.0
        if numlines < fitorder:
            return fit, mean

        #Check if there is a large gap between the telluric lines and the end of the order (can cause the fit to go crazy)
        keepfirst = False
        keeplast = False
        if min(model_lines) - data.x[0] > 1:
            model_lines = np.r_[data.x[0], model_lines]
            dx = np.r_[0.0, dx]
            keepfirst = True
        if data.x[-1] - max(model_lines) > 1:
            model_lines = np.r_[model_lines, data.x[-1]]
            dx = np.r_[dx, 0.0]
            keeplast = True

        #Iteratively fit with sigma-clipping
        done = False
        iternum = 0
        mean = np.mean(data.x)
        while not done and len(model_lines) >= fitorder and iternum < numiters:
            iternum += 1
            done = True
            fit = np.poly1d(np.polyfit(model_lines - mean, dx, fitorder))
            residuals = fit(model_lines - mean) - dx
            std = np.std(residuals)
            badindices = np.where(np.abs(residuals) > 3 * std)[0]
            if 0 in badindices and keepfirst:
                idx = np.where(badindices == 0)[0]
                badindices = np.delete(badindices, idx)
            if data.size() - 1 in badindices and keeplast:
                idx = np.where(badindices == data.size() - 1)[0]
                badindices = np.delete(badindices, idx)
            if badindices.size > 0 and model_lines.size - badindices.size > 2 * fitorder:
                done = False
                model_lines = np.delete(model_lines, badindices)
                dx = np.delete(dx, badindices)

        if self.debug and self.debug_level >= 5:
            plt.figure(3)
            plt.plot(model_lines, fit(model_lines - mean) - dx, 'ro')
            plt.title("Residuals")
            plt.xlabel("Wavelength")
            plt.ylabel("Delta-lambda")
            plt.show()

        return fit, mean


    ### -----------------------------------------------
dataset/ETHPy150Open kgullikson88/Telluric-Fitter/src/TelluricFitter.py/TelluricFitter.FitWavelength/original