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 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
import plotly

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")
πŸ“ kap123/
β”œβ”€πŸ“„ metadata.json
β””β”€πŸ“„ data.npy

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)
fig
  0%|          | 0/20 [00:00<?, ?it/s]
 10%|#         | 2/20 [00:00<00:01, 16.64it/s]
 25%|##5       | 5/20 [00:00<00:00, 22.97it/s]
100%|##########| 20/20 [00:00<00:00, 70.90it/s]

  0%|          | 0/20 [00:00<?, ?it/s]
  5%|5         | 1/20 [00:01<00:23,  1.24s/it]
 10%|#         | 2/20 [00:02<00:22,  1.24s/it]
 15%|#5        | 3/20 [00:03<00:21,  1.25s/it]
 20%|##        | 4/20 [00:04<00:19,  1.25s/it]
 25%|##5       | 5/20 [00:06<00:18,  1.25s/it]
 30%|###       | 6/20 [00:06<00:13,  1.06it/s]
 35%|###5      | 7/20 [00:06<00:09,  1.34it/s]
 40%|####      | 8/20 [00:07<00:07,  1.62it/s]
 45%|####5     | 9/20 [00:07<00:05,  1.88it/s]
 50%|#####     | 10/20 [00:07<00:04,  2.12it/s]
 55%|#####5    | 11/20 [00:08<00:03,  2.68it/s]
 60%|######    | 12/20 [00:08<00:02,  3.30it/s]
 65%|######5   | 13/20 [00:08<00:01,  3.91it/s]
 70%|#######   | 14/20 [00:08<00:01,  4.51it/s]
 75%|#######5  | 15/20 [00:08<00:00,  5.05it/s]
 80%|########  | 16/20 [00:08<00:00,  5.73it/s]
 85%|########5 | 17/20 [00:08<00:00,  6.34it/s]
 90%|######### | 18/20 [00:09<00:00,  6.81it/s]
 95%|#########5| 19/20 [00:09<00:00,  7.26it/s]
100%|##########| 20/20 [00:09<00:00,  7.56it/s]
100%|##########| 20/20 [00:09<00:00,  2.16it/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()
{
    '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)
  0%|          | 0/21 [00:00<?, ?it/s]
 14%|#4        | 3/21 [00:00<00:00, 29.07it/s]
 86%|########5 | 18/21 [00:00<00:00, 99.25it/s]
100%|##########| 21/21 [00:00<00:00, 102.77it/s]

  0%|          | 0/21 [00:00<?, ?it/s]
  5%|4         | 1/21 [00:00<00:13,  1.46it/s]
 10%|9         | 2/21 [00:01<00:13,  1.45it/s]
 14%|#4        | 3/21 [00:02<00:12,  1.45it/s]
 19%|#9        | 4/21 [00:02<00:11,  1.46it/s]
 24%|##3       | 5/21 [00:03<00:11,  1.45it/s]
 29%|##8       | 6/21 [00:04<00:10,  1.45it/s]
 33%|###3      | 7/21 [00:04<00:09,  1.45it/s]
 38%|###8      | 8/21 [00:05<00:06,  1.87it/s]
 43%|####2     | 9/21 [00:05<00:05,  2.33it/s]
 48%|####7     | 10/21 [00:05<00:03,  2.78it/s]
 52%|#####2    | 11/21 [00:05<00:03,  3.21it/s]
 57%|#####7    | 12/21 [00:05<00:02,  3.61it/s]
 62%|######1   | 13/21 [00:06<00:02,  3.93it/s]
 67%|######6   | 14/21 [00:06<00:01,  4.20it/s]
 71%|#######1  | 15/21 [00:06<00:01,  4.95it/s]
 76%|#######6  | 16/21 [00:06<00:00,  5.67it/s]
 81%|########  | 17/21 [00:06<00:00,  6.30it/s]
 86%|########5 | 18/21 [00:06<00:00,  6.85it/s]
 90%|######### | 19/21 [00:06<00:00,  7.28it/s]
 95%|#########5| 20/21 [00:06<00:00,  7.64it/s]
100%|##########| 21/21 [00:07<00:00,  7.92it/s]
100%|##########| 21/21 [00:07<00:00,  2.98it/s]

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

Gallery generated by Sphinx-Gallery