pyerrors.input.bdio

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