pyerrors.input.misc
1import os 2import fnmatch 3import re 4import struct 5import warnings 6import numpy as np # Thinly-wrapped numpy 7import matplotlib.pyplot as plt 8from matplotlib import gridspec 9from ..obs import Obs 10from ..fits import fit_lin 11 12 13def fit_t0(t2E_dict, fit_range, plot_fit=False, observable='t0'): 14 """Compute the root of (flow-based) data based on a dictionary that contains 15 the necessary information in key-value pairs a la (flow time: observable at flow time). 16 17 It is assumed that the data is monotonically increasing and passes zero from below. 18 No exception is thrown if this is not the case (several roots, no monotonic increase). 19 An exception is thrown if no root can be found in the data. 20 21 A linear fit in the vicinity of the root is performed to exctract the root from the 22 two fit parameters. 23 24 Parameters 25 ---------- 26 t2E_dict : dict 27 Dictionary with pairs of (flow time: observable at flow time) where the flow times 28 are of type float and the observables of type Obs. 29 fit_range : int 30 Number of data points left and right of the zero 31 crossing to be included in the linear fit. 32 plot_fit : bool 33 If true, the fit for the extraction of t0 is shown together with the data. (Default: False) 34 observable: str 35 Keyword to identify the observable to print the correct ylabel (if plot_fit is True) 36 for the observables 't0' and 'w0'. No y label is printed otherwise. (Default: 't0') 37 38 Returns 39 ------- 40 root : Obs 41 The root of the data series. 42 """ 43 44 zero_crossing = np.argmax(np.array( 45 [o.value for o in t2E_dict.values()]) > 0.0) 46 47 if zero_crossing == 0: 48 raise Exception('Desired flow time not in data') 49 50 x = list(t2E_dict.keys())[zero_crossing - fit_range: 51 zero_crossing + fit_range] 52 y = list(t2E_dict.values())[zero_crossing - fit_range: 53 zero_crossing + fit_range] 54 [o.gamma_method() for o in y] 55 56 if len(x) < 2 * fit_range: 57 warnings.warn('Fit range smaller than expected! Fitting from %1.2e to %1.2e' % (x[0], x[-1])) 58 59 fit_result = fit_lin(x, y) 60 61 if plot_fit is True: 62 plt.figure() 63 gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1], wspace=0.0, hspace=0.0) 64 ax0 = plt.subplot(gs[0]) 65 xmore = list(t2E_dict.keys())[zero_crossing - fit_range - 2: zero_crossing + fit_range + 2] 66 ymore = list(t2E_dict.values())[zero_crossing - fit_range - 2: zero_crossing + fit_range + 2] 67 [o.gamma_method() for o in ymore] 68 ax0.errorbar(xmore, [yi.value for yi in ymore], yerr=[yi.dvalue for yi in ymore], fmt='x') 69 xplot = np.linspace(np.min(x), np.max(x)) 70 yplot = [fit_result[0] + fit_result[1] * xi for xi in xplot] 71 [yi.gamma_method() for yi in yplot] 72 ax0.fill_between(xplot, y1=[yi.value - yi.dvalue for yi in yplot], y2=[yi.value + yi.dvalue for yi in yplot]) 73 retval = (-fit_result[0] / fit_result[1]) 74 retval.gamma_method() 75 ylim = ax0.get_ylim() 76 ax0.fill_betweenx(ylim, x1=retval.value - retval.dvalue, x2=retval.value + retval.dvalue, color='gray', alpha=0.4) 77 ax0.set_ylim(ylim) 78 if observable == 't0': 79 ax0.set_ylabel(r'$t^2 \langle E(t) \rangle - 0.3 $') 80 elif observable == 'w0': 81 ax0.set_ylabel(r'$t d(t^2 \langle E(t) \rangle)/dt - 0.3 $') 82 xlim = ax0.get_xlim() 83 84 fit_res = [fit_result[0] + fit_result[1] * xi for xi in x] 85 residuals = (np.asarray([o.value for o in y]) - [o.value for o in fit_res]) / np.asarray([o.dvalue for o in y]) 86 ax1 = plt.subplot(gs[1]) 87 ax1.plot(x, residuals, 'ko', ls='none', markersize=5) 88 ax1.tick_params(direction='out') 89 ax1.tick_params(axis="x", bottom=True, top=True, labelbottom=True) 90 ax1.axhline(y=0.0, ls='--', color='k') 91 ax1.fill_between(xlim, -1.0, 1.0, alpha=0.1, facecolor='k') 92 ax1.set_xlim(xlim) 93 ax1.set_ylabel('Residuals') 94 ax1.set_xlabel(r'$t/a^2$') 95 96 plt.draw() 97 return -fit_result[0] / fit_result[1] 98 99 100def read_pbp(path, prefix, **kwargs): 101 """Read pbp format from given folder structure. 102 103 Parameters 104 ---------- 105 r_start : list 106 list which contains the first config to be read for each replicum 107 r_stop : list 108 list which contains the last config to be read for each replicum 109 110 Returns 111 ------- 112 result : list[Obs] 113 list of observables read 114 """ 115 116 ls = [] 117 for (dirpath, dirnames, filenames) in os.walk(path): 118 ls.extend(filenames) 119 break 120 121 if not ls: 122 raise Exception('Error, directory not found') 123 124 # Exclude files with different names 125 for exc in ls: 126 if not fnmatch.fnmatch(exc, prefix + '*.dat'): 127 ls = list(set(ls) - set([exc])) 128 if len(ls) > 1: 129 ls.sort(key=lambda x: int(re.findall(r'\d+', x[len(prefix):])[0])) 130 replica = len(ls) 131 132 if 'r_start' in kwargs: 133 r_start = kwargs.get('r_start') 134 if len(r_start) != replica: 135 raise Exception('r_start does not match number of replicas') 136 # Adjust Configuration numbering to python index 137 r_start = [o - 1 if o else None for o in r_start] 138 else: 139 r_start = [None] * replica 140 141 if 'r_stop' in kwargs: 142 r_stop = kwargs.get('r_stop') 143 if len(r_stop) != replica: 144 raise Exception('r_stop does not match number of replicas') 145 else: 146 r_stop = [None] * replica 147 148 print(r'Read <bar{psi}\psi> from', prefix[:-1], ',', replica, 'replica', end='') 149 150 print_err = 0 151 if 'print_err' in kwargs: 152 print_err = 1 153 print() 154 155 deltas = [] 156 157 for rep in range(replica): 158 tmp_array = [] 159 with open(path + '/' + ls[rep], 'rb') as fp: 160 161 t = fp.read(4) # number of reweighting factors 162 if rep == 0: 163 nrw = struct.unpack('i', t)[0] 164 for k in range(nrw): 165 deltas.append([]) 166 else: 167 if nrw != struct.unpack('i', t)[0]: 168 raise Exception('Error: different number of factors for replicum', rep) 169 170 for k in range(nrw): 171 tmp_array.append([]) 172 173 # This block is necessary for openQCD1.6 ms1 files 174 nfct = [] 175 for i in range(nrw): 176 t = fp.read(4) 177 nfct.append(struct.unpack('i', t)[0]) 178 print('nfct: ', nfct) # Hasenbusch factor, 1 for rat reweighting 179 180 nsrc = [] 181 for i in range(nrw): 182 t = fp.read(4) 183 nsrc.append(struct.unpack('i', t)[0]) 184 185 # body 186 while True: 187 t = fp.read(4) 188 if len(t) < 4: 189 break 190 if print_err: 191 config_no = struct.unpack('i', t) 192 for i in range(nrw): 193 tmp_nfct = 1.0 194 for j in range(nfct[i]): 195 t = fp.read(8 * nsrc[i]) 196 t = fp.read(8 * nsrc[i]) 197 tmp_rw = struct.unpack('d' * nsrc[i], t) 198 tmp_nfct *= np.mean(np.asarray(tmp_rw)) 199 if print_err: 200 print(config_no, i, j, np.mean(np.asarray(tmp_rw)), np.std(np.asarray(tmp_rw))) 201 print('Sources:', np.asarray(tmp_rw)) 202 print('Partial factor:', tmp_nfct) 203 tmp_array[i].append(tmp_nfct) 204 205 for k in range(nrw): 206 deltas[k].append(tmp_array[k][r_start[rep]:r_stop[rep]]) 207 208 rep_names = [] 209 for entry in ls: 210 truncated_entry = entry.split('.')[0] 211 idx = truncated_entry.index('r') 212 rep_names.append(truncated_entry[:idx] + '|' + truncated_entry[idx:]) 213 print(',', nrw, r'<bar{psi}\psi> with', nsrc, 'sources') 214 result = [] 215 for t in range(nrw): 216 result.append(Obs(deltas[t], rep_names)) 217 218 return result
def
fit_t0(t2E_dict, fit_range, plot_fit=False, observable='t0'):
14def fit_t0(t2E_dict, fit_range, plot_fit=False, observable='t0'): 15 """Compute the root of (flow-based) data based on a dictionary that contains 16 the necessary information in key-value pairs a la (flow time: observable at flow time). 17 18 It is assumed that the data is monotonically increasing and passes zero from below. 19 No exception is thrown if this is not the case (several roots, no monotonic increase). 20 An exception is thrown if no root can be found in the data. 21 22 A linear fit in the vicinity of the root is performed to exctract the root from the 23 two fit parameters. 24 25 Parameters 26 ---------- 27 t2E_dict : dict 28 Dictionary with pairs of (flow time: observable at flow time) where the flow times 29 are of type float and the observables of type Obs. 30 fit_range : int 31 Number of data points left and right of the zero 32 crossing to be included in the linear fit. 33 plot_fit : bool 34 If true, the fit for the extraction of t0 is shown together with the data. (Default: False) 35 observable: str 36 Keyword to identify the observable to print the correct ylabel (if plot_fit is True) 37 for the observables 't0' and 'w0'. No y label is printed otherwise. (Default: 't0') 38 39 Returns 40 ------- 41 root : Obs 42 The root of the data series. 43 """ 44 45 zero_crossing = np.argmax(np.array( 46 [o.value for o in t2E_dict.values()]) > 0.0) 47 48 if zero_crossing == 0: 49 raise Exception('Desired flow time not in data') 50 51 x = list(t2E_dict.keys())[zero_crossing - fit_range: 52 zero_crossing + fit_range] 53 y = list(t2E_dict.values())[zero_crossing - fit_range: 54 zero_crossing + fit_range] 55 [o.gamma_method() for o in y] 56 57 if len(x) < 2 * fit_range: 58 warnings.warn('Fit range smaller than expected! Fitting from %1.2e to %1.2e' % (x[0], x[-1])) 59 60 fit_result = fit_lin(x, y) 61 62 if plot_fit is True: 63 plt.figure() 64 gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1], wspace=0.0, hspace=0.0) 65 ax0 = plt.subplot(gs[0]) 66 xmore = list(t2E_dict.keys())[zero_crossing - fit_range - 2: zero_crossing + fit_range + 2] 67 ymore = list(t2E_dict.values())[zero_crossing - fit_range - 2: zero_crossing + fit_range + 2] 68 [o.gamma_method() for o in ymore] 69 ax0.errorbar(xmore, [yi.value for yi in ymore], yerr=[yi.dvalue for yi in ymore], fmt='x') 70 xplot = np.linspace(np.min(x), np.max(x)) 71 yplot = [fit_result[0] + fit_result[1] * xi for xi in xplot] 72 [yi.gamma_method() for yi in yplot] 73 ax0.fill_between(xplot, y1=[yi.value - yi.dvalue for yi in yplot], y2=[yi.value + yi.dvalue for yi in yplot]) 74 retval = (-fit_result[0] / fit_result[1]) 75 retval.gamma_method() 76 ylim = ax0.get_ylim() 77 ax0.fill_betweenx(ylim, x1=retval.value - retval.dvalue, x2=retval.value + retval.dvalue, color='gray', alpha=0.4) 78 ax0.set_ylim(ylim) 79 if observable == 't0': 80 ax0.set_ylabel(r'$t^2 \langle E(t) \rangle - 0.3 $') 81 elif observable == 'w0': 82 ax0.set_ylabel(r'$t d(t^2 \langle E(t) \rangle)/dt - 0.3 $') 83 xlim = ax0.get_xlim() 84 85 fit_res = [fit_result[0] + fit_result[1] * xi for xi in x] 86 residuals = (np.asarray([o.value for o in y]) - [o.value for o in fit_res]) / np.asarray([o.dvalue for o in y]) 87 ax1 = plt.subplot(gs[1]) 88 ax1.plot(x, residuals, 'ko', ls='none', markersize=5) 89 ax1.tick_params(direction='out') 90 ax1.tick_params(axis="x", bottom=True, top=True, labelbottom=True) 91 ax1.axhline(y=0.0, ls='--', color='k') 92 ax1.fill_between(xlim, -1.0, 1.0, alpha=0.1, facecolor='k') 93 ax1.set_xlim(xlim) 94 ax1.set_ylabel('Residuals') 95 ax1.set_xlabel(r'$t/a^2$') 96 97 plt.draw() 98 return -fit_result[0] / fit_result[1]
Compute the root of (flow-based) data based on a dictionary that contains the necessary information in key-value pairs a la (flow time: observable at flow time).
It is assumed that the data is monotonically increasing and passes zero from below. No exception is thrown if this is not the case (several roots, no monotonic increase). An exception is thrown if no root can be found in the data.
A linear fit in the vicinity of the root is performed to exctract the root from the two fit parameters.
Parameters
- t2E_dict (dict): Dictionary with pairs of (flow time: observable at flow time) where the flow times are of type float and the observables of type Obs.
- fit_range (int): Number of data points left and right of the zero crossing to be included in the linear fit.
- plot_fit (bool): If true, the fit for the extraction of t0 is shown together with the data. (Default: False)
- observable (str): Keyword to identify the observable to print the correct ylabel (if plot_fit is True) for the observables 't0' and 'w0'. No y label is printed otherwise. (Default: 't0')
Returns
- root (Obs): The root of the data series.
def
read_pbp(path, prefix, **kwargs):
101def read_pbp(path, prefix, **kwargs): 102 """Read pbp format from given folder structure. 103 104 Parameters 105 ---------- 106 r_start : list 107 list which contains the first config to be read for each replicum 108 r_stop : list 109 list which contains the last config to be read for each replicum 110 111 Returns 112 ------- 113 result : list[Obs] 114 list of observables read 115 """ 116 117 ls = [] 118 for (dirpath, dirnames, filenames) in os.walk(path): 119 ls.extend(filenames) 120 break 121 122 if not ls: 123 raise Exception('Error, directory not found') 124 125 # Exclude files with different names 126 for exc in ls: 127 if not fnmatch.fnmatch(exc, prefix + '*.dat'): 128 ls = list(set(ls) - set([exc])) 129 if len(ls) > 1: 130 ls.sort(key=lambda x: int(re.findall(r'\d+', x[len(prefix):])[0])) 131 replica = len(ls) 132 133 if 'r_start' in kwargs: 134 r_start = kwargs.get('r_start') 135 if len(r_start) != replica: 136 raise Exception('r_start does not match number of replicas') 137 # Adjust Configuration numbering to python index 138 r_start = [o - 1 if o else None for o in r_start] 139 else: 140 r_start = [None] * replica 141 142 if 'r_stop' in kwargs: 143 r_stop = kwargs.get('r_stop') 144 if len(r_stop) != replica: 145 raise Exception('r_stop does not match number of replicas') 146 else: 147 r_stop = [None] * replica 148 149 print(r'Read <bar{psi}\psi> from', prefix[:-1], ',', replica, 'replica', end='') 150 151 print_err = 0 152 if 'print_err' in kwargs: 153 print_err = 1 154 print() 155 156 deltas = [] 157 158 for rep in range(replica): 159 tmp_array = [] 160 with open(path + '/' + ls[rep], 'rb') as fp: 161 162 t = fp.read(4) # number of reweighting factors 163 if rep == 0: 164 nrw = struct.unpack('i', t)[0] 165 for k in range(nrw): 166 deltas.append([]) 167 else: 168 if nrw != struct.unpack('i', t)[0]: 169 raise Exception('Error: different number of factors for replicum', rep) 170 171 for k in range(nrw): 172 tmp_array.append([]) 173 174 # This block is necessary for openQCD1.6 ms1 files 175 nfct = [] 176 for i in range(nrw): 177 t = fp.read(4) 178 nfct.append(struct.unpack('i', t)[0]) 179 print('nfct: ', nfct) # Hasenbusch factor, 1 for rat reweighting 180 181 nsrc = [] 182 for i in range(nrw): 183 t = fp.read(4) 184 nsrc.append(struct.unpack('i', t)[0]) 185 186 # body 187 while True: 188 t = fp.read(4) 189 if len(t) < 4: 190 break 191 if print_err: 192 config_no = struct.unpack('i', t) 193 for i in range(nrw): 194 tmp_nfct = 1.0 195 for j in range(nfct[i]): 196 t = fp.read(8 * nsrc[i]) 197 t = fp.read(8 * nsrc[i]) 198 tmp_rw = struct.unpack('d' * nsrc[i], t) 199 tmp_nfct *= np.mean(np.asarray(tmp_rw)) 200 if print_err: 201 print(config_no, i, j, np.mean(np.asarray(tmp_rw)), np.std(np.asarray(tmp_rw))) 202 print('Sources:', np.asarray(tmp_rw)) 203 print('Partial factor:', tmp_nfct) 204 tmp_array[i].append(tmp_nfct) 205 206 for k in range(nrw): 207 deltas[k].append(tmp_array[k][r_start[rep]:r_stop[rep]]) 208 209 rep_names = [] 210 for entry in ls: 211 truncated_entry = entry.split('.')[0] 212 idx = truncated_entry.index('r') 213 rep_names.append(truncated_entry[:idx] + '|' + truncated_entry[idx:]) 214 print(',', nrw, r'<bar{psi}\psi> with', nsrc, 'sources') 215 result = [] 216 for t in range(nrw): 217 result.append(Obs(deltas[t], rep_names)) 218 219 return result
Read pbp format from given folder structure.
Parameters
- r_start (list): list which contains the first config to be read for each replicum
- r_stop (list): list which contains the last config to be read for each replicum
Returns
- result (list[Obs]): list of observables read