-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6be2224
commit f3f6c58
Showing
364 changed files
with
93,133 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Sphinx build info version 1 | ||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. | ||
config: 3c9d378ff3de7aeefd70c7543966cea6 | ||
tags: 645f666f9bcd5a90fca523b33c5a78b7 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
|
||
FiNNPy API | ||
========== | ||
|
||
This section documents the functions offered by FiNNPy. | ||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
basic | ||
cfc | ||
cleansing | ||
file_io | ||
filters | ||
misc | ||
sfc | ||
src_rec | ||
statistical | ||
visualization |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
|
||
Basic | ||
============= | ||
|
||
.. automodule:: basic | ||
:members: | ||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
basic/car | ||
basic/downsample | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
|
||
Common Average Re-Referencing | ||
============================= | ||
|
||
|
||
.. currentmodule:: basic.car | ||
.. autofunction:: run | ||
|
||
|
||
The following example shows how to apply car. | ||
|
||
.. code:: python | ||
import numpy as np | ||
import finn.basic.common_average_rereferncing as car | ||
import matplotlib | ||
matplotlib.use("Qt5agg") | ||
import matplotlib.pyplot as plt | ||
import random | ||
def main(): | ||
#Configure sample data | ||
channel_count = 256 | ||
frequency = [random.randint(5, 50) for _ in range(channel_count)] | ||
data_range = np.arange(0, 10000) | ||
frequency_sampling = 200 | ||
#Configure noise data | ||
frequency_noise = 50 | ||
shared_noise_strength = 10 | ||
random_noise_strength = 1 | ||
#Generate some sample data | ||
raw_data = [None for _ in range(channel_count)] | ||
for idx in range(channel_count): | ||
genuine_signal = np.sin(2 * np.pi * frequency[idx] * data_range / frequency_sampling) | ||
shared_noise_signal = np.sin(2 * np.pi * frequency_noise * data_range / frequency_sampling) | ||
* shared_noise_strength | ||
random_noise_signal = np.random.random(len(data_range)) * random_noise_strength | ||
raw_data[idx] = genuine_signal + shared_noise_signal + random_noise_signal | ||
raw_data = np.asarray(raw_data) | ||
car_data = car.run(raw_data) | ||
#visualize result | ||
(fig, axes) = plt.subplots(3, 2) | ||
fig.suptitle("Peaks are supposedly at %i, %i and %iHz" % (frequency[0], frequency[1], frequency[2])) | ||
for idx in range(3): | ||
axes[idx, 0].psd(raw_data[idx, :], NFFT = frequency_sampling, Fs = frequency_sampling) | ||
axes[idx, 1].psd(car_data[idx, :], NFFT = frequency_sampling, Fs = frequency_sampling) | ||
plt.show(block = True) | ||
main() | ||
While there is an artifact at 50Hz on the left side (pre car application), this artifact is gone on the right side. As this artifact was introduced by the shared reference, applying a car filter removed the artifact: | ||
|
||
.. image:: img/car.png | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
|
||
Downsampling | ||
============ | ||
|
||
|
||
.. currentmodule:: basic.downsampling | ||
.. autofunction:: run | ||
|
||
The following code example shows how to apply downsampling. | ||
|
||
.. code:: python | ||
def main(): | ||
#Configure sample data | ||
channel_count = 1 | ||
frequency = [random.randint(10, 25) for _ in range(channel_count)] | ||
data_range = np.arange(0, 1000) | ||
frequency_sampling = 10000 | ||
frequency_downsampled = 1000 | ||
#Generate some sample data | ||
raw_data = [None for _ in range(channel_count)] | ||
for idx in range(channel_count): | ||
genuine_signal = np.sin(2 * np.pi * frequency[idx] * data_range / frequency_sampling) | ||
raw_data[idx] = genuine_signal | ||
raw_data = np.asarray(raw_data) | ||
ds_data = ds.run(raw_data[0], frequency_sampling, frequency_downsampled) | ||
#visualize result | ||
plt.figure() | ||
plt.plot(np.arange(0, len(data_range), 1), raw_data[0], color = "red") | ||
plt.scatter(np.arange(0, len(data_range), frequency_sampling/frequency_downsampled), ds_data, color = "blue") | ||
plt.show(block = True) | ||
main() | ||
Applying downsampling reduced the high-density red line to the data points identified by the blue dots: | ||
|
||
.. image:: img/downsample.png | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
|
||
Cross frequency connectivity (cfc) | ||
================================== | ||
|
||
.. automodule:: cfc | ||
:members: | ||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
cfc/dmi | ||
cfc/mi | ||
cfc/mvl | ||
cfc/plv | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
|
||
Direct Modulation Index | ||
======================= | ||
|
||
|
||
.. currentmodule:: cfc.pac | ||
.. autofunction:: run_dmi | ||
|
||
|
||
The following example shows how to apply the dmi to estimate PAC. | ||
|
||
.. code-block:: python | ||
import numpy as np | ||
import matplotlib | ||
matplotlib.use("Qt5agg") | ||
import matplotlib.pyplot as plt | ||
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 visualize(scores, best_fits, amplitude_signals, frequencies_between_bursts, tgt_frequency_between_bursts, high_freq_frame_offsets): | ||
if(len(scores) < 5): | ||
(_, axes) = plt.subplots(2, 2) | ||
elif(len(scores) < 10): | ||
(_, axes) = plt.subplots(3, 3) | ||
elif(len(scores) < 17): | ||
(_, axes) = plt.subplots(4, 4) | ||
elif(len(scores) < 26): | ||
(_, axes) = plt.subplots(5, 5) | ||
else: | ||
raise NotImplementedError | ||
axes = np.reshape(axes, -1) | ||
for (ax_idx, ax) in enumerate(axes): | ||
ax.plot(np.arange(0, 1, 1/len(amplitude_signals[ax_idx])), amplitude_signals[ax_idx], label = "original data") | ||
ax.plot(np.arange(0, 1, 1/len(amplitude_signals[ax_idx])), best_fits[ax_idx], label = "fitted curve") | ||
if (frequencies_between_bursts[int(ax_idx % len(high_freq_frame_offsets))] < tgt_frequency_between_bursts): | ||
ax.set_title("No PAC, low frequency too low. PAC score: %2.2f" % (scores[ax_idx],)) | ||
elif (frequencies_between_bursts[int(ax_idx % len(high_freq_frame_offsets))] > tgt_frequency_between_bursts): | ||
ax.set_title("No PAC, low frequency too high. PAC score: %2.2f" % (scores[ax_idx],)) | ||
else: | ||
ax.set_title("Good PAC, low frequency matches. PAC score: %2.2f" % (scores[ax_idx],)) | ||
def main(): | ||
#Configure sample data | ||
data_range = np.arange(0, 10000) | ||
frequency_sampling = 1000 | ||
frequencies_between_bursts = [5, 10, 15] | ||
tgt_frequency_between_bursts = 10 | ||
frequency_within_bursts = 200 | ||
high_freq_frame_offsets = [0, 20, 40] | ||
#Configure noise data | ||
random_noise_strength = 1 | ||
#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 = list(); best_fits = list(); amplitude_signals = list() | ||
for high_freq_signal in high_freq_signals: | ||
for low_freq_signal in low_freq_signals: | ||
tmp = pac.run_dmi(low_freq_signal, high_freq_signal, phase_window_half_size = 20, phase_step_width = 5) | ||
scores.append(tmp[0]); best_fits.append(tmp[1]); amplitude_signals.append(tmp[2]) | ||
#visualization | ||
visualize(scores, best_fits, amplitude_signals, frequencies_between_bursts, tgt_frequency_between_bursts, high_freq_frame_offsets) | ||
plt.tight_layout() | ||
plt.legend() | ||
figManager = plt.get_current_fig_manager() | ||
figManager.window.showMaximized() | ||
plt.show(block = True) | ||
main() | ||
Using the direct modulation index, PAC has been detected only where there was a match between the high frequency component and the low frequency component: | ||
|
||
.. image:: img/dmi.png |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
|
||
Modulation Index | ||
======================= | ||
|
||
|
||
.. currentmodule:: cfc.pac | ||
.. autofunction:: run_mi | ||
|
||
|
||
The following example shows how to apply the mi to estimate PAC. | ||
|
||
.. code-block:: python | ||
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 | ||
===== ===== ===== ===== ===== | ||
|
||
|
Oops, something went wrong.