Quick configurationΒΆ

If no configuration is passed, the quick processing functions in resistics will use the default configuration. However, it is possible to use a different configuration if preferred.

The dataset in this example has been provided for use by the SAMTEX consortium. For more information, please refer to [Jones2009]. Additional details about the dataset can be found at https://www.mtnet.info/data/kap03/kap03.html.

from pathlib import Path
import seedir as sd
import plotly
import resistics.letsgo as letsgo
from resistics.config import Configuration
from resistics.time import InterpolateNans, RemoveMean, Multiply
from resistics.decimate import DecimationSetup
from resistics.window import WindowerTarget

Define the data path. This is dependent on where the data is stored.

time_data_path = Path("..", "..", "data", "time", "quick", "kap123")
sd.seedir(str(time_data_path), style="emoji")

Out:

πŸ“ kap123/
β”œβ”€πŸ“„ data.npy
β””β”€πŸ“„ metadata.json

Quick calculation of the transfer function using default parameters.

soln_default = letsgo.quick_tf(time_data_path)
fig = soln_default.tf.plot(
    soln_default.freqs,
    soln_default.components,
    to_plot=["ExHy", "EyHx"],
    x_lim=[1, 5],
    res_lim=[0, 4],
    legend="Default config",
    symbol="circle",
)
fig.update_layout(height=800)
plotly.io.show(fig)

Out:

  0%|          | 0/20 [00:00<?, ?it/s]
 15%|#5        | 3/20 [00:00<00:00, 25.22it/s]
100%|##########| 20/20 [00:00<00:00, 94.13it/s]

  0%|          | 0/20 [00:00<?, ?it/s]
  5%|5         | 1/20 [00:01<00:22,  1.17s/it]
 10%|#         | 2/20 [00:02<00:20,  1.16s/it]
 15%|#5        | 3/20 [00:03<00:19,  1.15s/it]
 20%|##        | 4/20 [00:04<00:18,  1.15s/it]
 25%|##5       | 5/20 [00:05<00:17,  1.15s/it]
 30%|###       | 6/20 [00:06<00:12,  1.16it/s]
 35%|###5      | 7/20 [00:06<00:08,  1.46it/s]
 40%|####      | 8/20 [00:06<00:06,  1.76it/s]
 45%|####5     | 9/20 [00:07<00:05,  2.04it/s]
 50%|#####     | 10/20 [00:07<00:04,  2.29it/s]
 55%|#####5    | 11/20 [00:07<00:03,  2.91it/s]
 60%|######    | 12/20 [00:07<00:02,  3.59it/s]
 65%|######5   | 13/20 [00:07<00:01,  4.27it/s]
 70%|#######   | 14/20 [00:07<00:01,  4.91it/s]
 75%|#######5  | 15/20 [00:07<00:00,  5.51it/s]
 80%|########  | 16/20 [00:08<00:00,  6.27it/s]
 85%|########5 | 17/20 [00:08<00:00,  6.96it/s]
 90%|######### | 18/20 [00:08<00:00,  7.52it/s]
 95%|#########5| 19/20 [00:08<00:00,  7.99it/s]
100%|##########| 20/20 [00:08<00:00,  8.37it/s]
100%|##########| 20/20 [00:08<00:00,  2.34it/s]

Looking at the transfer function, it’s clear that the phases are in the wrong quadrants. A new time process can be added to correct this by multiplying the electric channels by -1.

Further, let’s use a different windower that will change the window size (subject to a minimum) to try and generate a target number of windows. The WindowTarget ignores the min_size in the WindowSetup and uses its own. This alternative windower will be combined with a modified decimation setup.

config = Configuration(
    name="custom",
    time_processors=[
        InterpolateNans(),
        RemoveMean(),
        Multiply(multiplier={"Ex": -1, "Ey": -1}),
    ],
    dec_setup=DecimationSetup(n_levels=3, per_level=7),
    windower=WindowerTarget(target=2_000, min_size=180),
)
config.summary()

Out:

{
    'name': 'custom',
    'time_readers': [
        {
            'name': 'TimeReaderAscii',
            'apply_scalings': True,
            'extension': '.txt',
            'delimiter': None,
            'n_header': 0
        },
        {
            'name': 'TimeReaderNumpy',
            'apply_scalings': True,
            'extension': '.npy'
        }
    ],
    'time_processors': [
        {'name': 'InterpolateNans'},
        {'name': 'RemoveMean'},
        {'name': 'Multiply', 'multiplier': {'Ex': -1.0, 'Ey': -1.0}}
    ],
    'dec_setup': {
        'name': 'DecimationSetup',
        'n_levels': 3,
        'per_level': 7,
        'min_samples': 256,
        'div_factor': 2,
        'eval_freqs': None
    },
    'decimator': {
        'name': 'Decimator',
        'resample': True,
        'max_single_factor': 3
    },
    'win_setup': {
        'name': 'WindowSetup',
        'min_size': 128,
        'min_olap': 32,
        'win_factor': 4,
        'olap_proportion': 0.25,
        'min_n_wins': 5,
        'win_sizes': None,
        'olap_sizes': None
    },
    'windower': {
        'name': 'WindowerTarget',
        'target': 2000,
        'min_size': 180,
        'olap_proportion': 0.25
    },
    'fourier': {
        'name': 'FourierTransform',
        'win_fnc': ['kaiser', 14],
        'detrend': 'linear',
        'workers': -2
    },
    'spectra_processors': [],
    'evals': {'name': 'EvaluationFreqs'},
    'sensor_calibrator': {
        'name': 'SensorCalibrator',
        'chans': None,
        'readers': [
            {
                'name': 'SensorCalibrationJSON',
                'extension': '.json',
                'file_str': 'IC_$sensor$extension'
            }
        ]
    },
    'tf': {
        'name': 'ImpedanceTensor',
        'variation': 'default',
        'out_chans': ['Ex', 'Ey'],
        'in_chans': ['Hx', 'Hy'],
        'cross_chans': ['Hx', 'Hy'],
        'n_out': 2,
        'n_in': 2,
        'n_cross': 2
    },
    'regression_preparer': {'name': 'RegressionPreparerGathered'},
    'solver': {
        'name': 'SolverScikitTheilSen',
        'fit_intercept': False,
        'normalize': False,
        'n_jobs': -2,
        'max_subpopulation': 2000,
        'n_subsamples': None
    }
}

Quick calculate the impedance tensor using the new custom configuration and plot the result.

soln_custom = letsgo.quick_tf(time_data_path, config)
fig = soln_custom.tf.plot(
    soln_custom.freqs,
    soln_custom.components,
    to_plot=["ExHy", "EyHx"],
    x_lim=[1, 5],
    res_lim=[0, 4],
    phs_lim=[0, 100],
    legend="Custom config",
    symbol="diamond",
)
fig.update_layout(height=800)
plotly.io.show(fig)

Out:

  0%|          | 0/21 [00:00<?, ?it/s]
 24%|##3       | 5/21 [00:00<00:00, 45.04it/s]
100%|##########| 21/21 [00:00<00:00, 132.84it/s]

  0%|          | 0/21 [00:00<?, ?it/s]
  5%|4         | 1/21 [00:00<00:13,  1.52it/s]
 10%|9         | 2/21 [00:01<00:12,  1.52it/s]
 14%|#4        | 3/21 [00:01<00:11,  1.52it/s]
 19%|#9        | 4/21 [00:02<00:11,  1.52it/s]
 24%|##3       | 5/21 [00:03<00:10,  1.53it/s]
 29%|##8       | 6/21 [00:03<00:09,  1.53it/s]
 33%|###3      | 7/21 [00:04<00:09,  1.53it/s]
 38%|###8      | 8/21 [00:04<00:06,  1.97it/s]
 43%|####2     | 9/21 [00:04<00:04,  2.46it/s]
 48%|####7     | 10/21 [00:05<00:03,  2.96it/s]
 52%|#####2    | 11/21 [00:05<00:02,  3.44it/s]
 57%|#####7    | 12/21 [00:05<00:02,  3.87it/s]
 62%|######1   | 13/21 [00:05<00:01,  4.22it/s]
 67%|######6   | 14/21 [00:05<00:01,  4.54it/s]
 71%|#######1  | 15/21 [00:05<00:01,  5.38it/s]
 76%|#######6  | 16/21 [00:06<00:00,  6.19it/s]
 81%|########  | 17/21 [00:06<00:00,  6.91it/s]
 86%|########5 | 18/21 [00:06<00:00,  7.52it/s]
 90%|######### | 19/21 [00:06<00:00,  8.02it/s]
 95%|#########5| 20/21 [00:06<00:00,  8.33it/s]
100%|##########| 21/21 [00:06<00:00,  8.63it/s]
100%|##########| 21/21 [00:06<00:00,  3.17it/s]

Total running time of the script: ( 0 minutes 16.706 seconds)

Gallery generated by Sphinx-Gallery