def test_loading_normal(): seit = reda.sEIT() seit.import_eit_fzj( basepath + 'eit_data_mnu0.mat', basepath + 'configs.dat', multiplexer_group=1 )
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
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)
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)
#!/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'):
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
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
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)
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)