From 738d04ec974bcb624afa20e908f18ee5fd33271e Mon Sep 17 00:00:00 2001 From: fjosw Date: Fri, 18 Nov 2022 16:33:10 +0000 Subject: [PATCH] Documentation updated --- docs/pyerrors/input/openQCD.html | 658 ++++++++++++++++--------------- 1 file changed, 330 insertions(+), 328 deletions(-) diff --git a/docs/pyerrors/input/openQCD.html b/docs/pyerrors/input/openQCD.html index fee0da62..0be05f9a 100644 --- a/docs/pyerrors/input/openQCD.html +++ b/docs/pyerrors/input/openQCD.html @@ -816,266 +816,268 @@ 723 if fnmatch.fnmatch(f, prefix + "*" + postfix): 724 files.append(f) 725 -726 if 'r_start' in kwargs: -727 r_start = kwargs.get('r_start') -728 if len(r_start) != len(files): -729 raise Exception('r_start does not match number of replicas') -730 r_start = [o if o else None for o in r_start] -731 else: -732 r_start = [None] * len(files) -733 -734 if 'r_stop' in kwargs: -735 r_stop = kwargs.get('r_stop') -736 if len(r_stop) != len(files): -737 raise Exception('r_stop does not match number of replicas') -738 else: -739 r_stop = [None] * len(files) -740 rep_names = [] -741 -742 zeuthen = kwargs.get('Zeuthen_flow', False) -743 if zeuthen and version not in ['sfqcd']: -744 raise Exception('Zeuthen flow can only be used for version==sfqcd') -745 -746 r_start_index = [] -747 r_stop_index = [] -748 deltas = [] -749 configlist = [] -750 if not zeuthen: -751 obspos += 8 -752 for rep, file in enumerate(files): -753 with open(path + "/" + file, "rb") as fp: -754 -755 Q = [] -756 traj_list = [] -757 if version in ['sfqcd']: -758 t = fp.read(12) -759 header = struct.unpack('<iii', t) -760 zthfl = header[0] # Zeuthen flow -> if it's equal to 2 it means that the Zeuthen flow is also 'measured' (apart from the Wilson flow) -761 ncs = header[1] # number of different values for c in t_flow=1/8 c² L² -> measurements done for ncs c's -762 tmax = header[2] # lattice T/a -763 -764 t = fp.read(12) -765 Ls = struct.unpack('<iii', t) -766 if (Ls[0] == Ls[1] and Ls[1] == Ls[2]): -767 L = Ls[0] -768 if not (supposed_L == L) and supposed_L: -769 raise Exception("It seems the length given in the header and by you contradict each other") -770 else: -771 raise Exception("Found more than one spatial length in header!") -772 -773 t = fp.read(16) -774 header2 = struct.unpack('<dd', t) -775 tol = header2[0] -776 cmax = header2[1] # highest value of c used -777 -778 if c > cmax: -779 raise Exception('Flow has been determined between c=0 and c=%lf with tolerance %lf' % (cmax, tol)) -780 -781 if (zthfl == 2): -782 nfl = 2 # number of flows -783 else: -784 nfl = 1 -785 iobs = 8 * nfl # number of flow observables calculated -786 -787 while True: -788 t = fp.read(4) -789 if (len(t) < 4): -790 break -791 traj_list.append(struct.unpack('i', t)[0]) # trajectory number when measurement was done -792 -793 for j in range(ncs + 1): -794 for i in range(iobs): -795 t = fp.read(8 * tmax) -796 if (i == obspos): # determines the flow observable -> i=0 <-> Zeuthen flow -797 Q.append(struct.unpack('d' * tmax, t)) -798 -799 else: -800 t = fp.read(12) -801 header = struct.unpack('<iii', t) -802 # step size in integration steps "dnms" -803 dn = header[0] -804 # number of measurements, so "ntot"/dn -805 nn = header[1] -806 # lattice T/a -807 tmax = header[2] -808 -809 t = fp.read(8) -810 eps = struct.unpack('d', t)[0] -811 -812 while True: -813 t = fp.read(4) -814 if (len(t) < 4): -815 break -816 traj_list.append(struct.unpack('i', t)[0]) -817 # Wsl -818 t = fp.read(8 * tmax * (nn + 1)) -819 # Ysl +726 files = sorted(files) +727 +728 if 'r_start' in kwargs: +729 r_start = kwargs.get('r_start') +730 if len(r_start) != len(files): +731 raise Exception('r_start does not match number of replicas') +732 r_start = [o if o else None for o in r_start] +733 else: +734 r_start = [None] * len(files) +735 +736 if 'r_stop' in kwargs: +737 r_stop = kwargs.get('r_stop') +738 if len(r_stop) != len(files): +739 raise Exception('r_stop does not match number of replicas') +740 else: +741 r_stop = [None] * len(files) +742 rep_names = [] +743 +744 zeuthen = kwargs.get('Zeuthen_flow', False) +745 if zeuthen and version not in ['sfqcd']: +746 raise Exception('Zeuthen flow can only be used for version==sfqcd') +747 +748 r_start_index = [] +749 r_stop_index = [] +750 deltas = [] +751 configlist = [] +752 if not zeuthen: +753 obspos += 8 +754 for rep, file in enumerate(files): +755 with open(path + "/" + file, "rb") as fp: +756 +757 Q = [] +758 traj_list = [] +759 if version in ['sfqcd']: +760 t = fp.read(12) +761 header = struct.unpack('<iii', t) +762 zthfl = header[0] # Zeuthen flow -> if it's equal to 2 it means that the Zeuthen flow is also 'measured' (apart from the Wilson flow) +763 ncs = header[1] # number of different values for c in t_flow=1/8 c² L² -> measurements done for ncs c's +764 tmax = header[2] # lattice T/a +765 +766 t = fp.read(12) +767 Ls = struct.unpack('<iii', t) +768 if (Ls[0] == Ls[1] and Ls[1] == Ls[2]): +769 L = Ls[0] +770 if not (supposed_L == L) and supposed_L: +771 raise Exception("It seems the length given in the header and by you contradict each other") +772 else: +773 raise Exception("Found more than one spatial length in header!") +774 +775 t = fp.read(16) +776 header2 = struct.unpack('<dd', t) +777 tol = header2[0] +778 cmax = header2[1] # highest value of c used +779 +780 if c > cmax: +781 raise Exception('Flow has been determined between c=0 and c=%lf with tolerance %lf' % (cmax, tol)) +782 +783 if (zthfl == 2): +784 nfl = 2 # number of flows +785 else: +786 nfl = 1 +787 iobs = 8 * nfl # number of flow observables calculated +788 +789 while True: +790 t = fp.read(4) +791 if (len(t) < 4): +792 break +793 traj_list.append(struct.unpack('i', t)[0]) # trajectory number when measurement was done +794 +795 for j in range(ncs + 1): +796 for i in range(iobs): +797 t = fp.read(8 * tmax) +798 if (i == obspos): # determines the flow observable -> i=0 <-> Zeuthen flow +799 Q.append(struct.unpack('d' * tmax, t)) +800 +801 else: +802 t = fp.read(12) +803 header = struct.unpack('<iii', t) +804 # step size in integration steps "dnms" +805 dn = header[0] +806 # number of measurements, so "ntot"/dn +807 nn = header[1] +808 # lattice T/a +809 tmax = header[2] +810 +811 t = fp.read(8) +812 eps = struct.unpack('d', t)[0] +813 +814 while True: +815 t = fp.read(4) +816 if (len(t) < 4): +817 break +818 traj_list.append(struct.unpack('i', t)[0]) +819 # Wsl 820 t = fp.read(8 * tmax * (nn + 1)) -821 # Qsl, which is asked for in this method +821 # Ysl 822 t = fp.read(8 * tmax * (nn + 1)) -823 # unpack the array of Qtops, -824 # on each timeslice t=0,...,tmax-1 and the -825 # measurement number in = 0...nn (see README.qcd1) -826 tmpd = struct.unpack('d' * tmax * (nn + 1), t) -827 Q.append(tmpd) -828 -829 if len(np.unique(np.diff(traj_list))) != 1: -830 raise Exception("Irregularities in stepsize found") -831 else: -832 if 'steps' in kwargs: -833 if steps != traj_list[1] - traj_list[0]: -834 raise Exception("steps and the found stepsize are not the same") -835 else: -836 steps = traj_list[1] - traj_list[0] -837 -838 configlist.append([tr // steps // dtr_cnfg for tr in traj_list]) -839 if configlist[-1][0] > 1: -840 offset = configlist[-1][0] - 1 -841 warnings.warn('Assume thermalization and that the first measurement belongs to the first config. Offset = %d configs (%d trajectories / cycles)' % ( -842 offset, offset * steps)) -843 configlist[-1] = [item - offset for item in configlist[-1]] -844 -845 if r_start[rep] is None: -846 r_start_index.append(0) -847 else: -848 try: -849 r_start_index.append(configlist[-1].index(r_start[rep])) -850 except ValueError: -851 raise Exception('Config %d not in file with range [%d, %d]' % ( -852 r_start[rep], configlist[-1][0], configlist[-1][-1])) from None -853 -854 if r_stop[rep] is None: -855 r_stop_index.append(len(configlist[-1]) - 1) -856 else: -857 try: -858 r_stop_index.append(configlist[-1].index(r_stop[rep])) -859 except ValueError: -860 raise Exception('Config %d not in file with range [%d, %d]' % ( -861 r_stop[rep], configlist[-1][0], configlist[-1][-1])) from None -862 -863 if version in ['sfqcd']: -864 cstepsize = cmax / ncs -865 index_aim = round(c / cstepsize) -866 else: -867 t_aim = (c * L) ** 2 / 8 -868 index_aim = round(t_aim / eps / dn) -869 -870 Q_sum = [] -871 for i, item in enumerate(Q): -872 if sum_t is True: -873 Q_sum.append([sum(item[current:current + tmax]) -874 for current in range(0, len(item), tmax)]) -875 else: -876 Q_sum.append([item[int(tmax / 2)]]) -877 Q_top = [] -878 if version in ['sfqcd']: -879 for i in range(len(Q_sum) // (ncs + 1)): -880 Q_top.append(Q_sum[i * (ncs + 1) + index_aim][0]) -881 else: -882 for i in range(len(Q) // dtr_cnfg): -883 Q_top.append(Q_sum[dtr_cnfg * i][index_aim]) -884 if len(Q_top) != len(traj_list) // dtr_cnfg: -885 raise Exception("qtops and traj_list dont have the same length") -886 -887 if kwargs.get('integer_charge', False): -888 Q_top = [round(q) for q in Q_top] -889 -890 truncated_file = file[:-len(postfix)] +823 # Qsl, which is asked for in this method +824 t = fp.read(8 * tmax * (nn + 1)) +825 # unpack the array of Qtops, +826 # on each timeslice t=0,...,tmax-1 and the +827 # measurement number in = 0...nn (see README.qcd1) +828 tmpd = struct.unpack('d' * tmax * (nn + 1), t) +829 Q.append(tmpd) +830 +831 if len(np.unique(np.diff(traj_list))) != 1: +832 raise Exception("Irregularities in stepsize found") +833 else: +834 if 'steps' in kwargs: +835 if steps != traj_list[1] - traj_list[0]: +836 raise Exception("steps and the found stepsize are not the same") +837 else: +838 steps = traj_list[1] - traj_list[0] +839 +840 configlist.append([tr // steps // dtr_cnfg for tr in traj_list]) +841 if configlist[-1][0] > 1: +842 offset = configlist[-1][0] - 1 +843 warnings.warn('Assume thermalization and that the first measurement belongs to the first config. Offset = %d configs (%d trajectories / cycles)' % ( +844 offset, offset * steps)) +845 configlist[-1] = [item - offset for item in configlist[-1]] +846 +847 if r_start[rep] is None: +848 r_start_index.append(0) +849 else: +850 try: +851 r_start_index.append(configlist[-1].index(r_start[rep])) +852 except ValueError: +853 raise Exception('Config %d not in file with range [%d, %d]' % ( +854 r_start[rep], configlist[-1][0], configlist[-1][-1])) from None +855 +856 if r_stop[rep] is None: +857 r_stop_index.append(len(configlist[-1]) - 1) +858 else: +859 try: +860 r_stop_index.append(configlist[-1].index(r_stop[rep])) +861 except ValueError: +862 raise Exception('Config %d not in file with range [%d, %d]' % ( +863 r_stop[rep], configlist[-1][0], configlist[-1][-1])) from None +864 +865 if version in ['sfqcd']: +866 cstepsize = cmax / ncs +867 index_aim = round(c / cstepsize) +868 else: +869 t_aim = (c * L) ** 2 / 8 +870 index_aim = round(t_aim / eps / dn) +871 +872 Q_sum = [] +873 for i, item in enumerate(Q): +874 if sum_t is True: +875 Q_sum.append([sum(item[current:current + tmax]) +876 for current in range(0, len(item), tmax)]) +877 else: +878 Q_sum.append([item[int(tmax / 2)]]) +879 Q_top = [] +880 if version in ['sfqcd']: +881 for i in range(len(Q_sum) // (ncs + 1)): +882 Q_top.append(Q_sum[i * (ncs + 1) + index_aim][0]) +883 else: +884 for i in range(len(Q) // dtr_cnfg): +885 Q_top.append(Q_sum[dtr_cnfg * i][index_aim]) +886 if len(Q_top) != len(traj_list) // dtr_cnfg: +887 raise Exception("qtops and traj_list dont have the same length") +888 +889 if kwargs.get('integer_charge', False): +890 Q_top = [round(q) for q in Q_top] 891 -892 if "names" not in kwargs: -893 try: -894 idx = truncated_file.index('r') -895 except Exception: -896 if "names" not in kwargs: -897 raise Exception("Automatic recognition of replicum failed, please enter the key word 'names'.") -898 ens_name = truncated_file[:idx] -899 rep_names.append(ens_name + '|' + truncated_file[idx:]) -900 else: -901 names = kwargs.get("names") -902 rep_names = names -903 deltas.append(Q_top) -904 -905 idl = [range(int(configlist[rep][r_start_index[rep]]), int(configlist[rep][r_stop_index[rep]]) + 1, 1) for rep in range(len(deltas))] -906 deltas = [deltas[nrep][r_start_index[nrep]:r_stop_index[nrep] + 1] for nrep in range(len(deltas))] -907 result = Obs(deltas, rep_names, idl=idl) -908 result.tag = {"T": tmax - 1, -909 "L": L} -910 return result -911 -912 -913def qtop_projection(qtop, target=0): -914 """Returns the projection to the topological charge sector defined by target. -915 -916 Parameters -917 ---------- -918 path : Obs -919 Topological charge. -920 target : int -921 Specifies the topological sector to be reweighted to (default 0) -922 """ -923 if qtop.reweighted: -924 raise Exception('You can not use a reweighted observable for reweighting!') -925 -926 proj_qtop = [] -927 for n in qtop.deltas: -928 proj_qtop.append(np.array([1 if round(qtop.value + q) == target else 0 for q in qtop.deltas[n]])) -929 -930 reto = Obs(proj_qtop, qtop.names, idl=[qtop.idl[name] for name in qtop.names]) -931 reto.is_merged = qtop.is_merged -932 return reto -933 -934 -935def read_qtop_sector(path, prefix, c, target=0, **kwargs): -936 """Constructs reweighting factors to a specified topological sector. -937 -938 Parameters -939 ---------- -940 path : str -941 path of the measurement files -942 prefix : str -943 prefix of the measurement files, e.g. <prefix>_id0_r0.ms.dat -944 c : double -945 Smearing radius in units of the lattice extent, c = sqrt(8 t0) / L -946 target : int -947 Specifies the topological sector to be reweighted to (default 0) -948 dtr_cnfg : int -949 (optional) parameter that specifies the number of trajectories -950 between two configs. -951 if it is not set, the distance between two measurements -952 in the file is assumed to be the distance between two configurations. -953 steps : int -954 (optional) Distance between two configurations in units of trajectories / -955 cycles. Assumed to be the distance between two measurements * dtr_cnfg if not given -956 version : str -957 version string of the openQCD (sfqcd) version used to create -958 the ensemble. Default is 2.0. May also be set to sfqcd. -959 L : int -960 spatial length of the lattice in L/a. -961 HAS to be set if version != sfqcd, since openQCD does not provide -962 this in the header -963 r_start : list -964 offset of the first ensemble, making it easier to match -965 later on with other Obs -966 r_stop : list -967 last configurations that need to be read (per replicum) -968 files : list -969 specify the exact files that need to be read -970 from path, practical if e.g. only one replicum is needed -971 names : list -972 Alternative labeling for replicas/ensembles. -973 Has to have the appropriate length -974 Zeuthen_flow : bool -975 (optional) If True, the Zeuthen flow is used for Qtop. Only possible -976 for version=='sfqcd' If False, the Wilson flow is used. -977 """ -978 -979 if not isinstance(target, int): -980 raise Exception("'target' has to be an integer.") -981 -982 kwargs['integer_charge'] = True -983 qtop = read_qtop(path, prefix, c, **kwargs) -984 -985 return qtop_projection(qtop, target=target) +892 truncated_file = file[:-len(postfix)] +893 +894 if "names" not in kwargs: +895 try: +896 idx = truncated_file.index('r') +897 except Exception: +898 if "names" not in kwargs: +899 raise Exception("Automatic recognition of replicum failed, please enter the key word 'names'.") +900 ens_name = truncated_file[:idx] +901 rep_names.append(ens_name + '|' + truncated_file[idx:]) +902 else: +903 names = kwargs.get("names") +904 rep_names = names +905 deltas.append(Q_top) +906 +907 idl = [range(int(configlist[rep][r_start_index[rep]]), int(configlist[rep][r_stop_index[rep]]) + 1, 1) for rep in range(len(deltas))] +908 deltas = [deltas[nrep][r_start_index[nrep]:r_stop_index[nrep] + 1] for nrep in range(len(deltas))] +909 result = Obs(deltas, rep_names, idl=idl) +910 result.tag = {"T": tmax - 1, +911 "L": L} +912 return result +913 +914 +915def qtop_projection(qtop, target=0): +916 """Returns the projection to the topological charge sector defined by target. +917 +918 Parameters +919 ---------- +920 path : Obs +921 Topological charge. +922 target : int +923 Specifies the topological sector to be reweighted to (default 0) +924 """ +925 if qtop.reweighted: +926 raise Exception('You can not use a reweighted observable for reweighting!') +927 +928 proj_qtop = [] +929 for n in qtop.deltas: +930 proj_qtop.append(np.array([1 if round(qtop.value + q) == target else 0 for q in qtop.deltas[n]])) +931 +932 reto = Obs(proj_qtop, qtop.names, idl=[qtop.idl[name] for name in qtop.names]) +933 reto.is_merged = qtop.is_merged +934 return reto +935 +936 +937def read_qtop_sector(path, prefix, c, target=0, **kwargs): +938 """Constructs reweighting factors to a specified topological sector. +939 +940 Parameters +941 ---------- +942 path : str +943 path of the measurement files +944 prefix : str +945 prefix of the measurement files, e.g. <prefix>_id0_r0.ms.dat +946 c : double +947 Smearing radius in units of the lattice extent, c = sqrt(8 t0) / L +948 target : int +949 Specifies the topological sector to be reweighted to (default 0) +950 dtr_cnfg : int +951 (optional) parameter that specifies the number of trajectories +952 between two configs. +953 if it is not set, the distance between two measurements +954 in the file is assumed to be the distance between two configurations. +955 steps : int +956 (optional) Distance between two configurations in units of trajectories / +957 cycles. Assumed to be the distance between two measurements * dtr_cnfg if not given +958 version : str +959 version string of the openQCD (sfqcd) version used to create +960 the ensemble. Default is 2.0. May also be set to sfqcd. +961 L : int +962 spatial length of the lattice in L/a. +963 HAS to be set if version != sfqcd, since openQCD does not provide +964 this in the header +965 r_start : list +966 offset of the first ensemble, making it easier to match +967 later on with other Obs +968 r_stop : list +969 last configurations that need to be read (per replicum) +970 files : list +971 specify the exact files that need to be read +972 from path, practical if e.g. only one replicum is needed +973 names : list +974 Alternative labeling for replicas/ensembles. +975 Has to have the appropriate length +976 Zeuthen_flow : bool +977 (optional) If True, the Zeuthen flow is used for Qtop. Only possible +978 for version=='sfqcd' If False, the Wilson flow is used. +979 """ +980 +981 if not isinstance(target, int): +982 raise Exception("'target' has to be an integer.") +983 +984 kwargs['integer_charge'] = True +985 qtop = read_qtop(path, prefix, c, **kwargs) +986 +987 return qtop_projection(qtop, target=target) @@ -1907,26 +1909,26 @@ postfix of the file to read, e.g. '.gfms.dat' for openQCD-files -
914def qtop_projection(qtop, target=0):
-915    """Returns the projection to the topological charge sector defined by target.
-916
-917    Parameters
-918    ----------
-919    path : Obs
-920        Topological charge.
-921    target : int
-922        Specifies the topological sector to be reweighted to (default 0)
-923    """
-924    if qtop.reweighted:
-925        raise Exception('You can not use a reweighted observable for reweighting!')
-926
-927    proj_qtop = []
-928    for n in qtop.deltas:
-929        proj_qtop.append(np.array([1 if round(qtop.value + q) == target else 0 for q in qtop.deltas[n]]))
-930
-931    reto = Obs(proj_qtop, qtop.names, idl=[qtop.idl[name] for name in qtop.names])
-932    reto.is_merged = qtop.is_merged
-933    return reto
+            
916def qtop_projection(qtop, target=0):
+917    """Returns the projection to the topological charge sector defined by target.
+918
+919    Parameters
+920    ----------
+921    path : Obs
+922        Topological charge.
+923    target : int
+924        Specifies the topological sector to be reweighted to (default 0)
+925    """
+926    if qtop.reweighted:
+927        raise Exception('You can not use a reweighted observable for reweighting!')
+928
+929    proj_qtop = []
+930    for n in qtop.deltas:
+931        proj_qtop.append(np.array([1 if round(qtop.value + q) == target else 0 for q in qtop.deltas[n]]))
+932
+933    reto = Obs(proj_qtop, qtop.names, idl=[qtop.idl[name] for name in qtop.names])
+934    reto.is_merged = qtop.is_merged
+935    return reto
 
@@ -1955,57 +1957,57 @@ Specifies the topological sector to be reweighted to (default 0)
-
936def read_qtop_sector(path, prefix, c, target=0, **kwargs):
-937    """Constructs reweighting factors to a specified topological sector.
-938
-939    Parameters
-940    ----------
-941    path : str
-942        path of the measurement files
-943    prefix : str
-944        prefix of the measurement files, e.g. <prefix>_id0_r0.ms.dat
-945    c : double
-946        Smearing radius in units of the lattice extent, c = sqrt(8 t0) / L
-947    target : int
-948        Specifies the topological sector to be reweighted to (default 0)
-949    dtr_cnfg : int
-950        (optional) parameter that specifies the number of trajectories
-951        between two configs.
-952        if it is not set, the distance between two measurements
-953        in the file is assumed to be the distance between two configurations.
-954    steps : int
-955        (optional) Distance between two configurations in units of trajectories /
-956         cycles. Assumed to be the distance between two measurements * dtr_cnfg if not given
-957    version : str
-958        version string of the openQCD (sfqcd) version used to create
-959        the ensemble. Default is 2.0. May also be set to sfqcd.
-960    L : int
-961        spatial length of the lattice in L/a.
-962        HAS to be set if version != sfqcd, since openQCD does not provide
-963        this in the header
-964    r_start : list
-965        offset of the first ensemble, making it easier to match
-966        later on with other Obs
-967    r_stop : list
-968        last configurations that need to be read (per replicum)
-969    files : list
-970        specify the exact files that need to be read
-971        from path, practical if e.g. only one replicum is needed
-972    names : list
-973        Alternative labeling for replicas/ensembles.
-974        Has to have the appropriate length
-975    Zeuthen_flow : bool
-976        (optional) If True, the Zeuthen flow is used for Qtop. Only possible
-977        for version=='sfqcd' If False, the Wilson flow is used.
-978    """
-979
-980    if not isinstance(target, int):
-981        raise Exception("'target' has to be an integer.")
-982
-983    kwargs['integer_charge'] = True
-984    qtop = read_qtop(path, prefix, c, **kwargs)
-985
-986    return qtop_projection(qtop, target=target)
+            
938def read_qtop_sector(path, prefix, c, target=0, **kwargs):
+939    """Constructs reweighting factors to a specified topological sector.
+940
+941    Parameters
+942    ----------
+943    path : str
+944        path of the measurement files
+945    prefix : str
+946        prefix of the measurement files, e.g. <prefix>_id0_r0.ms.dat
+947    c : double
+948        Smearing radius in units of the lattice extent, c = sqrt(8 t0) / L
+949    target : int
+950        Specifies the topological sector to be reweighted to (default 0)
+951    dtr_cnfg : int
+952        (optional) parameter that specifies the number of trajectories
+953        between two configs.
+954        if it is not set, the distance between two measurements
+955        in the file is assumed to be the distance between two configurations.
+956    steps : int
+957        (optional) Distance between two configurations in units of trajectories /
+958         cycles. Assumed to be the distance between two measurements * dtr_cnfg if not given
+959    version : str
+960        version string of the openQCD (sfqcd) version used to create
+961        the ensemble. Default is 2.0. May also be set to sfqcd.
+962    L : int
+963        spatial length of the lattice in L/a.
+964        HAS to be set if version != sfqcd, since openQCD does not provide
+965        this in the header
+966    r_start : list
+967        offset of the first ensemble, making it easier to match
+968        later on with other Obs
+969    r_stop : list
+970        last configurations that need to be read (per replicum)
+971    files : list
+972        specify the exact files that need to be read
+973        from path, practical if e.g. only one replicum is needed
+974    names : list
+975        Alternative labeling for replicas/ensembles.
+976        Has to have the appropriate length
+977    Zeuthen_flow : bool
+978        (optional) If True, the Zeuthen flow is used for Qtop. Only possible
+979        for version=='sfqcd' If False, the Wilson flow is used.
+980    """
+981
+982    if not isinstance(target, int):
+983        raise Exception("'target' has to be an integer.")
+984
+985    kwargs['integer_charge'] = True
+986    qtop = read_qtop(path, prefix, c, **kwargs)
+987
+988    return qtop_projection(qtop, target=target)