pyerrors.input.bdio

  1import ctypes
  2import hashlib
  3import autograd.numpy as np  # Thinly-wrapped numpy
  4from ..obs import Obs
  5
  6
  7def read_ADerrors(file_path, bdio_path='./libbdio.so', **kwargs):
  8    """ Extract generic MCMC data from a bdio file
  9
 10    read_ADerrors requires bdio to be compiled into a shared library. This can be achieved by
 11    adding the flag -fPIC to CC and changing the all target to
 12
 13    all:		bdio.o $(LIBDIR)
 14                gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o
 15                cp $(BUILDDIR)/libbdio.so $(LIBDIR)/
 16
 17    Parameters
 18    ----------
 19    file_path -- path to the bdio file
 20    bdio_path -- path to the shared bdio library libbdio.so (default ./libbdio.so)
 21    """
 22    bdio = ctypes.cdll.LoadLibrary(bdio_path)
 23
 24    bdio_open = bdio.bdio_open
 25    bdio_open.restype = ctypes.c_void_p
 26
 27    bdio_close = bdio.bdio_close
 28    bdio_close.restype = ctypes.c_int
 29    bdio_close.argtypes = [ctypes.c_void_p]
 30
 31    bdio_seek_record = bdio.bdio_seek_record
 32    bdio_seek_record.restype = ctypes.c_int
 33    bdio_seek_record.argtypes = [ctypes.c_void_p]
 34
 35    bdio_get_rlen = bdio.bdio_get_rlen
 36    bdio_get_rlen.restype = ctypes.c_int
 37    bdio_get_rlen.argtypes = [ctypes.c_void_p]
 38
 39    bdio_get_ruinfo = bdio.bdio_get_ruinfo
 40    bdio_get_ruinfo.restype = ctypes.c_int
 41    bdio_get_ruinfo.argtypes = [ctypes.c_void_p]
 42
 43    bdio_read = bdio.bdio_read
 44    bdio_read.restype = ctypes.c_size_t
 45    bdio_read.argtypes = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_void_p]
 46
 47    bdio_read_f64 = bdio.bdio_read_f64
 48    bdio_read_f64.restype = ctypes.c_size_t
 49    bdio_read_f64.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
 50
 51    bdio_read_int32 = bdio.bdio_read_int32
 52    bdio_read_int32.restype = ctypes.c_size_t
 53    bdio_read_int32.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
 54
 55    b_path = file_path.encode('utf-8')
 56    read = 'r'
 57    b_read = read.encode('utf-8')
 58
 59    fbdio = bdio_open(ctypes.c_char_p(b_path), ctypes.c_char_p(b_read), None)
 60
 61    return_list = []
 62
 63    print('Reading of bdio file started')
 64    while True:
 65        bdio_seek_record(fbdio)
 66        ruinfo = bdio_get_ruinfo(fbdio)
 67
 68        if ruinfo == 7:
 69            print('MD5sum found')  # For now we just ignore these entries and do not perform any checks on them
 70            continue
 71
 72        if ruinfo < 0:
 73            # EOF reached
 74            break
 75        bdio_get_rlen(fbdio)
 76
 77        def read_c_double():
 78            d_buf = ctypes.c_double
 79            pd_buf = d_buf()
 80            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
 81            bdio_read_f64(ppd_buf, ctypes.c_size_t(8), ctypes.c_void_p(fbdio))
 82            return pd_buf.value
 83
 84        mean = read_c_double()
 85        print('mean', mean)
 86
 87        def read_c_size_t():
 88            d_buf = ctypes.c_size_t
 89            pd_buf = d_buf()
 90            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
 91            bdio_read_int32(ppd_buf, ctypes.c_size_t(4), ctypes.c_void_p(fbdio))
 92            return pd_buf.value
 93
 94        neid = read_c_size_t()
 95        print('neid', neid)
 96
 97        ndata = []
 98        for index in range(neid):
 99            ndata.append(read_c_size_t())
100        print('ndata', ndata)
101
102        nrep = []
103        for index in range(neid):
104            nrep.append(read_c_size_t())
105        print('nrep', nrep)
106
107        vrep = []
108        for index in range(neid):
109            vrep.append([])
110            for jndex in range(nrep[index]):
111                vrep[-1].append(read_c_size_t())
112        print('vrep', vrep)
113
114        ids = []
115        for index in range(neid):
116            ids.append(read_c_size_t())
117        print('ids', ids)
118
119        nt = []
120        for index in range(neid):
121            nt.append(read_c_size_t())
122        print('nt', nt)
123
124        zero = []
125        for index in range(neid):
126            zero.append(read_c_double())
127        print('zero', zero)
128
129        four = []
130        for index in range(neid):
131            four.append(read_c_double())
132        print('four', four)
133
134        d_buf = ctypes.c_double * np.sum(ndata)
135        pd_buf = d_buf()
136        ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
137        bdio_read_f64(ppd_buf, ctypes.c_size_t(8 * np.sum(ndata)), ctypes.c_void_p(fbdio))
138        delta = pd_buf[:]
139
140        samples = np.split(np.asarray(delta) + mean, np.cumsum([a for su in vrep for a in su])[:-1])
141        no_reps = [len(o) for o in vrep]
142        assert len(ids) == len(no_reps)
143        tmp_names = []
144        ens_length = max([len(str(o)) for o in ids])
145        for loc_id, reps in zip(ids, no_reps):
146            for index in range(reps):
147                missing_chars = ens_length - len(str(loc_id))
148                tmp_names.append(str(loc_id) + ' ' * missing_chars + '|r' + '{0:03d}'.format(index))
149
150        return_list.append(Obs(samples, tmp_names))
151
152    bdio_close(fbdio)
153    print()
154    print(len(return_list), 'observable(s) extracted.')
155    return return_list
156
157
158def write_ADerrors(obs_list, file_path, bdio_path='./libbdio.so', **kwargs):
159    """ Write Obs to a bdio file according to ADerrors conventions
160
161    read_mesons requires bdio to be compiled into a shared library. This can be achieved by
162    adding the flag -fPIC to CC and changing the all target to
163
164    all:		bdio.o $(LIBDIR)
165                gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o
166                cp $(BUILDDIR)/libbdio.so $(LIBDIR)/
167
168    Parameters
169    ----------
170    file_path -- path to the bdio file
171    bdio_path -- path to the shared bdio library libbdio.so (default ./libbdio.so)
172    """
173
174    for obs in obs_list:
175        if not hasattr(obs, 'e_names'):
176            raise Exception('Run the gamma method first for all obs.')
177
178    bdio = ctypes.cdll.LoadLibrary(bdio_path)
179
180    bdio_open = bdio.bdio_open
181    bdio_open.restype = ctypes.c_void_p
182
183    bdio_close = bdio.bdio_close
184    bdio_close.restype = ctypes.c_int
185    bdio_close.argtypes = [ctypes.c_void_p]
186
187    bdio_start_record = bdio.bdio_start_record
188    bdio_start_record.restype = ctypes.c_int
189    bdio_start_record.argtypes = [ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p]
190
191    bdio_flush_record = bdio.bdio_flush_record
192    bdio_flush_record.restype = ctypes.c_int
193    bdio_flush_record.argytpes = [ctypes.c_void_p]
194
195    bdio_write_f64 = bdio.bdio_write_f64
196    bdio_write_f64.restype = ctypes.c_size_t
197    bdio_write_f64.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
198
199    bdio_write_int32 = bdio.bdio_write_int32
200    bdio_write_int32.restype = ctypes.c_size_t
201    bdio_write_int32.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
202
203    b_path = file_path.encode('utf-8')
204    write = 'w'
205    b_write = write.encode('utf-8')
206    form = 'pyerrors ADerror export'
207    b_form = form.encode('utf-8')
208
209    fbdio = bdio_open(ctypes.c_char_p(b_path), ctypes.c_char_p(b_write), b_form)
210
211    for obs in obs_list:
212        # mean = obs.value
213        neid = len(obs.e_names)
214        vrep = [[obs.shape[o] for o in sl] for sl in list(obs.e_content.values())]
215        vrep_write = [item for sublist in vrep for item in sublist]
216        ndata = [np.sum(o) for o in vrep]
217        nrep = [len(o) for o in vrep]
218        print('ndata', ndata)
219        print('nrep', nrep)
220        print('vrep', vrep)
221        keys = list(obs.e_content.keys())
222        ids = []
223        for key in keys:
224            try:  # Try to convert key to integer
225                ids.append(int(key))
226            except Exception:  # If not possible construct a hash
227                ids.append(int(hashlib.sha256(key.encode('utf-8')).hexdigest(), 16) % 10 ** 8)
228        print('ids', ids)
229        nt = []
230        for e, e_name in enumerate(obs.e_names):
231
232            r_length = []
233            for r_name in obs.e_content[e_name]:
234                r_length.append(len(obs.deltas[r_name]))
235
236            # e_N = np.sum(r_length)
237            nt.append(max(r_length) // 2)
238        print('nt', nt)
239        zero = neid * [0.0]
240        four = neid * [4.0]
241        print('zero', zero)
242        print('four', four)
243        delta = np.concatenate([item for sublist in [[obs.deltas[o] for o in sl] for sl in list(obs.e_content.values())] for item in sublist])
244
245        bdio_start_record(0x00, 8, fbdio)
246
247        def write_c_double(double):
248            pd_buf = ctypes.c_double(double)
249            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
250            bdio_write_f64(ppd_buf, ctypes.c_size_t(8), ctypes.c_void_p(fbdio))
251
252        def write_c_size_t(int32):
253            pd_buf = ctypes.c_size_t(int32)
254            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
255            bdio_write_int32(ppd_buf, ctypes.c_size_t(4), ctypes.c_void_p(fbdio))
256
257        write_c_double(obs.value)
258        write_c_size_t(neid)
259
260        for element in ndata:
261            write_c_size_t(element)
262        for element in nrep:
263            write_c_size_t(element)
264        for element in vrep_write:
265            write_c_size_t(element)
266        for element in ids:
267            write_c_size_t(element)
268        for element in nt:
269            write_c_size_t(element)
270
271        for element in zero:
272            write_c_double(element)
273        for element in four:
274            write_c_double(element)
275
276        for element in delta:
277            write_c_double(element)
278
279    bdio_close(fbdio)
280    return 0
281
282
283def _get_kwd(string, key):
284    return (string.split(key, 1)[1]).split(" ", 1)[0]
285
286
287def _get_corr_name(string, key):
288    return (string.split(key, 1)[1]).split(' NDIM=', 1)[0]
289
290
291def read_mesons(file_path, bdio_path='./libbdio.so', **kwargs):
292    """ Extract mesons data from a bdio file and return it as a dictionary
293
294    The dictionary can be accessed with a tuple consisting of (type, source_position, kappa1, kappa2)
295
296    read_mesons requires bdio to be compiled into a shared library. This can be achieved by
297    adding the flag -fPIC to CC and changing the all target to
298
299    all:		bdio.o $(LIBDIR)
300                gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o
301                cp $(BUILDDIR)/libbdio.so $(LIBDIR)/
302
303    Parameters
304    ----------
305    file_path : str
306        path to the bdio file
307    bdio_path : str
308        path to the shared bdio library libbdio.so (default ./libbdio.so)
309    start : int
310        The first configuration to be read (default 1)
311    stop : int
312        The last configuration to be read (default None)
313    step : int
314        Fixed step size between two measurements (default 1)
315    alternative_ensemble_name : str
316        Manually overwrite ensemble name
317    """
318
319    start = kwargs.get('start', 1)
320    stop = kwargs.get('stop', None)
321    step = kwargs.get('step', 1)
322
323    bdio = ctypes.cdll.LoadLibrary(bdio_path)
324
325    bdio_open = bdio.bdio_open
326    bdio_open.restype = ctypes.c_void_p
327
328    bdio_close = bdio.bdio_close
329    bdio_close.restype = ctypes.c_int
330    bdio_close.argtypes = [ctypes.c_void_p]
331
332    bdio_seek_record = bdio.bdio_seek_record
333    bdio_seek_record.restype = ctypes.c_int
334    bdio_seek_record.argtypes = [ctypes.c_void_p]
335
336    bdio_get_rlen = bdio.bdio_get_rlen
337    bdio_get_rlen.restype = ctypes.c_int
338    bdio_get_rlen.argtypes = [ctypes.c_void_p]
339
340    bdio_get_ruinfo = bdio.bdio_get_ruinfo
341    bdio_get_ruinfo.restype = ctypes.c_int
342    bdio_get_ruinfo.argtypes = [ctypes.c_void_p]
343
344    bdio_read = bdio.bdio_read
345    bdio_read.restype = ctypes.c_size_t
346    bdio_read.argtypes = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_void_p]
347
348    bdio_read_f64 = bdio.bdio_read_f64
349    bdio_read_f64.restype = ctypes.c_size_t
350    bdio_read_f64.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
351
352    b_path = file_path.encode('utf-8')
353    read = 'r'
354    b_read = read.encode('utf-8')
355    form = 'Generic Correlator Format 1.0'
356    b_form = form.encode('utf-8')
357
358    ensemble_name = ''
359    volume = []  # lattice volume
360    boundary_conditions = []
361    corr_name = []  # Contains correlator names
362    corr_type = []  # Contains correlator data type (important for reading out numerical data)
363    corr_props = []  # Contanis propagator types (Component of corr_kappa)
364    d0 = 0  # tvals
365    d1 = 0  # nnoise
366    prop_kappa = []  # Contains propagator kappas (Component of corr_kappa)
367    prop_source = []  # Contains propagator source positions
368    # Check noise type for multiple replica?
369    corr_no = -1
370    data = []
371    idl = []
372
373    fbdio = bdio_open(ctypes.c_char_p(b_path), ctypes.c_char_p(b_read), ctypes.c_char_p(b_form))
374
375    print('Reading of bdio file started')
376    while True:
377        bdio_seek_record(fbdio)
378        ruinfo = bdio_get_ruinfo(fbdio)
379        if ruinfo < 0:
380            # EOF reached
381            break
382        rlen = bdio_get_rlen(fbdio)
383        if ruinfo == 5:
384            d_buf = ctypes.c_double * (2 + d0 * d1 * 2)
385            pd_buf = d_buf()
386            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
387            bdio_read_f64(ppd_buf, ctypes.c_size_t(rlen), ctypes.c_void_p(fbdio))
388            if corr_type[corr_no] == 'complex':
389                tmp_mean = np.mean(np.asarray(np.split(np.asarray(pd_buf[2 + 2 * d1:-2 * d1:2]), d0 - 2)), axis=1)
390            else:
391                tmp_mean = np.mean(np.asarray(np.split(np.asarray(pd_buf[2 + d1:-d0 * d1 - d1]), d0 - 2)), axis=1)
392
393            data[corr_no].append(tmp_mean)
394            corr_no += 1
395        else:
396            alt_buf = ctypes.create_string_buffer(1024)
397            palt_buf = ctypes.c_char_p(ctypes.addressof(alt_buf))
398            iread = bdio_read(palt_buf, ctypes.c_size_t(rlen), ctypes.c_void_p(fbdio))
399            if rlen != iread:
400                print('Error')
401            for i, item in enumerate(alt_buf):
402                if item == b'\x00':
403                    alt_buf[i] = b' '
404            tmp_string = (alt_buf[:].decode("utf-8")).rstrip()
405            if ruinfo == 0:
406                ensemble_name = _get_kwd(tmp_string, 'ENSEMBLE=')
407                volume.append(int(_get_kwd(tmp_string, 'L0=')))
408                volume.append(int(_get_kwd(tmp_string, 'L1=')))
409                volume.append(int(_get_kwd(tmp_string, 'L2=')))
410                volume.append(int(_get_kwd(tmp_string, 'L3=')))
411                boundary_conditions.append(_get_kwd(tmp_string, 'BC0='))
412                boundary_conditions.append(_get_kwd(tmp_string, 'BC1='))
413                boundary_conditions.append(_get_kwd(tmp_string, 'BC2='))
414                boundary_conditions.append(_get_kwd(tmp_string, 'BC3='))
415
416            if ruinfo == 1:
417                corr_name.append(_get_corr_name(tmp_string, 'CORR_NAME='))
418                corr_type.append(_get_kwd(tmp_string, 'DATATYPE='))
419                corr_props.append([_get_kwd(tmp_string, 'PROP0='), _get_kwd(tmp_string, 'PROP1=')])
420                if d0 == 0:
421                    d0 = int(_get_kwd(tmp_string, 'D0='))
422                else:
423                    if d0 != int(_get_kwd(tmp_string, 'D0=')):
424                        print('Error: Varying number of time values')
425                if d1 == 0:
426                    d1 = int(_get_kwd(tmp_string, 'D1='))
427                else:
428                    if d1 != int(_get_kwd(tmp_string, 'D1=')):
429                        print('Error: Varying number of random sources')
430            if ruinfo == 2:
431                prop_kappa.append(_get_kwd(tmp_string, 'KAPPA='))
432                prop_source.append(_get_kwd(tmp_string, 'x0='))
433            if ruinfo == 4:
434                cnfg_no = int(_get_kwd(tmp_string, 'CNFG_ID='))
435                if stop:
436                    if cnfg_no > kwargs.get('stop'):
437                        break
438                idl.append(cnfg_no)
439                print('\r%s %i' % ('Reading configuration', cnfg_no), end='\r')
440                if len(idl) == 1:
441                    no_corrs = len(corr_name)
442                    data = []
443                    for c in range(no_corrs):
444                        data.append([])
445
446                corr_no = 0
447
448    bdio_close(fbdio)
449
450    print('\nEnsemble: ', ensemble_name)
451    if 'alternative_ensemble_name' in kwargs:
452        ensemble_name = kwargs.get('alternative_ensemble_name')
453        print('Ensemble name overwritten to', ensemble_name)
454    print('Lattice volume: ', volume)
455    print('Boundary conditions: ', boundary_conditions)
456    print('Number of time values: ', d0)
457    print('Number of random sources: ', d1)
458    print('Number of corrs: ', len(corr_name))
459    print('Number of configurations: ', len(idl))
460
461    corr_kappa = []  # Contains kappa values for both propagators of given correlation function
462    corr_source = []
463    for item in corr_props:
464        corr_kappa.append([float(prop_kappa[int(item[0])]), float(prop_kappa[int(item[1])])])
465        if prop_source[int(item[0])] != prop_source[int(item[1])]:
466            raise Exception('Source position do not match for correlator' + str(item))
467        else:
468            corr_source.append(int(prop_source[int(item[0])]))
469
470    if stop is None:
471        stop = idl[-1]
472    idl_target = range(start, stop + 1, step)
473
474    if set(idl) != set(idl_target):
475        try:
476            indices = [idl.index(i) for i in idl_target]
477        except ValueError as err:
478            raise Exception('Configurations in file do no match target list!', err)
479    else:
480        indices = None
481
482    result = {}
483    for c in range(no_corrs):
484        tmp_corr = []
485        tmp_data = np.asarray(data[c])
486        for t in range(d0 - 2):
487            if indices:
488                deltas = [tmp_data[:, t][index] for index in indices]
489            else:
490                deltas = tmp_data[:, t]
491            tmp_corr.append(Obs([deltas], [ensemble_name], idl=[idl_target]))
492        result[(corr_name[c], corr_source[c]) + tuple(corr_kappa[c])] = tmp_corr
493
494    # Check that all data entries have the same number of configurations
495    if len(set([o[0].N for o in list(result.values())])) != 1:
496        raise Exception('Error: Not all correlators have the same number of configurations. bdio file is possibly corrupted.')
497
498    return result
499
500
501def read_dSdm(file_path, bdio_path='./libbdio.so', **kwargs):
502    """ Extract dSdm data from a bdio file and return it as a dictionary
503
504    The dictionary can be accessed with a tuple consisting of (type, kappa)
505
506    read_dSdm requires bdio to be compiled into a shared library. This can be achieved by
507    adding the flag -fPIC to CC and changing the all target to
508
509    all:		bdio.o $(LIBDIR)
510                gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o
511                cp $(BUILDDIR)/libbdio.so $(LIBDIR)/
512
513    Parameters
514    ----------
515    file_path : str
516        path to the bdio file
517    bdio_path : str
518        path to the shared bdio library libbdio.so (default ./libbdio.so)
519    start : int
520        The first configuration to be read (default 1)
521    stop : int
522        The last configuration to be read (default None)
523    step : int
524        Fixed step size between two measurements (default 1)
525    alternative_ensemble_name : str
526        Manually overwrite ensemble name
527    """
528
529    start = kwargs.get('start', 1)
530    stop = kwargs.get('stop', None)
531    step = kwargs.get('step', 1)
532
533    bdio = ctypes.cdll.LoadLibrary(bdio_path)
534
535    bdio_open = bdio.bdio_open
536    bdio_open.restype = ctypes.c_void_p
537
538    bdio_close = bdio.bdio_close
539    bdio_close.restype = ctypes.c_int
540    bdio_close.argtypes = [ctypes.c_void_p]
541
542    bdio_seek_record = bdio.bdio_seek_record
543    bdio_seek_record.restype = ctypes.c_int
544    bdio_seek_record.argtypes = [ctypes.c_void_p]
545
546    bdio_get_rlen = bdio.bdio_get_rlen
547    bdio_get_rlen.restype = ctypes.c_int
548    bdio_get_rlen.argtypes = [ctypes.c_void_p]
549
550    bdio_get_ruinfo = bdio.bdio_get_ruinfo
551    bdio_get_ruinfo.restype = ctypes.c_int
552    bdio_get_ruinfo.argtypes = [ctypes.c_void_p]
553
554    bdio_read = bdio.bdio_read
555    bdio_read.restype = ctypes.c_size_t
556    bdio_read.argtypes = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_void_p]
557
558    bdio_read_f64 = bdio.bdio_read_f64
559    bdio_read_f64.restype = ctypes.c_size_t
560    bdio_read_f64.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
561
562    b_path = file_path.encode('utf-8')
563    read = 'r'
564    b_read = read.encode('utf-8')
565    form = 'Generic Correlator Format 1.0'
566    b_form = form.encode('utf-8')
567
568    ensemble_name = ''
569    volume = []  # lattice volume
570    boundary_conditions = []
571    corr_name = []  # Contains correlator names
572    corr_type = []  # Contains correlator data type (important for reading out numerical data)
573    corr_props = []  # Contains propagator types (Component of corr_kappa)
574    d0 = 0  # tvals
575    # d1 = 0  # nnoise
576    prop_kappa = []  # Contains propagator kappas (Component of corr_kappa)
577    # Check noise type for multiple replica?
578    corr_no = -1
579    data = []
580    idl = []
581
582    fbdio = bdio_open(ctypes.c_char_p(b_path), ctypes.c_char_p(b_read), ctypes.c_char_p(b_form))
583
584    print('Reading of bdio file started')
585    while True:
586        bdio_seek_record(fbdio)
587        ruinfo = bdio_get_ruinfo(fbdio)
588        if ruinfo < 0:
589            # EOF reached
590            break
591        rlen = bdio_get_rlen(fbdio)
592        if ruinfo == 5:
593            d_buf = ctypes.c_double * (2 + d0)
594            pd_buf = d_buf()
595            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
596            bdio_read_f64(ppd_buf, ctypes.c_size_t(rlen), ctypes.c_void_p(fbdio))
597            tmp_mean = np.mean(np.asarray(pd_buf[2:]))
598
599            data[corr_no].append(tmp_mean)
600            corr_no += 1
601        else:
602            alt_buf = ctypes.create_string_buffer(1024)
603            palt_buf = ctypes.c_char_p(ctypes.addressof(alt_buf))
604            iread = bdio_read(palt_buf, ctypes.c_size_t(rlen), ctypes.c_void_p(fbdio))
605            if rlen != iread:
606                print('Error')
607            for i, item in enumerate(alt_buf):
608                if item == b'\x00':
609                    alt_buf[i] = b' '
610            tmp_string = (alt_buf[:].decode("utf-8")).rstrip()
611            if ruinfo == 0:
612                creator = _get_kwd(tmp_string, 'CREATOR=')
613                ensemble_name = _get_kwd(tmp_string, 'ENSEMBLE=')
614                volume.append(int(_get_kwd(tmp_string, 'L0=')))
615                volume.append(int(_get_kwd(tmp_string, 'L1=')))
616                volume.append(int(_get_kwd(tmp_string, 'L2=')))
617                volume.append(int(_get_kwd(tmp_string, 'L3=')))
618                boundary_conditions.append(_get_kwd(tmp_string, 'BC0='))
619                boundary_conditions.append(_get_kwd(tmp_string, 'BC1='))
620                boundary_conditions.append(_get_kwd(tmp_string, 'BC2='))
621                boundary_conditions.append(_get_kwd(tmp_string, 'BC3='))
622
623            if ruinfo == 1:
624                corr_name.append(_get_corr_name(tmp_string, 'CORR_NAME='))
625                corr_type.append(_get_kwd(tmp_string, 'DATATYPE='))
626                corr_props.append(_get_kwd(tmp_string, 'PROP0='))
627                if d0 == 0:
628                    d0 = int(_get_kwd(tmp_string, 'D0='))
629                else:
630                    if d0 != int(_get_kwd(tmp_string, 'D0=')):
631                        print('Error: Varying number of time values')
632            if ruinfo == 2:
633                prop_kappa.append(_get_kwd(tmp_string, 'KAPPA='))
634            if ruinfo == 4:
635                cnfg_no = int(_get_kwd(tmp_string, 'CNFG_ID='))
636                if stop:
637                    if cnfg_no > kwargs.get('stop'):
638                        break
639                idl.append(cnfg_no)
640                print('\r%s %i' % ('Reading configuration', cnfg_no), end='\r')
641                if len(idl) == 1:
642                    no_corrs = len(corr_name)
643                    data = []
644                    for c in range(no_corrs):
645                        data.append([])
646
647                corr_no = 0
648    bdio_close(fbdio)
649
650    print('\nCreator: ', creator)
651    print('Ensemble: ', ensemble_name)
652    print('Lattice volume: ', volume)
653    print('Boundary conditions: ', boundary_conditions)
654    print('Number of random sources: ', d0)
655    print('Number of corrs: ', len(corr_name))
656    print('Number of configurations: ', cnfg_no + 1)
657
658    corr_kappa = []  # Contains kappa values for both propagators of given correlation function
659    for item in corr_props:
660        corr_kappa.append(float(prop_kappa[int(item)]))
661
662    if stop is None:
663        stop = idl[-1]
664    idl_target = range(start, stop + 1, step)
665    try:
666        indices = [idl.index(i) for i in idl_target]
667    except ValueError as err:
668        raise Exception('Configurations in file do no match target list!', err)
669
670    result = {}
671    for c in range(no_corrs):
672        deltas = [np.asarray(data[c])[index] for index in indices]
673        result[(corr_name[c], str(corr_kappa[c]))] = Obs([deltas], [ensemble_name], idl=[idl_target])
674
675    # Check that all data entries have the same number of configurations
676    if len(set([o.N for o in list(result.values())])) != 1:
677        raise Exception('Error: Not all correlators have the same number of configurations. bdio file is possibly corrupted.')
678
679    return result
def read_ADerrors(file_path, bdio_path='./libbdio.so', **kwargs):
  8def read_ADerrors(file_path, bdio_path='./libbdio.so', **kwargs):
  9    """ Extract generic MCMC data from a bdio file
 10
 11    read_ADerrors requires bdio to be compiled into a shared library. This can be achieved by
 12    adding the flag -fPIC to CC and changing the all target to
 13
 14    all:		bdio.o $(LIBDIR)
 15                gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o
 16                cp $(BUILDDIR)/libbdio.so $(LIBDIR)/
 17
 18    Parameters
 19    ----------
 20    file_path -- path to the bdio file
 21    bdio_path -- path to the shared bdio library libbdio.so (default ./libbdio.so)
 22    """
 23    bdio = ctypes.cdll.LoadLibrary(bdio_path)
 24
 25    bdio_open = bdio.bdio_open
 26    bdio_open.restype = ctypes.c_void_p
 27
 28    bdio_close = bdio.bdio_close
 29    bdio_close.restype = ctypes.c_int
 30    bdio_close.argtypes = [ctypes.c_void_p]
 31
 32    bdio_seek_record = bdio.bdio_seek_record
 33    bdio_seek_record.restype = ctypes.c_int
 34    bdio_seek_record.argtypes = [ctypes.c_void_p]
 35
 36    bdio_get_rlen = bdio.bdio_get_rlen
 37    bdio_get_rlen.restype = ctypes.c_int
 38    bdio_get_rlen.argtypes = [ctypes.c_void_p]
 39
 40    bdio_get_ruinfo = bdio.bdio_get_ruinfo
 41    bdio_get_ruinfo.restype = ctypes.c_int
 42    bdio_get_ruinfo.argtypes = [ctypes.c_void_p]
 43
 44    bdio_read = bdio.bdio_read
 45    bdio_read.restype = ctypes.c_size_t
 46    bdio_read.argtypes = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_void_p]
 47
 48    bdio_read_f64 = bdio.bdio_read_f64
 49    bdio_read_f64.restype = ctypes.c_size_t
 50    bdio_read_f64.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
 51
 52    bdio_read_int32 = bdio.bdio_read_int32
 53    bdio_read_int32.restype = ctypes.c_size_t
 54    bdio_read_int32.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
 55
 56    b_path = file_path.encode('utf-8')
 57    read = 'r'
 58    b_read = read.encode('utf-8')
 59
 60    fbdio = bdio_open(ctypes.c_char_p(b_path), ctypes.c_char_p(b_read), None)
 61
 62    return_list = []
 63
 64    print('Reading of bdio file started')
 65    while True:
 66        bdio_seek_record(fbdio)
 67        ruinfo = bdio_get_ruinfo(fbdio)
 68
 69        if ruinfo == 7:
 70            print('MD5sum found')  # For now we just ignore these entries and do not perform any checks on them
 71            continue
 72
 73        if ruinfo < 0:
 74            # EOF reached
 75            break
 76        bdio_get_rlen(fbdio)
 77
 78        def read_c_double():
 79            d_buf = ctypes.c_double
 80            pd_buf = d_buf()
 81            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
 82            bdio_read_f64(ppd_buf, ctypes.c_size_t(8), ctypes.c_void_p(fbdio))
 83            return pd_buf.value
 84
 85        mean = read_c_double()
 86        print('mean', mean)
 87
 88        def read_c_size_t():
 89            d_buf = ctypes.c_size_t
 90            pd_buf = d_buf()
 91            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
 92            bdio_read_int32(ppd_buf, ctypes.c_size_t(4), ctypes.c_void_p(fbdio))
 93            return pd_buf.value
 94
 95        neid = read_c_size_t()
 96        print('neid', neid)
 97
 98        ndata = []
 99        for index in range(neid):
100            ndata.append(read_c_size_t())
101        print('ndata', ndata)
102
103        nrep = []
104        for index in range(neid):
105            nrep.append(read_c_size_t())
106        print('nrep', nrep)
107
108        vrep = []
109        for index in range(neid):
110            vrep.append([])
111            for jndex in range(nrep[index]):
112                vrep[-1].append(read_c_size_t())
113        print('vrep', vrep)
114
115        ids = []
116        for index in range(neid):
117            ids.append(read_c_size_t())
118        print('ids', ids)
119
120        nt = []
121        for index in range(neid):
122            nt.append(read_c_size_t())
123        print('nt', nt)
124
125        zero = []
126        for index in range(neid):
127            zero.append(read_c_double())
128        print('zero', zero)
129
130        four = []
131        for index in range(neid):
132            four.append(read_c_double())
133        print('four', four)
134
135        d_buf = ctypes.c_double * np.sum(ndata)
136        pd_buf = d_buf()
137        ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
138        bdio_read_f64(ppd_buf, ctypes.c_size_t(8 * np.sum(ndata)), ctypes.c_void_p(fbdio))
139        delta = pd_buf[:]
140
141        samples = np.split(np.asarray(delta) + mean, np.cumsum([a for su in vrep for a in su])[:-1])
142        no_reps = [len(o) for o in vrep]
143        assert len(ids) == len(no_reps)
144        tmp_names = []
145        ens_length = max([len(str(o)) for o in ids])
146        for loc_id, reps in zip(ids, no_reps):
147            for index in range(reps):
148                missing_chars = ens_length - len(str(loc_id))
149                tmp_names.append(str(loc_id) + ' ' * missing_chars + '|r' + '{0:03d}'.format(index))
150
151        return_list.append(Obs(samples, tmp_names))
152
153    bdio_close(fbdio)
154    print()
155    print(len(return_list), 'observable(s) extracted.')
156    return return_list

Extract generic MCMC data from a bdio file

read_ADerrors requires bdio to be compiled into a shared library. This can be achieved by adding the flag -fPIC to CC and changing the all target to

all: bdio.o $(LIBDIR) gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o cp $(BUILDDIR)/libbdio.so $(LIBDIR)/

Parameters
  • file_path -- path to the bdio file
  • bdio_path -- path to the shared bdio library libbdio.so (default ./libbdio.so)
def write_ADerrors(obs_list, file_path, bdio_path='./libbdio.so', **kwargs):
159def write_ADerrors(obs_list, file_path, bdio_path='./libbdio.so', **kwargs):
160    """ Write Obs to a bdio file according to ADerrors conventions
161
162    read_mesons requires bdio to be compiled into a shared library. This can be achieved by
163    adding the flag -fPIC to CC and changing the all target to
164
165    all:		bdio.o $(LIBDIR)
166                gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o
167                cp $(BUILDDIR)/libbdio.so $(LIBDIR)/
168
169    Parameters
170    ----------
171    file_path -- path to the bdio file
172    bdio_path -- path to the shared bdio library libbdio.so (default ./libbdio.so)
173    """
174
175    for obs in obs_list:
176        if not hasattr(obs, 'e_names'):
177            raise Exception('Run the gamma method first for all obs.')
178
179    bdio = ctypes.cdll.LoadLibrary(bdio_path)
180
181    bdio_open = bdio.bdio_open
182    bdio_open.restype = ctypes.c_void_p
183
184    bdio_close = bdio.bdio_close
185    bdio_close.restype = ctypes.c_int
186    bdio_close.argtypes = [ctypes.c_void_p]
187
188    bdio_start_record = bdio.bdio_start_record
189    bdio_start_record.restype = ctypes.c_int
190    bdio_start_record.argtypes = [ctypes.c_size_t, ctypes.c_size_t, ctypes.c_void_p]
191
192    bdio_flush_record = bdio.bdio_flush_record
193    bdio_flush_record.restype = ctypes.c_int
194    bdio_flush_record.argytpes = [ctypes.c_void_p]
195
196    bdio_write_f64 = bdio.bdio_write_f64
197    bdio_write_f64.restype = ctypes.c_size_t
198    bdio_write_f64.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
199
200    bdio_write_int32 = bdio.bdio_write_int32
201    bdio_write_int32.restype = ctypes.c_size_t
202    bdio_write_int32.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
203
204    b_path = file_path.encode('utf-8')
205    write = 'w'
206    b_write = write.encode('utf-8')
207    form = 'pyerrors ADerror export'
208    b_form = form.encode('utf-8')
209
210    fbdio = bdio_open(ctypes.c_char_p(b_path), ctypes.c_char_p(b_write), b_form)
211
212    for obs in obs_list:
213        # mean = obs.value
214        neid = len(obs.e_names)
215        vrep = [[obs.shape[o] for o in sl] for sl in list(obs.e_content.values())]
216        vrep_write = [item for sublist in vrep for item in sublist]
217        ndata = [np.sum(o) for o in vrep]
218        nrep = [len(o) for o in vrep]
219        print('ndata', ndata)
220        print('nrep', nrep)
221        print('vrep', vrep)
222        keys = list(obs.e_content.keys())
223        ids = []
224        for key in keys:
225            try:  # Try to convert key to integer
226                ids.append(int(key))
227            except Exception:  # If not possible construct a hash
228                ids.append(int(hashlib.sha256(key.encode('utf-8')).hexdigest(), 16) % 10 ** 8)
229        print('ids', ids)
230        nt = []
231        for e, e_name in enumerate(obs.e_names):
232
233            r_length = []
234            for r_name in obs.e_content[e_name]:
235                r_length.append(len(obs.deltas[r_name]))
236
237            # e_N = np.sum(r_length)
238            nt.append(max(r_length) // 2)
239        print('nt', nt)
240        zero = neid * [0.0]
241        four = neid * [4.0]
242        print('zero', zero)
243        print('four', four)
244        delta = np.concatenate([item for sublist in [[obs.deltas[o] for o in sl] for sl in list(obs.e_content.values())] for item in sublist])
245
246        bdio_start_record(0x00, 8, fbdio)
247
248        def write_c_double(double):
249            pd_buf = ctypes.c_double(double)
250            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
251            bdio_write_f64(ppd_buf, ctypes.c_size_t(8), ctypes.c_void_p(fbdio))
252
253        def write_c_size_t(int32):
254            pd_buf = ctypes.c_size_t(int32)
255            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
256            bdio_write_int32(ppd_buf, ctypes.c_size_t(4), ctypes.c_void_p(fbdio))
257
258        write_c_double(obs.value)
259        write_c_size_t(neid)
260
261        for element in ndata:
262            write_c_size_t(element)
263        for element in nrep:
264            write_c_size_t(element)
265        for element in vrep_write:
266            write_c_size_t(element)
267        for element in ids:
268            write_c_size_t(element)
269        for element in nt:
270            write_c_size_t(element)
271
272        for element in zero:
273            write_c_double(element)
274        for element in four:
275            write_c_double(element)
276
277        for element in delta:
278            write_c_double(element)
279
280    bdio_close(fbdio)
281    return 0

Write Obs to a bdio file according to ADerrors conventions

read_mesons requires bdio to be compiled into a shared library. This can be achieved by adding the flag -fPIC to CC and changing the all target to

all: bdio.o $(LIBDIR) gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o cp $(BUILDDIR)/libbdio.so $(LIBDIR)/

Parameters
  • file_path -- path to the bdio file
  • bdio_path -- path to the shared bdio library libbdio.so (default ./libbdio.so)
def read_mesons(file_path, bdio_path='./libbdio.so', **kwargs):
292def read_mesons(file_path, bdio_path='./libbdio.so', **kwargs):
293    """ Extract mesons data from a bdio file and return it as a dictionary
294
295    The dictionary can be accessed with a tuple consisting of (type, source_position, kappa1, kappa2)
296
297    read_mesons requires bdio to be compiled into a shared library. This can be achieved by
298    adding the flag -fPIC to CC and changing the all target to
299
300    all:		bdio.o $(LIBDIR)
301                gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o
302                cp $(BUILDDIR)/libbdio.so $(LIBDIR)/
303
304    Parameters
305    ----------
306    file_path : str
307        path to the bdio file
308    bdio_path : str
309        path to the shared bdio library libbdio.so (default ./libbdio.so)
310    start : int
311        The first configuration to be read (default 1)
312    stop : int
313        The last configuration to be read (default None)
314    step : int
315        Fixed step size between two measurements (default 1)
316    alternative_ensemble_name : str
317        Manually overwrite ensemble name
318    """
319
320    start = kwargs.get('start', 1)
321    stop = kwargs.get('stop', None)
322    step = kwargs.get('step', 1)
323
324    bdio = ctypes.cdll.LoadLibrary(bdio_path)
325
326    bdio_open = bdio.bdio_open
327    bdio_open.restype = ctypes.c_void_p
328
329    bdio_close = bdio.bdio_close
330    bdio_close.restype = ctypes.c_int
331    bdio_close.argtypes = [ctypes.c_void_p]
332
333    bdio_seek_record = bdio.bdio_seek_record
334    bdio_seek_record.restype = ctypes.c_int
335    bdio_seek_record.argtypes = [ctypes.c_void_p]
336
337    bdio_get_rlen = bdio.bdio_get_rlen
338    bdio_get_rlen.restype = ctypes.c_int
339    bdio_get_rlen.argtypes = [ctypes.c_void_p]
340
341    bdio_get_ruinfo = bdio.bdio_get_ruinfo
342    bdio_get_ruinfo.restype = ctypes.c_int
343    bdio_get_ruinfo.argtypes = [ctypes.c_void_p]
344
345    bdio_read = bdio.bdio_read
346    bdio_read.restype = ctypes.c_size_t
347    bdio_read.argtypes = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_void_p]
348
349    bdio_read_f64 = bdio.bdio_read_f64
350    bdio_read_f64.restype = ctypes.c_size_t
351    bdio_read_f64.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
352
353    b_path = file_path.encode('utf-8')
354    read = 'r'
355    b_read = read.encode('utf-8')
356    form = 'Generic Correlator Format 1.0'
357    b_form = form.encode('utf-8')
358
359    ensemble_name = ''
360    volume = []  # lattice volume
361    boundary_conditions = []
362    corr_name = []  # Contains correlator names
363    corr_type = []  # Contains correlator data type (important for reading out numerical data)
364    corr_props = []  # Contanis propagator types (Component of corr_kappa)
365    d0 = 0  # tvals
366    d1 = 0  # nnoise
367    prop_kappa = []  # Contains propagator kappas (Component of corr_kappa)
368    prop_source = []  # Contains propagator source positions
369    # Check noise type for multiple replica?
370    corr_no = -1
371    data = []
372    idl = []
373
374    fbdio = bdio_open(ctypes.c_char_p(b_path), ctypes.c_char_p(b_read), ctypes.c_char_p(b_form))
375
376    print('Reading of bdio file started')
377    while True:
378        bdio_seek_record(fbdio)
379        ruinfo = bdio_get_ruinfo(fbdio)
380        if ruinfo < 0:
381            # EOF reached
382            break
383        rlen = bdio_get_rlen(fbdio)
384        if ruinfo == 5:
385            d_buf = ctypes.c_double * (2 + d0 * d1 * 2)
386            pd_buf = d_buf()
387            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
388            bdio_read_f64(ppd_buf, ctypes.c_size_t(rlen), ctypes.c_void_p(fbdio))
389            if corr_type[corr_no] == 'complex':
390                tmp_mean = np.mean(np.asarray(np.split(np.asarray(pd_buf[2 + 2 * d1:-2 * d1:2]), d0 - 2)), axis=1)
391            else:
392                tmp_mean = np.mean(np.asarray(np.split(np.asarray(pd_buf[2 + d1:-d0 * d1 - d1]), d0 - 2)), axis=1)
393
394            data[corr_no].append(tmp_mean)
395            corr_no += 1
396        else:
397            alt_buf = ctypes.create_string_buffer(1024)
398            palt_buf = ctypes.c_char_p(ctypes.addressof(alt_buf))
399            iread = bdio_read(palt_buf, ctypes.c_size_t(rlen), ctypes.c_void_p(fbdio))
400            if rlen != iread:
401                print('Error')
402            for i, item in enumerate(alt_buf):
403                if item == b'\x00':
404                    alt_buf[i] = b' '
405            tmp_string = (alt_buf[:].decode("utf-8")).rstrip()
406            if ruinfo == 0:
407                ensemble_name = _get_kwd(tmp_string, 'ENSEMBLE=')
408                volume.append(int(_get_kwd(tmp_string, 'L0=')))
409                volume.append(int(_get_kwd(tmp_string, 'L1=')))
410                volume.append(int(_get_kwd(tmp_string, 'L2=')))
411                volume.append(int(_get_kwd(tmp_string, 'L3=')))
412                boundary_conditions.append(_get_kwd(tmp_string, 'BC0='))
413                boundary_conditions.append(_get_kwd(tmp_string, 'BC1='))
414                boundary_conditions.append(_get_kwd(tmp_string, 'BC2='))
415                boundary_conditions.append(_get_kwd(tmp_string, 'BC3='))
416
417            if ruinfo == 1:
418                corr_name.append(_get_corr_name(tmp_string, 'CORR_NAME='))
419                corr_type.append(_get_kwd(tmp_string, 'DATATYPE='))
420                corr_props.append([_get_kwd(tmp_string, 'PROP0='), _get_kwd(tmp_string, 'PROP1=')])
421                if d0 == 0:
422                    d0 = int(_get_kwd(tmp_string, 'D0='))
423                else:
424                    if d0 != int(_get_kwd(tmp_string, 'D0=')):
425                        print('Error: Varying number of time values')
426                if d1 == 0:
427                    d1 = int(_get_kwd(tmp_string, 'D1='))
428                else:
429                    if d1 != int(_get_kwd(tmp_string, 'D1=')):
430                        print('Error: Varying number of random sources')
431            if ruinfo == 2:
432                prop_kappa.append(_get_kwd(tmp_string, 'KAPPA='))
433                prop_source.append(_get_kwd(tmp_string, 'x0='))
434            if ruinfo == 4:
435                cnfg_no = int(_get_kwd(tmp_string, 'CNFG_ID='))
436                if stop:
437                    if cnfg_no > kwargs.get('stop'):
438                        break
439                idl.append(cnfg_no)
440                print('\r%s %i' % ('Reading configuration', cnfg_no), end='\r')
441                if len(idl) == 1:
442                    no_corrs = len(corr_name)
443                    data = []
444                    for c in range(no_corrs):
445                        data.append([])
446
447                corr_no = 0
448
449    bdio_close(fbdio)
450
451    print('\nEnsemble: ', ensemble_name)
452    if 'alternative_ensemble_name' in kwargs:
453        ensemble_name = kwargs.get('alternative_ensemble_name')
454        print('Ensemble name overwritten to', ensemble_name)
455    print('Lattice volume: ', volume)
456    print('Boundary conditions: ', boundary_conditions)
457    print('Number of time values: ', d0)
458    print('Number of random sources: ', d1)
459    print('Number of corrs: ', len(corr_name))
460    print('Number of configurations: ', len(idl))
461
462    corr_kappa = []  # Contains kappa values for both propagators of given correlation function
463    corr_source = []
464    for item in corr_props:
465        corr_kappa.append([float(prop_kappa[int(item[0])]), float(prop_kappa[int(item[1])])])
466        if prop_source[int(item[0])] != prop_source[int(item[1])]:
467            raise Exception('Source position do not match for correlator' + str(item))
468        else:
469            corr_source.append(int(prop_source[int(item[0])]))
470
471    if stop is None:
472        stop = idl[-1]
473    idl_target = range(start, stop + 1, step)
474
475    if set(idl) != set(idl_target):
476        try:
477            indices = [idl.index(i) for i in idl_target]
478        except ValueError as err:
479            raise Exception('Configurations in file do no match target list!', err)
480    else:
481        indices = None
482
483    result = {}
484    for c in range(no_corrs):
485        tmp_corr = []
486        tmp_data = np.asarray(data[c])
487        for t in range(d0 - 2):
488            if indices:
489                deltas = [tmp_data[:, t][index] for index in indices]
490            else:
491                deltas = tmp_data[:, t]
492            tmp_corr.append(Obs([deltas], [ensemble_name], idl=[idl_target]))
493        result[(corr_name[c], corr_source[c]) + tuple(corr_kappa[c])] = tmp_corr
494
495    # Check that all data entries have the same number of configurations
496    if len(set([o[0].N for o in list(result.values())])) != 1:
497        raise Exception('Error: Not all correlators have the same number of configurations. bdio file is possibly corrupted.')
498
499    return result

Extract mesons data from a bdio file and return it as a dictionary

The dictionary can be accessed with a tuple consisting of (type, source_position, kappa1, kappa2)

read_mesons requires bdio to be compiled into a shared library. This can be achieved by adding the flag -fPIC to CC and changing the all target to

all: bdio.o $(LIBDIR) gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o cp $(BUILDDIR)/libbdio.so $(LIBDIR)/

Parameters
  • file_path (str): path to the bdio file
  • bdio_path (str): path to the shared bdio library libbdio.so (default ./libbdio.so)
  • start (int): The first configuration to be read (default 1)
  • stop (int): The last configuration to be read (default None)
  • step (int): Fixed step size between two measurements (default 1)
  • alternative_ensemble_name (str): Manually overwrite ensemble name
def read_dSdm(file_path, bdio_path='./libbdio.so', **kwargs):
502def read_dSdm(file_path, bdio_path='./libbdio.so', **kwargs):
503    """ Extract dSdm data from a bdio file and return it as a dictionary
504
505    The dictionary can be accessed with a tuple consisting of (type, kappa)
506
507    read_dSdm requires bdio to be compiled into a shared library. This can be achieved by
508    adding the flag -fPIC to CC and changing the all target to
509
510    all:		bdio.o $(LIBDIR)
511                gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o
512                cp $(BUILDDIR)/libbdio.so $(LIBDIR)/
513
514    Parameters
515    ----------
516    file_path : str
517        path to the bdio file
518    bdio_path : str
519        path to the shared bdio library libbdio.so (default ./libbdio.so)
520    start : int
521        The first configuration to be read (default 1)
522    stop : int
523        The last configuration to be read (default None)
524    step : int
525        Fixed step size between two measurements (default 1)
526    alternative_ensemble_name : str
527        Manually overwrite ensemble name
528    """
529
530    start = kwargs.get('start', 1)
531    stop = kwargs.get('stop', None)
532    step = kwargs.get('step', 1)
533
534    bdio = ctypes.cdll.LoadLibrary(bdio_path)
535
536    bdio_open = bdio.bdio_open
537    bdio_open.restype = ctypes.c_void_p
538
539    bdio_close = bdio.bdio_close
540    bdio_close.restype = ctypes.c_int
541    bdio_close.argtypes = [ctypes.c_void_p]
542
543    bdio_seek_record = bdio.bdio_seek_record
544    bdio_seek_record.restype = ctypes.c_int
545    bdio_seek_record.argtypes = [ctypes.c_void_p]
546
547    bdio_get_rlen = bdio.bdio_get_rlen
548    bdio_get_rlen.restype = ctypes.c_int
549    bdio_get_rlen.argtypes = [ctypes.c_void_p]
550
551    bdio_get_ruinfo = bdio.bdio_get_ruinfo
552    bdio_get_ruinfo.restype = ctypes.c_int
553    bdio_get_ruinfo.argtypes = [ctypes.c_void_p]
554
555    bdio_read = bdio.bdio_read
556    bdio_read.restype = ctypes.c_size_t
557    bdio_read.argtypes = [ctypes.c_char_p, ctypes.c_size_t, ctypes.c_void_p]
558
559    bdio_read_f64 = bdio.bdio_read_f64
560    bdio_read_f64.restype = ctypes.c_size_t
561    bdio_read_f64.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p]
562
563    b_path = file_path.encode('utf-8')
564    read = 'r'
565    b_read = read.encode('utf-8')
566    form = 'Generic Correlator Format 1.0'
567    b_form = form.encode('utf-8')
568
569    ensemble_name = ''
570    volume = []  # lattice volume
571    boundary_conditions = []
572    corr_name = []  # Contains correlator names
573    corr_type = []  # Contains correlator data type (important for reading out numerical data)
574    corr_props = []  # Contains propagator types (Component of corr_kappa)
575    d0 = 0  # tvals
576    # d1 = 0  # nnoise
577    prop_kappa = []  # Contains propagator kappas (Component of corr_kappa)
578    # Check noise type for multiple replica?
579    corr_no = -1
580    data = []
581    idl = []
582
583    fbdio = bdio_open(ctypes.c_char_p(b_path), ctypes.c_char_p(b_read), ctypes.c_char_p(b_form))
584
585    print('Reading of bdio file started')
586    while True:
587        bdio_seek_record(fbdio)
588        ruinfo = bdio_get_ruinfo(fbdio)
589        if ruinfo < 0:
590            # EOF reached
591            break
592        rlen = bdio_get_rlen(fbdio)
593        if ruinfo == 5:
594            d_buf = ctypes.c_double * (2 + d0)
595            pd_buf = d_buf()
596            ppd_buf = ctypes.c_void_p(ctypes.addressof(pd_buf))
597            bdio_read_f64(ppd_buf, ctypes.c_size_t(rlen), ctypes.c_void_p(fbdio))
598            tmp_mean = np.mean(np.asarray(pd_buf[2:]))
599
600            data[corr_no].append(tmp_mean)
601            corr_no += 1
602        else:
603            alt_buf = ctypes.create_string_buffer(1024)
604            palt_buf = ctypes.c_char_p(ctypes.addressof(alt_buf))
605            iread = bdio_read(palt_buf, ctypes.c_size_t(rlen), ctypes.c_void_p(fbdio))
606            if rlen != iread:
607                print('Error')
608            for i, item in enumerate(alt_buf):
609                if item == b'\x00':
610                    alt_buf[i] = b' '
611            tmp_string = (alt_buf[:].decode("utf-8")).rstrip()
612            if ruinfo == 0:
613                creator = _get_kwd(tmp_string, 'CREATOR=')
614                ensemble_name = _get_kwd(tmp_string, 'ENSEMBLE=')
615                volume.append(int(_get_kwd(tmp_string, 'L0=')))
616                volume.append(int(_get_kwd(tmp_string, 'L1=')))
617                volume.append(int(_get_kwd(tmp_string, 'L2=')))
618                volume.append(int(_get_kwd(tmp_string, 'L3=')))
619                boundary_conditions.append(_get_kwd(tmp_string, 'BC0='))
620                boundary_conditions.append(_get_kwd(tmp_string, 'BC1='))
621                boundary_conditions.append(_get_kwd(tmp_string, 'BC2='))
622                boundary_conditions.append(_get_kwd(tmp_string, 'BC3='))
623
624            if ruinfo == 1:
625                corr_name.append(_get_corr_name(tmp_string, 'CORR_NAME='))
626                corr_type.append(_get_kwd(tmp_string, 'DATATYPE='))
627                corr_props.append(_get_kwd(tmp_string, 'PROP0='))
628                if d0 == 0:
629                    d0 = int(_get_kwd(tmp_string, 'D0='))
630                else:
631                    if d0 != int(_get_kwd(tmp_string, 'D0=')):
632                        print('Error: Varying number of time values')
633            if ruinfo == 2:
634                prop_kappa.append(_get_kwd(tmp_string, 'KAPPA='))
635            if ruinfo == 4:
636                cnfg_no = int(_get_kwd(tmp_string, 'CNFG_ID='))
637                if stop:
638                    if cnfg_no > kwargs.get('stop'):
639                        break
640                idl.append(cnfg_no)
641                print('\r%s %i' % ('Reading configuration', cnfg_no), end='\r')
642                if len(idl) == 1:
643                    no_corrs = len(corr_name)
644                    data = []
645                    for c in range(no_corrs):
646                        data.append([])
647
648                corr_no = 0
649    bdio_close(fbdio)
650
651    print('\nCreator: ', creator)
652    print('Ensemble: ', ensemble_name)
653    print('Lattice volume: ', volume)
654    print('Boundary conditions: ', boundary_conditions)
655    print('Number of random sources: ', d0)
656    print('Number of corrs: ', len(corr_name))
657    print('Number of configurations: ', cnfg_no + 1)
658
659    corr_kappa = []  # Contains kappa values for both propagators of given correlation function
660    for item in corr_props:
661        corr_kappa.append(float(prop_kappa[int(item)]))
662
663    if stop is None:
664        stop = idl[-1]
665    idl_target = range(start, stop + 1, step)
666    try:
667        indices = [idl.index(i) for i in idl_target]
668    except ValueError as err:
669        raise Exception('Configurations in file do no match target list!', err)
670
671    result = {}
672    for c in range(no_corrs):
673        deltas = [np.asarray(data[c])[index] for index in indices]
674        result[(corr_name[c], str(corr_kappa[c]))] = Obs([deltas], [ensemble_name], idl=[idl_target])
675
676    # Check that all data entries have the same number of configurations
677    if len(set([o.N for o in list(result.values())])) != 1:
678        raise Exception('Error: Not all correlators have the same number of configurations. bdio file is possibly corrupted.')
679
680    return result

Extract dSdm data from a bdio file and return it as a dictionary

The dictionary can be accessed with a tuple consisting of (type, kappa)

read_dSdm requires bdio to be compiled into a shared library. This can be achieved by adding the flag -fPIC to CC and changing the all target to

all: bdio.o $(LIBDIR) gcc -shared -Wl,-soname,libbdio.so -o $(BUILDDIR)/libbdio.so $(BUILDDIR)/bdio.o cp $(BUILDDIR)/libbdio.so $(LIBDIR)/

Parameters
  • file_path (str): path to the bdio file
  • bdio_path (str): path to the shared bdio library libbdio.so (default ./libbdio.so)
  • start (int): The first configuration to be read (default 1)
  • stop (int): The last configuration to be read (default None)
  • step (int): Fixed step size between two measurements (default 1)
  • alternative_ensemble_name (str): Manually overwrite ensemble name