pyerrors.misc

  1import pickle
  2import numpy as np
  3import matplotlib.pyplot as plt
  4from .obs import Obs
  5
  6
  7def errorbar(x, y, axes=plt, **kwargs):
  8    """pyerrors wrapper for the errorbars method of matplotlib
  9
 10    Parameters
 11    ----------
 12    x : list
 13        A list of x-values which can be Obs.
 14    y : list
 15        A list of y-values which can be Obs.
 16    axes : (matplotlib.pyplot.axes)
 17        The axes to plot on. default is plt.
 18    """
 19    val = {}
 20    err = {}
 21    for name, comp in zip(["x", "y"], [x, y]):
 22        if all(isinstance(o, Obs) for o in comp):
 23            if not all(hasattr(o, 'e_dvalue') for o in comp):
 24                [o.gamma_method() for o in comp]
 25            val[name] = [o.value for o in comp]
 26            err[name] = [o.dvalue for o in comp]
 27        else:
 28            val[name] = comp
 29            err[name] = None
 30
 31        if f"{name}err" in kwargs:
 32            err[name] = kwargs.get(f"{name}err")
 33            kwargs.pop(f"{name}err", None)
 34
 35    axes.errorbar(val["x"], val["y"], xerr=err["x"], yerr=err["y"], **kwargs)
 36
 37
 38def dump_object(obj, name, **kwargs):
 39    """Dump object into pickle file.
 40
 41    Parameters
 42    ----------
 43    obj : object
 44        object to be saved in the pickle file
 45    name : str
 46        name of the file
 47    path : str
 48        specifies a custom path for the file (default '.')
 49
 50    Returns
 51    -------
 52    None
 53    """
 54    if 'path' in kwargs:
 55        file_name = kwargs.get('path') + '/' + name + '.p'
 56    else:
 57        file_name = name + '.p'
 58    with open(file_name, 'wb') as fb:
 59        pickle.dump(obj, fb)
 60
 61
 62def load_object(path):
 63    """Load object from pickle file.
 64
 65    Parameters
 66    ----------
 67    path : str
 68        path to the file
 69
 70    Returns
 71    -------
 72    object : Obs
 73        Loaded Object
 74    """
 75    with open(path, 'rb') as file:
 76        return pickle.load(file)
 77
 78
 79def pseudo_Obs(value, dvalue, name, samples=1000):
 80    """Generate an Obs object with given value, dvalue and name for test purposes
 81
 82    Parameters
 83    ----------
 84    value : float
 85        central value of the Obs to be generated.
 86    dvalue : float
 87        error of the Obs to be generated.
 88    name : str
 89        name of the ensemble for which the Obs is to be generated.
 90    samples: int
 91        number of samples for the Obs (default 1000).
 92
 93    Returns
 94    -------
 95    res : Obs
 96        Generated Observable
 97    """
 98    if dvalue <= 0.0:
 99        return Obs([np.zeros(samples) + value], [name])
100    else:
101        for _ in range(100):
102            deltas = [np.random.normal(0.0, dvalue * np.sqrt(samples), samples)]
103            deltas -= np.mean(deltas)
104            deltas *= dvalue / np.sqrt((np.var(deltas) / samples)) / np.sqrt(1 + 3 / samples)
105            deltas += value
106            res = Obs(deltas, [name])
107            res.gamma_method(S=2, tau_exp=0)
108            if abs(res.dvalue - dvalue) < 1e-10 * dvalue:
109                break
110
111        res._value = float(value)
112
113        return res
114
115
116def gen_correlated_data(means, cov, name, tau=0.5, samples=1000):
117    """ Generate observables with given covariance and autocorrelation times.
118
119    Parameters
120    ----------
121    means : list
122        list containing the mean value of each observable.
123    cov : numpy.ndarray
124        covariance matrix for the data to be generated.
125    name : str
126        ensemble name for the data to be geneated.
127    tau : float or list
128        can either be a real number or a list with an entry for
129        every dataset.
130    samples : int
131        number of samples to be generated for each observable.
132
133    Returns
134    -------
135    corr_obs : list[Obs]
136        Generated observable list
137    """
138
139    assert len(means) == cov.shape[-1]
140    tau = np.asarray(tau)
141    if np.min(tau) < 0.5:
142        raise Exception('All integrated autocorrelations have to be >= 0.5.')
143
144    a = (2 * tau - 1) / (2 * tau + 1)
145    rand = np.random.multivariate_normal(np.zeros_like(means), cov * samples, samples)
146
147    # Normalize samples such that sample variance matches input
148    norm = np.array([np.var(o, ddof=1) / samples for o in rand.T])
149    rand = rand @ np.diag(np.sqrt(np.diag(cov))) @ np.diag(1 / np.sqrt(norm))
150
151    data = [rand[0]]
152    for i in range(1, samples):
153        data.append(np.sqrt(1 - a ** 2) * rand[i] + a * data[-1])
154    corr_data = np.array(data) - np.mean(data, axis=0) + means
155    return [Obs([dat], [name]) for dat in corr_data.T]
156
157
158def _assert_equal_properties(ol, otype=Obs):
159    otype = type(ol[0])
160    for o in ol[1:]:
161        if not isinstance(o, otype):
162            raise Exception("Wrong data type in list.")
163        for attr in ["reweighted", "e_content", "idl"]:
164            if hasattr(ol[0], attr):
165                if not getattr(ol[0], attr) == getattr(o, attr):
166                    raise Exception(f"All Obs in list have to have the same state '{attr}'.")
def errorbar( x, y, axes=<module 'matplotlib.pyplot' from '/opt/hostedtoolcache/Python/3.10.9/x64/lib/python3.10/site-packages/matplotlib/pyplot.py'>, **kwargs):
 8def errorbar(x, y, axes=plt, **kwargs):
 9    """pyerrors wrapper for the errorbars method of matplotlib
10
11    Parameters
12    ----------
13    x : list
14        A list of x-values which can be Obs.
15    y : list
16        A list of y-values which can be Obs.
17    axes : (matplotlib.pyplot.axes)
18        The axes to plot on. default is plt.
19    """
20    val = {}
21    err = {}
22    for name, comp in zip(["x", "y"], [x, y]):
23        if all(isinstance(o, Obs) for o in comp):
24            if not all(hasattr(o, 'e_dvalue') for o in comp):
25                [o.gamma_method() for o in comp]
26            val[name] = [o.value for o in comp]
27            err[name] = [o.dvalue for o in comp]
28        else:
29            val[name] = comp
30            err[name] = None
31
32        if f"{name}err" in kwargs:
33            err[name] = kwargs.get(f"{name}err")
34            kwargs.pop(f"{name}err", None)
35
36    axes.errorbar(val["x"], val["y"], xerr=err["x"], yerr=err["y"], **kwargs)

pyerrors wrapper for the errorbars method of matplotlib

Parameters
  • x (list): A list of x-values which can be Obs.
  • y (list): A list of y-values which can be Obs.
  • axes ((matplotlib.pyplot.axes)): The axes to plot on. default is plt.
def dump_object(obj, name, **kwargs):
39def dump_object(obj, name, **kwargs):
40    """Dump object into pickle file.
41
42    Parameters
43    ----------
44    obj : object
45        object to be saved in the pickle file
46    name : str
47        name of the file
48    path : str
49        specifies a custom path for the file (default '.')
50
51    Returns
52    -------
53    None
54    """
55    if 'path' in kwargs:
56        file_name = kwargs.get('path') + '/' + name + '.p'
57    else:
58        file_name = name + '.p'
59    with open(file_name, 'wb') as fb:
60        pickle.dump(obj, fb)

Dump object into pickle file.

Parameters
  • obj (object): object to be saved in the pickle file
  • name (str): name of the file
  • path (str): specifies a custom path for the file (default '.')
Returns
  • None
def load_object(path):
63def load_object(path):
64    """Load object from pickle file.
65
66    Parameters
67    ----------
68    path : str
69        path to the file
70
71    Returns
72    -------
73    object : Obs
74        Loaded Object
75    """
76    with open(path, 'rb') as file:
77        return pickle.load(file)

Load object from pickle file.

Parameters
  • path (str): path to the file
Returns
  • object (Obs): Loaded Object
def pseudo_Obs(value, dvalue, name, samples=1000):
 80def pseudo_Obs(value, dvalue, name, samples=1000):
 81    """Generate an Obs object with given value, dvalue and name for test purposes
 82
 83    Parameters
 84    ----------
 85    value : float
 86        central value of the Obs to be generated.
 87    dvalue : float
 88        error of the Obs to be generated.
 89    name : str
 90        name of the ensemble for which the Obs is to be generated.
 91    samples: int
 92        number of samples for the Obs (default 1000).
 93
 94    Returns
 95    -------
 96    res : Obs
 97        Generated Observable
 98    """
 99    if dvalue <= 0.0:
100        return Obs([np.zeros(samples) + value], [name])
101    else:
102        for _ in range(100):
103            deltas = [np.random.normal(0.0, dvalue * np.sqrt(samples), samples)]
104            deltas -= np.mean(deltas)
105            deltas *= dvalue / np.sqrt((np.var(deltas) / samples)) / np.sqrt(1 + 3 / samples)
106            deltas += value
107            res = Obs(deltas, [name])
108            res.gamma_method(S=2, tau_exp=0)
109            if abs(res.dvalue - dvalue) < 1e-10 * dvalue:
110                break
111
112        res._value = float(value)
113
114        return res

Generate an Obs object with given value, dvalue and name for test purposes

Parameters
  • value (float): central value of the Obs to be generated.
  • dvalue (float): error of the Obs to be generated.
  • name (str): name of the ensemble for which the Obs is to be generated.
  • samples (int): number of samples for the Obs (default 1000).
Returns
  • res (Obs): Generated Observable
def gen_correlated_data(means, cov, name, tau=0.5, samples=1000):
117def gen_correlated_data(means, cov, name, tau=0.5, samples=1000):
118    """ Generate observables with given covariance and autocorrelation times.
119
120    Parameters
121    ----------
122    means : list
123        list containing the mean value of each observable.
124    cov : numpy.ndarray
125        covariance matrix for the data to be generated.
126    name : str
127        ensemble name for the data to be geneated.
128    tau : float or list
129        can either be a real number or a list with an entry for
130        every dataset.
131    samples : int
132        number of samples to be generated for each observable.
133
134    Returns
135    -------
136    corr_obs : list[Obs]
137        Generated observable list
138    """
139
140    assert len(means) == cov.shape[-1]
141    tau = np.asarray(tau)
142    if np.min(tau) < 0.5:
143        raise Exception('All integrated autocorrelations have to be >= 0.5.')
144
145    a = (2 * tau - 1) / (2 * tau + 1)
146    rand = np.random.multivariate_normal(np.zeros_like(means), cov * samples, samples)
147
148    # Normalize samples such that sample variance matches input
149    norm = np.array([np.var(o, ddof=1) / samples for o in rand.T])
150    rand = rand @ np.diag(np.sqrt(np.diag(cov))) @ np.diag(1 / np.sqrt(norm))
151
152    data = [rand[0]]
153    for i in range(1, samples):
154        data.append(np.sqrt(1 - a ** 2) * rand[i] + a * data[-1])
155    corr_data = np.array(data) - np.mean(data, axis=0) + means
156    return [Obs([dat], [name]) for dat in corr_data.T]

Generate observables with given covariance and autocorrelation times.

Parameters
  • means (list): list containing the mean value of each observable.
  • cov (numpy.ndarray): covariance matrix for the data to be generated.
  • name (str): ensemble name for the data to be geneated.
  • tau (float or list): can either be a real number or a list with an entry for every dataset.
  • samples (int): number of samples to be generated for each observable.
Returns
  • corr_obs (list[Obs]): Generated observable list