Modulation Index#
- cfc.pac.run_mi(low_freq_data, high_freq_data, phase_window_half_size=10, phase_step_width=20)#
Calculate the modulation index between a low frequency signal and a high frequency signal.
- Parameters:
low_freq_data (np.ndarray, shape(n_samples,)) – Single array of low frequency data.
high_freq_data (np.ndarray, shape(n_samples,)) – Single array of high frequency data.
phase_window_half_size (int) – Width of the phase window used for calculation of frequency/phase histogram. Amplitude gets added to every phase bin within the window size. Larger windows result in more smooth/increased PAC estimates.
phase_step_width (int) – Step width/shift of the phase window used for calculation of frequency/phase histogram.
- Returns:
Amount of phase amplitude coupling measured using the modulation index.
- Return type:
float
The following example shows how to apply the mi to estimate PAC.
import numpy as np
import finn.cfc.pac as pac
def generate_high_frequency_signal(n, frequency_sampling, frequency_within_bursts, random_noise_strength,
offset, burst_count, burst_length):
signal = np.random.normal(0, 1, n) * random_noise_strength
for burst_start in np.arange(offset, n, n/burst_count):
burst_end = burst_start + (burst_length/2)
signal[int(burst_start):int(burst_end)] = np.sin(2 * np.pi * frequency_within_bursts * np.arange(0, (int(burst_end) - int(burst_start))) / frequency_sampling)
return signal
def main():
#Configure sample data
data_range = np.arange(0, 10000)
frequency_sampling = 1000
frequencies_between_bursts = [2, 5, 10, 15, 50]
tgt_frequency_between_bursts = 10
frequency_within_bursts = 200
high_freq_frame_offsets = [0, 20, 40]
#Configure noise data
random_noise_strength = 0.3
#Generate sample data
burst_length = frequency_sampling / tgt_frequency_between_bursts
burst_count = len(data_range) / frequency_sampling * tgt_frequency_between_bursts
high_freq_signals = [generate_high_frequency_signal(len(data_range), frequency_sampling, frequency_within_bursts,
random_noise_strength, high_freq_frame_offset, burst_count, burst_length) for high_freq_frame_offset in high_freq_frame_offsets]
low_freq_signals = [np.sin(2 * np.pi * frequency_between_bursts * data_range / frequency_sampling) for frequency_between_bursts in frequencies_between_bursts]
scores = np.zeros((len(high_freq_signals), len(low_freq_signals)));
for (high_freq_idx, high_freq_signal) in enumerate(high_freq_signals):
for (low_freq_idx, low_freq_signal) in enumerate(low_freq_signals):
scores[high_freq_idx, low_freq_idx] = pac.run_mi(low_freq_signal, high_freq_signal,
phase_window_half_size = 20, phase_step_width = 5)
print("target frequency: ", tgt_frequency_between_bursts)
for x in range(len(frequencies_between_bursts)):
print("%.3f" % (frequencies_between_bursts[x]), end = "\t")
print("")
for y in range(len(high_freq_frame_offsets)):
for x in range(len(frequencies_between_bursts)):
print("%.3f" % (scores[y][x],), end = "\t")
print("")
main()
Using the direct modulation index, PAC between the low frequency signal (2/5/10/15/50Hz) signal and the high frequency signal (10Hz amplitude modulation).
2Hz |
5Hz |
10Hz |
15Hz |
50Hz |
|---|---|---|---|---|
0.002 |
0.005 |
0.004 |
0.001 |
0.001 |
0.003 |
0.004 |
0.006 |
0.001 |
0.001 |
0.002 |
0.004 |
0.005 |
0.001 |
0.001 |