def import_bin(filename, **kwargs):
    """Read a .bin file generated by the IRIS Instruments Syscal Pro System and
    return a curated dataframe for further processing. This dataframe contains
    only information currently deemed important. Use the function
    reda.importers.iris_syscal_pro_binary._import_bin to extract ALL
    information from a given .bin file.

    Parameters
    ----------
    filename : string
        path to input filename
    x0 : float, optional
        position of first electrode. If not given, then use the smallest
        x-position in the data as the first electrode.
    spacing : float
        electrode spacing. This is important if not all electrodes are used in
        a given measurement setup. If not given, then the smallest distance
        between electrodes is assumed to be the electrode spacing. Naturally,
        this requires measurements (or injections) with subsequent electrodes.
    reciprocals : int, optional
        if provided, then assume that this is a reciprocal measurements where
        only the electrode cables were switched. The provided number N is
        treated as the maximum electrode number, and denotations are renamed
        according to the equation :math:`X_n = N - (X_a - 1)`
    check_meas_nums : bool
        if True, then check that the measurement numbers are consecutive. Don't
        return data after a jump to smaller measurement numbers (this usually
        indicates that more data points were downloaded than are part of a
        specific measurement. Default: True
    skip_rows : int
        Ignore this number of rows at the beginning, e.g., because they were
        inadvertently imported from an earlier measurement. Default: 0

    Returns
    -------
    data : :py:class:`pandas.DataFrame`
        Contains the measurement data
    electrodes : :py:class:`pandas.DataFrame`
        Contains electrode positions (None at the moment)
    topography : None
        No topography information is contained in the text files, so we always
        return None

    """
    metadata, data_raw = _import_bin(filename)

    skip_rows = kwargs.get('skip_rows', 0)
    if skip_rows > 0:
        data_raw.drop(data_raw.index[range(0, skip_rows)], inplace=True)
        data_raw = data_raw.reset_index()

    if kwargs.get('check_meas_nums', True):
        # check that first number is 0
        if data_raw['measurement_num'].iloc[0] != 0:
            print('WARNING: Measurement numbers do not start with 0 ' +
                  '(did you download ALL data?)')

        # check that all measurement numbers increase by one
        if not np.all(np.diff(data_raw['measurement_num'])) == 1:
            print(
                'WARNING '
                'Measurement numbers are not consecutive. '
                'Perhaps the first measurement belongs to another measurement?'
                ' Use the skip_rows parameter to skip those measurements'
            )

        # now check if there is a jump in measurement numbers somewhere
        # ignore first entry as this will always be nan
        diff = data_raw['measurement_num'].diff()[1:]
        jump = np.where(diff != 1)[0]
        if len(jump) > 0:
            print('WARNING: One or more jumps in measurement numbers detected')
            print('The jump indices are:')
            for jump_nr in jump:
                print(jump_nr)

            print('Removing data points subsequent to the first jump')
            data_raw = data_raw.iloc[0:jump[0] + 1, :]

    if data_raw.shape[0] == 0:
        # no data present, return a bare DataFrame
        return pd.DataFrame(columns=['a', 'b', 'm', 'n', 'r']), None, None

    data = _convert_coords_to_abmn_X(
        data_raw[['x_a', 'x_b', 'x_m', 'x_n']],
        **kwargs
    )
    # [mV] / [mA]
    data['r'] = data_raw['vp'] / data_raw['Iab']
    data['Vmn'] = data_raw['vp']
    data['vab'] = data_raw['vab']
    data['Iab'] = data_raw['Iab']

    data['mdelay'] = data_raw['mdelay']
    data['Tm'] = data_raw['Tm']
    data['Mx'] = data_raw['Mx']
    data['chargeability'] = data_raw['m']
    data['q'] = data_raw['q']

    # rename electrode denotations
    rec_max = kwargs.get('reciprocals', None)
    if rec_max is not None:
        print('renumbering electrode numbers')
        data[['a', 'b', 'm', 'n']] = rec_max + 1 - data[['a', 'b', 'm', 'n']]

    # print(data)
    return data, None, None
def import_bin ( filename , ** kwargs ) : metadata , data_raw = _import_bin ( filename ) skip_rows = kwargs . get ( 'skip_rows' , 0 ) if skip_rows > 0 : data_raw . drop ( data_raw . index [ range ( 0 , skip_rows ) ] , inplace = True ) data_raw = data_raw . reset_index ( ) if kwargs . get ( 'check_meas_nums' , True ) : if data_raw [ 'measurement_num' ] . iloc [ 0 ] != 0 : print ( 'WARNING: Measurement numbers do not start with 0 ' + '(did you download ALL data?)' ) if not np . all ( np . diff ( data_raw [ 'measurement_num' ] ) ) == 1 : print ( 'WARNING ' 'Measurement numbers are not consecutive. ' 'Perhaps the first measurement belongs to another measurement?' ' Use the skip_rows parameter to skip those measurements' ) diff = data_raw [ 'measurement_num' ] . diff ( ) [ 1 : ] jump = np . where ( diff != 1 ) [ 0 ] if len ( jump ) > 0 : print ( 'WARNING: One or more jumps in measurement numbers detected' ) print ( 'The jump indices are:' ) for jump_nr in jump : print ( jump_nr ) print ( 'Removing data points subsequent to the first jump' ) data_raw = data_raw . iloc [ 0 : jump [ 0 ] + 1 , : ] if data_raw . shape [ 0 ] == 0 : return pd . DataFrame ( columns = [ 'a' , 'b' , 'm' , 'n' , 'r' ] ) , None , None data = _convert_coords_to_abmn_X ( data_raw [ [ 'x_a' , 'x_b' , 'x_m' , 'x_n' ] ] , ** kwargs ) data [ 'r' ] = data_raw [ 'vp' ] / data_raw [ 'Iab' ] data [ 'Vmn' ] = data_raw [ 'vp' ] data [ 'vab' ] = data_raw [ 'vab' ] data [ 'Iab' ] = data_raw [ 'Iab' ] data [ 'mdelay' ] = data_raw [ 'mdelay' ] data [ 'Tm' ] = data_raw [ 'Tm' ] data [ 'Mx' ] = data_raw [ 'Mx' ] data [ 'chargeability' ] = data_raw [ 'm' ] data [ 'q' ] = data_raw [ 'q' ] rec_max = kwargs . get ( 'reciprocals' , None ) if rec_max is not None : print ( 'renumbering electrode numbers' ) data [ [ 'a' , 'b' , 'm' , 'n' ] ] = rec_max + 1 - data [ [ 'a' , 'b' , 'm' , 'n' ] ] return data , None , None
Read a .bin file generated by the IRIS Instruments Syscal Pro System and
    return a curated dataframe for further processing. This dataframe contains
    only information currently deemed important. Use the function
    reda.importers.iris_syscal_pro_binary._import_bin to extract ALL
    information from a given .bin file.

    Parameters
    ----------
    filename : string
        path to input filename
    x0 : float, optional
        position of first electrode. If not given, then use the smallest
        x-position in the data as the first electrode.
    spacing : float
        electrode spacing. This is important if not all electrodes are used in
        a given measurement setup. If not given, then the smallest distance
        between electrodes is assumed to be the electrode spacing. Naturally,
        this requires measurements (or injections) with subsequent electrodes.
    reciprocals : int, optional
        if provided, then assume that this is a reciprocal measurements where
        only the electrode cables were switched. The provided number N is
        treated as the maximum electrode number, and denotations are renamed
        according to the equation :math:`X_n = N - (X_a - 1)`
    check_meas_nums : bool
        if True, then check that the measurement numbers are consecutive. Don't
        return data after a jump to smaller measurement numbers (this usually
        indicates that more data points were downloaded than are part of a
        specific measurement. Default: True
    skip_rows : int
        Ignore this number of rows at the beginning, e.g., because they were
        inadvertently imported from an earlier measurement. Default: 0

    Returns
    -------
    data : :py:class:`pandas.DataFrame`
        Contains the measurement data
    electrodes : :py:class:`pandas.DataFrame`
        Contains electrode positions (None at the moment)
    topography : None
        No topography information is contained in the text files, so we always
        return None