Importing FZJ EIT40/EIT160 data

This example shows how to import data from the various versions of the EIT system developed by Zimmermann et al. 2008 (http://iopscience.iop.org/article/10.1088/0957-0233/19/9/094010/meta).

At this point we only support 3-point data, i.e., data which uses two electrodes to inject current, and then uses all electrodes to measure the resulting potential distribution against system ground. Classical four-point configurations are then computed using superposition.

Required are two files: a data file (usually eit_data_mnu0.mat and a text file (usually configs.dat containing the measurement configurations to extract.

The configs.dat 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:

1   2   4   3
2   3   5   6

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'
)
Constructing four-point measurements
Summary:
                a           b  ...     frequency          rpha
count  16280.0000  16280.0000  ...  16280.000000  16280.000000
mean      10.5250     30.4750  ...   1328.935406   1232.306629
std        5.8096      5.8096  ...   2885.893725   1823.550170
min        1.0000     20.0000  ...      0.100000  -3141.584482
25%        5.7500     25.7500  ...      1.000000     -9.388102
50%       10.5000     30.5000  ...     31.250000     -1.038730
75%       15.2500     35.2500  ...   1000.000000   3132.171261
max       21.0000     40.0000  ...  10000.000000   3141.580651

[8 rows x 7 columns]

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',
    configfile=MD_ConfigsPermutate
)
Constructing four-point measurements
Summary:
                a           b  ...     frequency          rpha
count  16280.0000  16280.0000  ...  16280.000000  16280.000000
mean      10.5250     30.4750  ...   1328.935406    217.078193
std        5.8096      5.8096  ...   2885.893725   1129.623431
min        1.0000     20.0000  ...      0.100000  -3141.556931
25%        5.7500     25.7500  ...      1.000000    -15.614618
50%       10.5000     30.5000  ...     31.250000     -7.626176
75%       15.2500     35.2500  ...   1000.000000     -5.227314
max       21.0000     40.0000  ...  10000.000000   3141.584591

[8 rows x 7 columns]

Compute geometric factors

import reda.utils.geometric_factors as redaK
import reda.utils.fix_sign_with_K as redafixK

K = redaK.compute_K_analytical(seit.data, spacing=0.25)
redaK.apply_K(seit.data, K)
redafixK.fix_sign_with_K(seit.data)
a b m n datetime frequency Zg1 Zg2 Zg3 Zg Is Il Iab Ileakage Zt r Vmn rpha id norrec rdiff rphadiff k rho_a sigma_a rho_a_complex
55 1 22 2 21 2018-01-27 08:03:45.233560 0.1 1845.514039- 309.918615j 1830.103481- 336.538264j 1830.135759- 348.659106j 1835.251093- 331.705328j 0.004369+0.000378j -7.781986e-07-2.016430e- 07j 4.384991 0.000804 67.613572- 0.476405j 67.615251 296.492266 -7.045880 74 nor -135.370540 3141.166197 0.826735 55.899888 0.017889 55.898501- 0.393861j
74 2 21 1 22 2018-01-27 08:47:03.645680 0.1 1740.676857- 298.630656j 1729.294712- 322.735738j 1730.518216- 332.929183j 1733.496595- 318.098526j 0.004488+0.000382j -2.603903e-06-6.249216e- 07j 4.504308 0.002678 67.753805- 0.448498j 67.755289 305.190720 -6.619423 74 rec -135.370540 3141.166197 0.826735 56.015663 0.017852 56.014436- 0.370789j
18 1 20 2 21 2018-01-27 09:28:11.962861 0.1 1882.449148- 332.761564j 1867.017051- 353.821789j 1868.918746- 358.069064j 1872.794982- 348.217472j 0.004324+0.000389j 8.166327e-07+2.159040e- 07j 4.341069 0.000845 68.595685- 0.552429j 68.597910 297.788253 -8.053239 92 nor -0.106258 -0.590684 0.829159 56.878598 0.017581 56.876754- 0.458052j
92 2 21 1 20 2018-01-27 08:47:03.645680 0.1 1740.676857- 298.630656j 1729.294712- 322.735738j 1730.518216- 332.929183j 1733.496595- 318.098526j 0.004488+0.000382j -2.603903e-06-6.249216e- 07j 4.504308 0.002678 68.489745- 0.511118j 68.491652 308.507526 -7.462554 92 rec -0.106258 -0.590684 0.829159 56.790494 0.017609 56.788913- 0.423798j
37 1 22 2 23 2018-01-27 08:03:45.233560 0.1 1845.514039- 309.918615j 1830.103481- 336.538264j 1830.135759- 348.659106j 1835.251093- 331.705328j 0.004369+0.000378j -7.781986e-07-2.016430e- 07j 4.384991 0.000804 61.405722- 0.426200j 61.407201 269.270026 -6.940618 111 nor -0.180274 0.614708 0.824762 50.646313 0.019745 50.645094- 0.351514j
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
16277 21 40 18 37 2018-01-27 08:45:26.153105 10000.0 1214.971601- 99.776976j 1214.970677- 99.777250j 1214.970820- 99.776733j 1214.971033- 99.776987j 0.005267+0.000167j 3.035386e-04-5.237910e- 05j 5.269442 0.308025 14.400491- 0.787052j 14.421983 75.995798 -54.600210 1477 rec -0.176318 -14.544220 2.811459 40.546816 0.024663 40.486393- 2.212765j
16168 19 38 21 40 2018-01-27 08:41:06.303742 10000.0 1487.062804- 137.106700j 1487.062909- 137.107755j 1487.061286- 137.107605j 1487.062333- 137.107354j 0.004855+0.000194j -1.159057e-04-8.547126e- 05j 4.858639 0.144012 24.556856- 1.833682j 24.625222 119.645077 -74.532549 1478 nor -0.246324 -11.928511 1.757913 43.289002 0.023101 43.168820- 3.223453j
16278 21 40 19 38 2018-01-27 08:45:26.153105 10000.0 1214.971601- 99.776976j 1214.970677- 99.777250j 1214.970820- 99.776733j 1214.971033- 99.776987j 0.005267+0.000167j 3.035386e-04-5.237910e- 05j 5.269442 0.308025 24.331140- 1.525221j 24.378898 128.463180 -62.604038 1478 rec -0.246324 -11.928511 1.757913 42.855985 0.023334 42.772030- 2.681205j
16242 20 39 21 40 2018-01-27 09:26:34.516287 10000.0 1420.095538- 150.390175j 1420.096385- 150.391266j 1420.096148- 150.391203j 1420.096023- 150.390881j 0.004947+0.000221j -2.085763e-04-4.436973e- 05j 4.952257 0.213243 62.432660- 5.558812j 62.679642 310.405690 -88.802752 1479 nor -0.022068 -16.100432 0.829159 51.971411 0.019241 51.766624- 4.609141j
16279 21 40 20 39 2018-01-27 08:45:26.153105 10000.0 1214.971601- 99.776976j 1214.970677- 99.777250j 1214.970820- 99.776733j 1214.971033- 99.776987j 0.005267+0.000167j 3.035386e-04-5.237910e- 05j 5.269442 0.308025 62.492054- 4.551339j 62.657574 330.170428 -72.702319 1479 rec -0.022068 -16.100432 0.829159 51.953113 0.019248 51.815871- 3.773785j

16280 rows × 26 columns



compute normal and reciprocal pairs note that this is usually done on import once.

import reda.utils.norrec as norrec
seit.data = norrec.assign_norrec_to_df(seit.data)

quadrupoles can be directly accessed using a pandas grouper

print(seit.abmn)
quadpole_data = seit.abmn.get_group((10, 29, 15, 34))
print(quadpole_data[['a', 'b', 'm', 'n', 'frequency', 'r', 'rpha']])
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f76cec24fd0>
        a   b   m   n     frequency         r        rpha
748    10  29  15  34      0.100000  7.356375   -5.205543
2228   10  29  15  34      0.314465  7.323810   -6.903037
3708   10  29  15  34      1.000000  7.282164   -7.242394
5188   10  29  15  34      3.125000  7.239073   -6.332998
6668   10  29  15  34     10.000000  7.199660  -12.081013
8148   10  29  15  34     31.250000  7.176920   -3.132819
9628   10  29  15  34    110.000000  7.170031    4.958888
11108  10  29  15  34    312.500000  7.211899    8.671063
12588  10  29  15  34   1000.000000  7.325287   -2.429873
14068  10  29  15  34   3150.000000  7.313380  -37.892727
15548  10  29  15  34  10000.000000  7.035541 -100.904824

in a similar fashion, spectra can be extracted and plotted

spec_nor, spec_rec = seit.get_spectrum(abmn=(10, 29, 15, 34))

print(type(spec_nor))
print(type(spec_rec))

with reda.CreateEnterDirectory('output_eit_fzj'):
    spec_nor.plot(filename='spectrum_10_29_15_34.pdf')

# Note that there is also the convenient script
# :py:meth:`reda.sEIT.plot_all_spectra`, which can be used to plot all spectra
# of the container into separate files, given an output directory.
<class 'reda.eis.plots.sip_response'>
<class 'reda.eis.plots.sip_response'>

filter data

seit.remove_frequencies(1e-3, 300)
seit.query('rpha < 10')
seit.query('rpha > -40')
seit.query('rho_a > 15 and rho_a < 35')
seit.query('k < 400')
Remaining frequencies:
[0.1, 0.31446541, 1.0, 3.125, 10.0, 31.25, 110.0]

Plotting histograms Raw data plots (execute before applying the filters):

# import os
# import reda.plotters.histograms as redahist

# if not os.path.isdir('hists_raw'):
#     os.makedirs('hists_raw')

# # plot histograms for all frequencies
# r = redahist.plot_histograms_extra_dims(
#     seit.data, ['R', 'rpha'], ['frequency']
# )
# for f in sorted(r.keys()):
#     r[f]['all'].savefig('hists_raw/hist_raw_f_{0}.png'.format(f), dpi=300)

# if not os.path.isdir('hists_filtered'):
#     os.makedirs('hists_filtered')

# r = redahist.plot_histograms_extra_dims(
#     seit.data, ['R', 'rpha'], ['frequency']
# )

# for f in sorted(r.keys()):
#     r[f]['all'].savefig(
#         'hists_filtered/hist_filtered_f_{0}.png'.format(f), dpi=300
#     )

Now export the data to CRTomo-compatible files this context manager executes all code within the given directory

with reda.CreateEnterDirectory('output_eit_fzj'):
    import reda.exporters.crtomo as redaex
    redaex.write_files_to_directory(seit.data, 'crt_results', norrec='nor', )

Plot pseudosections of all frequencies

import reda.plotters.pseudoplots as PS
import pylab as plt

with reda.CreateEnterDirectory('output_eit_fzj'):
    g = seit.data.groupby('frequency')
    fig, axes = plt.subplots(
        4, 2,
        figsize=(15 / 2.54, 20 / 2.54),
        sharex=True, sharey=True
    )
    for ax, (key, item) in zip(axes.flat, g):
        fig, ax, cb = PS.plot_pseudosection_type1(item, ax=ax, column='r')
        ax.set_title('f: {} Hz'.format(key))
    fig.tight_layout()
    fig.savefig('pseudosections_eit40.pdf')
f: 0.1 Hz, f: 0.31446541 Hz, f: 1.0 Hz, f: 3.125 Hz, f: 10.0 Hz, f: 31.25 Hz, f: 110.0 Hz

alternative

with reda.CreateEnterDirectory('output_eit_fzj'):
    seit.plot_pseudosections(
        column='r', filename='pseudosections_eit40_v2.pdf'
    )

Total running time of the script: (1 minutes 13.632 seconds)

Gallery generated by Sphinx-Gallery