seapipe 0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- seapipe-0.1/LICENSE +21 -0
- seapipe-0.1/PKG-INFO +61 -0
- seapipe-0.1/README.md +10 -0
- seapipe-0.1/pyproject.toml +47 -0
- seapipe-0.1/seapipe/__init__.py +14 -0
- seapipe-0.1/seapipe/cfc/__init__.py +10 -0
- seapipe-0.1/seapipe/cfc/cfc_func.py +221 -0
- seapipe-0.1/seapipe/cfc/erpac.py +823 -0
- seapipe-0.1/seapipe/cfc/event_cfc.py +314 -0
- seapipe-0.1/seapipe/cfc/mean_amps.py +1232 -0
- seapipe-0.1/seapipe/cfc/plots.py +598 -0
- seapipe-0.1/seapipe/cfc/synchrony.py +295 -0
- seapipe-0.1/seapipe/dataset.py +569 -0
- seapipe-0.1/seapipe/events/__init__.py +7 -0
- seapipe-0.1/seapipe/events/eel.py +20 -0
- seapipe-0.1/seapipe/events/fish.py +886 -0
- seapipe-0.1/seapipe/events/seasnakes.py +336 -0
- seapipe-0.1/seapipe/events/surf.py +449 -0
- seapipe-0.1/seapipe/events/whales.py +365 -0
- seapipe-0.1/seapipe/spectrum/__init__.py +8 -0
- seapipe-0.1/seapipe/spectrum/psa.py +1052 -0
- seapipe-0.1/seapipe/spectrum/spectrogram.py +476 -0
- seapipe-0.1/seapipe/stats/__init__.py +6 -0
- seapipe-0.1/seapipe/stats/peth.py +143 -0
- seapipe-0.1/seapipe/stats/sleepstats.py +269 -0
- seapipe-0.1/seapipe/utils/__init__.py +19 -0
- seapipe-0.1/seapipe/utils/audit.py +577 -0
- seapipe-0.1/seapipe/utils/load.py +421 -0
- seapipe-0.1/seapipe/utils/logs.py +126 -0
- seapipe-0.1/seapipe/utils/misc.py +571 -0
- seapipe-0.1/seapipe/utils/process.py +17 -0
- seapipe-0.1/seapipe/utils/splitter.py +113 -0
- seapipe-0.1/seapipe/version.py +1 -0
- seapipe-0.1/seapipe.egg-info/PKG-INFO +61 -0
- seapipe-0.1/seapipe.egg-info/SOURCES.txt +40 -0
- seapipe-0.1/seapipe.egg-info/dependency_links.txt +1 -0
- seapipe-0.1/seapipe.egg-info/entry_points.txt +2 -0
- seapipe-0.1/seapipe.egg-info/requires.txt +10 -0
- seapipe-0.1/seapipe.egg-info/top_level.txt +1 -0
- seapipe-0.1/setup.cfg +10 -0
- seapipe-0.1/setup.py +56 -0
seapipe-0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 nathanecross
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
seapipe-0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: seapipe
|
|
3
|
+
Version: 0.1
|
|
4
|
+
Summary: A package pipeline for Sleep Events Analysis of EEG data.
|
|
5
|
+
Home-page: https://github.com/nathanecross/seapipe
|
|
6
|
+
Author: Nathan E. Cross
|
|
7
|
+
Author-email: Nathan Cross <nathan.cross@sydney.edu.au>
|
|
8
|
+
Maintainer-email: Nathan Cross <nathan.cross@sydney.edu.au>
|
|
9
|
+
License: MIT License
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2023 nathanecross
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
14
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
15
|
+
in the Software without restriction, including without limitation the rights
|
|
16
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
17
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
18
|
+
furnished to do so, subject to the following conditions:
|
|
19
|
+
|
|
20
|
+
The above copyright notice and this permission notice shall be included in all
|
|
21
|
+
copies or substantial portions of the Software.
|
|
22
|
+
|
|
23
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
25
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
26
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
27
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
28
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
29
|
+
SOFTWARE.
|
|
30
|
+
|
|
31
|
+
Project-URL: Homepage, https://seapipe.readthedocs.io/
|
|
32
|
+
Project-URL: Documentation, https://seapipe.readthedocs.io/
|
|
33
|
+
Project-URL: Repository, https://github.com/nathanecross/seapipe
|
|
34
|
+
Project-URL: Bug Tracker, https://github.com/nathanecross/seapipe/issues
|
|
35
|
+
Project-URL: Changelog, https://github.com/nathanecross/seapipe/blob/master/CHANGELOG.md
|
|
36
|
+
Keywords: sleep,eeg,detection,signal processing,neuroscience,analysis
|
|
37
|
+
Classifier: Development Status :: 4 - Beta
|
|
38
|
+
Classifier: Programming Language :: Python
|
|
39
|
+
Requires-Python: >=3.7
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
License-File: LICENSE
|
|
42
|
+
Requires-Dist: pandas
|
|
43
|
+
Requires-Dist: wonambi>7.0
|
|
44
|
+
Requires-Dist: fooof
|
|
45
|
+
Requires-Dist: scipy>=0.19
|
|
46
|
+
Requires-Dist: mne>1.6.0
|
|
47
|
+
Requires-Dist: tensorpac>0.5.6
|
|
48
|
+
Provides-Extra: plot
|
|
49
|
+
Requires-Dist: PyQt5; extra == "plot"
|
|
50
|
+
Requires-Dist: matplotlib; extra == "plot"
|
|
51
|
+
|
|
52
|
+
# seapipe
|
|
53
|
+
A package pipeline for Sleep Events Analysis of EEG data.
|
|
54
|
+
|
|
55
|
+
seapipe is a Python pipeline for **S**leep **E**vents **A**nalysis. The package reads EEG recordings with the purpose of detecting and analysing sleep neurophysiology, such as sleep architecture statistics, sleep spindles, slow oscillations, phase amplitude coupling, and power spectral analyses.
|
|
56
|
+
|
|
57
|
+
It pulls functions from a range of other open source packages, including: Wonambi, the MNE and Tensorpac
|
|
58
|
+
|
|
59
|
+
It offers a simple and intuitive, yet fully customisable API. The major advantage of seapipe is that it can be deployed on full, diverse datasets that might require flexibility in certain parameters (e.g. electrode names, polarity of recordings, individualised frequency bands etc). The only requirement is that the data should be structured in BIDS.
|
|
60
|
+
|
|
61
|
+
|
seapipe-0.1/README.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# seapipe
|
|
2
|
+
A package pipeline for Sleep Events Analysis of EEG data.
|
|
3
|
+
|
|
4
|
+
seapipe is a Python pipeline for **S**leep **E**vents **A**nalysis. The package reads EEG recordings with the purpose of detecting and analysing sleep neurophysiology, such as sleep architecture statistics, sleep spindles, slow oscillations, phase amplitude coupling, and power spectral analyses.
|
|
5
|
+
|
|
6
|
+
It pulls functions from a range of other open source packages, including: Wonambi, the MNE and Tensorpac
|
|
7
|
+
|
|
8
|
+
It offers a simple and intuitive, yet fully customisable API. The major advantage of seapipe is that it can be deployed on full, diverse datasets that might require flexibility in certain parameters (e.g. electrode names, polarity of recordings, individualised frequency bands etc). The only requirement is that the data should be structured in BIDS.
|
|
9
|
+
|
|
10
|
+
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools >= 61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "seapipe"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
"pandas",
|
|
11
|
+
"wonambi>7.0",
|
|
12
|
+
"fooof",
|
|
13
|
+
"scipy>=0.19",
|
|
14
|
+
"mne>1.6.0",
|
|
15
|
+
"tensorpac>0.5.6",
|
|
16
|
+
]
|
|
17
|
+
requires-python = ">=3.8"
|
|
18
|
+
authors = [
|
|
19
|
+
{name = "Nathan Cross", email = "nathan.cross@sydney.edu.au"},
|
|
20
|
+
]
|
|
21
|
+
maintainers = [
|
|
22
|
+
{name = "Nathan Cross", email = "nathan.cross@sydney.edu.au"}
|
|
23
|
+
]
|
|
24
|
+
description = "A package pipeline for Sleep Events Analysis of EEG data."
|
|
25
|
+
readme = "README.md"
|
|
26
|
+
license = {file = "LICENSE"}
|
|
27
|
+
keywords = ["sleep", "eeg", "detection", "signal processing", "neuroscience", "analysis"]
|
|
28
|
+
classifiers = [
|
|
29
|
+
"Development Status :: 4 - Beta",
|
|
30
|
+
"Programming Language :: Python"
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
plot = ["PyQt5",
|
|
35
|
+
"matplotlib"]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://seapipe.readthedocs.io/"
|
|
40
|
+
Documentation = "https://seapipe.readthedocs.io/"
|
|
41
|
+
Repository = "https://github.com/nathanecross/seapipe"
|
|
42
|
+
"Bug Tracker" = "https://github.com/nathanecross/seapipe/issues"
|
|
43
|
+
Changelog = "https://github.com/nathanecross/seapipe/blob/master/CHANGELOG.md"
|
|
44
|
+
|
|
45
|
+
[project.scripts]
|
|
46
|
+
seapipe = "dataset:pipeline"
|
|
47
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
|
|
2
|
+
from .cfc_func import circ_wwtest, circ_kappa, mean_amp, klentropy, cohend
|
|
3
|
+
from .erpac import pac_it, cfc_grouplevel, generate_adap_bands, watson_williams
|
|
4
|
+
from .event_cfc import pac_it_joint
|
|
5
|
+
from .mean_amps import pac_it, pac_it_2, cfc_grouplevel, generate_adap_bands, watson_williams
|
|
6
|
+
from .plots import plot_mean_amps, plot_prefphase, plot_prefphase_group, plot_meanamps_group
|
|
7
|
+
from .synchrony import event_sync, event_sync_dataset
|
|
8
|
+
|
|
9
|
+
__all__ = ['circ_wwtest', 'circ_kappa', 'mean_amp', 'klentropy', 'cohend', 'pac_it', 'cfc_grouplevel', 'generate_adap_bands', 'watson_williams', 'pac_it_joint', 'pac_it', 'pac_it_2', 'cfc_grouplevel', 'generate_adap_bands', 'watson_williams', 'plot_mean_amps', 'plot_prefphase', 'plot_prefphase_group', 'plot_meanamps_group', 'event_sync', 'event_sync_dataset']
|
|
10
|
+
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Mon May 13 13:10:09 2019
|
|
4
|
+
|
|
5
|
+
CFC Functions
|
|
6
|
+
|
|
7
|
+
@author: jordan
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from numpy import (any, arange, arctan2, argmin, around, array, asarray,
|
|
11
|
+
atleast_2d, ceil, concatenate, cumsum, dot, empty, exp, floor, genfromtxt,
|
|
12
|
+
hstack, hypot, identity, linalg, linspace, log, logical_and,
|
|
13
|
+
max, mean, minimum, multiply, nan, nanmean, nanstd, ones,
|
|
14
|
+
pi, power, prod, reshape, roll, sin, sqrt, squeeze, std, sum,
|
|
15
|
+
transpose, vstack, where, zeros)
|
|
16
|
+
from os import listdir, mkdir, path
|
|
17
|
+
from scipy.stats import f as fdist
|
|
18
|
+
from scipy.special import lpn
|
|
19
|
+
import matplotlib.pyplot as plt
|
|
20
|
+
from pingouin import circ_r
|
|
21
|
+
from safepickle import load
|
|
22
|
+
import warnings
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def circ_wwtest(alpha1, alpha2, w1, w2, warnings=True):
|
|
26
|
+
"""Parametric Watson-Williams multi-sample test for equal means. Can be
|
|
27
|
+
used as a one-way ANOVA test for cicular data. Adapted for binned data."""
|
|
28
|
+
n1 = sum(w1)
|
|
29
|
+
n2 = sum(w2)
|
|
30
|
+
N = n1 + n2
|
|
31
|
+
|
|
32
|
+
r1 = circ_r(alpha1, w1)
|
|
33
|
+
r2 = circ_r(alpha2, w2)
|
|
34
|
+
|
|
35
|
+
r = circ_r(concatenate((alpha1, alpha2)), concatenate((w1, w2)))
|
|
36
|
+
rw = sum((n1 * r1, n2 * r2)) / N
|
|
37
|
+
|
|
38
|
+
if warnings:
|
|
39
|
+
# check assumptions
|
|
40
|
+
if N >= 11 and rw < .45:
|
|
41
|
+
print('Warning: Test not applicable.'
|
|
42
|
+
'Average resultant vector length < 0.45.')
|
|
43
|
+
elif N < 11 and N >= 7 and rw < .5:
|
|
44
|
+
print('Test not applicable. Average number of samples per population '
|
|
45
|
+
'6 < x < 11 and average resultant vector length < 0.5.')
|
|
46
|
+
elif N >= 5 and N < 7 and rw < .55:
|
|
47
|
+
print('Test not applicable. Average number of samples per population '
|
|
48
|
+
'4 < x < 7 and average resultant vector length < 0.55.')
|
|
49
|
+
elif N < 5:
|
|
50
|
+
print('Test not applicable. '
|
|
51
|
+
'Average number of samples per population < 5.')
|
|
52
|
+
|
|
53
|
+
# test statistic
|
|
54
|
+
kk = circ_kappa(rw)
|
|
55
|
+
beta = 1 + 3 / (8 * kk) # correction factor
|
|
56
|
+
A = sum((n1 * r1, n2 * r2)) - r * N
|
|
57
|
+
B = N - sum((n1 * r1, n2 * r2))
|
|
58
|
+
|
|
59
|
+
F = beta * (N - 2) * A / B
|
|
60
|
+
pval = 1 - fdist.cdf(F, 1, N - 2)
|
|
61
|
+
|
|
62
|
+
return F, pval
|
|
63
|
+
|
|
64
|
+
def circ_kappa(alpha, w=None):
|
|
65
|
+
""" Computes an approximation to the ML estimate of the concentration
|
|
66
|
+
parameter kappa of the von Mises distribution."""
|
|
67
|
+
if isinstance(alpha, float):
|
|
68
|
+
r = alpha
|
|
69
|
+
N = 1
|
|
70
|
+
else:
|
|
71
|
+
r = circ_r(alpha, w)
|
|
72
|
+
N = len(alpha)
|
|
73
|
+
|
|
74
|
+
if r < .53:
|
|
75
|
+
kappa = (2 * r) + (r ** 3) + (5 * r ** (5/6))
|
|
76
|
+
elif r >= .53 and r < .85:
|
|
77
|
+
kappa = -.4 + 1.39 * r + .43 / (1 - r)
|
|
78
|
+
else:
|
|
79
|
+
kappa = 1 / (r ** 3 - 4 * r ** 2 + 3 * r)
|
|
80
|
+
|
|
81
|
+
if N < 15 and N > 1:
|
|
82
|
+
if kappa < 2:
|
|
83
|
+
kappa = max(kappa - 2 / (N * kappa), 0)
|
|
84
|
+
else:
|
|
85
|
+
kappa = (N - 1) ** 3 * kappa / (N ** 3 + N)
|
|
86
|
+
|
|
87
|
+
return kappa
|
|
88
|
+
|
|
89
|
+
def polar_plot(w, bin_edges):
|
|
90
|
+
nbins = len(bin_edges) - 1
|
|
91
|
+
width = 2 * pi / nbins
|
|
92
|
+
f, ax = plt.subplots(1, 1, subplot_kw=dict(projection='polar'))
|
|
93
|
+
ax.bar(bin_edges[:nbins], w, width=width, bottom=0.0)
|
|
94
|
+
xL = ['0', '', '', '', r'+/- $\pi$', '', '', '']
|
|
95
|
+
ax.set_xticklabels(xL)
|
|
96
|
+
ax.set_yticks([])
|
|
97
|
+
f.show()
|
|
98
|
+
|
|
99
|
+
def mean_amp(phase, amp, nbins=18):
|
|
100
|
+
# Meanamp taking Hilbert transformed phase and amplitude signals (for comodulogram)
|
|
101
|
+
# phase is the phase time series, type = array
|
|
102
|
+
# amp is the amplitude time series, type = array
|
|
103
|
+
# position is the array of phase bin left boundaries, type = array
|
|
104
|
+
# First, we break 2pi into phase bins
|
|
105
|
+
# 0 degrees corresponds to the negative trough of the Phase freq
|
|
106
|
+
# 180 degrees corresponds to the positive peak of the Phase freq
|
|
107
|
+
position = zeros(nbins)
|
|
108
|
+
winsize = 2 * pi / nbins
|
|
109
|
+
for i in range(nbins):
|
|
110
|
+
position[i] = -pi + i * winsize
|
|
111
|
+
position = roll(position, int(floor(nbins/4)-1), axis=-1)
|
|
112
|
+
# Then, we compute mean amplitude in each phase bin:
|
|
113
|
+
ma = zeros(nbins)
|
|
114
|
+
with warnings.catch_warnings():
|
|
115
|
+
warnings.simplefilter("ignore", category=RuntimeWarning)
|
|
116
|
+
for i, j in enumerate(position):
|
|
117
|
+
ma[i] = nanmean(amp[where(
|
|
118
|
+
logical_and(phase < (j + winsize), phase >= j)
|
|
119
|
+
)])
|
|
120
|
+
return ma
|
|
121
|
+
|
|
122
|
+
def klentropy(MeanAmp, axis=-1):
|
|
123
|
+
# Quantify the amount of amp modulation by means of a normalized
|
|
124
|
+
# Kullback-Leibler entropy index
|
|
125
|
+
nbin = MeanAmp.shape[-1]
|
|
126
|
+
MI = (log(nbin) - (-sum((MeanAmp / sum(MeanAmp, axis=axis, keepdims=True)) * \
|
|
127
|
+
log((MeanAmp / sum(MeanAmp, axis=axis, keepdims=True))), axis=axis,
|
|
128
|
+
keepdims=True))) / log(nbin)
|
|
129
|
+
return MI.squeeze()
|
|
130
|
+
|
|
131
|
+
# =============================================================================
|
|
132
|
+
# ALL NIGHT AMPBIN WITH STD DEV
|
|
133
|
+
# def _allnight_ampbin(a, nodat, nbins, norm=True, sd=False):
|
|
134
|
+
# out = zeros((*a.shape[:-2], nbins))
|
|
135
|
+
# out_sd = zeros((*a.shape[:-2], nbins))
|
|
136
|
+
# for i in range(a.shape[0]): # part
|
|
137
|
+
# for j in range(a.shape[1]): # night
|
|
138
|
+
# allcyc = [x for x in a[i, j, 0, :] if x is not nodat]
|
|
139
|
+
# allcyc = concatenate(allcyc)
|
|
140
|
+
# if norm:
|
|
141
|
+
# allcyc /= allcyc.sum(axis=1, keepdims=True)
|
|
142
|
+
# out[i, j, :] = nanmean(allcyc, axis=0)
|
|
143
|
+
# if std:
|
|
144
|
+
# out_sd[i, j, :] = nanstd(allcyc, axis=0)
|
|
145
|
+
# out = (out, out_sd)
|
|
146
|
+
# return out
|
|
147
|
+
#
|
|
148
|
+
# OLD _allnight_ampbin
|
|
149
|
+
# def _allnight_ampbin(a, nodat, nbins, norm=True):
|
|
150
|
+
# out = zeros((*a.shape[:-2], nbins))
|
|
151
|
+
# for i in range(a.shape[0]): # part
|
|
152
|
+
# for j in range(a.shape[1]): # night
|
|
153
|
+
# allcyc = [x for x in a[i, j, 0, :] if x is not nodat]
|
|
154
|
+
# allcyc = concatenate(allcyc)
|
|
155
|
+
# if norm:
|
|
156
|
+
# allcyc /= allcyc.sum(axis=1, keepdims=True)
|
|
157
|
+
# out[i, j, :] = nanmean(allcyc, axis=0)
|
|
158
|
+
# return out
|
|
159
|
+
# =============================================================================
|
|
160
|
+
|
|
161
|
+
def _allnight_ampbin(a, nodat, nbins, norm=True):
|
|
162
|
+
out = zeros((*a.shape[:-2], nbins))
|
|
163
|
+
for i in range(a.shape[0]): # part
|
|
164
|
+
allcyc = [x for x in a[i] if x is not nodat]
|
|
165
|
+
allcyc = concatenate(allcyc)
|
|
166
|
+
if norm:
|
|
167
|
+
allcyc /= allcyc.sum(axis=1, keepdims=True)
|
|
168
|
+
out[i, :] = nanmean(allcyc, axis=0)
|
|
169
|
+
return out
|
|
170
|
+
|
|
171
|
+
def ab_loader(ab_file, nbins, shift, norm=True):
|
|
172
|
+
with open(ab_file, 'rb') as f:
|
|
173
|
+
ab = load(f)
|
|
174
|
+
try:
|
|
175
|
+
ab = _allnight_ampbin(ab, 0, nbins, norm=norm)
|
|
176
|
+
except(ValueError):
|
|
177
|
+
ab = ab / ab.sum(-1, keepdims=True)
|
|
178
|
+
ab = ab.squeeze()
|
|
179
|
+
ab = roll(ab, shift, axis=-1)
|
|
180
|
+
|
|
181
|
+
return ab
|
|
182
|
+
|
|
183
|
+
def _idx_to_phase(idx, vecbin):
|
|
184
|
+
phase = zeros(idx.shape, dtype='O')
|
|
185
|
+
for i in range(idx.shape[0]):
|
|
186
|
+
for j in range(idx.shape[1]):
|
|
187
|
+
one_idx = asarray(idx[i][j], dtype='int')
|
|
188
|
+
phase[i][j] = vecbin[one_idx]
|
|
189
|
+
|
|
190
|
+
return phase
|
|
191
|
+
|
|
192
|
+
def logsd(m, sd):
|
|
193
|
+
print('M: ' + str(around(exp(m), 3)))
|
|
194
|
+
print('SD: ' + str(around(sqrt((exp(sd ** 2) - 1) * exp(2 * m + sd ** 2)), 3)))
|
|
195
|
+
|
|
196
|
+
def logse(m, sd, N=15):
|
|
197
|
+
print('M: ' + str(around(exp(m), 3)))
|
|
198
|
+
print('SE: ' + str(around(
|
|
199
|
+
sqrt((exp(sd ** 2) - 1) * exp(2 * m + sd ** 2)) / sqrt(N), 3)))
|
|
200
|
+
|
|
201
|
+
def cohend(x, y):
|
|
202
|
+
mean_diff = x.mean() - y.mean()
|
|
203
|
+
pooled_sd = sqrt((x.std() ** 2 + y.std() ** 2) / 2)
|
|
204
|
+
return mean_diff / pooled_sd
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def paplot(ma):
|
|
208
|
+
f, axarr = plt.subplots(nrows=2, sharex=True)
|
|
209
|
+
width = 2 * pi / len(ma)
|
|
210
|
+
pos = arange(0, 4 * pi, width)
|
|
211
|
+
x = linspace(0, 4 * pi, 1000)
|
|
212
|
+
pa = axarr[0]
|
|
213
|
+
pa.bar(pos, hstack((ma, ma)), width=width, color='k', edgecolor='w')
|
|
214
|
+
pa.set_xticks([0, pi/2, pi, 3 * pi / 2, 2 * pi, 5 * pi / 2, 3 * pi, 7 * pi / 2, 4 * pi])
|
|
215
|
+
pa.set_xticklabels(['0'] + [r'$\pi$/2', r'$\pi$', r'3$\pi$/2', r'2$\pi$'] * 2)
|
|
216
|
+
sine = axarr[1]
|
|
217
|
+
sine.plot(sin(x))
|
|
218
|
+
sine.set_xticks([])
|
|
219
|
+
sine.set_yticks([])
|
|
220
|
+
plt.show()
|
|
221
|
+
|