def test_loading_normal():
    seit = reda.sEIT()
    seit.import_eit_fzj(
        basepath + 'eit_data_mnu0.mat',
        basepath + 'configs.dat',
        multiplexer_group=1
    )
Example #2
0
def load_data_into_container(datadir):
    seit = reda.sEIT()
    for nr in range(0, 4):
        seit.import_crtomo(directory=datadir + '/modV_0{}_noisy/'.format(nr),
                           timestep=nr)
    seit.compute_K_analytical(spacing=1)
    return seit
Example #3
0
def test_load_one_dataset():
    seit = reda.sEIT()
    seit.import_crtomo(directory=basepath + 'data/modV_00_noisy/', timestep=0)

    group_frequencies = seit.data.groupby('frequency')
    # nr of frequencies
    assert len(group_frequencies.groups.keys()) == 15
    # nr of data points
    assert np.all(group_frequencies['r'].count() == 1406)
    assert 'timestep' in seit.data.columns
    assert np.all(seit.data['timestep'] == 0)
Example #4
0
def test_load_four_datasets():
    seit = reda.sEIT()
    for nr in range(0, 4):
        seit.import_crtomo(directory=basepath +
                           'data/modV_0{}_noisy/'.format(nr),
                           timestep=nr)
    assert 'timestep' in seit.data.columns
    group_timesteps = seit.data.groupby('timestep')
    assert len(group_timesteps.groups.keys()) == 4
    assert tuple(group_timesteps.groups.keys()) == (0, 1, 2, 3)

    group_frequencies = seit.data.groupby('frequency')
    # nr of frequencies
    assert len(group_frequencies.groups.keys()) == 15
    # nr of data points
    for ts, item_ts in group_timesteps:
        g_ts_f = item_ts.groupby('frequency')
        assert np.all(g_ts_f['r'].count() == 1406)
Example #5
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Visualizing multi-dimensional sEIT data
---------------------------------------

This is work in progress
"""
###############################################################################
# imports
import reda
###############################################################################
# load the data set

seit = reda.sEIT()
for nr in range(0, 4):
    seit.import_crtomo(
        directory='data_synthetic_4d/modV_0{}_noisy/'.format(nr), timestep=nr)
seit.compute_K_analytical(spacing=1)
###############################################################################
# Plotting pseudosections
with reda.CreateEnterDirectory('output_visualize_4d'):
    pass
    print('at this point the plotting routines do not honor'
          ' timestep dimensionality')

###############################################################################
# Plot a single spectrum
nor, rec = seit.get_spectrum(abmn=[1, 2, 4, 3])

with reda.CreateEnterDirectory('output_visualize_4d'):
Example #6
0
def check_resistor_board_measurements(data_file,
                                      reference_data_file=None,
                                      create_plot=True,
                                      **kwargs):
    """ To check basic system function a test board was built with multiple
    resistors attached to for connectors each. Measurements can thus be
    validated against known electrical (ohmic) resistances.

    Note that the normal-reciprocal difference is not yet analyzed!

    The referenc_data_file should have the following structure:
    The file contains the four-point spreads to be imported from
    the measurement. This file is a text file with four columns (A, B, M, N),
    separated by spaces or tabs. Each line denotes one measurement and its
    expected resistance, the allowed variation, and its allow difference
    towards its reciprocal counterpart: ::

        1   2   4   3   1000    1    20
        4   3   2   1   1000    1    20

    Parameters
    ----------
    data_file : string
        path to mnu0 data file
    reference_data_file: string, optional
        path to reference data file with structure as describe above. Default
        data is used if set to None
    create_plot : bool, optional
        if True, create a plot with measured and expected resistances
    kwargs : dict, optional
        kwargs will be redirected to the sEIT.import_eit_fzj call

    Returns
    -------
    fig : figure object, optional
        if create_plot is True, return a matplotlib figure
    """
    # reference_data = np.loadtxt(reference_data_file)
    # configs = reference_data[:, 0:4]
    column_names = [
        'a', 'b', 'm', 'n', 'expected_r', 'variation_r', 'variation_diffr'
    ]
    if reference_data_file is None:
        ref_data = pd.DataFrame(_resistor_data, columns=column_names)
    else:
        ref_data = pd.read_csv(
            reference_data_file,
            names=column_names,
            delim_whitespace=True,
        )
    print(ref_data)
    configs = ref_data[['a', 'b', 'm', 'n']].values.astype(int)

    seit = reda.sEIT()
    seit.import_eit_fzj(data_file, configs, **kwargs)
    seit.data = seit.data.merge(ref_data, on=('a', 'b', 'm', 'n'))

    # iterate through the test configurations
    test_frequency = 1
    failing = []
    for nr, row in enumerate(ref_data.values):
        print(nr, row)
        key = tuple(row[0:4].astype(int))
        item = seit.abmn.get_group(key)
        expected_r = row[4]
        allowed_variation = row[5]
        # expected_r_diff = row[6]

        measured_r, measured_rdiff = item.query(
            'frequency == {}'.format(test_frequency))[['r', 'rdiff'
                                                       ]].values.squeeze()
        minr = expected_r - allowed_variation
        maxr = expected_r + allowed_variation
        if not (minr <= measured_r and maxr >= measured_r):
            print('    ', 'not passing', row)
            print('    ', minr, maxr)
            print('    ', measured_r)
            failing.append((nr, measured_r))
    if len(failing) == 0:
        failing = None
    else:
        failing = np.atleast_2d(np.array(failing))

    if create_plot:
        fig, ax = plt.subplots(1, 1, figsize=(16 / 2.54, 8 / 2.54))
        data = seit.data.query('frequency == 1')
        x = np.arange(0, data.shape[0])

        ax.plot(
            x,
            data['r'],
            '.-',
            label='data',
        )
        ax.fill_between(
            x,
            data['expected_r'] - data['variation_r'],
            data['expected_r'] + data['variation_r'],
            color='green',
            alpha=0.8,
            label='allowed limits',
        )
        if failing is not None:
            ax.scatter(
                failing[:, 0],
                failing[:, 1],
                color='r',
                label='not passing',
                s=40,
            )

        ax.legend()
        ax.set_xticks(x)
        xticklabels = [
            '{}-{} {}-{}'.format(*row)
            for row in data[['a', 'b', 'm', 'n']].values.astype(int)
        ]
        ax.set_xticklabels(xticklabels, rotation=45)

        ax.set_ylabel(r'resistance $[\Omega]$')
        ax.set_xlabel('configuration a-b m-n')
        if failing is None:
            suffix = ' PASSED'
        else:
            suffix = ''
        ax.set_title('Resistor-check for FZJ-EIT systems' + suffix)

        fig.tight_layout()
        # fig.savefig('out.pdf')
        return fig
Example #7
0
An alternative to the config.dat file is to permute all current injection
dipoles as voltage dipoles, resulting in a fully normal-reciprocal
configuration set. This set can be automatically generated from the measurement
data by providing a special function as the config-parameter in the import
function. This is explained below.

"""

##############################################################################
# Import reda
import reda

##############################################################################
# Initialize an sEIT container
seit = reda.sEIT()

# import the data
seit.import_eit_fzj(
    filename='data_EIT40_v_EZ-2017/eit_data_mnu0.mat',
    configfile='data_EIT40_v_EZ-2017/configs_large_dipoles_norrec.dat')
##############################################################################
# an alternative would be to automatically create measurement configurations
# from the current injection dipoles:
from reda.importers.eit_fzj import MD_ConfigsPermutate

# initialize an sEIT container
seit_not_used = reda.sEIT()

# import the data
seit_not_used.import_eit_fzj(filename='data_EIT40_v_EZ-2017/eit_data_mnu0.mat',
def test_loading_normal():
    seit = reda.sEIT()
    seit.import_mpt_das1(basepath + 'SIP2.Data')
* conduct a full measurements on water with known conductivity
* calculate synthetic forward results using 2D-CRMod using the true water
  conductivity

"""
###############################################################################
# imports
import pandas as pd
import crtomo
import reda
###############################################################################
# compute correction factors using data from this frequency
target_frequency = 70
###############################################################################
# dataset 1
seit1 = reda.sEIT()
seit1.import_eit_fzj(
    'data/CalibrationData/bnk_water_blubber_20130428_1810_34_einzel.mat',
    'data/configs.dat')
configurations = seit1.data.query(
    'frequency == {}'.format(target_frequency))[['a', 'b', 'm', 'n']].values
# extract configurations for one frequency
###############################################################################
# synthetic forward modeling
grid = crtomo.crt_grid('data/elem.dat', 'data/elec.dat')
tdman = crtomo.tdMan(grid=grid)

# add configuration added from the measurement data
tdman.configs.add_to_configs(configurations)

# true water conductivity 37.5 mS/m
Example #10
0
def test_loading_normal():
    seit = reda.sEIT()
    seit.import_eit_fzj(
        basepath + 'eit_data_mnu0.mat',
        basepath + 'configs_large_dipoles_norrec.dat',
    )
# imports
import os

import numpy as np

import reda
import reda.utils.geometric_factors as geom_facs
from reda.utils.fix_sign_with_K import fix_sign_with_K
import reda.importers.eit_fzj as eit_fzj
###############################################################################
# define an output directory for all files
output_directory = 'output_single_freq_inversion_sEIT'

###############################################################################
# import the sEIT data set
seit = reda.sEIT()
seit.import_eit_fzj('data/bnk_raps_20130408_1715_03_einzel.mat',
                    'data/configs.dat')
###############################################################################
with reda.CreateEnterDirectory(output_directory):
    # export the data into CRTomo-style data files. Each frequency gets its own
    # file
    seit.export_to_crtomo_multi_frequency('result_raw_data')

    # just for demonstration purposes, data could be imported from this
    # directory:
    # create a new sEIT container
    seit_temp = reda.sEIT()
    seit_temp.import_crtomo('result_raw_data')
    # delete it to prevent any confusions
    del (seit_temp)
Example #12
0
def testboard_evaluation(datapath,
                         configdat,
                         outputname,
                         frequencies=np.logspace(-1, 4, 40),
                         error_percentage=1):
    """
    A testboard with resistors and capacitors was built to test the
    basic operation performance of eit-systems from FZJ. This function plots
    the results of measurements on this board in terms of impedance magnitude
    and phase.

    Parameters
    ----------
    datapath : str
        Path to the eit_data_mnu0.mat file containing the measurements.

    configdat: np.ndarray or txt-file
        input configuration of the used testboard configurations,
        e.g. for first two rows of the board:
        1 4 2 3
        2 3 1 4
        5 8 6 7
        6 7 5 8
        Note that normal and reciprocal measurements have to be measured.

    outputname: str
        output name of plot in png-format

    frequencies: numpy array
        frequency range (in log10-space) to compare the measurements to;
        default range is from 0.1 Hz to 10 kHz

    error_percentage: float
        percentage of allowed measurement error. The range inside this
        limit will be shown as a grey shadow in the plot.

    Returns
    -------
    fig: figure object
        Saves the plot with the given output name in the execution location of
        the script.

    """
    def calc_response(frequencies):
        # calculates theoretical |Z| and Zpha of the testboard for given
        # frequencies
        omega = 2 * np.pi * frequencies
        # settings of the specific testboard; if a new testboard with different
        # resistors/capacitors is built, parameters can be changed here
        rs = 1000
        r1 = 500

        #
        c1 = 330e-9

        r2 = 500
        c2 = 47e-6

        cp = 5e-12

        # the terms
        term1 = (r1 - 1j * omega * r1 ** 2 * c1) / \
            (1 + omega ** 2 * c1 ** 2 * r1 ** 2)
        term2 = (r2 - 1j * omega * r2 ** 2 * c2) / \
            (1 + omega ** 2 * c2 ** 2 * r2 ** 2)

        z1 = rs + term1 + term2
        z2 = -1j / (omega * cp)

        z = 1 / (1 / z1 + 1 / z2)

        rmag = np.abs(z)
        rpha = np.arctan2(z.imag, z.real) * 1000

        return rmag, rpha

    # load configurations
    if type(configdat) == np.ndarray:
        configs = configdat
    else:
        configs = np.loadtxt(configdat)

    # load measurements
    seit = reda.sEIT()
    seit.import_eit_fzj(datapath, configs)

    # append measurements to either the "normal" or "reciprocal" list
    nor = []
    rec = []
    for i in configs:
        data = seit.abmn.get_group((i[0], i[1], i[2], i[3]))
        if data['norrec'].all() == 'nor':
            nor.append(data)
        else:
            rec.append(data)

    # calculate theoretical testboard response and error
    rmag, rpha = calc_response(frequencies)
    error_rmag = rmag * error_percentage / 100
    error_rpha = rpha * error_percentage / 100

    # plotting results

    fig, axes = plt.subplots(int(len(nor)),
                             2,
                             figsize=(12, 3 * len(nor)),
                             sharex=True)

    # in case of only one measurement
    if len(nor) <= 1:
        # plot normal measurements and theoretical response
        for num, n in enumerate(nor):
            axes[0].set_title('Magnitude {} {} {} {}'.format(
                n.iloc[0]['a'], n.iloc[0]['b'], n.iloc[0]['m'],
                n.iloc[0]['n']))
            axes[0].plot(n["frequency"],
                         n['r'],
                         marker='o',
                         linestyle=' ',
                         label='nor')
            axes[0].plot(frequencies, rmag, label='calculated')
            axes[0].fill_between(frequencies,
                                 rmag + error_rmag,
                                 rmag - error_rmag,
                                 color='grey',
                                 alpha=0.3)
            axes[0].set_ylabel(r'|Z| [$\Omega$]')
            axes[1].set_title('Phase {} {} {} {}'.format(
                n.iloc[0]['a'], n.iloc[0]['b'], n.iloc[0]['m'],
                n.iloc[0]['n']))
            axes[1].plot(n["frequency"],
                         -1 * n['rpha'],
                         marker='o',
                         linestyle=' ',
                         label='nor')
            axes[1].plot(frequencies, -1 * rpha, label='calculated')
            axes[1].fill_between(frequencies,
                                 -1 * rpha + error_rpha,
                                 -1 * rpha - error_rpha,
                                 color='grey',
                                 alpha=0.3)
            axes[1].set_ylabel(r'-$\varphi_{Z}$ [mrad]')

        # plot reciprocal measurements
        for num, r in enumerate(rec):
            axes[0].plot(r["frequency"],
                         r['r'],
                         marker='x',
                         linestyle=' ',
                         label='rec')
            axes[1].plot(r["frequency"],
                         -1 * r['rpha'],
                         marker='x',
                         linestyle=' ',
                         label='rec')

        # axis labels for two plots
        axes[0].set_xlabel("frequency [Hz]")
        axes[1].set_xlabel("frequency [Hz]")

    # in case of several measurements
    else:
        # plot normal measurements and theoretical response
        for num, n in enumerate(nor):
            axes[num - 1][0].set_title('Magnitude {} {} {} {}'.format(
                n.iloc[0]['a'], n.iloc[0]['b'], n.iloc[0]['m'],
                n.iloc[0]['n']))
            axes[num - 1][0].plot(n["frequency"],
                                  n['r'],
                                  marker='o',
                                  linestyle=' ',
                                  label='nor')
            axes[num - 1][0].plot(frequencies, rmag, label='calculated')
            axes[num - 1][0].fill_between(frequencies,
                                          rmag + error_rmag,
                                          rmag - error_rmag,
                                          color='grey',
                                          alpha=0.3)
            axes[num - 1][0].set_ylabel(r'|Z| [$\Omega$]')
            axes[num - 1][1].set_title('Phase {} {} {} {}'.format(
                n.iloc[0]['a'], n.iloc[0]['b'], n.iloc[0]['m'],
                n.iloc[0]['n']))
            axes[num - 1][1].plot(n["frequency"],
                                  -1 * n['rpha'],
                                  marker='o',
                                  linestyle=' ',
                                  label='nor')
            axes[num - 1][1].plot(frequencies, -1 * rpha, label='calculated')
            axes[num - 1][1].fill_between(frequencies,
                                          -1 * rpha + error_rpha,
                                          -1 * rpha - error_rpha,
                                          color='grey',
                                          alpha=0.3)
            axes[num - 1][1].set_ylabel(r'-$\varphi_{Z}$ [mrad]')

        # plot reciprocal measurements
        for num, r in enumerate(rec):
            axes[num - 1][0].plot(r["frequency"],
                                  r['r'],
                                  marker='x',
                                  linestyle=' ',
                                  label='rec')
            axes[num - 1][1].plot(r["frequency"],
                                  -1 * r['rpha'],
                                  marker='x',
                                  linestyle=' ',
                                  label='rec')

        # axis labels for two bottom plots
        axes[len(nor) - 1][0].set_xlabel("frequency [Hz]")
        axes[len(nor) - 1][1].set_xlabel("frequency [Hz]")

    # axis scaling and legends
    for ax in axes.reshape(-1):
        ax.grid()
        ax.legend()
        ax.set_xscale("log")
        ax.set_xlim(min(frequencies), max(frequencies))

    fig.tight_layout()
    fig.savefig('{}.png'.format(outputname), dpi=300)