def GenerateModel(self, pars, nofit=False, separate_source=False, return_resolution=False, broaden=False, model=None):
        data = self.data

        #Update self.const_pars to include the new values in fitpars
        #  I know, it's confusing that const_pars holds some non-constant parameters...
        fit_idx = 0
        for i in range(len(self.parnames)):
            if self.fitting[i]:
                #Change from internal to bounded (physical) parameters
                if self.bounds[i][1] < np.inf:
                    self.const_pars[i] = self.bounds[i][0] + (np.sin(pars[fit_idx]*self.normalization[i]) + 1.0) * \
                                                             (self.bounds[i][1] - self.bounds[i][0])/2.0
                else:
                    self.const_pars[i] = self.bounds[i][0] - 1.0 + \
                                         np.sqrt((pars[fit_idx]*self.normalization[i])**2 + 1.0)
                fit_idx += 1
        self.DisplayVariables(fitonly=True)

        #Extract parameters from pars and const_pars. They will have variable
        #  names set from self.parnames
        fit_idx = 0
        for i in range(len(self.parnames)):
            #Assign to local variables by the parameter name
            exec("%s = %g" % (self.parnames[i], self.const_pars[i]))


        wavenum_start = 1e7 / waveend
        wavenum_end = 1e7 / wavestart
        lat = self.observatory["latitude"]
        alt = self.observatory["altitude"]


        #Generate the model:
        if model is None:
            model = self.Modeler.MakeModel(pressure, temperature, wavenum_start, wavenum_end, angle, h2o, co2, o3, n2o, co,
                                           ch4, o2, no, so2, no2, nh3, hno3, lat=lat, alt=alt, wavegrid=None,
                                           resolution=None, vac2air=self.air_wave)

            #Save each model if debugging
            if self.debug and self.debug_level >= 5:
                FittingUtilities.ensure_dir("Models/")
                model_name = "Models/transmission" + "-%.2f" % pressure + "-%.2f" % temperature + "-%.1f" % h2o + "-%.1f" % angle + "-%.2f" % (
                co2) + "-%.2f" % (o3 * 100) + "-%.2f" % ch4 + "-%.2f" % (co * 10)
                np.savetxt(model_name, np.transpose((model.x, model.y)), fmt="%.8f")

            #Interpolate to constant wavelength spacing
            xgrid = np.linspace(model.x[0], model.x[-1], model.x.size)
            model = FittingUtilities.RebinData(model, xgrid)

            #Use nofit if you want a model with reduced resolution. Probably easier
            #  to go through MakeModel directly though...
            if data == None or nofit:
                if broaden:
                    model = FittingUtilities.ReduceResolution(model, resolution)

                # Give units to the output model
                model.x *= u.nm.to(self.xunits)
                return model

        #Make a copy of the model before broadening it
        model_original = model.copy()

        #Reduce to initial guess resolution
        if (resolution - 10 < self.resolution_bounds[0] or resolution + 10 > self.resolution_bounds[1]):
            resolution = np.mean(self.resolution_bounds)
        model = FittingUtilities.ReduceResolution(model, resolution)
        model = FittingUtilities.RebinData(model, data.x)

        #Shift the data (or model) by a constant offset. This gets the wavelength calibration close
        shift = FittingUtilities.CCImprove(data, model, tol=0.1)
        logging.debug("Shifting model by {:.5g} pixels".format((shift)))
        if self.adjust_wave == "data" and shift != 0:
            data.x += shift
        elif self.adjust_wave == "model" and shift != 0:
            model_original.x -= shift
            # In this case, we need to adjust the resolution again
            model = FittingUtilities.ReduceResolution(model_original.copy(), resolution)
            model = FittingUtilities.RebinData(model, data.x)
        elif shift != 0:
            sys.exit("Error! adjust_wave parameter set to invalid value: %s" % self.adjust_wave)
        self.shift += shift

        resid = data.y / model.y
        nans = np.isnan(resid)
        resid[nans] = data.cont[nans]
        infs = np.isinf(resid)
        resid[infs] = data.cont[infs]

        #As the model gets better, the continuum will be less affected by
        #  telluric lines, and so will get better
        data.cont = FittingUtilities.Continuum(data.x, resid, fitorder=self.continuum_fit_order, lowreject=2,
                                               highreject=3)

        if separate_source or self.fit_source:
            logging.info("Generating Primary star model")
            primary_star = data.copy()
            primary_star.y = resid
            primary_star = self.source_fcn(primary_star, *self.source_args, **self.source_kwargs)
            data.cont *= primary_star.y



        if self.debug and self.debug_level >= 4:
            logging.debug("Saving data and model arrays right before fitting the wavelength")
            logging.debug("  and resolution to Debug_Output1.log")
            np.savetxt("Debug_Output1.log", np.transpose((data.x, data.y, data.cont, model.x, model.y)))


        #Fine-tune the wavelength calibration by fitting the location of several telluric lines
        modelfcn, mean = self.FitWavelengthNew(data, model.copy(), fitorder=self.wavelength_fit_order)

        if self.adjust_wave == "data":
            test = data.x + modelfcn(data.x - mean)
            xdiff = [test[j] - test[j - 1] for j in range(1, len(test) - 1)]
            if min(xdiff) > 0 and np.max(np.abs(test - data.x)) < 0.1 and min(test) > 0:
                logging.info("Adjusting data wavelengths by at most %.8g nm" % np.max(test - model.x))
                data.x = test.copy()
            else:
                logging.warn("Wavelength calibration did not succeed!")
        elif self.adjust_wave == "model":
            test = model_original.x - modelfcn(model_original.x - mean)
            test2 = model.x - modelfcn(model.x - mean)
            xdiff = [test[j] - test[j - 1] for j in range(1, len(test) - 1)]
            if min(xdiff) > 0 and np.max(np.abs(test2 - model.x)) < 0.1 and min(test) > 0 and abs(
                            test[0] - data.x[0]) < 50 and abs(test[-1] - data.x[-1]) < 50:
                logging.info("Adjusting wavelength calibration by at most %.8g nm" % max(test2 - model.x))
                model_original.x = test.copy()
                model.x = test2.copy()
            else:
                logging.warn("Wavelength calibration did not succeed!")

        else:
            sys.exit("Error! adjust_wave set to an invalid value: %s" % self.adjust_wave)

        if self.debug and self.debug_level >= 4:
            logging.debug("Saving data and model arrays after fitting the wavelength")
            logging.debug("  and before the resolution fit to Debug_Output2.log")
            np.savetxt("Debug_Output2.log", np.transpose((data.x, data.y, data.cont, model.x, model.y)))


        #Fit instrumental resolution
        done = False
        while not done:
            done = True
            if 'gauss' in self.resolution_fit_mode.lower() or min(model.y) > 0.95:
                model, resolution = self.FitResolution(data.copy(), model_original.copy(), resolution)
            elif "svd" in self.resolution_fit_mode.lower():
                model, self.broadstuff = self.Broaden2(data.copy(), model_original.copy(), full_output=True)
            else:
                done = False
                print("Resolution fit mode set to an invalid value: %s" % self.resolution_fit_mode)
                self.resolution_fit_mode = raw_input("Enter a valid mode (SVD or guass): ")

        self.data = data
        self.first_iteration = False
        if separate_source:
            if return_resolution:
                return primary_star, model, resolution
            else:
                return primary_star, model
        else:
            #if self.fit_source:
            #  data.cont /= primary_star.y
            if return_resolution:
                return model, resolution
            return model


    # ## -----------------------------------------------
    ### Several functions for refining the wavelength calibration
    ### -----------------------------------------------
L{util.switchUID} calls L{util.initgroups} and then C{os.seteuid} with
dataset/ETHPy150Open kgullikson88/Telluric-Fitter/src/TelluricFitter.py/TelluricFitter.GenerateModel--crossover with--dataset/ETHPy150Open nlloyd/SubliminalCollaborator/libs/twisted/python/test/test_util.py/SwitchUIDTest.test_euid