Example #1
0
    def plot_continuum(self,
                       fit_target,
                       title_addendum="",
                       extrapolation_method="bootstrap",
                       plateau_fit_size=20,
                       interpolation_rank=3,
                       plot_continuum_fit=False):
        """Method for plotting the continuum limit of topsus at a given
        fit_target.

        Args:
            fit_target: float or str. If float, will choose corresponding
                float time t_f value of where we extrapolate from. If string,
                one can choose either 't0', 't0cont', 'w0' and 'w0cont'. 't0' 
                and 'w0' will use values for given batch. For 't0cont' 
                and 'w0cont' will use extrapolated values to select topsus 
                values from.
            title_addendum: str, optional, default is an empty string, ''.
                Adds string to end of title.
            extrapolation_method: str, optional, method of selecting the
                extrapolation point to do the continuum limit. Method will be
                used on y values and tau int. Choices:
                    - plateau: line fits points neighbouring point in order to
                        reduce the error bars using y_raw for covariance
                        matrix.
                    - plateau_mean: line fits points neighbouring point in
                        order to reduce the error bars. Line will be weighted
                        by the y_err.
                    - nearest: line fit from the point nearest to what we seek
                    - interpolate: linear interpolation in order to retrieve
                        value and error. Does not work in conjecture with
                        use_raw_values.
                    - bootstrap: will create multiple line fits, and take
                        average. Assumes y_raw is the bootstrapped or
                        jackknifed samples.
            plateau_size: int, optional. Number of points in positive and
                negative direction to extrapolate fit target value from. This
                value also applies to the interpolation interval. Default is
                20.
            interpolation_rank: int, optional. Interpolation rank to use if
                extrapolation method is interpolation Default is 3.
            raw_func: function, optional, will modify the bootstrap data after
                samples has been taken by this function.
            raw_func_err: function, optional, will propagate the error of the
                bootstrapped line fitted data, raw_func_err(y, yerr).
                Calculated by regular error propagation.
        """

        if not self.check_continuum_extrapolation(): return

        self.extrapolation_method = extrapolation_method
        if not isinstance(self.reference_values, types.NoneType):
            if extrapolation_method in self.reference_values.keys():
                # Checking that the extrapolation method selected can be used.
                t0_values = (self.reference_values[self.extrapolation_method][
                    self.analysis_data_type])
            else:
                # If the extrapolation method is not among the used methods.
                t0_values = self.reference_values.values()[0][
                    self.analysis_data_type]
        else:
            t0_values = None

        # Retrieves data for analysis.
        if fit_target == -1:
            fit_target = self.plot_values[max(self.plot_values)]["x"][-1]

        fit_targets = self.get_fit_targets(fit_target)
        if self.verbose:
            print "Fit targets: ", fit_targets

        a, a_err, a_norm_factor, a_norm_factor_err, obs, obs_raw, obs_err, \
            tau_int_corr = [], [], [], [], [], [], [], []

        for i, bn in enumerate(self.sorted_batch_names):
            if self.with_autocorr and not "blocked" in self.analysis_data_type:
                tau_int = self.plot_values[bn]["tau_int"]
                tau_int_err = self.plot_values[bn]["tau_int_err"]
            else:
                tau_int = None
                tau_int_err = None

            # plt.plot(self.plot_values[bn]["x"], self.chi[bn](
            #     np.mean(self.plot_values[bn]["y_raw"], axis=1)))
            # plt.plot(self.plot_values[bn]["x"],
            #          self.plot_values[bn]["y"], color="red")
            # plt.show()
            # exit("Good @ 255")

            # Extrapolation of point to use in continuum extrapolation
            res = extract_fit_target(fit_targets[i],
                                     self.plot_values[bn]["x"],
                                     self.plot_values[bn]["y"],
                                     self.plot_values[bn]["y_err"],
                                     y_raw=self.plot_values[bn]["y_raw"],
                                     tau_int=tau_int,
                                     tau_int_err=tau_int_err,
                                     extrapolation_method=extrapolation_method,
                                     plateau_size=plateau_fit_size,
                                     interpolation_rank=3,
                                     plot_fit=plot_continuum_fit,
                                     raw_func=self.chi[bn],
                                     raw_func_err=self.chi_der[bn],
                                     plot_samples=False,
                                     verbose=False)

            _x0, _y0, _y0_error, _y0_raw, _tau_int0 = res

            # In case something is wrong -> skip
            if np.isnan([_y0, _y0_error]).any():
                print "NaN type detected: skipping calculation"
                return

            if self.verbose:
                msg = "Beta = %4.2f Topsus = %14.12f +/- %14.12f" % (
                    self.beta_values[bn], _y0, _y0_error)

            a.append(self.plot_values[bn]["a"])
            a_err.append(self.plot_values[bn]["a_err"])

            if isinstance(t0_values, types.NoneType):
                a_norm_factor.append(_x0)
                a_norm_factor_err.append(0)
            else:
                a_norm_factor.append(t0_values["t0cont"])
                a_norm_factor_err.append(t0_values["t0cont_err"])

                if self.verbose:
                    _tmp = t0_values["t0cont"] / (self.plot_values[bn]["a"]**2)
                    _tmp *= self.r0**2
                    msg += " t0 = %14.12f" % (_tmp)

            if self.verbose:
                print msg

            obs.append(_y0)
            obs_err.append(_y0_error)
            obs_raw.append(_y0_raw)
            tau_int_corr.append(_tau_int0)

        # Makes lists into arrays
        a = np.asarray(a)[::-1]
        a_err = np.asarray(a_err)[::-1]
        a_norm_factor = np.asarray(a_norm_factor)[::-1]
        a_norm_factor_err = np.asarray(a_norm_factor_err)[::-1]
        a_squared = a**2 / a_norm_factor
        a_squared_err = np.sqrt((2 * a * a_err / a_norm_factor)**2 +
                                (a**2 * a_norm_factor_err /
                                 a_norm_factor**2)**2)
        obs = np.asarray(obs)[::-1]
        obs_err = np.asarray(obs_err)[::-1]

        # Continuum limit arrays
        N_cont = 1000
        a_squared_cont = np.linspace(-0.0025, a_squared[-1] * 1.1, N_cont)

        # Fits to continuum and retrieves values to be plotted
        continuum_fit = LineFit(a_squared, obs, obs_err)

        y_cont, y_cont_err, fit_params, chi_squared = \
            continuum_fit.fit_weighted(a_squared_cont)
        self.chi_squared = chi_squared
        self.fit_params = fit_params

        # continuum_fit.plot(True)

        # Gets the continium value and its error
        y0_cont, y0_cont_err, _, _, = \
            continuum_fit.fit_weighted(0.0)

        # Matplotlib requires 2 point to plot error bars at
        a0_squared = [0, 0]
        y0 = [y0_cont[0], y0_cont[0]]
        y0_err = [y0_cont_err[0][0], y0_cont_err[1][0]]

        # Stores the chi continuum
        self.topsus_continuum = y0[0]
        self.topsus_continuum_error = (y0_err[1] - y0_err[0]) / 2.0

        y0_err = [self.topsus_continuum_error, self.topsus_continuum_error]

        # Sets of title string with the chi squared and fit target
        if isinstance(self.fit_target, str):
            title_string = r"$%s, \chi^2/\mathrm{d.o.f.} = %.2f$" % (
                self.fit_target, self.chi_squared)
        else:
            title_string = r"$\sqrt{8t_{f,\mathrm{extrap}}} = %.2f[fm], \chi^2 = %.2f$" % (
                self.fit_target, self.chi_squared)
        title_string += title_addendum

        # Creates figure and plot window
        fig = plt.figure()
        ax = fig.add_subplot(111)

        # Plots an ax-line at 0
        ax.axvline(0,
                   linestyle="dashed",
                   color=self.cont_axvline_color,
                   linewidth=0.5)

        if chi_squared < 0.01:
            chi_squared_label = r"$\chi^2/\mathrm{d.o.f.}=%.4f$" % chi_squared
        else:
            chi_squared_label = r"$\chi^2/\mathrm{d.o.f.}=%.2f$" % chi_squared

        topsus_continuum_label = sciprint.sciprint(self.topsus_continuum,
                                                   self.topsus_continuum_error,
                                                   prec=3)

        # Plots the fit
        ax.plot(a_squared_cont,
                y_cont,
                color=self.fit_color,
                alpha=0.5,
                label=chi_squared_label)
        ax.fill_between(a_squared_cont,
                        y_cont_err[0],
                        y_cont_err[1],
                        alpha=0.5,
                        edgecolor='',
                        facecolor=self.fit_fill_color)

        # Plot lattice points
        ax.errorbar(a_squared,
                    obs,
                    xerr=a_squared_err,
                    yerr=obs_err,
                    fmt="o",
                    capsize=5,
                    capthick=1,
                    color=self.lattice_points_color,
                    ecolor=self.lattice_points_color)

        # plots continuum limit, 5 is a good value for cap size
        ax.errorbar(a0_squared,
                    y0,
                    yerr=y0_err,
                    fmt="o",
                    capsize=5,
                    capthick=1,
                    color=self.cont_error_color,
                    ecolor=self.cont_error_color,
                    label=r"$\chi_{t_f}^{1/4}=%s$ GeV" %
                    (topsus_continuum_label))

        ax.set_ylabel(self.y_label_continuum)
        ax.set_xlabel(self.x_label_continuum)
        if self.include_title:
            ax.set_title(title_string)
        ax.set_xlim(a_squared_cont[0], a_squared_cont[-1])
        ax.legend()
        ax.grid(True)

        if self.verbose:
            print "Target: %.16f +/- %.16f GeV" % (self.topsus_continuum,
                                                   self.topsus_continuum_error)

        # Saves figure
        fname = os.path.join(
            self.output_folder_path,
            "post_analysis_extrapmethod%s_%s_continuum%s_%s.pdf" %
            (extrapolation_method, self.observable_name_compact,
             str(fit_target).replace(".", ""), self.analysis_data_type))

        fig.savefig(fname, dpi=self.dpi)

        if self.verbose:
            print "Continuum plot of %s created in %s" % (
                self.observable_name_compact, fname)

        # plt.show()
        plt.close(fig)

        self.print_continuum_estimate()
    def get_w0_scale(self, extrapolation_method="bootstrap", W0=0.3, **kwargs):
        """
        Method for retrieving the w0 reference scale setting, based on paper:
        http://xxx.lanl.gov/pdf/1203.4469v2
        """
        if self.verbose:
            print "Scale w0 extraction method:      " + extrapolation_method
            print "Scale w0 extraction data:        " + self.analysis_data_type

        # Retrieves t0 values from data
        a_values = []
        a_values_err = []
        w0_values = []
        w0err_values = []
        w0a_values = []
        w0aerr_values = []

        # Since we are slicing tau int, and it will only be ignored
        # if it is None in extract_fit_targets, we set it manually
        # if we have provided it.

        for bn in self.sorted_batch_names:
            bval = self.plot_values[bn]

            # Sets correct tau int to pass to fit extraction
            if "blocked" in self.analysis_data_type:
                _tmp_tau_int = None
                _tmp_tau_int_err = None
            else:
                _tmp_tau_int = bval["tau_int"][1:-1]
                _tmp_tau_int_err = bval["tau_int_err"][1:-1]

            y0, t_w0, t_w0_err, _, _ = extract_fit_target(
                W0,
                bval["tder"],
                bval["W"],
                y_err=bval["W_err"],
                y_raw=bval["W_raw"],
                tau_int=_tmp_tau_int,
                tau_int_err=_tmp_tau_int_err,
                extrapolation_method=extrapolation_method,
                plateau_size=10,
                inverse_fit=True,
                **kwargs)

            # NOTE: w0 has units of [fm].
            # t_w0 = a^2 * t_f / r0^2
            # Returns t_w0 = (w0)^2 / r0^2.

            # Lattice spacing
            a_values.append(bval["a"]**2)
            a_values_err.append(2 * bval["a_err"] * bval["a"])

            # Plain w_0 retrieval
            w0_values.append(np.sqrt(t_w0))
            w0err_values.append(0.5 * t_w0_err / np.sqrt(t_w0))

            # w_0 / a
            w0a_values.append(np.sqrt(t_w0) / bval["a"])
            w0aerr_values.append(
                np.sqrt((t_w0_err / (2 * np.sqrt(t_w0)) / bval["a"])**2 +
                        (np.sqrt(t_w0) * bval["a_err"] / bval["a"]**2)**2))

        # Reverse lists and converts them to arrays
        a_values = np.asarray(a_values[::-1])
        a_values_err = np.asarray(a_values_err[::-1])
        w0_values = np.asarray(w0_values[::-1])
        w0err_values = np.asarray(w0err_values[::-1])
        w0a_values, w0aerr_values = map(np.asarray,
                                        (w0a_values, w0aerr_values))

        # Extrapolates t0 to continuum
        N_cont = 1000
        a_squared_cont = np.linspace(-0.00025, a_values[-1] * 1.1, N_cont)

        # Fits to continuum and retrieves values to be plotted
        continuum_fit = LineFit(a_values, w0_values, y_err=w0err_values)
        y_cont, y_cont_err, fit_params, chi_squared = \
            continuum_fit.fit_weighted(a_squared_cont)

        res = continuum_fit(0, weighted=True)
        self.w0_cont = res[0][0]
        self.w0_cont_error = (res[1][-1][0] - res[1][0][0]) / 2
        # self.sqrt8w0_cont = np.sqrt(8*self.w0_cont)
        # self.sqrt8w0_cont_error = 4*self.w0_cont_error/np.sqrt(8*self.w0_cont)

        # Creates continuum extrapolation plot
        fname = os.path.join(
            self.output_folder_path,
            "post_analysis_extrapmethod%s_w0reference_continuum_%s.pdf" %
            (extrapolation_method, self.analysis_data_type))
        self.plot_continuum_fit(a_squared_cont,
                                y_cont,
                                y_cont_err,
                                chi_squared,
                                a_values,
                                a_values_err,
                                w0_values,
                                w0err_values,
                                0,
                                0,
                                self.w0_cont,
                                self.w0_cont_error,
                                r"w_{0,\mathrm{cont}}",
                                fname,
                                r"$w_0[\mathrm{fm}]$",
                                r"$a^2[\mathrm{GeV}^{-2}]$",
                                y_limits=[0.1625, 0.1750],
                                cont_label_unit=" fm")

        # Reverses values for storage.
        a_values, a_values_err, w0_values, w0err_values, = map(
            lambda k: np.flip(k, 0),
            (a_values, a_values_err, w0_values, w0err_values))

        # Populates dictionary with w0 values for each batch
        _tmp_batch_dict = {
            bn: {
                "w0":
                w0_values[i],
                "w0err":
                w0err_values[i],
                "w0a":
                w0a_values[i],
                "w0aerr":
                w0aerr_values[i],
                "w0r0":
                w0_values[i] / self.r0,
                "w0r0err":
                w0err_values[i] / self.r0,
                "aL":
                self.plot_values[bn]["a"] * self.lattice_sizes[bn][0],
                "aLerr":
                (self.plot_values[bn]["a_err"] * self.lattice_sizes[bn][0]),
                "L":
                self.lattice_sizes[bn][0],
                "a":
                self.plot_values[bn]["a"],
                "a_err":
                self.plot_values[bn]["a_err"],
            }
            for i, bn in enumerate(self.sorted_batch_names)
        }

        # Populates dictionary with continuum w0 value
        w0_dict = {
            "w0cont": self.w0_cont,
            "w0cont_err": self.w0_cont_error,
        }
        w0_dict.update(_tmp_batch_dict)

        if self.verbose:
            print "w0 reference values table: "
            print "w0 = %.16f +/- %.16f" % (self.w0_cont, self.w0_cont_error)
            print "chi^2/dof = %.16f" % chi_squared
            for bn in self.sorted_batch_names:
                msg = "beta = %.2f" % self.beta_values[bn]
                msg += " || w0 = %10f +/- %-10f" % (w0_dict[bn]["w0"],
                                                    w0_dict[bn]["w0err"])
                msg += " || w0/a = %10f +/- %-10f" % (w0_dict[bn]["w0a"],
                                                      w0_dict[bn]["w0aerr"])
                msg += " || w0/r0 = %10f +/- %-10f" % (w0_dict[bn]["w0r0"],
                                                       w0_dict[bn]["w0r0err"])
                print msg

        if self.print_latex:
            # Header:
            # beta  w0  a^2  L/a  L  a

            header = [
                r"Ensemble",
                r"$w_0[\fm]$",
                # r"$a^2[\mathrm{GeV}^{-2}]$",
                r"$w_0/a$",
                r"$L/a$",
                r"$L[\fm]$",
                r"$a[\fm]$"
            ]

            bvals = self.sorted_batch_names
            tab = [
                [r"{0:s}".format(self.ensemble_names[bn]) for bn in bvals],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(w0_dict[bn]["w0"],
                                          w0_dict[bn]["w0err"]))
                    for bn in bvals
                ],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(w0_dict[bn]["w0a"],
                                          w0_dict[bn]["w0aerr"]))
                    for bn in bvals
                ],
                # [r"{0:s}".format(sciprint.sciprint(
                #     self.plot_values[bn]["a"]**2,
                #     self.plot_values[bn]["a_err"]*2*self.plot_values[bn]["a"]))
                #  for bn in bvals],
                [r"{0:d}".format(self.lattice_sizes[bn][0]) for bn in bvals],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(
                            self.lattice_sizes[bn][0] *
                            self.plot_values[bn]["a"],
                            self.lattice_sizes[bn][0] *
                            self.plot_values[bn]["a_err"])) for bn in bvals
                ],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(self.plot_values[bn]["a"],
                                          self.plot_values[bn]["a_err"]))
                    for bn in bvals
                ],
            ]

            table_filename = "energy_w0_" + self.analysis_data_type
            table_filename += "-".join(self.batch_names) + ".txt"
            ptab = TablePrinter(header, tab)
            ptab.print_table(latex=True, width=15, filename=table_filename)

        return w0_dict
    def get_t0_scale(self,
                     extrapolation_method="plateau_mean",
                     E0=0.3,
                     **kwargs):
        """
        Method for retrieveing reference value t0 based on Luscher(2010),
        Properties and uses of the Wilson flow in lattice QCD.
        t^2<E_t>|_{t=t_0} = 0.3
        Will return t0 values and make a plot of the continuum value 
        extrapolation.

        Args:
                extrapolation_method: str, optional. Method of t0 extraction. 
                        Default is plateau_mean.
                E0: float, optional. Default is 0.3.

        Returns:
                t0: dictionary of t0 values for each of the batches, and a 
                        continuum value extrapolation.
        """
        if self.verbose:
            print "Scale t0 extraction method:      " + extrapolation_method
            print "Scale t0 extraction data:        " + self.analysis_data_type

        # Retrieves t0 values from data
        a_values = []
        a_values_err = []
        t0_values = []
        t0err_values = []

        for bn in self.sorted_batch_names:
            bval = self.plot_values[bn]
            y0, t0, t0_err, _, _ = extract_fit_target(
                E0,
                bval["t"],
                bval["y"],
                y_err=bval["y_err"],
                y_raw=bval[self.analysis_data_type],
                tau_int=bval["tau_int"],
                tau_int_err=bval["tau_int_err"],
                extrapolation_method=extrapolation_method,
                plateau_size=10,
                inverse_fit=True,
                **kwargs)

            a_values.append(bval["a"]**2 / t0)
            a_values_err.append(
                np.sqrt((2 * bval["a_err"] * bval["a"] / t0)**2 +
                        (bval["a"]**2 * t0_err / t0**2)**2))

            t0_values.append(t0)
            t0err_values.append(t0_err)

        a_values = np.asarray(a_values[::-1])
        a_values_err = np.asarray(a_values_err[::-1])
        t0_values = np.asarray(t0_values[::-1])
        t0err_values = np.asarray(t0err_values[::-1])

        # Functions for t0 and propagating uncertainty
        def t0_func(_t0):
            return np.sqrt(8 * _t0) / self.r0

        def t0err_func(_t0, _t0_err):            return _t0_err * \
np.sqrt(8/_t0)/(2.0*self.r0)

        # Sets up t0 and t0_error values to plot
        y = t0_func(t0_values)
        yerr = t0err_func(t0_values, t0err_values)

        # Extrapolates t0 to continuum
        N_cont = 1000
        a_squared_cont = np.linspace(-0.025, a_values[-1] * 1.1, N_cont)

        # Fits to continuum and retrieves values to be plotted
        continuum_fit = LineFit(a_values, y, y_err=yerr)
        y_cont, y_cont_err, fit_params, chi_squared = \
            continuum_fit.fit_weighted(a_squared_cont)

        res = continuum_fit(0, weighted=True)
        self.sqrt_8t0_cont = res[0][0]
        self.sqrt_8t0_cont_error = (res[1][-1][0] - res[1][0][0]) / 2
        self.t0_cont = self.sqrt_8t0_cont**2 / 8
        self.t0_cont_error = self.sqrt_8t0_cont_error * np.sqrt(
            self.t0_cont / 2.0)

        # Creates continuum extrapolation figure
        fname = os.path.join(
            self.output_folder_path,
            "post_analysis_extrapmethod%s_t0reference_continuum_%s.pdf" %
            (extrapolation_method, self.analysis_data_type))
        self.plot_continuum_fit(a_squared_cont, y_cont, y_cont_err,
                                chi_squared, a_values, a_values_err, y, yerr,
                                0, 0, self.sqrt_8t0_cont,
                                self.sqrt_8t0_cont_error,
                                r"\frac{\sqrt{8t_{0,\mathrm{cont}}}}{r_0}",
                                fname, r"$\frac{\sqrt{8t_0}}{r_0}$",
                                r"$a^2/t_0$")

        self.extrapolation_method = extrapolation_method

        # Reverses values for storage.
        a_values, a_values_err, t0_values, t0err_values = map(
            lambda k: np.flip(k, 0),
            (a_values, a_values_err, t0_values, t0err_values))

        _tmp_batch_dict = {
            bn: {
                "t0": t0_values[i],
                "t0err": t0err_values[i],
                "t0a2": t0_values[i]/self.plot_values[bn]["a"]**2,
                # Including error term in lattice spacing, a
                "t0a2err": np.sqrt((t0err_values[i] / \
                                    self.plot_values[bn]["a"]**2)**2 \
                                   + (2*self.plot_values[bn]["a_err"] * \
                                      t0_values[i] /\
                                      self.plot_values[bn]["a"]**3)**2),
                "t0r02": t0_values[i]/self.r0**2,
                "t0r02err": t0err_values[i]/self.r0**2,
                "aL": self.plot_values[bn]["a"]*self.lattice_sizes[bn][0],
                "aLerr": (self.plot_values[bn]["a_err"] \
                          * self.lattice_sizes[bn][0]),
                "L": self.lattice_sizes[bn][0],
                "a": self.plot_values[bn]["a"],
                "a_err": self.plot_values[bn]["a_err"],
            }
            for i, bn in enumerate(self.batch_names)
        }

        t0_dict = {"t0cont": self.t0_cont, "t0cont_err": self.t0_cont_error}
        t0_dict.update(_tmp_batch_dict)

        if self.verbose:
            print "t0 reference values table: "
            print "sqrt(8t0)/r0 = %.16f +/- %.16f" % (self.sqrt_8t0_cont,
                                                      self.sqrt_8t0_cont_error)
            print "t0/r0^2 = %.16f +/- %.16f" % (self.t0_cont,
                                                 self.t0_cont_error)
            print "chi^2/dof = %.16f" % chi_squared
            for bn in self.batch_names:
                msg = "beta = %.2f || t0 = %10f +/- %-10f" % (
                    self.beta_values[bn], t0_dict[bn]["t0"],
                    t0_dict[bn]["t0err"])
                msg += " || t0/a^2 = %10f +/- %-10f" % (t0_dict[bn]["t0a2"],
                                                        t0_dict[bn]["t0a2err"])
                msg += " || t0/r0^2 = %10f +/- %-10f" % (
                    t0_dict[bn]["t0r02"], t0_dict[bn]["t0r02err"])
                print msg

        if self.print_latex:
            # Header:
            # beta   t0a2   t0r02   L/a   L   a

            header = [
                r"$\beta$", r"$t_0$[fm]", r"$t_0/a^2$", r"$t_0/r_0^2$",
                r"$L/a$", r"$L[\fm]$", r"$a[\fm]$"
            ]

            bvals = self.batch_names
            tab = [
                [r"{0:s}".format(self.ensemble_names[bn]) for bn in bvals],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(t0_dict[bn]["t0"],
                                          t0_dict[bn]["t0err"]))
                    for bn in bvals
                ],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(t0_dict[bn]["t0a2"],
                                          t0_dict[bn]["t0a2err"]))
                    for bn in bvals
                ],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(t0_dict[bn]["t0r02"],
                                          t0_dict[bn]["t0r02err"]))
                    for bn in bvals
                ],
                [r"{0:d}".format(self.lattice_sizes[bn][0]) for bn in bvals],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(
                            self.lattice_sizes[bn][0] *
                            self.plot_values[bn]["a"],
                            self.lattice_sizes[bn][0] *
                            self.plot_values[bn]["a_err"])) for bn in bvals
                ],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(self.plot_values[bn]["a"],
                                          self.plot_values[bn]["a_err"]))
                    for bn in bvals
                ],
            ]

            table_filename = "energy_t0_" + self.analysis_data_type
            table_filename += "-".join(self.batch_names) + ".txt"
            ptab = TablePrinter(header, tab)
            ptab.print_table(latex=True, width=15, filename=table_filename)

        return t0_dict
Example #4
0
    def get_w0_scale(self,
                     extrapolation_method="plateau_mean",
                     W0=0.3,
                     **kwargs):
        """
        Method for retrieving the w0 reference scale setting, based on paper:
        http://xxx.lanl.gov/pdf/1203.4469v2
        """
        if self.verbose:
            print "Scale w0 extraction method:      " + extrapolation_method
            print "Scale w0 extraction data:        " + self.analysis_data_type

        # Retrieves t0 values from data
        a_values = []
        a_values_err = []
        w0_values = []
        w0err_values = []

        for bn in self.sorted_batch_names:
            bval = self.plot_values[bn]
            y0, w0, w0_err, _, _ = extract_fit_target(
                W0,
                bval["xraw"],
                bval["y"],
                y_err=bval["y_err"],
                y_raw=bval[self.analysis_data_type],
                tau_int=bval["tau_int"][1:-1],
                tau_int_err=bval["tau_int_err"][1:-1],
                extrapolation_method=extrapolation_method,
                plateau_size=10,
                inverse_fit=True,
                **kwargs)

            # TODO: fix a lattice spacing error here @ w_t
            a_values.append(bval["a"]**2)
            a_values_err.append(2 * bval["a"] * bval["a_err"])
            w0_values.append(np.sqrt(w0) * bval["a"])
            w0err_values.append(0.5 * w0_err / np.sqrt(w0))

        a_values = np.asarray(a_values[::-1])
        a_values_err = np.asarray(a_values_err[::-1])
        w0_values = np.asarray(w0_values[::-1])
        w0err_values = np.asarray(w0err_values[::-1])

        # # Functions for t0 and propagating uncertainty
        # t0_func = lambda _t0: np.sqrt(8*_t0)/self.r0
        # t0err_func = lambda _t0, _t0_err: _t0_err*np.sqrt(8/_t0)/(2.0*self.r0)

        # # Sets up t0 and t0_error values to plot
        # y = t0_func(t0_values)
        # yerr = t0err_func(t0_values, t0err_values)

        # Extrapolates t0 to continuum
        N_cont = 1000
        a_squared_cont = np.linspace(-0.00025, a_values[-1] * 1.1, N_cont)

        # Fits to continuum and retrieves values to be plotted
        continuum_fit = LineFit(a_values, w0_values, y_err=w0err_values)
        y_cont, y_cont_err, fit_params, chi_squared = \
            continuum_fit.fit_weighted(a_squared_cont)

        res = continuum_fit(0, weighted=True)
        self.w0_cont = res[0][0]
        self.w0_cont_error = (res[1][-1][0] - res[1][0][0]) / 2
        # self.t0_cont = self.sqrt_8t0_cont**2/8
        # self.t0_cont_error = self.sqrt_8t0_cont_error*np.sqrt(self.t0_cont/2.0)

        # Creates figure and plot window
        fig = plt.figure()
        ax = fig.add_subplot(111)
        # Plots linefit with errorband
        ax.plot(a_squared_cont,
                y_cont,
                color="tab:red",
                alpha=0.5,
                label=r"$\chi=%.2f$" % chi_squared)
        ax.fill_between(a_squared_cont,
                        y_cont_err[0],
                        y_cont_err[1],
                        alpha=0.5,
                        edgecolor='',
                        facecolor="tab:red")
        ax.axvline(0, linestyle="dashed", color="tab:red")
        ax.errorbar(a_values,
                    w0_values,
                    xerr=a_values_err,
                    yerr=w0err_values,
                    fmt="o",
                    capsize=5,
                    capthick=1,
                    color="#000000",
                    ecolor="#000000")
        ax.set_ylabel(r"$w_0[\mathrm{fm}]$")
        ax.set_xlabel(r"$a^2[\mathrm{GeV}^{-2}]$")
        ax.set_xlim(a_squared_cont[0], a_squared_cont[-1])
        ax.legend()
        ax.grid(True)

        # Saves figure
        fname = os.path.join(
            self.output_folder_path,
            "post_analysis_extrapmethod%s_w0reference_continuum_%s.pdf" %
            (extrapolation_method, self.analysis_data_type))
        fig.savefig(fname, dpi=self.dpi)
        if self.verbose:
            print "Figure saved in %s" % fname

        plt.close(fig)

        w0_values = w0_values[::-1]
        w0err_values = w0err_values[::-1]

        _tmp_beta_dict = {
            b: {
                "w0": w0_values[i],
                "w0err": w0err_values[i],
                "aL": self.plot_values[b]["a"]*self.lattice_sizes[b][0],
                "aLerr": (self.plot_values[b]["a_err"] \
                    * self.lattice_sizes[b][0]),
                "L": self.lattice_sizes[b][0],
                "a": self.plot_values[bn]["a"],
                "a_err": self.plot_values[b]["a_err"],
            }
            for i, b in enumerate(self.batch_names)
        }

        w0_dict = {"w0cont": self.w0_cont, "w0cont_err": self.w0_cont_error}
        w0_dict.update(_tmp_beta_dict)

        if self.verbose:
            print "w0 reference values table: "
            print "w0 = %.16f +/- %.16f" % (self.w0_cont, self.w0_cont_error)
            for b in self.batch_names:
                msg = "beta = %.2f || w0 = %10f +/- %-10f" % (
                    self.beta_values[b], w0_dict[b]["w0"], w0_dict[b]["w0err"])
                print msg

        if self.print_latex:
            # Header:
            # beta  w0  a^2  L/a  L  a

            header = [
                r"$\beta$", r"$w_0[\fm]$", r"$a^2[\mathrm{GeV}^{-2}]$",
                r"$L/a$", r"$L[\fm]$", r"$a[\fm]$"
            ]

            bvals = self.sorted_batch_names
            tab = [
                [r"{0:.2f}".format(self.beta_values[b]) for b in bvals],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(w0_dict[b]["w0"],
                                          w0_dict[b]["w0err"])) for b in bvals
                ],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(
                            self.plot_values[b]["a"]**2,
                            self.plot_values[b]["a_err"] * 2 *
                            self.plot_values[b]["a"])) for b in bvals
                ],
                [r"{0:d}".format(self.lattice_sizes[b][0]) for b in bvals],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(
                            self.lattice_sizes[b][0] *
                            self.plot_values[b]["a"],
                            self.lattice_sizes[b][0] *
                            self.plot_values[b]["a_err"])) for b in bvals
                ],
                [
                    r"{0:s}".format(
                        sciprint.sciprint(self.plot_values[b]["a"],
                                          self.plot_values[b]["a_err"]))
                    for b in bvals
                ],
            ]

            ptab = TablePrinter(header, tab)
            ptab.print_table(latex=True, width=15)
Example #5
0
    def plot_continuum(self,
                       fit_target,
                       title_addendum="",
                       extrapolation_method="bootstrap",
                       plateau_fit_size=20,
                       interpolation_rank=3,
                       plot_continuum_fit=False):
        """Method for plotting the continuum limit of topsus at a given 
		fit_target.

		Args:
			fit_target: float, value of where we extrapolate from.
			title_addendum: str, optional, default is an empty string, ''. 
				Adds string to end of title.
			extrapolation_method: str, optional, method of selecting the 
				extrapolation point to do the continuum limit. Method will be
				used on y values and tau int. Choices:
					- plateau: line fits points neighbouring point in order to 
						reduce the error bars using y_raw for covariance matrix.
					- plateau_mean: line fits points neighbouring point in order to
						reduce the error bars. Line will be weighted by the y_err.
					- nearest: line fit from the point nearest to what we seek
					- interpolate: linear interpolation in order to retrieve value
						and error. Does not work in conjecture with use_raw_values.
					- bootstrap: will create multiple line fits, and take average. 
						Assumes y_raw is the bootstrapped or jackknifed samples.
			plateau_size: int, optional. Number of points in positive and 
				negative direction to extrapolate fit target value from. This 
				value also applies to the interpolation interval. Default is 20.
			interpolation_rank: int, optional. Interpolation rank to use if 
				extrapolation method is interpolation Default is 3.
			raw_func: function, optional, will modify the bootstrap data after 
				samples has been taken by this function.
			raw_func_err: function, optional, will propagate the error of the 
				bootstrapped line fitted data, raw_func_err(y, yerr). Calculated
				by regular error propagation.
		"""
        self.extrapolation_method = extrapolation_method
        if not isinstance(self.reference_values, types.NoneType):
            if extrapolation_method in self.reference_values.keys():
                # Checking that the extrapolation method selected can be used.
                t0_values = self.reference_values[self.extrapolation_method]\
                 [self.analysis_data_type]
            else:
                # If the extrapolation method is not among the used methods.
                t0_values = self.reference_values.values()[0]\
                 [self.analysis_data_type]
        else:
            t0_values = None

        # Retrieves data for analysis.
        if fit_target == -1:
            fit_target = self.plot_values[max(self.plot_values)]["x"][-1]

        a, a_err, a_norm_factor, a_norm_factor_err, obs, obs_raw, obs_err, \
         tau_int_corr = [], [], [], [], [], [], [], []

        for beta in sorted(self.plot_values):
            x = self.plot_values[beta]["x"]
            y = self.plot_values[beta]["y"]
            y_err = self.plot_values[beta]["y_err"]
            y_raw = self.plot_values[beta]["y_raw"]

            if self.with_autocorr:
                tau_int = self.plot_values[beta]["tau_int"]
                tau_int_err = self.plot_values[beta]["tau_int_err"]
            else:
                tau_int = None
                tau_int_err = None

            # Extrapolation of point to use in continuum extrapolation
            res = extract_fit_target(fit_target,
                                     x,
                                     y,
                                     y_err,
                                     y_raw=y_raw,
                                     tau_int=tau_int,
                                     tau_int_err=tau_int_err,
                                     extrapolation_method=extrapolation_method,
                                     plateau_size=plateau_fit_size,
                                     interpolation_rank=3,
                                     plot_fit=plot_continuum_fit,
                                     raw_func=self.chi[beta],
                                     raw_func_err=self.chi_der[beta],
                                     plot_samples=False,
                                     verbose=False)

            _x0, _y0, _y0_error, _y0_raw, _tau_int0 = res

            if np.isnan([_y0, _y0_error]).any():
                print "NaN type detected: skipping calculation"
                return

            if self.verbose:
                msg = "Beta = %4.2f Topsus = %14.12f +/- %14.12f" % (beta, _y0,
                                                                     _y0_error)

            a.append(self.plot_values[beta]["a"])
            a_err.append(self.plot_values[beta]["a_err"])

            if isinstance(t0_values, types.NoneType):
                a_norm_factor.append(_x0)
                a_norm_factor_err.append(0)
            else:
                a_norm_factor.append(t0_values["t0cont"])
                a_norm_factor_err.append(t0_values["t0cont_err"])

                if self.verbose:
                    msg += " t0 = %14.12f" % (t0_values["t0cont"]\
                     / (self.plot_values[beta]["a"]**2) * self.r0**2)

            if self.verbose:
                print msg

            obs.append(_y0)
            obs_err.append(_y0_error)
            obs_raw.append(_y0_raw)
            tau_int_corr.append(_tau_int0)

        # Makes lists into arrays
        a = np.asarray(a)[::-1]
        a_err = np.asarray(a_err)[::-1]
        a_norm_factor = np.asarray(a_norm_factor)[::-1]
        a_norm_factor_err = np.asarray(a_norm_factor_err)[::-1]
        a_squared = a**2 / a_norm_factor
        a_squared_err = np.sqrt((2*a*a_err/a_norm_factor)**2 \
         + (a**2*a_norm_factor_err/a_norm_factor**2)**2)
        obs = np.asarray(obs)[::-1]
        obs_err = np.asarray(obs_err)[::-1]

        # Continuum limit arrays
        N_cont = 1000
        a_squared_cont = np.linspace(-0.0025, a_squared[-1] * 1.1, N_cont)

        # Fits to continuum and retrieves values to be plotted
        continuum_fit = LineFit(a_squared, obs, obs_err)

        y_cont, y_cont_err, fit_params, chi_squared = \
         continuum_fit.fit_weighted(a_squared_cont)
        self.chi_squared = chi_squared
        self.fit_params = fit_params
        self.fit_target = fit_target

        # continuum_fit.plot(True)

        # Gets the continium value and its error
        y0_cont, y0_cont_err, _, _, = \
         continuum_fit.fit_weighted(0.0)

        # Matplotlib requires 2 point to plot error bars at
        a0_squared = [0, 0]
        y0 = [y0_cont[0], y0_cont[0]]
        y0_err = [y0_cont_err[0][0], y0_cont_err[1][0]]

        # Stores the chi continuum
        self.topsus_continuum = y0[0]
        self.topsus_continuum_error = (y0_err[1] - y0_err[0]) / 2.0

        y0_err = [self.topsus_continuum_error, self.topsus_continuum_error]

        # Sets of title string with the chi squared and fit target
        title_string = r"$t_{f,0} = %.2f[fm], \chi^2 = %.2f$" % (
            self.fit_target, self.chi_squared)
        title_string += title_addendum

        # Creates figure and plot window
        fig = plt.figure()
        ax = fig.add_subplot(111)

        # Plots linefit with errorband
        ax.plot(a_squared_cont, y_cont, color="tab:blue", alpha=0.5)
        ax.fill_between(a_squared_cont,
                        y_cont_err[0],
                        y_cont_err[1],
                        alpha=0.5,
                        edgecolor='',
                        facecolor="tab:blue")

        # Plot lattice points
        ax.errorbar(a_squared,
                    obs,
                    xerr=a_squared_err,
                    yerr=obs_err,
                    fmt="o",
                    color="tab:orange",
                    ecolor="tab:orange")

        # plots continuum limit, 5 is a good value for cap size
        ax.errorbar(a0_squared,
                    y0,
                    yerr=y0_err,
                    fmt="o",
                    capsize=None,
                    capthick=1,
                    color="tab:red",
                    ecolor="tab:red",
                    label=r"$\chi^{1/4}=%.3f\pm%.3f$" %
                    (self.topsus_continuum, self.topsus_continuum_error))

        ax.set_ylabel(self.y_label_continuum)
        ax.set_xlabel(self.x_label_continuum)
        ax.set_title(title_string)
        ax.set_xlim(a_squared_cont[0], a_squared_cont[-1])
        ax.legend()
        ax.grid(True)

        if self.verbose:
            print "Target: %.16f +/- %.16f" % (self.topsus_continuum,
                                               self.topsus_continuum_error)

        # Saves figure
        fname = os.path.join(
            self.output_folder_path,
            "post_analysis_extrapmethod%s_%s_continuum%s_%s.png" %
            (extrapolation_method, self.observable_name_compact,
             str(fit_target).replace(".", ""), self.analysis_data_type))
        fig.savefig(fname, dpi=self.dpi)

        if self.verbose:
            print "Continuum plot of %s created in %s" % (
                self.observable_name_compact, fname)

        # plt.show()
        plt.close(fig)

        self.print_continuum_estimate()
	def get_t0_scale(self, extrapolation_method="plateau_mean", E0=0.3, **kwargs):
		"""
		Method for retrieveing reference value t0 based on Luscher(2010),
		Properties and uses of the Wilson flow in lattice QCD.
		t^2<E_t>|_{t=t_0} = 0.3
		Will return t0 values and make a plot of the continuum value 
		extrapolation.

		Args:
			extrapolation_method: str, optional. Method of t0 extraction. 
				Default is plateau_mean.
			E0: float, optional. Default is 0.3.

		Returns:
			t0: dictionary of t0 values for each of the betas, and a continuum
				value extrapolation.
		"""
		if self.verbose:
			print "Scale t0 extraction method:      " + extrapolation_method
			print "Scale t0 extraction data:        " + self.analysis_data_type

		# Retrieves t0 values from data
		a_values = []
		a_values_err = []
		t0_values = []
		t0err_values = []

		for beta, bval in sorted(self.plot_values.items(), key=lambda i: i[0]):
			y0, t0, t0_err, _, _ = extract_fit_target(E0, bval["t"], bval["y"],
				y_err=bval["y_err"], y_raw=bval[self.analysis_data_type], 
				tau_int=bval["tau_int"], tau_int_err=bval["tau_int_err"],
				extrapolation_method=extrapolation_method, plateau_size=10,
				inverse_fit=True, **kwargs)

			a_values.append(bval["a"]**2/t0)
			a_values_err.append(np.sqrt((2*bval["a_err"]*bval["a"]/t0)**2 \
				+ (bval["a"]**2*t0_err/t0**2)**2))

			t0_values.append(t0)
			t0err_values.append(t0_err)

		a_values = np.asarray(a_values[::-1])
		a_values_err = np.asarray(a_values_err[::-1])
		t0_values = np.asarray(t0_values[::-1])
		t0err_values = np.asarray(t0err_values[::-1])		

		# Functions for t0 and propagating uncertainty
		t0_func = lambda _t0: np.sqrt(8*_t0)/self.r0
		t0err_func = lambda _t0, _t0_err: _t0_err*np.sqrt(8/_t0)/(2.0*self.r0)

		# Sets up t0 and t0_error values to plot
		y = t0_func(t0_values)
		yerr = t0err_func(t0_values, t0err_values)

		# Extrapolates t0 to continuum
		N_cont = 1000
		a_squared_cont = np.linspace(-0.025, a_values[-1]*1.1, N_cont)

		# Fits to continuum and retrieves values to be plotted
		continuum_fit = LineFit(a_values, y, y_err=yerr)
		y_cont, y_cont_err, fit_params, chi_squared = \
			continuum_fit.fit_weighted(a_squared_cont)

		res = continuum_fit(0, weighted=True)
		self.sqrt_8t0_cont = res[0][0]
		self.sqrt_8t0_cont_error = (res[1][-1][0] - res[1][0][0])/2
		self.t0_cont = self.sqrt_8t0_cont**2/8
		self.t0_cont_error = self.sqrt_8t0_cont_error*np.sqrt(self.t0_cont/2.0)

		# Creates figure and plot window
		fig = plt.figure()
		ax = fig.add_subplot(111)
		# Plots linefit with errorband
		ax.plot(a_squared_cont, y_cont, color="tab:red", alpha=0.5,
			label=r"$\chi=%.2f$" % chi_squared)
		ax.fill_between(a_squared_cont, y_cont_err[0], 
			y_cont_err[1], alpha=0.5, edgecolor='',
			facecolor="tab:red")
		ax.axvline(0, linestyle="dashed", color="tab:red")
		ax.errorbar(a_values, y, xerr=a_values_err, yerr=yerr, fmt="o", capsize=5,
			capthick=1, color="#000000", ecolor="#000000")
		ax.set_ylabel(r"$\sqrt{8t_0}/r_0$")
		ax.set_xlabel(r"$a^2/t_0$")
		ax.set_xlim(a_squared_cont[0], a_squared_cont[-1])
		ax.legend()
		ax.grid(True)

		# Saves figure
		fname = os.path.join(self.output_folder_path, 
			"post_analysis_extrapmethod%s_t0reference_continuum_%s.png" % (
				extrapolation_method, self.analysis_data_type))
		fig.savefig(fname, dpi=self.dpi)
		if self.verbose:
			print "Figure saved in %s" % fname

		plt.close(fig)

		self.extrapolation_method = extrapolation_method

		_tmp_beta_dict = {
			b: {
				"t0": t0_values[i],
				"t0err": t0err_values[i],
				"t0a2": t0_values[i]/self.plot_values[b]["a"]**2,
				# Including error term in lattice spacing, a
				"t0a2err": np.sqrt((t0err_values[i]/self.plot_values[b]["a"]**2)**2 \
					+ (2*self.plot_values[b]["a_err"]*t0_values[i]/self.plot_values[b]["a"]**3)**2),
				"t0r02": t0_values[i]/self.r0**2,
				"t0r02err": t0err_values[i]/self.r0**2,
				"aL": self.plot_values[b]["a"]*self.lattice_sizes[b][0],
				"aLerr": (self.plot_values[b]["a_err"] \
					* self.lattice_sizes[b][0]),
				"L": self.lattice_sizes[b][0],
				"a": self.plot_values[beta]["a"],
				"a_err": self.plot_values[b]["a_err"],
			}
			for i, b in enumerate(self.beta_values)
		}

		t0_dict = {"t0cont": self.t0_cont, "t0cont_err": self.t0_cont_error}
		t0_dict.update(_tmp_beta_dict)

		if self.verbose:
			print "t0 reference values table: "
			print "sqrt(8t0)/r0 = %.16f +/- %.16f" % (self.sqrt_8t0_cont,
				self.sqrt_8t0_cont_error)
			print "t0 = %.16f +/- %.16f" % (self.t0_cont,
				self.t0_cont_error)
			for b in self.beta_values:
				msg = "beta = %.2f || t0 = %10f +/- %-10f" % (b, 
					t0_dict[b]["t0"], t0_dict[b]["t0err"])
				msg += " || t0/a^2 = %10f +/- %-10f" % (t0_dict[b]["t0a2"], 
					t0_dict[b]["t0a2err"])
				msg += " || t0/a^2 = %10f +/- %-10f" % (t0_dict[b]["t0a2"], 
					t0_dict[b]["t0a2err"])
				msg += " || t0/r0^2 = %10f +/- %-10f" % (t0_dict[b]["t0r02"],
					t0_dict[b]["t0r02err"])
				print msg

		if self.print_latex:
			# Header:
			# beta   t0a2   t0r02   L/a   L   a

			header = [r"$\beta$", r"$t_0/a^2$", r"$t_0/{r_0^2}$", r"$L/a$",
				r"$L[\fm]$", r"$a[\fm]$"]

			bvals = self.beta_values
			tab = [
				[r"{0:.2f}".format(b) for b in bvals],
				[r"{0:s}".format(sciprint.sciprint(t0_dict[b]["t0a2"], 
					t0_dict[b]["t0a2err"])) for b in bvals],
				[r"{0:s}".format(sciprint.sciprint(t0_dict[b]["t0r02"], 
					t0_dict[b]["t0r02err"])) for b in bvals],
				[r"{0:d}".format(self.lattice_sizes[b][0]) for b in bvals],
				[r"{0:s}".format(sciprint.sciprint(
					self.lattice_sizes[b][0]*self.plot_values[b]["a"], 
					self.lattice_sizes[b][0]*self.plot_values[b]["a_err"])) 
					for b in bvals],
				[r"{0:s}".format(sciprint.sciprint(
					self.plot_values[b]["a"],
					self.plot_values[b]["a_err"])) for b in bvals],
			]

			ptab = TablePrinter(header, tab)			
			ptab.print_table(latex=True, width=15)

		return t0_dict