diff --git a/.github/workflows/build_doc.yml b/.github/workflows/build_doc.yml new file mode 100644 index 0000000..a7be6d0 --- /dev/null +++ b/.github/workflows/build_doc.yml @@ -0,0 +1,46 @@ +name: Build doc + +on: + workflow_dispatch: + pull_request: + push: + branches: + - 'master' + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + # Standard drop-in approach that should work for most people. + + - name: Set up Python 3.9 + uses: actions/setup-python@v1 + with: + python-version: 3.9 + + - name: Get Python running + run: | + python -m pip install --user --upgrade --progress-bar off pip + python -m pip install --user --upgrade --progress-bar off -r requirements.txt + python -m pip install --user --upgrade --progress-bar off -r doc/requirements.txt + python -m pip install --user --upgrade --progress-bar off ipython "https://api.github.com/repos/sphinx-gallery/sphinx-gallery/zipball/master" memory_profiler + sudo apt install pandoc + python -m pip install --user -e . + # Look at what we have and fail early if there is some library conflict + - name: Check installation + run: | + which python + python -c "import coffeine" + python -c "import pandoc" + # Build docs + - name: Generate HTML docs + uses: rickstaa/sphinx-action@master + with: + docs-folder: "doc/" + - uses: actions/upload-artifact@v2 + with: + name: Documentation + path: doc/_build/html/ diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index 8ced8b7..a78a5a1 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7] + python-version: [3.9] steps: - uses: actions/checkout@v2 diff --git a/.gitignore b/.gitignore index 903bcf4..6ee28da 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ junit-results.xml *.swp *.egg-info __pycache__ +doc/generated/*rst \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in index 6d5aa0f..132fb4a 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,3 +2,17 @@ include LICENSE recursive-include coffeine *.py recursive-include notebooks *.ipynb exclude requirements.txt +doc/generated/coffeine.spatial_filters.ProjRandomSpace.rst +doc/generated/coffeine.spatial_filters.ProjSPoCSpace.rst +doc/index.ipynb +doc/make.bat +doc/requirements.txt +doc/tutorials.ipynb +doc/tutorials/filterbank_classification_bci.ipynb +doc/tutorials/filterbank_kernel_classification_bci.ipynb +recursive-include doc *.bat +recursive-include doc *.ipynb +recursive-include doc *.py +recursive-include doc *.rst +recursive-include doc *.txt +recursive-include doc Makefile \ No newline at end of file diff --git a/coffeine/__init__.py b/coffeine/__init__.py index c600412..8142eb5 100644 --- a/coffeine/__init__.py +++ b/coffeine/__init__.py @@ -26,6 +26,6 @@ from .pipelines import make_filter_bank_transformer, make_filter_bank_regressor, make_filter_bank_classifier # noqa -from .power_features import compute_features # noqa +from .power_features import compute_features, get_frequency_bands, compute_coffeine, make_coffeine_data_frame # noqa from .spatial_filters import ProjIdentitySpace, ProjCommonSpace, ProjLWSpace, ProjRandomSpace, ProjSPoCSpace # noqa diff --git a/coffeine/covariance_transformers.py b/coffeine/covariance_transformers.py index 1bfa515..219cb04 100644 --- a/coffeine/covariance_transformers.py +++ b/coffeine/covariance_transformers.py @@ -1,7 +1,9 @@ +from typing import Union import numpy as np import pandas as pd from pyriemann.tangentspace import TangentSpace from sklearn.base import BaseEstimator, TransformerMixin +from sklearn.pipeline import Pipeline def _check_data(X): @@ -22,33 +24,112 @@ def _check_data(X): return out -class Riemann(BaseEstimator, TransformerMixin): - def __init__(self, metric='riemann', return_data_frame=True): - self.metric = metric +class NaiveVec(BaseEstimator, TransformerMixin): + """Vectorize SPD matrix by flattening the upper triangle. + + Upper "naive" vectorization as described in [1]_. + + Parameters + ---------- + metric : str, default='riemann' + The Riemannian metric to use. See PyRiemann documentation for details + and valid choices. + return_data_frame : bool, default=True + Returning the result in a pandas data frame or not. + + References + ---------- + .. [1] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. + Predictive regression modeling with MEG/EEG: from source power + to signals and cognitive states. + *NeuroImage*, page 116893,2020. ISSN 1053-8119. + https://doi.org/10.1016/j.neuroimage.2020.116893 + """ + def __init__(self, method, return_data_frame=True): + self.method = method self.return_data_frame = return_data_frame + return None - def fit(self, X, y=None): - X = _check_data(X) - self.ts = TangentSpace(metric=self.metric).fit(X) + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Fit the model according to the given training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ return self - def transform(self, X): + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Extract vectorized upper triangle. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ X = _check_data(X) - X_out = self.ts.transform(X) + n_sub, p, _ = X.shape + q = int(p * (p+1) / 2) + X_out = np.empty((n_sub, q)) + for sub in range(n_sub): + if self.method == 'upper': + X_out[sub] = X[sub][np.triu_indices(p)] if self.return_data_frame: X_out = pd.DataFrame(X_out) - return X_out # (sub, c*(c+1)/2) + return X_out # (sub, p*(p+1)/2) class Diag(BaseEstimator, TransformerMixin): + """Vectorize SPD matrix by extracting diagonal. + + This is equivalent of the M/EEG power spectrum in a given frequency bin. + + Parameters + ---------- + metric : str, default='riemann' + The Riemannian metric to use. See PyRiemann documentation for details + and valid choices. + return_data_frame : bool, default=True + Returning the result in a pandas data frame or not. + """ def __init__(self, return_data_frame=True): self.return_data_frame = return_data_frame return None - def fit(self, X, y=None): + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Provide expected API for scikit-learn pipeline. + + .. note:: + The diagonal step does not fit any parameters. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ return self - def transform(self, X): + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Extract diagonal from X. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ X = _check_data(X) n_sub, p, _ = X.shape X_out = np.empty((n_sub, p)) @@ -60,14 +141,57 @@ def transform(self, X): class LogDiag(BaseEstimator, TransformerMixin): + """Vectorize SPD matrix by extracting diagonal and computing the log. + + log diagonal vectorization as described in [1]_. + + Parameters + ---------- + metric : str, default='riemann' + The Riemannian metric to use. See PyRiemann documentation for details + and valid choices. + return_data_frame : bool, default=True + Returning the result in a pandas data frame or not. + + References + ---------- + .. [1] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. + Predictive regression modeling with MEG/EEG: from source power + to signals and cognitive states. + *NeuroImage*, page 116893,2020. ISSN 1053-8119. + https://doi.org/10.1016/j.neuroimage.2020.116893 + """ def __init__(self, return_data_frame=True): self.return_data_frame = return_data_frame return None - def fit(self, X, y=None): + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Provide expected API for scikit-learn pipeline. + + .. note:: + The diagonal step does not fit any parameters. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ return self - def transform(self, X): + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Extract log diagonal from X. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ X = _check_data(X) n_sub, p, _ = X.shape X_out = np.empty((n_sub, p)) @@ -79,61 +203,122 @@ def transform(self, X): return X_out # (sub,p) -class ExpandFeatures(BaseEstimator, TransformerMixin): - def __init__(self, estimator, expander_column): - self.expander_column = expander_column - self.estimator = estimator - - def fit(self, X, y=None): - if not isinstance(X, pd.DataFrame): - raise ValueError("X must be a DataFrame") - self.estimator.fit(X.drop(self.expander_column, axis=1), y) - return self - - def transform(self, X): - if not isinstance(X, pd.DataFrame): - raise ValueError("X must be a DataFrame") - indicator = X[self.expander_column].values[:, None] - Xt = self.estimator.transform(X.drop(self.expander_column, axis=1)) - Xt = np.concatenate((Xt, indicator * Xt, indicator), axis=1) - # (n, n_features + 1) - return Xt - - -class NaiveVec(BaseEstimator, TransformerMixin): - def __init__(self, method, return_data_frame=True): - self.method = method +class Riemann(BaseEstimator, TransformerMixin): + """Map SPD matrix to Riemannian tangent space. + + Riemannian embedding step as described in [1]_. + Implements affine invariant metric, which makes assumption of + full-rank inputs. + The transform implies a log non-linearity. + + Parameters + ---------- + metric : str, default='riemann' + The Riemannian metric to use. See PyRiemann documentation for details + and valid choices. + return_data_frame : bool, default=True + Returning the result in a pandas data frame or not. + + References + ---------- + .. [1] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. + Predictive regression modeling with MEG/EEG: from source power + to signals and cognitive states. + *NeuroImage*, page 116893,2020. ISSN 1053-8119. + https://doi.org/10.1016/j.neuroimage.2020.116893 + """ + def __init__(self, metric: str = 'riemann', + return_data_frame: bool = True): + self.metric = metric self.return_data_frame = return_data_frame - return None - def fit(self, X, y=None): + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Fit the model according to the given training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ + X = _check_data(X) + self.ts = TangentSpace(metric=self.metric).fit(X) return self - def transform(self, X): + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Project X to Riemannian tangent space defined by the training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ X = _check_data(X) - n_sub, p, _ = X.shape - q = int(p * (p+1) / 2) - X_out = np.empty((n_sub, q)) - for sub in range(n_sub): - if self.method == 'upper': - X_out[sub] = X[sub][np.triu_indices(p)] + X_out = self.ts.transform(X) if self.return_data_frame: X_out = pd.DataFrame(X_out) - return X_out # (sub, p*(p+1)/2) + return X_out # (sub, c*(c+1)/2) class RiemannSnp(BaseEstimator, TransformerMixin): + """Map SPD matrix to Riemannian Wasserstein tangent space. + + Riemannian Wasserstein embedding step as described in [1]_. + Implements Wasserstein metric that is not making a strong + assumption of full-rank inputs. + The transform implies a square-root non-linearity. + + Parameters + ---------- + metric : str, default='riemann' + The Riemannian metric to use. See PyRiemann documentation for details + and valid choices. + return_data_frame : bool, default=True + Returning the result in a pandas data frame or not. + + References + ---------- + .. [1] Sabbagh, D., Ablin, P., Varoquaux, G., Gramfort, A. and Engemann, + D.A., 2019. Manifold-regression to predict from MEG/EEG brain + signals without source modeling. Advances in Neural Information + Processing Systems, 32. + """ def __init__(self, rank='full', return_data_frame=True): self.rank = rank self.return_data_frame = return_data_frame - def fit(self, X, y=None): + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Fit the model according to the given training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ X = _check_data(X) self.rank = len(X[0]) if self.rank == 'full' else self.rank self.ts = Snp(rank=self.rank).fit(X) return self - def transform(self, X): + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Project X to Riemannian SNP tangent space defined by training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ X = _check_data(X) n_sub, p, _ = X.shape q = p * self.rank @@ -145,28 +330,68 @@ def transform(self, X): class Snp(TransformerMixin): - def __init__(self, rank): + """Map SPD matrix to Riemannian Wasserstein tangent space. + + Riemannian Wasserstein embedding step as described in [1]_. + Implements Wasserstein metric that is not making the assumption + of full-rank inputs. + The transform implies a square-root non-linearity. + + Parameters + ---------- + rank : int + The rank to be used for sub-space projection. + + References + ---------- + .. [1] Sabbagh, D., Ablin, P., Varoquaux, G., Gramfort, A. and Engemann, + D.A., 2019. Manifold-regression to predict from MEG/EEG brain + signals without source modeling. Advances in Neural Information + Processing Systems, 32. + """ + def __init__(self, rank: int): """Init.""" self.rank = rank - def fit(self, X, y=None, ref=None): + def fit(self, + X: np.ndarray, + y: Union[list[int, float], np.ndarray, None] = None, + ref: Union[np.ndarray, None] = None): + """Fit the model according to the given training data. + + Parameters + ---------- + X : {np.ndarray} of shape (n_samples, n_channles, n_channels) + Training vector, where `n_samples` is the number of samples. + y : array-like of shape (n_samples,) + Target vector relative to X. + ref : np.ndarray of shape(n_channels, n_channels) or None + A reference covaraiance. If None (default): arithmetic mean. + """ if ref is None: ref = np.mean(X, axis=0) - Y = to_quotient(ref, self.rank) + Y = _to_quotient(ref, self.rank) self.reference_ = ref self.Y_ref_ = Y return self - def transform(self, X, verbose=False): + def transform(self, X: np.ndarray): + """Project X to Riemannian SNP tangent space defined by training data. + + Parameters + ---------- + X : {np.ndarray} of shape (n_samples, n_channles, n_channels) + Training vector, where `n_samples` is the number of samples. + """ n_mat, n, _ = X.shape output = np.zeros((n_mat, n * self.rank)) for j, C in enumerate(X): - Y = to_quotient(C, self.rank) - output[j] = logarithm_(Y, self.Y_ref_).ravel() + Y = _to_quotient(C, self.rank) + output[j] = _logarithm(Y, self.Y_ref_).ravel() return output -def to_quotient(C, rank): +def _to_quotient(C, rank): d, U = np.linalg.eigh(C) U = U[:, -rank:] d = d[-rank:] @@ -174,8 +399,66 @@ def to_quotient(C, rank): return Y -def logarithm_(Y, Y_ref): +def _logarithm(Y, Y_ref): prod = np.dot(Y_ref.T, Y) U, D, V = np.linalg.svd(prod, full_matrices=False) Q = np.dot(U, V).T return np.dot(Y, Q) - Y_ref + + +class ExpandFeatures(BaseEstimator, TransformerMixin): + """Add binary interaction terms after projection step. + + Simple ad-hoc interaction features in projected space + by multiplying a scaler (continuous or categorical) sample-level feature + with the representation obtained from projection and vectorization, e.g., + drug dosage or biomarker value at baseline. + + Parameters + ---------- + estimator : sklearn pipeline + A coffeine filter-bank transformer, regressor or classifier. + expander_column : str + The column in the coffeine data frame (passed through as reminder) + that should be used for computing the interaction features by + multiplication. + """ + def __init__(self, estimator: Pipeline, expander_column: str): + self.expander_column = expander_column + self.estimator = estimator + + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Fit the model according to the given training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ + if not isinstance(X, pd.DataFrame): + raise ValueError("X must be a DataFrame") + self.estimator.fit(X.drop(self.expander_column, axis=1), y) + return self + + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Apply transform and add expanded features. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ + + if not isinstance(X, pd.DataFrame): + raise ValueError("X must be a DataFrame") + indicator = X[self.expander_column].values[:, None] + Xt = self.estimator.transform(X.drop(self.expander_column, axis=1)) + Xt = np.concatenate((Xt, indicator * Xt, indicator), axis=1) + # (n, n_features + 1) + return Xt diff --git a/coffeine/pipelines.py b/coffeine/pipelines.py index b1703ba..8533af3 100644 --- a/coffeine/pipelines.py +++ b/coffeine/pipelines.py @@ -1,3 +1,4 @@ +from typing import Union import numpy as np import pandas as pd from coffeine.covariance_transformers import ( @@ -27,20 +28,47 @@ class GaussianKernel(BaseEstimator, TransformerMixin): Efficient computation of squared exponential kernel for one column of covariances in a coffeine DataFrame. + + Parameters + ---------- + sigma : float + The sigma or length-scale parameter of the Gaussian kernel. """ - def __init__(self, sigma=1.): + def __init__(self, sigma: float = 1.): self.sigma = sigma - def fit(self, X, y=None): - """Prepare Kernel.""" + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Prepare fitting kernel on training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_covariances` = 1 (inside a column of a coffeine data frame). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ if isinstance(X, pd.DataFrame): X = X.values self.X = X.astype(np.float64) self.N = np.sum(self.X ** 2, axis=1) return self - def transform(self, X, y=None): - """Compute Kernel.""" + def transform(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Compute Kernel. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_covariances` = 1 (inside a column of a coffeine data frame). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ C = 1. if isinstance(X, pd.DataFrame): X = X.values @@ -56,7 +84,7 @@ def transform(self, X, y=None): return C - def get_params(self, deep=True): + def get_params(self, deep: bool = True): """Get parameters.""" return {"sigma": self.sigma} @@ -76,11 +104,35 @@ class KernelSum(BaseEstimator, TransformerMixin): def __init__(self): pass - def fit(self, X, y=None): + def fit(self, + X: np.ndarray, + y: Union[list[int, float], np.ndarray, None] = None): + """Implement API neede for scikit-learn pipeline. + + Parameters + ---------- + X : {np.array} of shape (n_samples, n_covariances * n_samples_train) + Training vector, where `n_samples` is the number of samples and + `n_covariances` = 1 (inside a column of a coffeine data frame). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ self.n_train_ = len(X) return self - def transform(self, X, y=None): + def transform(self, + X: np.ndarray, + y: Union[list[int, float], np.ndarray, None] = None): + """Sum various kernels returned by column transformer. + + Parameters + ---------- + X : {np.array} of shape (n_samples, n_covariances * n_samples_train) + Training vector, where `n_samples` is the number of samples and + `n_covariances` = 1 (inside a column of a coffeine data frame). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ X_out = X if X.shape not in ((len(X), self.n_train_), (len(X), len(X))): X_out = X.reshape(len(X), -1, self.n_train_).sum(axis=1) @@ -88,13 +140,13 @@ def transform(self, X, y=None): def make_filter_bank_transformer( - names, - method='riemann', - projection_params=None, - vectorization_params=None, - kernel=None, - combine_kernels=None, - categorical_interaction=None): + names: list[str], + method: str = 'riemann', + projection_params: Union[dict, None] = None, + vectorization_params: Union[dict, None] = None, + kernel: Union[str, Pipeline, None] = None, + combine_kernels: Union[str, Pipeline, None] = None, + categorical_interaction: Union[bool, None] = None): """Generate pipeline for filterbank models. Prepare filter bank models as used in [1]_. These models take as input @@ -137,22 +189,22 @@ def make_filter_bank_transformer( vectorization_params : dict | None The parameters for the vectorization step. kernel : None | 'gaussian' | sklearn.Pipeline - The Kernel option for kernel regression. If 'gaussian', a Gaussian Kernel - will be added per column and the results will be summed over frequencies. - If sklearn.pipeline.Pipeline is passed, it should return a meaningful - kernel. + The Kernel option for kernel regression. If 'gaussian', a Gaussian + Kernel will be added per column and the results will be summed over + frequencies. If sklearn.pipeline.Pipeline is passed, it should return + a meaningful kernel. combine_kernels : None | 'sum' | sklearn.pipeline.Pipeline - If kernel is used and multiple columns are defined, this option determines - how a combined kernel is constructed. 'sum' adds the kernels with equal - weights. A custom pipeline pipeline can be passed to implement alternative - rules. + If kernel is used and multiple columns are defined, this option + determines how a combined kernel is constructed. 'sum' adds the + kernels with equal weights. A custom pipeline pipeline can be passed to + implement alternative rules. categorical_interaction : str The column in the input data frame containing a binary descriptor used to fit 2-way interaction effects. References ---------- - [1] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. + .. [1] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. Predictive regression modeling with MEG/EEG: from source power to signals and cognitive states. *NeuroImage*, page 116893,2020. ISSN 1053-8119. @@ -233,7 +285,9 @@ def _get_projector_vectorizer(projection, vectorization, kernel=None): # add Kernel options if (isinstance(kernel, Pipeline) and not isinstance(kernel, (BaseEstimator, TransformerMixin))): - raise ValueError('Custom kernel must be an estimator and a transformer).') + raise ValueError( + 'Custom kernel must be an estimator and a transformer).' + ) elif kernel == 'gaussian': kernel = ( 'gaussiankernel', GaussianKernel @@ -241,7 +295,8 @@ def _get_projector_vectorizer(projection, vectorization, kernel=None): combine_kernels = 'sum' filter_bank_transformer = make_column_transformer( - *_get_projector_vectorizer(*steps, kernel=kernel), remainder='passthrough' + *_get_projector_vectorizer(*steps, kernel=kernel), + remainder='passthrough' ) if combine_kernels is not None: @@ -256,11 +311,14 @@ def _get_projector_vectorizer(projection, vectorization, kernel=None): return filter_bank_transformer -def make_filter_bank_regressor(names, method='riemann', - projection_params=None, - vectorization_params=None, - categorical_interaction=None, scaling=None, - estimator=None): +def make_filter_bank_regressor( + names: list[str], + method: str = 'riemann', + projection_params: Union[dict, None] = None, + vectorization_params: Union[dict, None] = None, + categorical_interaction: Union[bool, None] = None, + scaling: Union[BaseEstimator, None] = None, + estimator: Union[BaseEstimator, None] = None): """Generate pipeline for regression with filter bank model. Prepare filter bank models as used in [1]_. These models take as input @@ -314,12 +372,11 @@ def make_filter_bank_regressor(names, method='riemann', References ---------- - [1] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. + .. [1] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. Predictive regression modeling with MEG/EEG: from source power to signals and cognitive states. *NeuroImage*, page 116893,2020. ISSN 1053-8119. https://doi.org/10.1016/j.neuroimage.2020.116893 - """ filter_bank_transformer = make_filter_bank_transformer( names=names, method=method, projection_params=projection_params, @@ -344,11 +401,14 @@ def make_filter_bank_regressor(names, method='riemann', return filter_bank_regressor -def make_filter_bank_classifier(names, method='riemann', - projection_params=None, - vectorization_params=None, - categorical_interaction=None, scaling=None, - estimator=None): +def make_filter_bank_classifier( + names: list[str], + method: str = 'riemann', + projection_params: Union[dict, None] = None, + vectorization_params: Union[dict, None] = None, + categorical_interaction: Union[bool, None] = None, + scaling: Union[BaseEstimator, None] = None, + estimator: Union[BaseEstimator, None] = None): """Generate pipeline for classification with filter bank model. Prepare filter bank models as used in [1]_. These models take as input @@ -402,7 +462,7 @@ def make_filter_bank_classifier(names, method='riemann', References ---------- - [1] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. + .. [1] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. Predictive regression modeling with MEG/EEG: from source power to signals and cognitive states. *NeuroImage*, page 116893,2020. ISSN 1053-8119. @@ -423,10 +483,10 @@ def make_filter_bank_classifier(names, method='riemann', if estimator_ is None: estimator_ = LogisticRegression(solver='liblinear') - filter_bank_regressor = make_pipeline( + filter_bank_classifier = make_pipeline( filter_bank_transformer, scaling_, estimator_ ) - return filter_bank_regressor + return filter_bank_classifier diff --git a/coffeine/power_features.py b/coffeine/power_features.py index 641b7de..78ac510 100644 --- a/coffeine/power_features.py +++ b/coffeine/power_features.py @@ -1,4 +1,6 @@ +from typing import Union import numpy as np +import pandas as pd from scipy.stats import trim_mean from pyriemann.estimation import CospCovariances import mne @@ -6,7 +8,7 @@ from mne.epochs import BaseEpochs -def _compute_covs_raw(raw, clean_events, frequency_bands, duration): +def _compute_covs_raw(raw, clean_events, frequency_bands, duration, method): covs = list() for _, fb in frequency_bands.items(): rf = raw.copy().load_data().filter(fb[0], fb[1]) @@ -14,23 +16,23 @@ def _compute_covs_raw(raw, clean_events, frequency_bands, duration): rf, clean_events, event_id=3000, tmin=0, tmax=duration, proj=True, baseline=None, reject=None, preload=False, decim=1, picks=None) - cov = mne.compute_covariance(ec, method='oas', rank=None) + cov = mne.compute_covariance(ec, method=method, rank=None) covs.append(cov.data) return np.array(covs) -def _compute_covs_epochs(epochs, frequency_bands): +def _compute_covs_epochs(epochs, frequency_bands, method): covs = list() for _, fb in frequency_bands.items(): ec = epochs.copy().load_data().filter(fb[0], fb[1]) - cov = mne.compute_covariance(ec, method='oas', rank=None) + cov = mne.compute_covariance(ec, method=method, rank=None) covs.append(cov.data) return np.array(covs) -def _compute_cross_frequency_covs(epochs, frequency_bands): +def _compute_cross_frequency_covs(epochs, frequency_bands, method): epochs_frequency_bands = [] - for ii, (fbname, fb) in enumerate(frequency_bands.items()): + for fbname, fb in frequency_bands.items(): ef = epochs.copy().load_data().filter(fb[0], fb[1]) for ch in ef.ch_names: ef.rename_channels({ch: ch+'_'+fbname}) @@ -40,7 +42,7 @@ def _compute_cross_frequency_covs(epochs, frequency_bands): for e in epochs_frequency_bands[1:]: epochs_final.add_channels([e], force_update_info=True) n_chan = epochs_final.info['nchan'] - cov = mne.compute_covariance(epochs_final, method='oas', rank=None) + cov = mne.compute_covariance(epochs_final, method=method, rank=None) corr = np.corrcoef( epochs_final.get_data().transpose((1, 0, 2)).reshape(n_chan, -1)) return cov.data, corr @@ -53,19 +55,261 @@ def _compute_cospectral_covs(epochs, n_fft, n_overlap, fmin, fmax, fs): return cospectral_covs.transform(X).mean(axis=0).transpose((2, 0, 1)) +def get_frequency_bands( + collection: str = 'ipeg', + subset: Union[list[str], tuple[str], None] = None + ) -> dict[str, tuple[float, float]]: + """Get pre-specified frequency bands based on the literature. + + Next to sets of bands for defining filterbank models, the aggregate + defined in the corresponding literature are provided. + + .. note:: + The HCP-MEG[1] frequency band was historically based on the + documentation of the MEG analysis from the HCP-500 MEG2 release: + https://wiki.humanconnectome.org/display/PublicData/MEG+Data+FAQ + + As frequencies below 1.5Hz were omitted the work presented in [2,3] + also defined a 'low' band (0.1 - 1.5Hz) while retaining the the other + frequencies. + + .. note:: + The IPEG frequency bands were developed in [4]. + + .. note:: + Additional band definitions can be added as per (pull) request. + + Parameters + ---------- + collection : {'ipeg', 'ipeg_aggregated', 'hcp', 'hcp_aggregated'} + The set of frequency bands. Defaults to 'hcp'. + subset : list-like + A selection of valid keys to return a subset of frequency + bands from a collection. + + Returns + ------- + frequency_bands : dict + The band definitions. + + References + ---------- + [1] Larson-Prior, L. J., R. Oostenveld, S. Della Penna, G. Michalareas, + F. Prior, A. Babajani-Feremi, J-M Schoffelen, et al. 2013. + “Adding Dynamics to the Human Connectome Project with MEG.” + NeuroImage 80 (October): 190–201. + [2] D. Sabbagh, P. Ablin, G. Varoquaux, A. Gramfort, and D.A. Engemann. + Predictive regression modeling with MEG/EEG: from source power + to signals and cognitive states. + *NeuroImage*, page 116893,2020. ISSN 1053-8119. + https://doi.org/10.1016/j.neuroimage.2020.116893 + [3] D. A. Engemann, O. Kozynets, D. Sabbagh, G. Lemaître, G. Varoquaux, + F. Liem, and A. Gramfort Combining magnetoencephalography with + magnetic resonance imaging enhances learning of surrogate-biomarkers. + eLife, 9:e54055, 2020 + [4] Jobert, M., Wilson, F.J., Ruigt, G.S., Brunovsky, M., Prichep, + L.S., Drinkenburg, W.H. and IPEG Pharmaco-EEG Guideline Committee, + 2012. Guidelines for the recording and evaluation of pharmaco-EEG data + in man: the International Pharmaco-EEG Society (IPEG). + Neuropsychobiology, 66(4), pp.201-220. + """ + frequency_bands = dict() + if collection == 'ipeg': + frequency_bands.update({ + "delta": (1.5, 6.0), + "theta": (6.0, 8.5), + "alpha1": (8.5, 10.5), + "alpha2": (10.5, 12.5), + "beta1": (12.5, 18.5), + "beta2": (18.5, 21.0), + "beta3": (21.0, 30.0), + "gamma": (30.0, 40.0), + }) # total: 1.5-30; dominant: 6-12.5 + elif collection == 'ipeg_aggregated': + frequency_bands.update({ + 'total': (1.5, 30), + 'dominant': (6, 12.5) + }) + elif collection == 'hcp': + # https://www.humanconnectome.org/storage/app/media/documentation/ + # s500/hcps500meg2releasereferencemanual.pdf + frequency_bands.update({ + 'low': (0.1, 1.5), # added later in [2,3]. + 'delta': (1.5, 4.0), + 'theta': (4.0, 8.0), + 'alpha': (8.0, 15.0), + 'beta_low': (15.0, 26.0), + 'beta_high': (26.0, 35.0), + 'gamma_low': (35.0, 50.0), + 'gamma_mid': (50.0, 76.0), + 'gamma_high': (76.0, 120.0) + }) + elif collection == 'hcp_aggregated': + frequency_bands.update({ + 'wide_band': (1.5, 150.0) + }) + else: + raise ValueError(f'"{collection}" is not a valid collection.') + if subset is not None: + frequency_bands = { + name: frequency_bands[name] for name in subset + } + return frequency_bands + + +def make_coffeine_data_frame( + C: np.ndarray, + names: Union[dict[str, tuple[float, float]], + list[str], tuple[str], None] = None + ) -> pd.DataFrame: + """Put covariances in coffeine Data Frame. + + Parameters + ---------- + C : np.ndarray, shape(n_obs, n_frequencies, n_channels, n_channels) + A 2D collection of symmetric matrices. First dimension: samples. + Second dimension: batches within observations (e.g. frequencies). + names : dict or list-like, defaults to None + A descriptor for the second dimension of `C`. It is used to make + the columns of the coffeine Data Frame + + Returns + ------- + C_df : pd.DataFrame + The DataFrame of object type with lists of covariances accessible + as columns. + """ + if C.ndim != 4: + raise ValueError( + f'Expected input should have 4 dimensions, not {C.ndim}' + ) + if C.shape[-1] != C.shape[-2]: + raise ValueError( + 'The 2nd last dimensions should be the same. ' + f'You provided: {C.shape}.' + ) + names_ = None + if names is None: + names_ = [f'c{cc}' for cc in range(C.shape[1])] + else: + names_ = names + + C_df = pd.DataFrame( + {name: list(C[:, ii]) for ii, name in enumerate(names_)} + ) + return C_df + + +def _split_epochs(epochs): + out = list() + if len(epochs) > 1: + for ii in range(len(epochs)): + out.append(epochs[ii]) + else: + out.append(epochs) + return out + + +def compute_coffeine( + inst: Union[mne.io.BaseRaw, mne.BaseEpochs], + frequencies: Union[str, tuple, dict] = 'ipeg', + methods_params: Union[None, dict] = None + ) -> pd.DataFrame: + """Compute & spectral features as SPD matrices in a Data Frame. + + Parameters + ---------- + inst : mne.io.Raw | mne.Epochs or list-like + The MNE instance containing raw signals from which to compute + the features. If list-like, expected to contain MNE-Instances. + frequencies : str | dict + The frequency parameter. Either the name of a collection supported + by `get_frequency_bands`or a dictionary of frequency names and ranges. + methods_params : dict + The methods paramaters used in the down-stream function for feature + computation. + + Returns + ------- + C_df : pd.DataFrame + The coffeine DataFrame with columns filled with object arrays of + covariances. + """ + instance_list = list() + if isinstance(inst, mne.io.BaseRaw): + instance_list.append(inst) + elif isinstance(inst, mne.BaseEpochs): + instance_list.extend(_split_epochs(inst)) + elif isinstance(inst, (list, tuple)): + if isinstance(inst[0], mne.io.BaseRaw): + instance_list.extend(inst) + elif isinstance(inst[0], mne.BaseEpochs): + for epochs in inst: + instance_list.extend(_split_epochs(epochs)) + else: + raise ValueError('Unexpected value for instance.') + assert len(instance_list) >= 1 + + types = list({type(inst) for inst in instance_list}) + if len(types) > 1: + raise ValueError('Mixed instance types are not supported.') + inst_mode = '' + if 'raw' in str(types[0]).lower(): + inst_mode = 'raw' + elif 'epochs' in str(types[0]).lower(): + inst_mode = 'epochs' + assert inst_mode in ('raw', 'epochs') + + frequencies_ = None + if frequencies in ('ipeg', 'hcp'): + frequencies_ = get_frequency_bands(collection=frequencies) + elif isinstance(frequencies, tuple) and frequencies[0] in ('ipeg', 'hcp'): + frequencies_ = get_frequency_bands( + collection=frequencies[0], subset=frequencies[1] + ) + elif isinstance(frequencies, dict): + frequencies_ = frequencies + else: + raise NotImplementedError( + 'Currently, only collection names or fully-spelled band ranges ' + 'are supported as frequency definitions.' + ) + + freq_values = sum([list(v) for v in frequencies_.values()], []) + methods_params_fb_bands_ = dict( + features=('covs',), n_fft=1024, n_overlap=512, + cov_method='oas', fs=instance_list[0].info['sfreq'], + frequency_bands=frequencies_, + fmin=min(freq_values), fmax=max(freq_values) + ) + if methods_params is not None: + methods_params_fb_bands_.update(methods_params) + + C = list() + for this_inst in instance_list: + features, feature_info = compute_features( + this_inst, **methods_params_fb_bands_ + ) + C.append(features['covs']) + C = np.array(C) + C_df = make_coffeine_data_frame(C=C, names=frequencies_) + return C_df, feature_info + + def compute_features( - inst, - features=('psds', 'covs'), - duration=60., - shift=10., - n_fft=512, - n_overlap=256, - fs=63.0, - fmin=0, - fmax=30, - frequency_bands=None, - clean_func=lambda x: x, - n_jobs=1): + inst: Union[BaseEpochs, BaseRaw], + features: Union[tuple[str], list[str]] = ('psds', 'covs'), + duration: float = 60., + shift: float = 10., + n_fft: int = 512, + n_overlap: int = 256, + fs: float = 63.0, + fmin: float = 0., + fmax: float = 30., + frequency_bands: Union[dict[str, tuple[float, float]], None] = None, + clean_func: callable = lambda x: x, + cov_method: str = 'oas', + ) -> tuple[dict, dict]: """Compute features from raw data or clean epochs. Parameters @@ -106,8 +350,10 @@ def compute_features( If nothing is provided, defaults to {'alpha': (8.0, 12.0)}. clean_func : lambda function If nothing is provided, defaults to lambda x: x. - n_jobs : int - If nothing is provided, defaults to 1. + cov_method : str (default 'oas') + The covariance estimator to be used. Ignored for feature types not + not related to covariances. Must be a method accepted by MNE's + covariance functions. Returns ------- @@ -136,13 +382,14 @@ def compute_features( clean_events = events[epochs_clean.selection] if 'covs' in features: covs = _compute_covs_raw(inst, clean_events, frequency_bands_, - duration) + duration, method=cov_method) computed_features['covs'] = covs elif isinstance(inst, BaseEpochs): epochs_clean = clean_func(inst) if 'covs' in features: - covs = _compute_covs_epochs(epochs_clean, frequency_bands_) + covs = _compute_covs_epochs(epochs_clean, frequency_bands_, + method=cov_method) computed_features['covs'] = covs else: raise ValueError('Inst must be raw or epochs.') @@ -163,8 +410,8 @@ def compute_features( if 'psds' in features: spectrum = epochs_clean.compute_psd( - method="welch", fmin=fmin, fmax=fmax, n_fft=n_fft, - n_overlap=n_overlap, average='mean', picks=None) + method="welch", fmin=fmin, fmax=fmax, n_fft=n_fft, + n_overlap=n_overlap, average='mean', picks=None) psds_clean = spectrum.get_data() psds = trim_mean(psds_clean, 0.25, axis=0) computed_features['psds'] = psds @@ -174,7 +421,7 @@ def compute_features( 'cross_frequency_corrs' in features): (cross_frequency_covs, cross_frequency_corrs) = _compute_cross_frequency_covs( - epochs_clean, frequency_bands_) + epochs_clean, frequency_bands_, method=cov_method) computed_features['cross_frequency_covs'] = cross_frequency_covs computed_features['cross_frequency_corrs'] = cross_frequency_corrs diff --git a/coffeine/spatial_filters.py b/coffeine/spatial_filters.py index c832051..6dbaaa9 100644 --- a/coffeine/spatial_filters.py +++ b/coffeine/spatial_filters.py @@ -1,3 +1,4 @@ +from typing import Union import numpy as np import pandas as pd from mne import EvokedArray @@ -5,13 +6,13 @@ from sklearn.base import BaseEstimator, TransformerMixin -def shrink(cov, alpha): +def _shrink(cov, alpha): n = len(cov) shrink_cov = (1 - alpha) * cov + alpha * np.trace(cov) * np.eye(n) / n return shrink_cov -def fstd(y): +def _fstd(y): y = y.astype(np.float32) y -= y.mean(axis=0) y /= y.std(axis=0) @@ -34,24 +35,150 @@ def _check_X_df(X): class ProjIdentitySpace(BaseEstimator, TransformerMixin): + """Apply identy projection to SPD matrix. + + Helper to skip projection step. + """ def __init__(self): return None - def fit(self, X, y=None): + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Provide expected API for scikit-learn pipeline. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_covariances` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ return self def transform(self, X): + """Apply identity projection to X. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_covariances` is the number of covariances (inside the columns). + """ + X = _check_X_df(X) Xout = np.array(list(np.squeeze(X))).astype(float) return pd.DataFrame({'cov': list(Xout)}) +class ProjRandomSpace(BaseEstimator, TransformerMixin): + """Apply random projection to SPD matrix. + + Asses chance-level at projection step via random projections. + + Parameters + ---------- + n_compo : int + The size of the subspace to project onto. + random_state : int | np.random.RandomState + The random state. + """ + def __init__(self, n_compo: str = 'full', + random_state: Union[int, np.random.RandomState] = 42): + self.n_compo = n_compo + if isinstance(random_state, int): + self.random_state = np.random.RandomState(random_state) + elif isinstance(random_state, np.random.RandomState): + self.random_state = random_state + + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Fit the model according to the given training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ + X = _check_X_df(X) + self.n_compo = len(X[0]) if self.n_compo == 'full' else self.n_compo + _, n_chan, _ = X.shape + U = np.linalg.svd( + self.random_state.rand(n_chan, n_chan))[0][:self.n_compo] + self.filter_ = U # (compo, chan) row vec + return self + + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Apply random projection defined at training time. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ + X = _check_X_df(X) + n_sub = len(X) + Xout = np.empty((n_sub, self.n_compo, self.n_compo)) + filter_ = self.filter_ # (compo, chan) + for sub in range(n_sub): + Xout[sub] = filter_ @ X[sub] @ filter_.T + return pd.DataFrame({'cov': list(Xout)}) # (sub , compo, compo) + + class ProjCommonSpace(BaseEstimator, TransformerMixin): - def __init__(self, scale='auto', n_compo='full', reg=1e-7): + """Project SPD matrix to common subspace (PCA). + + Needed to define Riemannian metrics with rank deficient inputs as + described in [1]_. + + Parameters + ---------- + n_compo : int + The size of the subspace to project onto. + random_state : float | np.random.RandomState + The random state. + scale : float | 'auto' + Optional normalization that can be applied to the covariance. + If float, the value is directly used as a scaling factor. If auto, + scaling is obtained by 1 devided by the average of the trace across + covariances. + reg : float (defaults to 1e-15) + A regularization factor applied in subspace by reg * identity matrix. + The number is chose to be small and numerically stabilizing, assuming + EEG input scaled in volts. This is sensitive to the scale of the input + and may be different for MEG or other data types. Please check. + + References + ---------- + .. [1] Sabbagh, D., Ablin, P., Varoquaux, G., Gramfort, A. and Engemann, + D.A., 2019. Manifold-regression to predict from MEG/EEG brain + signals without source modeling. Advances in Neural Information + Processing Systems, 32. + """ + def __init__(self, scale: float = 1., n_compo: Union[int, str] = 'full', + reg: float = 1e-15): self.scale = scale self.n_compo = n_compo self.reg = reg - def fit(self, X, y=None): + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Compute filters for subspace projection given the training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ X = _check_X_df(X) self.n_compo = len(X[0]) if self.n_compo == 'full' else self.n_compo self.scale_ = _get_scale(X, self.scale) @@ -66,7 +193,15 @@ def fit(self, X, y=None): self.patterns_.append(pinv(evecs).T) # (fb, compo, chan) return self - def transform(self, X): + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Project X to subspace using the filters defined on training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ X = _check_X_df(X) n_sub, _, _ = X.shape self.n_compo = len(X[0]) if self.n_compo == 'full' else self.n_compo @@ -79,59 +214,69 @@ def transform(self, X): return pd.DataFrame({'cov': list(Xout)}) # (sub , compo, compo) -class ProjLWSpace(BaseEstimator, TransformerMixin): - def __init__(self, shrink): - self.shrink = shrink - - def fit(self, X, y=None): - return self - - def transform(self, X): - X = _check_X_df(X) - n_sub, p, _ = X.shape - Xout = np.empty((n_sub, p, p)) - for sub in range(n_sub): - Xout[sub] = shrink(X[sub], self.shrink) - return pd.DataFrame({'cov': list(Xout)}) # (sub , compo, compo) - - -class ProjRandomSpace(BaseEstimator, TransformerMixin): - def __init__(self, n_compo='full'): - self.n_compo = n_compo - - def fit(self, X, y=None): - X = _check_X_df(X) - self.n_compo = len(X[0]) if self.n_compo == 'full' else self.n_compo - n_sub, n_chan, _ = X.shape - U = np.linalg.svd(np.random.rand(n_chan, n_chan))[0][:self.n_compo] - self.filter_ = U # (compo, chan) row vec - return self - - def transform(self, X): - X = _check_X_df(X) - n_sub = len(X) - Xout = np.empty((n_sub, self.n_compo, self.n_compo)) - filter_ = self.filter_ # (compo, chan) - for sub in range(n_sub): - Xout[sub] = filter_ @ X[sub] @ filter_.T - return pd.DataFrame({'cov': list(Xout)}) # (sub , compo, compo) - - class ProjSPoCSpace(BaseEstimator, TransformerMixin): - def __init__(self, shrink=0, scale=1, n_compo='full', reg=1e-7): + """Project SPD matrix subspace given by SPoC. + + Computes Source Power Co-Modulation SPoC presented in [1]_. + + .. note:: + This implementation is absed on MNE-Python. + Contrary to the PyRiemann implementation, this implementation use + the arithmetic mean across the covariances as a reference. + + Parameters + ---------- + n_compo : int + The size of the subspace to project onto. + random_state : float | np.random.RandomState + The random state. + shrink : float + The shrinkage factor, like alpha in scikit-learn `shrunk_covariance`. + scale : float | 'auto' + Optional normalization that can be applied to the covariance. + If float, the value is directly used as a scaling factor. If auto, + scaling is obtained by 1 devided by the average of the trace across + covariances. + reg : float (defaults to 1e-15) + A regularization factor applied in subspace by reg * identity matrix. + The number is chose to be small and numerically stabilizing, assuming + EEG input scaled in volts. This is sensitive to the scale of the input + and may be different for MEG or other data types. Please check. + + References + ---------- + .. [1] Dähne, S., Meinecke, F.C., Haufe, S., Höhne, J., Tangermann, M., + Müller, K.R. and Nikulin, V.V., 2014. SPoC: a novel framework for + relating the amplitude of neuronal oscillations to behaviorally + relevant parameters. NeuroImage, 86, pp.111-122. + """ + def __init__(self, shrink: float = 0., scale: float = 1., + n_compo: Union[int, str] = 'full', reg: float = 1e-15): self.shrink = shrink self.scale = scale self.n_compo = n_compo self.reg = reg - def fit(self, X, y=None): + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Compute filters for subspace projection given the training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ X = _check_X_df(X) self.n_compo = len(X[0]) if self.n_compo == 'full' else self.n_compo - target = fstd(y) + target = _fstd(y) self.scale_ = _get_scale(X, self.scale) C = X.mean(axis=0) Cz = np.mean(X * target[:, None, None], axis=0) - C = shrink(C, self.shrink) + C = _shrink(C, self.shrink) eigvals, eigvecs = eigh(Cz, C) ix = np.argsort(np.abs(eigvals))[::-1] evecs = eigvecs[:, ix] @@ -141,7 +286,15 @@ def fit(self, X, y=None): self.pattern_ = pinv(evecs).T # (compo, chan) return self - def transform(self, X): + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Project X to subspace using the filters defined on training data. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ X = _check_X_df(X) n_sub = len(X) Xout = np.empty((n_sub, self.n_compo, self.n_compo)) @@ -161,7 +314,11 @@ def plot_patterns(self, info, components=None, mask_params=None, outlines='head', contours=6, image_interp='cubic', average=None, axes=None): + """"Plot topographic patterns of components (inverse of filters). + For detailed documentaiton, check out the MNE documentation + + """ if components is None: components = np.arange(self.n_compo) pattern = self.pattern_ @@ -189,7 +346,11 @@ def plot_filters(self, info, components=None, show=True, show_names=False, mask=None, mask_params=None, outlines='head', contours=6, image_interp='cubic', average=None, axes=None): + """"Plot topographic patterns of filters. + + For detailed documentaiton, check out the MNE documentation + """ if components is None: components = np.arange(self.n_compo) filter_ = self.filter_ @@ -207,3 +368,49 @@ def plot_filters(self, info, components=None, mask=mask, outlines=outlines, contours=contours, image_interp=image_interp, show=show, average=average, axes=axes) + + +class ProjLWSpace(BaseEstimator, TransformerMixin): + """Apply regularization on covariance matrices. + + A James-Stein type shrinkage is applied by weighting down + the off-diagonal (cross) terms proportional to a shrinkage factor. + + Parameters + ---------- + shrink : float + The shrinkage factor, like alpha in scikit-learn `shrunk_covariance`. + """ + def __init__(self, shrink: float): + self.shrink = shrink + + def fit(self, + X: Union[pd.DataFrame, np.ndarray], + y: Union[list[int, float], np.ndarray, None] = None): + """Provide expected API for scikit-learn pipeline. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + y : array-like of shape (n_samples,) + Target vector relative to X. + """ + return self + + def transform(self, X: Union[pd.DataFrame, np.ndarray]): + """Apply shrinkage implied by pre-specified shinkage faxtor. + + Parameters + ---------- + X : {pd.DataFrame} of shape (n_samples, n_covariances) + Training vector, where `n_samples` is the number of samples and + `n_features` is the number of covariances (inside the columns). + """ + X = _check_X_df(X) + n_sub, p, _ = X.shape + Xout = np.empty((n_sub, p, p)) + for sub in range(n_sub): + Xout[sub] = _shrink(X[sub], self.shrink) + return pd.DataFrame({'cov': list(Xout)}) # (sub , compo, compo) diff --git a/coffeine/tests/test_power_features.py b/coffeine/tests/test_power_features.py index e85a7a3..d018a19 100644 --- a/coffeine/tests/test_power_features.py +++ b/coffeine/tests/test_power_features.py @@ -1,9 +1,15 @@ +import re import os import pytest + import mne +import numpy as np + +from pyriemann.datasets import make_matrices +from coffeine import make_coffeine_data_frame, compute_coffeine -from coffeine.power_features import compute_features +from coffeine.power_features import compute_features, get_frequency_bands data_path = mne.datasets.sample.data_path() data_dir = os.path.join(data_path, 'MEG', 'sample') @@ -95,3 +101,139 @@ def test_compute_features_covs_freq_band_defaults(frequency_bands): n_bands = computed_features['covs'].shape[0] assert n_bands == 1 if frequency_bands is None \ else n_bands == len(frequency_bands) + + +def test_get_frequency_bands(): + fbands_ipeg = get_frequency_bands(collection='ipeg') + assert fbands_ipeg == { + 'delta': (1.5, 6.0), + 'theta': (6.0, 8.5), + 'alpha1': (8.5, 10.5), + 'alpha2': (10.5, 12.5), + 'beta1': (12.5, 18.5), + 'beta2': (18.5, 21.0), + 'beta3': (21.0, 30.0), + 'gamma': (30.0, 40.0) + } + fbands_ipeg_agg = get_frequency_bands( + collection='ipeg_aggregated') + assert fbands_ipeg_agg == { + 'total': (1.5, 30), + 'dominant': (6, 12.5) + } + fbands_hcp = get_frequency_bands(collection='hcp') + assert fbands_hcp == { + 'low': (0.1, 1.5), + 'delta': (1.5, 4.0), + 'theta': (4.0, 8.0), + 'alpha': (8.0, 15.0), + 'beta_low': (15.0, 26.0), + 'beta_high': (26.0, 35.0), + 'gamma_low': (35.0, 50.0), + 'gamma_mid': (50.0, 76.0), + 'gamma_high': (76.0, 120.0) + } + fbands_hcp_agg = get_frequency_bands( + collection='hcp_aggregated') + assert fbands_hcp_agg == {'wide_band': (1.5, 150)} + + fbands_ipeg_subset = get_frequency_bands( + collection='ipeg', subset=['alpha1', 'alpha2']) + assert fbands_ipeg_subset == { + 'alpha1': (8.5, 10.5), + 'alpha2': (10.5, 12.5) + } + with pytest.raises(KeyError, match="alpha3"): + fbands_ipeg_subset = get_frequency_bands( + collection='ipeg', subset=['alpha1', 'alpha3']) + with pytest.raises(ValueError, + match='"Hans Berger" is not a valid collection'): + fbands_ipeg_subset = get_frequency_bands( + collection='Hans Berger') + + +def test_make_coffeine_data_frame(): + C = make_matrices(100, 5, kind='spd').reshape(50, 2, 5, 5) + names = ['a', 'b'] + + C_df = make_coffeine_data_frame(C=C, names=names) + + assert C_df.columns.tolist() == names + assert np.all(np.array(C_df['a'].values.tolist()) == C[:, 0]) + assert np.all(np.array(C_df['b'].values.tolist()) == C[:, 1]) + + with pytest.raises( + ValueError, + match=re.escape( + 'The 2nd last dimensions should be the same. ' + 'You provided: (50, 2, 5, 3).')): + make_coffeine_data_frame(C=C[..., :3], names=names) + + with pytest.raises( + ValueError, + match='Expected input should have 4 dimensions, not 3'): + make_coffeine_data_frame(C=C[:, 0, ...], names=names) + + +def test_compute_coffeine(): + raw = mne.io.read_raw_fif(raw_fname, verbose=False) + raw = raw.copy().crop(0, 200).pick( + [0, 1, 330, 331, 332] # take some MEG and EEG + ) + raw.info.normalize_proj() + C_df1, _ = compute_coffeine(raw, frequencies=frequency_bands) + assert len(C_df1) == 1 + assert C_df1.columns.tolist() == list(frequency_bands) + + C_df2, _ = compute_coffeine( + [raw.copy().crop(0, 90), raw.copy().crop(90, 180)], + frequencies=frequency_bands + ) + assert len(C_df2) == 2 + assert C_df2.columns.tolist() == list(frequency_bands) + assert not np.all(C_df2['alpha'].iloc[0] == C_df2['alpha'].iloc[1]) + + C_df3, _ = compute_coffeine( + raw, frequencies=('ipeg', ('alpha1', 'alpha2')) + ) + assert len(C_df3) == 1 + assert C_df3.columns.tolist() == ['alpha1', 'alpha2'] + + epochs = mne.make_fixed_length_epochs(raw).load_data() + C_df4, _ = compute_coffeine( + epochs[:5], frequencies=('ipeg', ('alpha1', 'alpha2')) + ) + assert len(C_df4) == 5 + assert len({np.linalg.norm(c, 'nuc') for c + in C_df4['alpha1'].values}) == 5 + assert C_df4.columns.tolist() == ['alpha1', 'alpha2'] + + C_df5, _ = compute_coffeine( + [epochs[:5], epochs[5:10]], + frequencies=('ipeg', ('alpha1', 'alpha2')) + ) + assert len(C_df5) == 10 + assert len({np.linalg.norm(c, 'nuc') for c in + C_df5['alpha1'].values}) == 10 + assert C_df5.columns.tolist() == ['alpha1', 'alpha2'] + + with pytest.raises( + NotImplementedError, + match=re.escape( + 'Currently, only collection names or ' + 'fully-spelled band ranges ' + 'are supported as frequency definitions.')): + compute_coffeine(raw, frequencies=(0, 1)) + + with pytest.raises( + ValueError, + match=re.escape('Mixed instance types are ' + 'not supported.')): + compute_coffeine( + [raw, epochs], frequencies=frequency_bands) + + with pytest.raises( + ValueError, + match=re.escape('Unexpected value for instance.')): + compute_coffeine( + epochs.get_data(), frequencies=frequency_bands) diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/doc/api.rst b/doc/api.rst new file mode 100644 index 0000000..1aeabea --- /dev/null +++ b/doc/api.rst @@ -0,0 +1,77 @@ +.. _api_ref: + +============= +API reference +============= + + +Composing modeling pipelines +---------------------------- +.. _pipeline_api: +.. currentmodule:: coffeine.pipelines + +.. autosummary:: + :toctree: generated/ + :template: function.rst + + make_filter_bank_transformer + make_filter_bank_regressor + make_filter_bank_classifier + + +.. autosummary:: + :toctree: generated/ + :template: class.rst + + GaussianKernel + KernelSum + + +Computing Power-Spectral Features +--------------------------------- +.. _features_api: +.. currentmodule:: coffeine.power_features + +.. autosummary:: + :toctree: generated/ + :template: function.rst + + get_frequency_bands + make_coffeine_data_frame + compute_coffeine + compute_features + + +Covariance Transformers +----------------------- +.. _covariance_transformer_api: +.. currentmodule:: coffeine.covariance_transformers + +.. autosummary:: + :toctree: generated/ + :template: class.rst + + NaiveVec + Diag + LogDiag + Riemann + RiemannSnp + Snp + ExpandFeatures + + +Spatiel Filters +--------------- +.. _spatial_filters_api: +.. currentmodule:: coffeine.spatial_filters + +.. autosummary:: + :toctree: generated/ + :template: class.rst + + ProjIdentitySpace + ProjCommonSpace + ProjLWSpace + ProjRandomSpace + ProjSPoCSpace + diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 0000000..83d5d28 --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,110 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +import os +import sys +import pydata_sphinx_theme + +# -- Path setup -------------------------------------------------------------- +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +curdir = os.path.dirname(__file__) +sys.path.append(os.path.abspath(os.path.join(curdir, "..", "coffeine"))) + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'coffeine' +copyright = '2021-2023, coffeine contributors' +author = 'Denis A. Engemann' +release = '0.3dev' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + 'nbsphinx', + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.coverage', + 'sphinx.ext.doctest', + 'sphinx.ext.graphviz', + 'sphinx.ext.intersphinx', + 'sphinx.ext.mathjax', + 'sphinx.ext.todo', + 'numpydoc', + 'sphinx_copybutton' + # 'sphinx_gallery.gen_gallery' +] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +autosummary_generate = True +numpydoc_show_class_members = False + +# -- nbsphinx configuration -------------------------------------------------- + +nbsphinx_prolog = """ +.. raw:: html + + +""" + +# -- Intersphinx configuration ----------------------------------------------- +# copied from MNE + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "numpy": ("https://numpy.org/doc/stable", None), + "scipy": ("https://docs.scipy.org/doc/scipy", None), + "matplotlib": ("https://matplotlib.org/stable", None), + "sklearn": ("https://scikit-learn.org/stable", None), + "numba": ("https://numba.readthedocs.io/en/latest", None), + "joblib": ("https://joblib.readthedocs.io/en/latest", None), + "pyriemann": ("https://pyriemann.readthedocs.io/en/latest", None), + "mne": ("https://mne.tools/stable", None), + "mne_bids": ("https://mne.tools/mne-bids/stable", None), + "mne-connectivity": ("https://mne.tools/mne-connectivity/stable", None), + "mne-gui-addons": ("https://mne.tools/mne-gui-addons", None), + "pandas": ("https://pandas.pydata.org/pandas-docs/stable", None), + "altair": ("https://altair-viz.github.io/", None) +} + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +# Activate the theme. +html_theme = "pydata_sphinx_theme" +# html_context = { +# "default_mode": "light", +# } + +html_theme_options = { + "header_links_before_dropdown": 4, + "navbar_end": ["theme-switcher", "navbar-icon-links"], + "external_links": [ + { + "url": "https://pyriemann.readthedocs.io", + "name": "PyRiemann", + }, + { + "url": "https://scikit-learn.org", + "name": "scikit-learn", + }, + { + "url": "https://mne.tools", + "name": "MNE-Python" + } +], +} + +html_context = {"default_mode": "light"} diff --git a/doc/index.ipynb b/doc/index.ipynb new file mode 100644 index 0000000..c45fae2 --- /dev/null +++ b/doc/index.ipynb @@ -0,0 +1,302 @@ +{ + "cells": [ + { + "cell_type": "raw", + "id": "20915c70", + "metadata": { + "raw_mimetype": "text/restructuredtext" + }, + "source": [ + "Coffeine: Covariance Data Frames for Predictive M/EEG Pipelines\n", + "===============================================================" + ] + }, + { + "cell_type": "markdown", + "id": "fba6e8ad", + "metadata": {}, + "source": [ + "## Covariances in Data Frames for predictive modeling\n", + "\n", + "Coffeine is designed for building biomedical prediction models from M/EEG signals. The library provides a high-level interface facilitating the use of M/EEG covariance matrix as representation of the signal. The methods implemented here make use of tools and concepts implemented in [PyRiemann](https://pyriemann.readthedocs.io/). The API is fully compatible with [scikit-learn](https://scikit-learn.org/))." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "39898548", + "metadata": { + "nbsphinx": "hidden" + }, + "outputs": [], + "source": [ + "# this is a hidden cell (see metadata)\n", + "import mne\n", + "mne.utils.set_log_level('critical')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "18fb6cda", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
Pipeline(steps=[('columntransformer',\n",
+       "                 ColumnTransformer(remainder='passthrough',\n",
+       "                                   transformers=[('pipeline-1',\n",
+       "                                                  Pipeline(steps=[('projcommonspace',\n",
+       "                                                                   ProjCommonSpace(reg=1e-05)),\n",
+       "                                                                  ('riemann',\n",
+       "                                                                   Riemann())]),\n",
+       "                                                  'delta'),\n",
+       "                                                 ('pipeline-2',\n",
+       "                                                  Pipeline(steps=[('projcommonspace',\n",
+       "                                                                   ProjCommonSpace(reg=1e-05)),\n",
+       "                                                                  ('riemann',\n",
+       "                                                                   Riemann())]),\n",
+       "                                                  'theta'),\n",
+       "                                                 ('pipeline-3',\n",
+       "                                                  Pipeline(steps=[('projc...\n",
+       "       1.38488637e+03, 1.66810054e+03, 2.00923300e+03, 2.42012826e+03,\n",
+       "       2.91505306e+03, 3.51119173e+03, 4.22924287e+03, 5.09413801e+03,\n",
+       "       6.13590727e+03, 7.39072203e+03, 8.90215085e+03, 1.07226722e+04,\n",
+       "       1.29154967e+04, 1.55567614e+04, 1.87381742e+04, 2.25701972e+04,\n",
+       "       2.71858824e+04, 3.27454916e+04, 3.94420606e+04, 4.75081016e+04,\n",
+       "       5.72236766e+04, 6.89261210e+04, 8.30217568e+04, 1.00000000e+05])))])
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + ], + "text/plain": [ + "Pipeline(steps=[('columntransformer',\n", + " ColumnTransformer(remainder='passthrough',\n", + " transformers=[('pipeline-1',\n", + " Pipeline(steps=[('projcommonspace',\n", + " ProjCommonSpace(reg=1e-05)),\n", + " ('riemann',\n", + " Riemann())]),\n", + " 'delta'),\n", + " ('pipeline-2',\n", + " Pipeline(steps=[('projcommonspace',\n", + " ProjCommonSpace(reg=1e-05)),\n", + " ('riemann',\n", + " Riemann())]),\n", + " 'theta'),\n", + " ('pipeline-3',\n", + " Pipeline(steps=[('projc...\n", + " 1.38488637e+03, 1.66810054e+03, 2.00923300e+03, 2.42012826e+03,\n", + " 2.91505306e+03, 3.51119173e+03, 4.22924287e+03, 5.09413801e+03,\n", + " 6.13590727e+03, 7.39072203e+03, 8.90215085e+03, 1.07226722e+04,\n", + " 1.29154967e+04, 1.55567614e+04, 1.87381742e+04, 2.25701972e+04,\n", + " 2.71858824e+04, 3.27454916e+04, 3.94420606e+04, 4.75081016e+04,\n", + " 5.72236766e+04, 6.89261210e+04, 8.30217568e+04, 1.00000000e+05])))])" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import mne\n", + "from coffeine import compute_coffeine, make_filter_bank_regressor\n", + "\n", + "# load EEG data from linguistic experiment\n", + "eeg_fname = mne.datasets.kiloword.data_path() / \"kword_metadata-epo.fif\"\n", + "epochs = mne.read_epochs(eeg_fname)[:50] # 50 samples\n", + "\n", + "# compute covariances in different frequency bands \n", + "X_df, feature_info = compute_coffeine( # (defined by IPEG consortium)\n", + " epochs, frequencies=('ipeg', ('delta', 'theta', 'alpha1'))\n", + ") # ... and put results in a pandas DataFrame.\n", + "y = epochs.metadata[\"WordFrequency\"] # regression target\n", + "\n", + "# compose a pipeline\n", + "model = make_filter_bank_regressor(method='riemann', names=X_df.columns)\n", + "model.fit(X_df, y)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "a03fac9b", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAApsAAAD7CAYAAAAl+V8XAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABV3ElEQVR4nO2deXgUZbb/v51ek16y7yEh7LIIsgUQ2VQGRhgBZ1xmEfw5jrvXQcc7jNcBnbni6Oh47zjqqCPqiMuM4oobsgmyCAiyKYsQCJCwhCSdtTudrt8fXKJNnxMJpJII38/z9AP5VtU59Va9p+rt6jrntRiGYYAQQgghhBATiGnrHSCEEEIIIWcuHGwSQgghhBDT4GCTEEIIIYSYBgebhBBCCCHENDjYJIQQQgghpsHBJiGEEEIIMQ0ONgkhhBBCiGlwsEkIIYQQQkyDg01CCCGEEGIaHGyeQcyaNQsWi6XZ202bNg0dO3aM0O6//368+eabLbNjhHwPWbFiBWbNmoXy8vIIvWPHjpgwYUKL+ampqcGsWbOwZMmSFrNJyPeVwsJCWCwWPPfcc6e0fUvHJwC88MILuPLKK9G9e3fExMRE3S/Jd8PBJhHhYJOc7axYsQL33ntv1GCzpampqcG9997LwSYh7ZR//vOf2LJlCwYPHozOnTu39e58L7G19Q4QQgghhLRXPvzwQ8TEHHs2N2HCBGzevLmN9+j7B59sfk+ZP38++vXrB6fTifz8fPz5z3+OWscwDDz++OPo168fYmNjkZiYiB//+MfYtWtXk7YtFguqq6vx/PPPw2KxwGKxYNSoUQCAw4cP46abbkLPnj3h8XiQlpaGMWPGYNmyZWY0k5A2YdasWfjNb34DAMjPz2+Mg28/ffzggw/Qv39/xMbGokePHnj22Wej7JSUlOD6669HTk4OHA4H8vPzce+99yIUCgE49pNhamoqAODee+9t9DNt2jQAwM6dO3HNNdega9euiIuLQ3Z2NiZOnIhNmzaZewAIaWFOpy8ff0Vs/fr1mDJlCnw+H+Lj4/Hzn/8chw8fFrf5rvhszr3s+ECTnDp8svk9ZOHChbj00ksxdOhQvPLKK2hoaMCDDz6IgwcPRqx3/fXX47nnnsNtt92GP/3pTzh69Cjuu+8+DBs2DF988QXS09NF+ytXrsSYMWMwevRo3HPPPQAAn88HADh69CgAYObMmcjIyEBVVRXeeOMNjBo1CgsXLmwclBLyfeaXv/wljh49ir/+9a+YN28eMjMzAQA9e/YEAHzxxRe444478Nvf/hbp6el45plncO2116JLly4YMWIEgGMDzcGDByMmJga///3v0blzZ6xcuRJ//OMfUVhYiDlz5iAzMxMffPABxo0bh2uvvRa//OUvAaBxAHrgwAEkJyfjgQceQGpqKo4ePYrnn38eBQUFWL9+Pbp3794GR4eQ5tMSfXny5Mm4/PLLccMNN2DLli245557sHXrVqxevRp2u71xvZOJT97LWhmDfO8oKCgwsrKyjNra2kbN7/cbSUlJxvFTunLlSgOA8fDDD0dsW1RUZMTGxhp33XVXozZ16lQjLy8vYj23221MnTr1O/clFAoZ9fX1xoUXXmhMnjz51BtFSDvjoYceMgAYu3fvjtDz8vIMl8tl7Nmzp1Grra01kpKSjOuvv75Ru/766w2PxxOxnmEYxp///GcDgLFlyxbDMAzj8OHDBgBj5syZ37lPoVDICAaDRteuXY1f//rXp944QtoYrS/v3r3bAGDMmTOnUZs5c6YBIKrPz5071wBgvPjii43aycantD8ncy+75JJLou6X5Lvhs+HvGdXV1VizZg2mTJkCl8vVqHu9XkycOLHx73fffRcWiwU///nPEQqFGj8ZGRno27fvaSUjPPnkk+jfvz9cLhdsNhvsdjsWLlyIL7/88nSaRsj3hn79+iE3N7fxb5fLhW7dumHPnj2N2rvvvovRo0cjKysrIgbHjx8PAFi6dOl3+gmFQrj//vvRs2dPOBwO2Gw2OBwO7Nixg/FGvle0RF/+2c9+FvH35ZdfDpvNhsWLF0foJxOfAO9lrQkHm98zysrKEA6HkZGREbXs29rBgwdhGAbS09Nht9sjPqtWrcKRI0dOyf8jjzyCG2+8EQUFBXj99dexatUqrFmzBuPGjUNtbe0pt4uQ7xPJyclRmtPpjIiBgwcP4p133omKv169egHAScXg9OnTcc8992DSpEl45513sHr1aqxZswZ9+/ZlvJHvFS3Rl0+879lsNiQnJ6O0tDRCP5n45L2sdeE7m98zEhMTYbFYUFJSErXs21pKSgosFguWLVsGp9MZta6knQwvvvgiRo0ahSeeeCJCr6ysPCV7hJyppKSk4Nxzz8V///d/i8uzsrK+08aLL76Iq6++Gvfff3+EfuTIESQkJLTEbhLSKrREXy4pKUF2dnbj36FQCKWlpeLg8mT2h/ey1oODze8ZbrcbgwcPxrx58/DQQw81/pReWVmJd955p3G9CRMm4IEHHsD+/ftx+eWXN9vPid8Cj2OxWKIGqhs3bsTKlSvRoUOHZvshpL1yvJ+f6lOOCRMm4L333kPnzp2RmJh4Sn6keJs/fz7279+PLl26nNJ+EdIWtERfnjt3LgYMGND497/+9S+EQqFTSubhvax14WDze8gf/vAHjBs3DhdffDHuuOMONDQ04E9/+hPcbndjht3555+PX/3qV7jmmmuwdu1ajBgxAm63G8XFxVi+fDn69OmDG2+8UfXRp08fLFmyBO+88w4yMzPh9XrRvXt3TJgwAX/4wx8wc+ZMjBw5Etu2bcN9992H/Pz8xnIuhJwJ9OnTBwDwP//zP5g6dSrsdnuzsr/vu+8+LFiwAMOGDcNtt92G7t27o66uDoWFhXjvvffw5JNPIicnB16vF3l5eXjrrbdw4YUXIikpCSkpKY0zoTz33HPo0aMHzj33XKxbtw4PPfQQcnJyzGo2IabQEn153rx5sNlsuPjiixuz0fv27XtKD1Sacy/bunUrtm7dCuDY09Wamhq89tprAI5VqDhepYI0QVtnKJFT4+233zbOPfdcw+FwGLm5ucYDDzzQmLH3bZ599lmjoKDAcLvdRmxsrNG5c2fj6quvNtauXdu4jpSNvmHDBuP888834uLiDADGyJEjDcMwjEAgYNx5551Gdna24XK5jP79+xtvvvmmaIOQ7zszZswwsrKyjJiYGAOAsXjxYiMvL8+45JJLotYdOXJkY5wc5/Dhw8Ztt91m5OfnG3a73UhKSjIGDBhg3H333UZVVVXjeh9//LFx3nnnGU6n0wDQWAmirKzMuPbaa420tDQjLi7OGD58uLFs2TLRFyHtmZPty01lo69bt86YOHGi4fF4DK/Xa1x11VXGwYMHI/ycbHw251523L/0OZkqEsQwLIZhGG0zzCWEEEIIaZpZs2bh3nvvxeHDh5GSktLWu0NOAWajE0IIIYQQ0+BgkxBCCCGEmAZ/RieEEEIIIabBJ5uEEEIIIcQ0ONgkhBBCCCGmwcEmIYQQQggxDQ42CSGEEEKIaXCwSQghhBBCTKNdDzYff/xx5Ofnw+VyYcCAAVi2bFmr+J01axYsFkvEJyMjwxRfn3zyCSZOnIisrCxYLBa8+eabEcsNw8CsWbOQlZWF2NhYjBo1Clu2bGk1/9OmTYs6FkOGDGkR37Nnz8agQYPg9XqRlpaGSZMmYdu2bRHrmNX+k/FtZtvbG4w1c2PtbI2zk/XPWDOX1owzgLHGWIum3Q42X331Vdx+++24++67sX79elxwwQUYP3489u7d2yr+e/XqheLi4sbPpk2bTPFTXV2Nvn374rHHHhOXP/jgg3jkkUfw2GOPYc2aNcjIyMDFF1+MysrKVvEPAOPGjYs4Fu+9916L+F66dCluvvlmrFq1CgsWLEAoFMLYsWNRXV3duI5Z7T8Z34B5bW9PMNaOYWasna1xdrL+Acaa2bRWnAGMNcaaQFvNk/ldDB482LjhhhsitB49ehi//e1vTfc9c+ZMo2/fvqb7OREAxhtvvNH4dzgcNjIyMowHHnigUaurqzPi4+ONJ5980nT/hnFs3vRLL720xX1JHDp0yABgLF261DCM1m3/ib4No3Xb3pYw1lq3r53NcSb5NwzGmtmx1lZxZhiMNcbaMdrlk81gMIh169Zh7NixEfrYsWOxYsWKVtmHHTt2ICsrC/n5+bjyyiuxa9euVvH7bXbv3o2SkpKI4+B0OjFy5MhWOw4AsGTJEqSlpaFbt2647rrrcOjQIVP8VFRUAACSkpIAtG77T/R9nNZqe1vBWDtGe4i1syHOJP/HYayZS3uIM4CxdrbGWrscbB45cgQNDQ1IT0+P0NPT01FSUmK6/4KCArzwwgv48MMP8fTTT6OkpATDhg1DaWmp6b6/zfG2ttVxAIDx48dj7ty5WLRoER5++GGsWbMGY8aMQSAQaFE/hmFg+vTpGD58OHr37g2g9dov+QZar+1tCWPtGG0da2dDnGn+Acaa2X2svcQZwFgDzs5Ys5lq/TSxWCwRfxuGEaWZwfjx4xv/36dPHwwdOhSdO3fG888/j+nTp5vu/0Ta6jgAwBVXXNH4/969e2PgwIHIy8vD/PnzMWXKlBbzc8stt2Djxo1Yvnx51DKz26/5bq22twcYa8doq+NwNsRZU/4Za+b2sfYWZwBj7ducDbHWLp9spqSkwGq1Ro30Dx06FPWNoDVwu93o06cPduzY0ap+j2cLtpfjAACZmZnIy8tr0WNx66234u2338bixYuRk5PTqLdG+zXfEma0va1hrB2jvcXamRZnTfmXYKyZS1vFGcBYA87OWGuXg02Hw4EBAwZgwYIFEfqCBQswbNiwVt+fQCCAL7/8EpmZma3qNz8/HxkZGRHHIRgMYunSpW1yHACgtLQURUVFLXIsDMPALbfcgnnz5mHRokXIz8+PWG5m+7/Lt0RLtr29wFg7RnuLtTMlzk7GvwRjzVzaKs4AxtpZG2utmo7UDF555RXDbrcb//jHP4ytW7cat99+u+F2u43CwkLTfd9xxx3GkiVLjF27dhmrVq0yJkyYYHi9XlN8V1ZWGuvXrzfWr19vADAeeeQRY/369caePXsMwzCMBx54wIiPjzfmzZtnbNq0ybjqqquMzMxMw+/3m+6/srLSuOOOO4wVK1YYu3fvNhYvXmwMHTrUyM7ObhH/N954oxEfH28sWbLEKC4ubvzU1NQ0rmNW+7/Lt9ltb08w1syPtbM1zk7GP2PN/FhrzTgzDMYaYy2adjvYNAzD+Nvf/mbk5eUZDofD6N+/f0T6vplcccUVRmZmpmG3242srCxjypQpxpYtW0zxtXjxYgNA1Gfq1KmGYRwrlTBz5kwjIyPDcDqdxogRI4xNmza1iv+amhpj7NixRmpqqmG3243c3Fxj6tSpxt69e1vEt+QXgDFnzpzGdcxq/3f5Nrvt7Q3GmrmxdrbG2cn4Z6yZH2utGWeGwVhjrEVj+b8dJIQQQgghpMVpl+9sEkIIIYSQMwMONgkhhBBCiGlwsEkIIYQQQkyDg01CCCGEEGIaHGwSQgghhBDT4GCTEEIIIYSYBgebhBBCCCHENNr9YDMQCGDWrFkIBAL0fZb4P5vb3la0dZvZ39j2s4W2bjP729nX9rY+7gDQ7ou6+/1+xMfHo6KiAj6fj77PAv9nc9vbirZuM/sb285YO/P9s+1nn+/jtPsnm4QQQggh5PsLB5uEEEIIIcQ0bGYZfvzxx/HQQw+huLgYvXr1wqOPPooLLrjgO7cLh8M4cOAAvF4vLBYL/H4/ADT+25qcrb7b2v+Z2nbDMFBZWYmsrCzExLTc97yWiLXKykoAZ94xb+++29r/mdp2M2LtVOMMYKy1B99t7f9M9N2sODNM4JVXXjHsdrvx9NNPG1u3bjX+4z/+w3C73caePXu+c9uioiIDAD/8nLGfoqIixho//LTCp6Vi7XTijLHGz5n+OZk4MyVBqKCgAP3798cTTzzRqJ1zzjmYNGkSZs+e3eS2FRUVSEhIwJR+M2G3uiKWxVj1kfOdT/5E1L/eclDUa2v1rKzeA3NFvaOnUNR3PjFZ1NdsrVF97On4lKiPntBP1At6VKi2LOGQqN9x8yZRv/QG/dt46UHZz9J/rRf1i38+WLU1+PA1ov7Urt+J+gXj+qq2hg5LkxcYYVF+/ZWvRD01I0H1kZ2fJOpds4OifnTupaqt4r3R/a46aOCSZ6tRXl6O+Ph4ddvm0BKxdt3kR+Cwx0YsS+soHwsAuGH6CFHfvLlU1EP1DaqtrA7ycci2bRf1ig9miPrfX96s+kga/4qoDx7ZXdTPTd+t2rJUfC3qf5qbIOpXXKfH2o6NJaL++eodon75L3Vb+/98jqh/2eVlUdfaDgDnZu4TdYtfPi7rK4eLetmRatVHx64pop6bLF8za+Zfr9r69+trorS6kIH/WlrfYrF2OnEGfBNrn67YCI/HG7HM6bSq26Xvf1bUGzpeIuphR7Jqy1pTKOoxu94T9d2L/iHqbyzXz+s1c3eJuheHRd32+V9UW9WlRbI+6nlRT6vfoNtKGCTqFX752p6Jraqt1+74kaiP+V+57T5XnWrLvvnvol5XskXUbaMeEPWgQ7k/AnAED8m2Dn4q6ocWPqzaeuvjyHNSFzLw+09OLs5a/Gf0YDCIdevW4be//W2EPnbsWKxYsSJq/UAgEJGOf/wnBrvVBYft5AebHq9X1OPi5MCwwN5sWz6PR17faRH1WLusA4DTESfqbrfi26vfsC3helE/cQDR6CNObgcA1MbKfhw22VZcE7a8Lvkiqra9CVtqBp0y2IyNdYt6U/t74k3gG9/yBaleaR8AVCp9AgAsFn1Zc2ipWHPYY+E8oa+4nPI5AvRz4XErx6mJwabXK9vy2eTzF45V+pRNP6axLtmWer698voAYGmQ40A7Xl7lWgIAcXFVLWbL7VCuQc1sO6C33xKW2+4xZFvBGv2cqNdYn3x+bbH6rSq2iXPfErHW3DgD9FjzeLxRfb6pwabP4xL1Bq98HQs79fNqtcrbxLidoq7d11xNHG81ni3ygMvmdqi2rDXyOY/RfNTrcWtVrllhQ75m+aDb0u7rattj9bGGXTn2jjh5G5tPiTWHnmHuCNbKtqrleK5t4r6mxdrJxFmLJwgdOXIEDQ0NSE9Pj9DT09NRUhL9TX727NmIj49v/HTo0KGld4mQMxLGGiHm09w4AxhrhJyIadnoJ450DcMQR78zZsxARUVF46eoSH50TgiRYawRYj4nG2cAY42QE2nxn9FTUlJgtVqjvvEdOnQo6pshADidTjid0Y+SY6wxUT+bf77iI9XvZ4vldzL27ZHfFRl8QQ/VlvZEuMGdL+pJGZmyvkt+vwsAdgblnxarKuSfG+o88jtZABBukF+7Pbh9gah/ulB/v+2Ci/uI+qFd8nsfn763UbV16c/OF3Vjm7y/tdXyTxoAcFRJoquX3yDA9i/ki3v3PjmqD0uMfOLDTvn9MneybstXdiRKiwm07OvRLRVraR2Ton66Ld4Rvf/H2btffq9OO3+ZeQmqLY9H+YmpVo4Pd2qeqHdJ2aD6cGXL75/GKj/hhV3Rx66RNNmW3SG/r7W/sFw3lSO/46T1w7075HdiASAvR/5JrDhF/nnN2sQrSQ1u+Z11KMelcq/8M11iiv5TpNMh/1RnxMj9wZfZVbXVNWN1lNbEpaTZNDfOAD3WnE5r1M/m+4v0DOHEPrc1a19tlTvVZdaAHNOGVY6D5Fz5vd6hXTaoPhx2uV9ZgsqFOnOgasudK78bXq7c7/xePX8gNiznIoTq5Z+xS+P0/IGCc+XXEWxK25ukg/wetit3lKj7LamiHhc6qrqw1Muv68Ah/ySf3Km/aqugR3HE31UBA1h0csHW4k82HQ4HBgwYgAULIgc6CxYswLBhw1raHSFnLYw1QsyHcUbI6WNKnc3p06fjF7/4BQYOHIihQ4fiqaeewt69e3HDDTeY4Y6QsxbGGiHmwzgj5PQwZbB5xRVXoLS0FPfddx+Ki4vRu3dvvPfee8jLk38CI4ScGow1QsyHcUbI6WHaDEI33XQTbrrpJrPME0L+D8YaIebDOCPk1OHc6IQQQgghxDQ42CSEEEIIIaZhynSVp4Pf70d8fDzWfb4rapaJzxbL07gBQLc+2aKelCaX3+joLlRtxVQpNdGqDohy6afy1JN1FXLZJQCwTpOnw0r2yCUibJXy9H2AXqpkw5fy7DrhsH7KB3aSSxyt3SVPhxUMyFNlAsDwBHkatJKMq0U9ySvvLwBY6+RpRwOxctuL9skzR3Vz69OQWQxlppsKuaxN1efyVIAAYHVGl6Lx19Qj6/99hIqKCn1GpFbkeKwdLCmO2h+tvBEAlJbIpTT6DVDKwOx+Vd+Javm8IlAp626lLFETM6eEMuTyIrbqPaIetuu2qmN7irp2GT1cqk9V19m+QdSPugtEvfiAPk3gOelycfGGWLk8V4xSBgcAws5EUS+tkmez0WbASahZp/qwNMjHxQL5GmDEyCVqAMCwRPv3V1Yjqecl7S7WyhbNipoVKNBbL2/08Xy5lNEPh8nxUf3xPaqtkDKTTGxihqg7c+V+2NBJnp4ZAKybn5YX1JWLsqXHFNVWqUeeBjWpTC6BuM81RrWVuvpaUXcOlKdB/armPN1WqlxmLHmHMvWmTe+7oS6Xi/rOEnnc0iVTuZ4s/U/Vh9Uh768loaO8QbZeYaEmOXKZ3+9HdlbmScUZn2wSQgghhBDT4GCTEEIIIYSYBgebhBBCCCHENDjYJIQQQgghpsHBJiGEEEIIMQ3TirqfLl9vOYi4uMjsy3179OzuIRd2E/WSogpRT+gtrw8AnvROom53bhT1UEDO8tu+o0z1Yf9KzgYNdpIzQbPj4lVbloDsZ/smOWs4v4ecfQgAFY5zRL1wm5zFndUxWbVVtelNUd9b+yNRt3RKUG2lKD3VEToq6uWH5Sz5QIfBqg9rg5zt6wgHRL2mrFi1VX4wOju4KtCuCj80snlzKTzuYIRWWx1U1gYGD5MrPxTulftbTq6ccQkAdsjH1l4ux5pl+zxR/+z1Z1UfnpvkjN6UlIGinmyVq04AgKdmk6iv3C5Xa8jtLMczAJTFDRH13TvleM7rqF8DDjw9TtSDV20R9Yx0uYoDAMQdWSZvE5b7xBHrSFGv8srHFwBcFr+o28vk8x5c+6Rqa+Oi96N9B9tnrDV0vAQNXs9Jr69lnWsVSDyDpunGgkqFB6UiRO0uuR/smfeA6qLbrxeLekydfL8zqvaptpIq5SoWoQ5yX88wlPYBsPX9mWzL20XUu7mUijQA9vx1rKgnXf+OqFu06jYAbF8+J+o9hAoLAGD4Rss+ekxUfaCmVNb9e0W5/KPfq6Z2fhF5/WtOnPHJJiGEEEIIMQ0ONgkhhBBCiGlwsEkIIYQQQkyDg01CCCGEEGIaHGwSQgghhBDTaLfZ6LW1AVhgj9AGX9BDXV+b61zLOv9smZyJBQADh3UQ9ZSjX4n69q1yRt3Knfpc3wW18hzoLpd8Sqw7/qXa0rIJs3Kni/p5A/Rs9BVL5eOSmCrPF31OHzkLFwC+eHmVqNelyNn7oQY929ZaLR97bb76jJwrRX3jBnnudwDo1EXOHE4Jy5ntUsb5cb76Ojqzvaa+fWbIhuobUF8fOS98Zl6Cur4217mWdV64W848BoCsbDkzN1GpsFC87m1R/+AL+RwBwEQl1mIs8pzB1sJ3VVsNxRtE3ZPzoKhnupS53wHsOJgk6q5Yu6gnQp7LHQDe3yQfry5TGkQ93NBEXzywWpSDJZtF3fcDOUO2qFiOcwDIzJBj3a5kvJfuXKPaWrUt+vzWhdpnrIUdyQg7I6+ltkq5WgKgz3WuZZ2H0vV5rVU/h+QKADvXLBf1N1bJFSQA4Hf/KfdpLRvd/9lzqi3/fvman3Gj3N9sW55RbYV6/VJeYJGft8Vsf021tXCNXHVj2u2Z8n6FalRbtUXrRP3orvWinj0pX9Qb0uR57AHAWqNk/Cv3ztK921RbSzZHxlpz4oxPNgkhhBBCiGlwsEkIIYQQQkyDg01CCCGEEGIaHGwSQgghhBDT4GCTEEIIIYSYRosPNmfNmgWLxRLxycjQs58JIacGY42Q1oGxRsjpYUrpo169euHjjz9u/NtqlSeVb4reA3Ph8UaWiLBY9PVjqraKuie9k6hr5Y0AwOdRxuDBStl3E/ul0aWnXDIowaeckrpy1VbAL5fzyeufLOq2OrnkAQCcV5At6uUVcrkLn0MuAwEAYaUqQo++8kU6zaeXr8FeuTwHaktFOaObXNYmPU3WgSaOyxG5b/kr5ZI6AFAlHC6lAs9p0RKxltUhHl6vL0LzeOTyOwCAr+VyPnbIfUQrbwQAViXULDanqDvccskcn7NY9ZGS5hZ1p1M5VjH6MTTCcimh5LQ42VTga9VWRkaOqIfq5ZJp1lo9brVrUHq6vF+uBr0EGKrlZcFKOdZiq3aLekZ6Z9WFs04px+IvEuVQnX6dcQinq6nKTqdKS8SataYQVmtkPFgDclkgAAgFlfJRyr2oqTJKCOmlqCTsdrlTeRz6wVXL7AQrRDmmiVizKMtUHwH5mACATemjWukjo0ovWabFmuqjXL8GBCqPinqwrk6xJfuwxaWoPowKuZxh2C9fTwIBvWTjiW1vztjHlMGmzWbjtz5CWgHGGiGtA2ONkFPHlHc2d+zYgaysLOTn5+PKK6/Erl271HUDgQD8fn/EhxBycjDWCGkdGGuEnDotPtgsKCjACy+8gA8//BBPP/00SkpKMGzYMJSWyj/BzJ49G/Hx8Y2fDh30n7cJId/AWCOkdWCsEXJ6tPhgc/z48bjsssvQp08fXHTRRZg/fz4A4PnnnxfXnzFjBioqKho/RUXyOzuEkEgYa4S0Dow1Qk4P0+dGd7vd6NOnD3bs2CEudzqdcDrlZABCyMnDWCOkdWCsEdI8TB9sBgIBfPnll7jggguatV1HTyF8nsisvQa3PAk9AGCXnFlld8pZzClHv9JtKZl+UDK+EhMdop4VX6O6yHXI/i37lazaet2WliGb6z0s6tYqJZsPQOKRt0Xd12GsbKtczwKOdckPzrNDq+UNdheqtoxyeVm9kqXqPPypbGj/CtUHDPk4NpTK2YRWq56K5xKSufUcv5bhVGMt27YdPtsJGdu18rE45kiOD3u5HGuJgTLVlJZ1big/uiTm9RX1i/oXqj6ynfK7dZYqJaZscgY3ANjiM0U90yb3EUu5/kQroVbO+jZcSmbp0e2qrU4d5X1Oqlwm+1AyVAEADXJVAYdXrm5hPSTHs9u6QfdRq2RgK9no7tRc1VTBOdEZ2FUBA/g4qPs/TU411mJ2vYcYd2SfN6zy/QMAYhOVhKRqJVv6kFK14xRI7ZAn6sP9ena1Zdd78gKlT8UmyvEE6NnolqKl8gZNZLZj22uy7koU5XBI7zvndlLO1463RLmhWn7Voim8KVnyfh3VrjOFqq0GpaJBTZl87/Z69GHhgPzI63J10ADkS0wULf4z+p133omlS5di9+7dWL16NX784x/D7/dj6tSpLe2KkLMaxhohrQNjjZDTo8WfbO7btw9XXXUVjhw5gtTUVAwZMgSrVq1CXp78LYkQcmow1ghpHRhrhJweLT7YfOWVV1raJCFEgLFGSOvAWCPk9ODc6IQQQgghxDQ42CSEEEIIIaZhMQzDhFlkTx2/34/4+His/nU8PM7IbN+kDD1zzWqXM8RCATkTa/tWPSNbm+9Tyzr3+eSMWptLnxO6/EjzMtQSUuRMUECfL7qmdL+oxyXL858DwKY1X4p6x1w52zU2QZ7jHQCqj8oZk1XVcqZzKKTna6ckK3Nle5JkW0qW+pdf6sddmytby6r3NJG15/FE729lXRi9/3gYFRUV8Pl8wlaty/FY2/3oAHhjI9vuTtXfRXN0VDJwy+R5mYvXyRUOAL3valnnMT1/LOr1yQNVHzWvXS7qdiU+4869TLUFr1ycu+bTR2VbXUeppoqXPCnq2rH3dRmu71dqT1EuXfigqFsdesZ9Qs+L5QWJXUS5YeeHol6yebHqQ7s2+rK6inps51GqrXDOyCjNX1mF5G5j2l2sfX5XYtR9LTm3u7pdQt9LRb12l5wCvHPNctWWNte5lnWe3E/2beRdpPoofGqSqDvj3KKeNWiyagspcp8u/vABUc9swtamd58V9aRkZb/6/UC1ZUnvI+o75v1B1G1NVC3J6DlU1GOz+4l62dYFor73K726jt0u378SkryintTpPNWWKz/y2u+vqkPi6HtOKs74ZJMQQgghhJgGB5uEEEIIIcQ0ONgkhBBCCCGmwcEmIYQQQggxDQ42CSGEEEKIaZg+N/qpsmZrDWJPyJ5L2qXPyTqgnzyf8PYd8rzMK3c2f6Zqba7zcaPkTPHUaco8sQDe/YWc0aYxrInV8/v3EPWPP9os6ud0qlNtacflYJk8H3bnDvocsgN+cpuoP3P/Q+o2GgU95e9FnfLlTMpl78vz5362R/9+5bLJWfJZ8SFRH3dRR9VW8mV/j9L8ldXAH+U55tuSv7+8GU5bZKx1Sdmgrv/T+38o6p+9Lmd8fvCFfPwAwOeU5+fV5jrvfoGciXp5v+jjfZyCDmtEPcMnF+KY1nGwaivYUc5Uf2aOnHn9/36hx8ecd+S2+1yyfu21enWLD/fK+7XrNTlLtUuqXoTkR8N+Jepa23c+J8f5myvlSiAAkJMgz41+0fnyNsaEf6m2fnf1y1FasF733Za8sbwarhNibWiXDer6wyc/J+p75slx8MYqeQ5yAPA45HOuzXWedKmcdT7jnj2qj7TCalFP8cjVQa4eos8LH+x8pagvWCb3t6sHyNdvQD8uHZPkfnL10ATV1tvbR4t64eoZop6lXGcA4McXyTf24Hm/EfWjHz0h6vPX6uc9zSP718YUWVfdqtp6ZUFkBntNrXy+JfhkkxBCCCGEmAYHm4QQQgghxDQ42CSEEEIIIabBwSYhhBBCCDENDjYJIYQQQohpcLBJCCGEEEJMo92WPtrT8Sk4HXER2s6gXtpg8DS5HIv9K7nERkFtvWqrS880Uc91yGVEtv31ElFvqryRv2CeqI8cf66on5NdqNqyhOSSTNvWXCPqnS/XS7sMvlC29elCuYxS1iX9VFv7l40Q9fBF78u+R3VXbfXMU0osGHKpJmuCXO7hhylu1Ud6llfUs527RP3AM/J5B4DVQomj6qBeAqMtSRr/CmJdkcfFlZ2krh/KSBB1z007RX1iE7GWkiafD+2YV752uahr5Y0AIOvKj0W935BOom6k7lBtOXa8KOqeiR+Kes0PzlNtjc4vFfU92w+Jeu1FPVVb3jvka9Y5t6wV9Z79s1RbCMllnBwbHxV1941y6ZwfXKaXRcnJ9Yl6KraLetnzw1RbPaqjr8u1ofYZa9fM3QWvN7LtDrv+zMe6fpaod/u1fI5+95963Fpr9om6ZZdcom/3U5NEXStvBAC/nCffb90h2TfWPazaqvv3paI+6QU5blAqxzkAzHj/HlEPGLHyBiXvqrb8fykQ9V+9VS7q9ir5uggAWP+/olz76gRR73TjfFH/zZ1yCUBAP+8xRYtEff/cqaqtko8jj31dM+KMTzYJIYQQQohpcLBJCCGEEEJMg4NNQgghhBBiGhxsEkIIIYQQ0+BgkxBCCCGEmEazs9E/+eQTPPTQQ1i3bh2Ki4vxxhtvYNKkSY3LDcPAvffei6eeegplZWUoKCjA3/72N/Tq1atZfkZP6Ae3OzI7uKqiTl0/2SNnvAY7JYq6y6U3PcEnL7PsL1a3aS5a1nlWjpwRbaks0o3VyNl5F1z8A1HXMkEBoGOnBFG3O6yint8tWbVVt1g+X8N/JPeFDjke1Zb1iJJt3BAQ5e59Lhb1lBSX6sPeUCHqMfu3inpNdVC1VV0TXTmhOdnorRVnADB4ZHd4PJH9LtbtUNe3VcuVCVJSBop6jEXJ+ATgdMr9ylIlV0Wwu+Q+kuHTj62WdZ6UKu+XpUG/ziBYKcrnDess6gkefb86dZUzhxOVigk+a5lqS8to7qJknWem63GALbtlvfKAbOtc2ZbXa1ddeB3y+Y0plqsQNNTrsZYQG32MHfXtM9a8OAyfJbJ/WYJ6tQbUlYtyTJ2c9a3pAICgfH3TrqHOOLkfpniqVBda1nlM8Ki+XwpWm3wNcoYPyhvU6m23VWyR98uZIm/g1++3ccql0VEp3ydiKvRs9ECVfO9uCMrxYSmXK2XY6/Vzgmpl3FIhtzEc0mPN54qMK3sz4qzZTzarq6vRt29fPPbYY+LyBx98EI888ggee+wxrFmzBhkZGbj44otRWSlfpAkh0TDOCGkdGGuEmE+zn2yOHz8e48ePF5cZhoFHH30Ud999N6ZMmQIAeP7555Geno6XXnoJ119//entLSFnCYwzQloHxhoh5tOi72zu3r0bJSUlGDv2m4LWTqcTI0eOxIoVK8RtAoEA/H5/xIcQonMqcQYw1ghpLow1QlqGFh1slpSUAADS09Mj9PT09MZlJzJ79mzEx8c3fjp06NCSu0TIGcepxBnAWCOkuTDWCGkZTMlGt1gsEX8bhhGlHWfGjBmoqKho/BQVNZEIQwhppDlxBjDWCDlVGGuEnB4tOjd6RkYGgGPfBjMzMxv1Q4cORX0zPI7T6YTT6YzSC3pUwOeNzOit85yj+rZVbBD17Lh4Ubfu+JdqS8sARL2cIZaQImdkD9OnRlfnOlezzquVDLwmGF6gZJyGm8ja2/KMqA8975eibjHkeZwBoDRZPuddPJ+LurGriTlktUzDWDmbMCdezqiNWfG07kMhWCVnUsY1kbHdKS/6RlQZMADImZ/N4VTiDNBj7dz03fB5IzNPwy7dTjgkV0xItsrZytZCfZ5hxMjZ6LDFiXLcuZeJ+rSOg1UX2lznWtZ52KnPL408ucpB3xi5fxp18jUDANIPyPMcp2XIcy8bdXp29wWX/0JeoMxzjh1NZC3HKRm6iV1E2XFY/jk56eA63YdyLdVI63eJuuzKntGJOv7qIK6bP6dZPiRaOtZsn/8FthOvG5lyFQcAsPSYIupGlZz17f/sOdVWjBJrsYmZop41aLKoXz1Ev+41Nde5SBNtd3dRzvlW5bx2uEC1Vb3oPlH35PaVN0iTq8UAwKRpV4p6eNWfRb0+pF/znb40Wc+VrwEo3SbK/tX/UH1oaNn+yZ31c3LlCUU3/DUh3LZAn5P+27Tok838/HxkZGRgwYIFjVowGMTSpUsxbNiwlnRFyFkL44yQ1oGxRkjL0Ownm1VVVdi585snULt378aGDRuQlJSE3Nxc3H777bj//vvRtWtXdO3aFffffz/i4uLw05/+tEV3nJAzGcYZIa0DY40Q82n2YHPt2rUYPXp049/Tp08HAEydOhXPPfcc7rrrLtTW1uKmm25qLID70UcfweuVf3ojhETDOCOkdWCsEWI+zR5sjho1CoahV423WCyYNWsWZs2adTr7RchZDeOMkNaBsUaI+XBudEIIIYQQYhocbBJCCCGEENNo0dJHLYklHIIlXB+hhRv0nzoa3LmynUCZvEETpYQCfrmcjxFuEHWHWy6vlN+/h+rDElJKf9SUqttoGEqpFBjy/hp2eX+P+W+iJIpA2KGXiUnrNUb2r5WC0I4JALgSZFupSokKi1zmI1RToboIK+c3VCvPgexOzVNtxWdHn3t/TRDAK+o2bYWl4mtYGmIjxTT9vFbH9hR1T80mUW8o3qDa0mLKFi+XY0H+D0Q52FEuiQQAjh0vyguCytzWSnkjQG+7r/wTUQ+k6uVYrEoZE4tSYiiUMlS1ZZx3u+xj7/vyBg1B3VaynGVdnyDHmr1sg6hbjjZRykwreeXJkm11lK8lAFDvi461kL8SwOmXPmppqkuLYK2JvO26c0eo65d6hot6UuWrou7f/5Vqy6Icc01358l9N9hZLv0DAHX/vlTUtTI7ankjADUZY0U9btcHol6fqJcr8hfL5c886Z1EPZShxy2yLxLl6tevEnWbI1bUAcDZ/YeiXp8rHxf7Tvn+UXVwl+rD5vKIujdDbntsR73KQjg/cn+DlVUA2qD0ESGEEEIIId+Gg01CCCGEEGIaHGwSQgghhBDT4GCTEEIIIYSYBgebhBBCCCHENCxGU9Vs2wC/34/4+Hhcc9Ff4LBHZnEd3C5niQPAjBenivr2TftFPSs3WbWV101elus9LOrFfx8l6ivWKZnwALZ1eknUL7i4j6gPL3CptrSs81+Of0vUf3i9nm2WlpUg6nMfWCDqQyf3Vm392DdT1B/f/mtRP//CXqqtwcOyRT2kVCh4+ZnPRL3fEDkDDwCS0tyinpvoF/XyF3+k2irZWxSlVQUMnP9XPyoqKuDz+dRtW4vjsfbbW16AyxkXsczu0AtV3HTXhaK++Qs5Pj0+ve8mp8WJeqbta1GvW/hfov7MnMWqD8/ED0X9vGGdRb1vrl6RwVpbLOq/f1jObL/i+pGqrfIj1aK+fMFmUb/0F3o2esX/yv16Z7+PRL3/cLntANA9Xs4it9TK53dDxSBRD9TUizoAZHeUK2JkuuQqIbXv3azamvfa8uj16w3c9EF9u4u1bdv3wuuN3B/tGgYA2bULRT2UqlQgaVAqfQCw1uwTdUvRUlEvXi5n8y9YdkD1MekFuZpKXFg+r7atTVQMqJXjsKT3n0Q91Sa3DwDCrnRRL6uRs+STLXtUWwvvkPv7sL/JbY+tl8cgAGDdrlQnqZKPcWjgf4q6YdWvsdZa2VbMgRWifmT5U6qtjxZuj/i7tt7Ar947uTjjk01CCCGEEGIaHGwSQgghhBDT4GCTEEIIIYSYBgebhBBCCCHENDjYJIQQQgghptFus9HffG0t3HGRc3p+ulDO0gSAH0wZKOoNDWFRP29AhmrLVidnb9mqdov60ffkDLH9O+WMWgAIXi7PI52TK2d0JTv0DFltrvM3XpPnS/XGyxnAADBmvJyl+s6/t4h6bJxTtXVJ0jOiviHhLlHPyfGqtuJdcuZuMEZu++er5XM4ZHCC6sPSIM/Nbqv4UtQrFv5RtRWojM5MrKxrQLffbm93GbLrv9gNrzfy2O8vLFe3y8yVj7nTKc+xrGUYA0BMQK7wYKmKzuYHAPhlvepLOesaAGp+8IaoJ3jkS5+1Tt/fhlh57u6du+X+2RCSrz8A0KOT/F3/630WUbfEyDoAdC+eLepHes4SdZ9bv+xrGfcNSkbv0Uq5HcmeOtVHTJ18PdN849AG1Vbt10uiNH9NPbL+30ftLtbKtrwNnzey6oXfO1jfrkrO6M/wyNUPbJue0HciIG+jzlOv6WG5+gkAIG+0rCuZ5fB2UE1pc53HBI6KemlYt5VW+JioN3SS53KviMlVbSXt/ru8ILGLrAfKVVsWtxxT9QlyVRpLSL5HWXe+pvpAOCTrShUb1Ms+AADByD7krw4icfIcZqMTQgghhJC2hYNNQgghhBBiGhxsEkIIIYQQ0+BgkxBCCCGEmAYHm4QQQgghxDSaPdj85JNPMHHiRGRlZcFiseDNN9+MWD5t2jRYLJaIz5AhQ1pqfwk5K2CcEdI6MNYIMR9bczeorq5G3759cc011+Cyyy4T1xk3bhzmzJnT+LfDIU923xSlBytQGxuZmn/BxXI5AAAY2OmQqFc4zhH1FUv3qrbOK8gW9cQjb4v6pjVyaZyVO/WyJ4MvlMsLdOyUIOq2LXIZIQBAjVxWIi3rN6I+dIReImLBOztE3e1xifqg4XqJiBW//4eoV4y9TtSTkmNVW6m1G0TdXrlf1LPzJ4v66rXlqo8uPVJEPcMilwA5UrhVtbXj66oorab+5KuMtVacAcCOjSWIi4vc37QcubwRAHS2bxD1sjj5BrzjYJJqKyMjR9QTauV4Ll7ypKjPeUcpmQNgdH50GSoA6NRV3q/0A/NVW9bSbaJe7pDLeQ3q7xZ1AFjzefPKJTVVtmvpg/JxsV99i6jnK20HgMyKNaJuPbhe1B197hX1zdvksj0AkN1BvgalOOTrYsXn/1ZtvfXOhiittp3GWnXCIFhPKBETG65Q13euvlnUbX1/JuqhXr9UbWml+7BNLpuz6b1XRP2NVQHVx4z375F9V8il86oX3afa8hfL96LUmz4X9bStcnkjAAj2uU1dJpH01dPqsufuvVvUf/qqfJ2xVe1UbVnW/a+ol++Urycpl/5F1Ot7/kr1Ya3dJ+ox+xaL+oFlc0QdAF77OPK6XBc6+Thr9mBz/PjxGD9+fJPrOJ1OZGTodSwJIU3DOCOkdWCsEWI+pryzuWTJEqSlpaFbt2647rrrcOiQ/JQCAAKBAPx+f8SHEPLdNCfOAMYaIacKY42Q06PFB5vjx4/H3LlzsWjRIjz88MNYs2YNxowZg0BAfvQ+e/ZsxMfHN346KD+vEEK+oblxBjDWCDkVGGuEnD7N/hn9u7jiiisa/9+7d28MHDgQeXl5mD9/PqZMmRK1/owZMzB9+vTGv/1+PwOTkO+guXEGMNYIORUYa4ScPi0+2DyRzMxM5OXlYccO+WVfp9MJp1OfX5sQ8t18V5wBjDVCWgLGGiHNx/TBZmlpKYqKipCZmdms7Zb+az0ctsjs5EO79Pdk4l68RtQLt8kZw4mpXtVWeYX884ivw1hR75j736J+sKxS1AHg04WbRd3ukDOfh56nZxlqzL3sA1E/crBA3UbLOn/h9++L+p5p/VVbPx0yUNQfUtputelvdSSOHCHqRrycDffu35aLet/BnVUfR4/WiXpybj9F767aCoe/itKqAgaAcnWb0+FU4wwAPl+9Ay5nXIRmibGo6+f/58Wivntnmai7Yu2qrVC9nHltuOTKAO7UPFH3ufRs9D3b5etGYoqcKZ6WoceHJbGLqC//h9ynk9L0Ejla1vlH89aKuid+uGorKVHOjl65rlDUHU790p/aXfZjTegq6ps+LxH1mCb6kD9Bvs4kpueLekKHXqqtFPeGKK1GT4Q/bU4n1ir8QYSNYIQWqtcHpXkDrxf1kFfuh7A08WactsyVKMpJyXJ8dEyqVV0EDLmiSIxTjmdPbl/Vlie9k6gfqpH7enKnS1VbGsWHgqKe1eVKdZvOGf8l6v4qOZ59brlPA4Cj42hRT0mSz28g9XxRtxgNog4AYbtcWSQmvvmx1i3tYMTfzamw0uzBZlVVFXbu/CaVf/fu3diwYQOSkpKQlJSEWbNm4bLLLkNmZiYKCwvxu9/9DikpKZg8WS5FQwiJhnFGSOvAWCPEfJo92Fy7di1Gj/5mNH78vZSpU6fiiSeewKZNm/DCCy+gvLwcmZmZGD16NF599VV4vfqTREJIJIwzQloHxhoh5tPsweaoUaNgGPqj0w8//PC0dogQwjgjpLVgrBFiPpwbnRBCCCGEmAYHm4QQQgghxDQsRlO/H7QBfr8f8fHx+OfTnyAuzhOx7NP3NqrbXXqtnqkpcU6fNHWZzxE9rzUA2Mvl+V0PvSHPu1q0S56TFABqJ8nzDOd3Sxb1DJeeiR92yPMc/3OOvL/pWfq8yAUj5Gzf116Q50uOc+uZlFefM0/UlwRuEPXcrnLbASAjXc5yrK2Vs/BWLpLnAR4xVs5wBACbXf7u5areLurBpTNVW7Vl0Rm6lbUNyL99HSoqKuA7YX7ktuB4rH2+YXfU+2d7d8jz/AJAapa87+npcaKeiD2qLWvtAXnBUfmYo/qgKNfu36D6qL3oZVH3WeXs+Zg62QcANCiZpbsONP8y2ilLztbevE2uilBbLWfOAsAwtxxr+zKuFXWPW68QYFfioKpKTvEur5D3Kz9XnxfeEpIrdcQE5HNirdGvpSj+LEryV9ch8cI/tLtYO/rl+/B5I49LqV3PyD5SKveFbklFoh6zXZ7nHACMKrlfh0Py+YuxyVnfltgE1QeylEoOfnl/ESdnqQNAKOMC2X+oRtQrrB1VW0l7nhH1eiXrfEeR/hyup2eDqBtWucJCUxUC6uN7i/qhcnn9eK98Trx7XlR9wKbco50JyvryvRYAYImsluOvrEZi70knFWd8skkIIYQQQkyDg01CCCGEEGIaHGwSQgghhBDT4GCTEEIIIYSYBgebhBBCCCHENDjYJIQQQgghptHsGYRai8GHr4HXFZlmf+nP5EnoAcCS4Bf1qk1vivoXL69SbYWVKiaxLnlsnpwklyMY8BO5JBIA7F82QtTrFsulLkqT01Vbab3GiPqPfZtF3Zekl9pY8ft/iPpPhwyUbXXsr9pCprxN13mjRT24Qm47AASyu4h6cu9xoj6qbrmor5m+UvXhdVtF3emU9bRs/ZykXzg9SrNW1QJYp27TVuz/8zlwOyLL8OTl6OUv8m5eKOoHnpbPxfub5HI2ABAjV/9Bp45yGaUe0/4m6h/uvUz14b1DLnPmUEr8XHD5L1Rbxnm3i3rF/w4S9cE/uU61tfTBJ0U9KVG+ngy78r9UW+/uGivqmf+US5kZKXrJsg5Xy2VUwglyeTnPxz8R9bV/WaH6SIiXSy91GihfFxsmyOWrAOCpueEora6uWl2/LXntjh8h1h7Z6QvO9ShrA6m3FYr6nr/K53vhGrlsH6DH2rmd5P428Jr7RP3t7fL1GwD8f5FLH8XJLjBpmlx6CACQfZEoL/yPXqI+9j/+qJp67t67Rb1zhhxTF/yXXEoMAO55UL6eDToyVdSz0pTGAxg4/SVRr8cwUY95Z7Kov/L6UtVHarx8nes7QL6nJvz8bdXWrBmR46ZAUC5DJcEnm4QQQgghxDQ42CSEEEIIIabBwSYhhBBCCDENDjYJIYQQQohpcLBJCCGEEEJMo91moz+163dwOiIzUo1tSpo4gFtm/lDU99b+SNTrUmpVWz36Zoh6dmi1qG/66xWi/sz9D6k+whe9L+rDfyRn2nXxfK7aMkIBUX980cWiPu5cOUscACrGytmzDy2UM9svzNSz0bWs839WPi7qI37QR7WV098t6qEGue1L9snZyXE/0bNwPR0TRb1LeqWoH/3nRNXW+md/E6VVBfT+25Z82eVlxLoij29xik9dPyc2R9SDV20R9S5TGlRb6ely1nlS5TJRPzJ/hqjveu0r1cc5t6yV96t/lrxBaLFqy7pXjtud/T4S9U495XgGAPvVt4j6ynWFop6YcZ5qS8s639LjPdn3kE6qrezYQ6LuPfyBqG/q87yoN2TqGeGOvARRt6bVi7rlo2tVWznrozOHa+rbZ6yN+d9d8HojY8umVEUAgISvHhH1pOvfEfVpt2eqtmxVu+UFO96S5Xl/EPXC1XIMAsCv3ioXdUflVlEPr/qzaqv69atEfdjfSuUNDi9Qbf30VXkbf1V0JQMAMILrVVta1vn5fzsi6j6nfI8CAGx7TpTzDr4m6uEJz4j65MtSVRfWwGFRtx1ZI+oVb1yt2up98LOIv5sTZ3yySQghhBBCTIODTUIIIYQQYhocbBJCCCGEENPgYJMQQgghhJhGswabs2fPxqBBg+D1epGWloZJkyZh27ZtEesYhoFZs2YhKysLsbGxGDVqFLZskRMHCCEyjDVCWgfGGiHm06xs9KVLl+Lmm2/GoEGDEAqFcPfdd2Ps2LHYunUr3O5j2awPPvggHnnkETz33HPo1q0b/vjHP+Liiy/Gtm3b4PV6T9rXBeP6wh0XOWdsbXVQXT/JK2eVWToliHqoIV61leYLyQt2F8q2QrLvphg8qruod8iR58k1du3UjYXk+UnPv1DOyM7J0c9DUrI8J7bVJn8vye2arNrS5jrXss4zc/VzYq0tEvWYwFFRzz+np6j74vVsdLdbDgdrYJe6jUa9kKUXCp185l5rxtrgkd3h8USub7Xq30NjAnLWZUZ6rqiHG/R2uxrkzGejYq+oWx1y9nqXVN1HTyXrPDPdJW+wQ24fAKBBvgb1H95Z1H1ufb/yuyaJusMp90OPW55PHNDnOteyzuMTlbYDMCyKH7t8bUpQbDUVay6XVVkiZ6PbkuXjCwDd8qP7xLHKDxXqNt+mNWPN56qDL1Y/j1HY5GNoqZKvhzblXgAAKP9alBuq5Uxtm1WeTD3Lp/dpe5V8n4qpkPV6pZIKANgc8r3IVb9f3iBQrttS9svnzpc3qNevf9pc51rWuSUs3wcBAF752hQTlCughMNKfNTI/QEAYCjjEyWe4zvoFTS65n4R8fexOJP36USaNdj84IPI0hdz5sxBWloa1q1bhxEjRsAwDDz66KO4++67MWXKFADA888/j/T0dLz00ku4/vrrm+OOkLMWxhohrQNjjRDzOa13Nisqjn1zTEo69g199+7dKCkpwdixYxvXcTqdGDlyJFasWHE6rgg5q2GsEdI6MNYIaXlOuai7YRiYPn06hg8fjt69ewMASkpKAADp6ekR66anp2PPnj2inUAggEDgm8fPfr//VHeJkDMSxhohrQNjjRBzOOUnm7fccgs2btyIl19+OWqZxRL5rodhGFHacWbPno34+PjGT4cOHU51lwg5I2GsEdI6MNYIMYdTGmzeeuutePvtt7F48WLk5HwzdV1GxrFpHo9/EzzOoUOHor4VHmfGjBmoqKho/BQVNfGiKyFnGYw1QloHxhoh5tGswaZhGLjlllswb948LFq0CPn5kZlc+fn5yMjIwIIF38xRGgwGsXTpUgwbNky06XQ64fP5Ij6EnO0w1ghpHRhrhJiPxTCMk67HctNNN+Gll17CW2+9he7dvyndEx8fj9jYY2UK/vSnP2H27NmYM2cOunbtivvvvx9Lliw56RIRfr8f8fHxOHhgb1SAHm3itZdUe/HJNgMAYK34Sl94aKMoG+WFor5v7TuiXl6hlwToOeMzUbeWb5U3OLhetQVXgigHzrlB1GPqy1VTjrINou5PGCHqVpv8MxIABOaOFnXPVW/Ltmr1c2gJnlwZk0bfSYNF3VX8ob6R0SDrlQdEuXa7bitQGV2SyV8bQv5ta1BRUfGdN5/WjLWjX30En9cdsazBLZcxAgAjRi7dYj+6Qd7gwGp9J6rl0kdoUEqiKKVCkKCUMAEAh3IsynfLelyKasqIV0rwWORSPmGHXN4IAKyH14h6KGO4qAfs8lM0AHCXLpP9x8rbqOWNANQ4Oop6Q1i+VcQqZYycJR+rPmBzi3KDM1XUw7GZui1Ex63fX4m0nK7tLtbKPrgTPvcJ5Yw6XKBuF/J1E3Xbl8+Jem3ROtWWdE1qCqdX7ruxWXLpOgBAjVw2LFAll1dy+tJ0W5kDZV25HluyBqmmwlv/LW/TUb5HBTtMUG05Di+XF5Ruk3XtmgUgmD1e1sNyeaVYpeyTddOTqg94FP/JcvnFBo9cLg0ADHtkX/f7K5Ga1/uk4qxZCUJPPPEEAGDUqFER+pw5czBt2jQAwF133YXa2lrcdNNNKCsrQ0FBAT766KNm1SIj5GyHsUZI68BYI8R8mjXYPJmHoBaLBbNmzcKsWbNOdZ8IOethrBHSOjDWCDEfzo1OCCGEEEJMg4NNQgghhBBiGhxsEkIIIYQQ0zjlGYRMxwhHTSBf38R87wGfnD3rCCkZeFVyRhsAoFbOnKuvq5J9eOSsvU75ebqPE9rWiJaFG9tEhmzquaIealDeRYqJV23ZK+VsNyNetlVbq7QDQHLvccp+yW2MCejZkoaS7VufILc9rL2HVaFkIANAWMlGrz4oyo64BNVUbOdRUVpMVR0AOQO5LbH4d8MSjo0UXXrmc2mNnBSREQ6KerBks2orWCnHmsObLOu5clWEYMfLVB+OjY/KC5SsViR2UW1p/c1RsljUG3znqLasSoUJa0JXUa8K6Jnt4QQ5g917+ANRh92j2mqwydet/fvk61/XfKeoo6SJChpOuQ9ZU/uKeo1Tz5AtEvarSt7VNqeuZAsccZGVAFy5o9T1d5bIWfs9lOvh0V36MQ/W1Ym6N0XOVk7oMUa2c95vVB+1r8pZ3A3BGlF35haotupzLxF1++p75fUT9Cz58p13iXpKkhzrh8pVU6iHXO4q7+Broh4TrFRtBTMvFfX1a+TKLMP6yXYqdun3FXdyjqjblCo2oYyLVFtrVkVeM6urmxiUnQCfbBJCCCGEENPgYJMQQgghhJgGB5uEEEIIIcQ0ONgkhBBCCCGmwcEmIYQQQggxjWbNjd4aHJ9D9vGHP0BsbGQm3vYvitTtfvFrOYOq/HC1qGfk6PN4ZqTHirrz8Keivn/uVFHftFmeJxYArFdtEPXufeQs4BxXE1nUSmbisy+VKz7k7DQAyM5PFPV3X5az3Tp11ed9HVX3a1Ff4vqLqOefo8+T27mznEGvZZ2/+y85A3rIGD3T2OWSizMk2Q+LevCDW1RbZXs2RmmVdWH0uq/kpOaRbQ2Ox9qihVvg8URmB1eW1arb9R0kn/OGkFyZwOfRv9Naq+R+bT0kz6fesHuJqG9bPl/14b7xa1HPTHeJuuPwCtWWNi/8F4fkfpWRqWd9Oxzycdn0eYlsKzdBtZWz5meivqvP86KekCi3HQDSUuVllgY5m3nLV/I1NitHn8pRm0891irbsu/7SLVVsfKpKM1fG0LHW1a1u1g7XPgFfL7I41JjkeeDB4A4yBU6rNV7RN3iL9R3olyOtfBROT4q9n8l6kf37VRddLpRjkNL+Q55A20+cQCIkytShPInyT7Cema0tXqvqAdSzxf1YFCvshLzzmRRd054Rt6gif2yGEoFFIXKGPnaG1/TROUHZXygxTPKlHMFoG7bexF/+2vqkTnt/ZOKMz7ZJIQQQgghpsHBJiGEEEIIMQ0ONgkhhBBCiGlwsEkIIYQQQkyDg01CCCGEEGIa7XZu9NSMBMTFRWZyNpVF3c29VdQDHQaL+sYNh1Rb6WlyNjr2y1mqX34pz+/82R59LP/DFHnO25QUORM0ZsXTqq1QTYWo9xvyJ1Hv2ytOtbV6bbm8zeDOon7eoEzV1prpK0U97ifyXMq+eGWOZQCu4g/lBcpc50PGyBUCln+kZz+OvkSex9oWkH3s+eoz1damr6InZ66pb1eFHxopO1KNYI0lQktU+icAJNSsE/Uq70BRLyrWM9sz0uV+5bZuEPWSzfIc5G+u1H384DI5w9nrlTPLkw7K7QMAy1E5EzfgvlvUkz1KxieAzdvkLNWYGIuo5+fq52TtX+RrU0Om3PamYs1Z8rG8QJnrPCv/P+R9Wi5nAANAn0HZou52l4l69bp/qrbmvx0dh7XtNNaCjjQEHZFZu3EhOeMcALDkP0XZ0mOiqDek6XON2+JSZFvlhaK+9ys5G33+2oDq4zd35om6vV6erN6/+h+qraqDu0Q99cYrRd22/WXVVn3PX4m6lg3u3TNXtfXK60tFffJlclUBW41eRce66UlR1+Y6j//B/aJeEz9A9eEMyvOs20qWiXrp8idUW2/N/zLi7+bEGZ9sEkIIIYQQ0+BgkxBCCCGEmAYHm4QQQgghxDQ42CSEEEIIIabBwSYhhBBCCDGNZg02Z8+ejUGDBsHr9SItLQ2TJk3Ctm2R2b3Tpk2DxWKJ+AwZMqRFd5qQMx3GGiGtA2ONEPNpVumjpUuX4uabb8agQYMQCoVw9913Y+zYsdi6dSvc7m/KcowbNw5z5sxp/NvhcDR7x7Lzk+DxeCM0i1ISBNBLGFgb5NIfnbokqrZsdQfkBYoPp1Oe6N5lk9cHgPQsr6jbG+QyRk0RDst+ktLkUikW5ZgAQJcecnmMo0flEi42u/59xeuWj4uno3zs3e4mumOZciyVtrtcsi2tvBEAxMYq/itl2dFE211CVZ2wunY0rRlrHbumwOON7I9Oh3zuAMDSIPcFl8Uv6pkZ8aotZ90+eUHtEVG2uTyinpMgrw8AObk+Ufc6auQN6hUdAGLk45LdUW5jjHYtAZDdoYOo+xPk8meWkNIRASTEy2WcHHkJou5y6ecX9UqJJad8zYpVbGnljQDArsSOYZVLMrlT5ZI6AJCXFh231UEDgFxa6kRaM9YcwUNwBCPLdFmUskAAEONQyvDVyOX2rDVKPAEwKuRSVA1BuWyYdo7SPHq5G9V/tVx+pym0WLfWKjEVDqm2rLXyfoXtyrXJppcGS42Xj4s1cFjewGjiyu/JEmV3slLm0SLHmlbe6Ng2yn0qNlnepfROqqm81MgvYcfi7ORo1mDzgw8+iPh7zpw5SEtLw7p16zBixIhG3el0IiMjozmmCSHfgrFGSOvAWCPEfE7rnc2KimNP4ZKSkiL0JUuWIC0tDd26dcN1112HQ4f0AuqBQAB+vz/iQwiJhLFGSOvAWCOk5TnlwaZhGJg+fTqGDx+O3r17N+rjx4/H3LlzsWjRIjz88MNYs2YNxowZg0BAnnVg9uzZiI+Pb/x0UH5aIuRshbFGSOvAWCPEHE55uspbbrkFGzduxPLlyyP0K664ovH/vXv3xsCBA5GXl4f58+djypQpUXZmzJiB6dOnN/7t9/sZmIR8C8YaIa0DY40Qczilweatt96Kt99+G5988glycvT5ygEgMzMTeXl52LFjh7jc6XTC6dRfxiXkbIaxRkjrwFgjxDyaNdg0DAO33nor3njjDSxZsgT5+fnfuU1paSmKioqQmZnZrB3rmh2EzxeM0MJOOVMaAPD1LlF2hOWfOVKayFzDka2i3FD6tajHuuS3EbLidR/ZTnl/Y/bLvoNVR1VboVo5SzU3UX5PyFaxXbWVoWS7Jef2E3VrtW5Ly9Lvki7vrzUgHxMAQKWSgVh9UJST7HJmoC2wuwkfiu4vFGV7nJ5l7XVHZzTHNCNDtjVjLTe5Bj5f5LkyYuTsZgCwlMnZlfayjbIeDoo6AMBf1Czdl9VV1C86X86oBYBUyH00priJ/qahZI9muuR+aK3Rs0RTlGz4xHT5XMcEylRbnQaOEHVrmtbf9H7YUJcq20rtK+qxVrm6hdut76+Wda7S5RJ10bDJ0RUp/DVB4Pm5J2W6NWPNdvBT2KpPyDB3yFn+AICEjrLulzPLUaVXPwj75WU1ZXIfTUiS92tYH9UFYooWyQsq5Hi22vSMfm+GnBUdc2CFvIFSLQYAYvYtlvV45Vw7E1RbfQd0EXXbkTXyBnY5qx4AkNxdtuVS/CuVQGwly3QfStY5bHLVCWeXi1RTQ8dGXmf9NSHg5Y9139+iWe9s3nzzzXjxxRfx0ksvwev1oqSkBCUlJaitPbYDVVVVuPPOO7Fy5UoUFhZiyZIlmDhxIlJSUjB58uTmuCLkrIaxRkjrwFgjxHya9WTziSeeAACMGjUqQp8zZw6mTZsGq9WKTZs24YUXXkB5eTkyMzMxevRovPrqq/B6m/j2RgiJgLFGSOvAWCPEfJr9M3pTxMbG4sMPPzytHSKEMNYIaS0Ya4SYD+dGJ4QQQgghpsHBJiGEEEIIMQ2L8V2/IbQyfr8f8fHx2HZ/Z3hPmHNXnS+0CbRMu/KDJfo+VMqZmlarPDd7bKycdZ2Spe9vnV/Olq6pljN349x61p42b3BDQM52tbsTVFtHCuVs+ORcOWvOFS9nrgJAxb6vRN2izC/dFFpmoiMuQdQDlfLcwcVffab60OY617LOvU3MIev0RmcA+mvqkfrT11FRUQGfT56vuzU5Hmt7Hj8fvhPmhfdlylnfAICeV4lycO2Tol66U8nSBBCqk+eFdqfminrSQNl3zTk3qT5qnx8m6g31cqyl9dMzny0dx4h65dI/i7qn53jVVtnn/xb1hA69ZN+9fqraCqbKbYz56FpRtyV3Vm3V971d1OvC8jzd3gPzRL163T9VH+pc50rW+RGvfNwBoGhvdNWNqqpKjBrds93FmnRfS+7UX93Odp58/so/+r2ol+7dJuoAEAjIVSS8HvltutQecp9yFdyq+tg/d6qoh0NyrCV3Hqjaiut8gagf+exlUU85d5xq68CqV0Vdi7W4829XbYV83US9+o2rRT1e8QEADf3kYxnyyPcW544XRL10+ROqD22ucy3rvL7T5aqtkrLIvltZ6Uef3h1PKs74ZJMQQgghhJgGB5uEEEIIIcQ0ONgkhBBCCCGmwcEmIYQQQggxDQ42CSGEEEKIaXCwSQghhBBCTKNZMwi1JsV7D6LSGVlqyFd2RF0/q9dQUddKHH31dbVqqyog6y67rA/ulyjqyZf9XfWx+o9jRb26pkHUO+XJZZcAID67h6hvXfKWqKflyD4AYMfXcimacFguY5SSq9tKv3C6qK9/9jeiXl+vV+HqppRriu08StTLNv9F1Dd9JbcP0M+v1y2XkCroMki1FbzoH9Ga3w/gdXWbtuLfr69BrC2yf3XNWK2uP+aPPxf1jYveF/VV2+RSYgDgUKpgFZyzU9QTJo0U9d9dLZdDAYAe1XLfTYiV+9uVPStVW/U+OdbmvbZc1H/yM7lcEAC89c4GUU9xy/qEX3dRbT01Vy5rk7NeLkvULT9OtdW1r1yOpWifHDvZq58S9flv62XG8tLkW8+wyfL1pChVL5FzzaAborQG6H2uLXnr46KoWCvoIZfnA4BzhOsIAOz8YpOoL9mstztGuYUMyJefOXUYL5ceemWBPkVnycdyyTmfS4k1vQIXwvk/FPWPZt8r6j/tcb5q67WPD4l6t7SDoj5u+B2qrVkzVol674Nyf++a+4Vqq++g34n6mlUHRH3gkfdE/a35X6o+8lLlclhDx9aKemmiXF4OACbm/SLi7+bEGZ9sEkIIIYQQ0+BgkxBCCCGEmAYHm4QQQgghxDQ42CSEEEIIIabR7hKEjk/VXh2MfqE4JqAnkPhr5BdVq5RtappIRqlV3nmVX8EHKuvkJf5KPQlJal9TemWTbZfnndXaHlunJ/Vox0Wz5azVbVmr5BeQNVuhUBNtrA2JekxVnahr56Sp866d3xjlnGh9DjieDHTCPlUeSzw53sfbmuP7UScc92q5SwHQ+3WVcpwk+8dpUBZpfcRfKSepBOvlvgYAtYp/h9IX/E00PuSXk4dqNVtN9BFtG20Tf7Xc1wGgrk4+J82NZwDwK22sUnLrtNjU2gfo1zn1WlalJ21JSQoNOLZP34dYa/pcRF9HgFOLNS1BSD0XyrW1pla/r2n+7Wp8yH0HAIJKrKux1kTcavulxUdT9+5AUE4YbclYq66WLwLa9eTUYk0+9pWVcp8DomOtOXFmMdpLNP4f+/btQ4cOHdp6NwgxjaKiIuTk5LT1bjDWyBkPY40Q8zmZOGt3g81wOIwDBw7A6/XCYrHA7/ejQ4cOKCoqgs/na9V9OVt9t7X/M7XthmGgsrISWVlZiIlp+zdYvh1rlZWVZ+Qxb+++29r/mdp2xpoO+9vZ1/b2EGft7mf0mJgYcYTs8/napHOezb7b2v+Z2Pb4+PgWtXc6fDvWLJZjv7Gdicf8++C7rf2fiW1nrDUN+9vZ1/a2jLO2/8pHCCGEEELOWDjYJIQQQgghptHuB5tOpxMzZ86E0+mk77PE/9nc9rairdvM/sa2ny20dZvZ386+trf1cQfaYYIQIYQQQgg5c2j3TzYJIYQQQsj3Fw42CSGEEEKIaXCwSQghhBBCTIODTUIIIYQQYhocbBJCCCGEENPgYJMQQgghhJgGB5uEEEIIIcQ0ONgkhBBCCCGm8f8BwGdNabB7KMcAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "fig, axes = plt.subplots(1, 3, figsize=(8, 3))\n", + "for ii, name in enumerate(('delta', 'theta', 'alpha1')):\n", + " axes[ii].matshow(X_df[name].mean(), cmap='PuOr')\n", + " axes[ii].set_title(name)" + ] + }, + { + "cell_type": "markdown", + "id": "e73177ac", + "metadata": {}, + "source": [ + "## Background\n", + "\n", + "For this purpose, `coffeine` uses DataFrames to handle multiple covariance matrices alongside scalar features. Vectorization and model composition functions are provided that handle composition of valid [scikit-learn](https://scikit-learn.org/) modeling pipelines from covariances alongside other types of features as inputs.\n", + "\n", + "The filter-bank pipelines (e.g. across multiple frequency bands or conditions) can the thought of as follows:\n", + "\n", + "![](https://user-images.githubusercontent.com/1908618/115611659-a6d5ab80-a2ea-11eb-935c-006cad4fc8e5.png)\n", + "**M/EEG covariance-based modeling pipeline from [Sabbagh et al. 2020, NeuroImage](https://doi.org/10.1016/j.neuroimage.2020.116893https://doi.org/10.1016/j.neuroimage.2020.116893)**\n", + "\n", + "After preprocessing, covariance matrices can be ___projected___ to a subspace by spatial filtering to mitigate field spread and deal with rank deficient signals.\n", + "Subsequently, ___vectorization___ is performed to extract column features from the variance, covariance or both.\n", + "Every path combnining different lines in the graph describes one particular prediction model.\n", + "The Riemannian embedding is special in mitigating field spread and providing vectorization in 1 step.\n", + "It can be combined with dimensionality reduction in the projection step to deal with rank deficiency.\n", + "Finally, a statistical learning algorithm can be applied.\n", + "\n", + "The representation, projection and vectorization steps are separately done for each frequency band (or condition)." + ] + }, + { + "cell_type": "markdown", + "id": "b5ad96af", + "metadata": {}, + "source": [ + "## Installation of Python package\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "You can clone this library, and then do:\n", + "\n", + " `$ pip install -e .`\n", + "\n", + "Everything worked if the following command do not return any error:\n", + "\n", + " `$ python -c 'import coffeine'`\n" + ] + }, + { + "cell_type": "markdown", + "id": "9abff667", + "metadata": {}, + "source": [ + "## Citation\n", + "\n", + "When publishing research using coffeine, please cite our core paper.\n", + "\n", + "```\n", + "@article{sabbagh2020predictive,\n", + " title={Predictive regression modeling with MEG/EEG: from source power to signals and cognitive states},\n", + " author={Sabbagh, David and Ablin, Pierre and Varoquaux, Ga{\\\"e}l and Gramfort, Alexandre and Engemann, Denis A},\n", + " journal={NeuroImage},\n", + " volume={222},\n", + " pages={116893},\n", + " year={2020},\n", + " publisher={Elsevier}\n", + "}\n", + "```\n", + "\n", + "Please also cite additional references highlighted in the documentation of specific functions when\n", + "using these functions. \n", + "\n", + "Please also cite the upstream software this package is building on, in particular [PyRiemann](https://pyriemann.readthedocs.io/)." + ] + }, + { + "cell_type": "raw", + "id": "77bb20e5", + "metadata": { + "raw_mimetype": "text/restructuredtext" + }, + "source": [ + "More documentation\n", + "------------------\n", + ".. toctree::\n", + " :maxdepth: 1\n", + "\n", + " Tutorials & Examples \n", + " API reference " + ] + } + ], + "metadata": { + "celltoolbar": "Edit Metadata", + "kernelspec": { + "display_name": "coffeine", + "language": "python", + "name": "coffeine" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/make.bat b/doc/make.bat new file mode 100644 index 0000000..32bb245 --- /dev/null +++ b/doc/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 0000000..9f3de8b --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1,7 @@ +sphinx +nbsphinx +numpydoc +memory_profiler +pydata-sphinx-theme +sphinx_copybutton +pandoc \ No newline at end of file diff --git a/doc/tutorials.ipynb b/doc/tutorials.ipynb new file mode 100644 index 0000000..b14d8f8 --- /dev/null +++ b/doc/tutorials.ipynb @@ -0,0 +1,44 @@ +{ + "cells": [ + { + "cell_type": "raw", + "id": "4cfc099f", + "metadata": { + "raw_mimetype": "text/restructuredtext" + }, + "source": [ + "Discover coffeine through examples and in-depth tutorials\n", + "=========================================================\n", + "\n", + ".. nblinkgallery::\n", + " :caption: Notebooks showcasing usage of coffeine\n", + " :name: Tutorials\n", + " \n", + " tutorials/filterbank_classification_bci\n", + " tutorials/filterbank_kernel_classification_bci" + ] + } + ], + "metadata": { + "celltoolbar": "Raw Cell Format", + "kernelspec": { + "display_name": "coffeine", + "language": "python", + "name": "coffeine" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/notebooks/filterbank_classification_bci.ipynb b/doc/tutorials/filterbank_classification_bci.ipynb similarity index 93% rename from notebooks/filterbank_classification_bci.ipynb rename to doc/tutorials/filterbank_classification_bci.ipynb index 959edf2..a829781 100644 --- a/notebooks/filterbank_classification_bci.ipynb +++ b/doc/tutorials/filterbank_classification_bci.ipynb @@ -13,7 +13,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -28,12 +28,12 @@ "from mne.io import concatenate_raws, read_raw_edf\n", "from mne.datasets import eegbci\n", "\n", - "import coffeine" + "from coffeine import compute_coffeine, make_filter_bank_classifier" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -42,7 +42,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -57,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -91,51 +91,15 @@ "source": [ "## Building a coffeine data frame of covariances per frequency\n", "\n", - "In the following, we compute covariances based on pre-defined frequencies and show how to make a coffeine data frame from them." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "frequency_bands = {\n", - " \"theta\": (4.0, 8.0),\n", - " \"alpha\": (8.0, 15.0),\n", - " \"beta_low\": (15.0, 26.0),\n", - " \"beta_mid\": (26.0, 35.0)\n", - "}\n", "\n", - "\n", - "def extract_fb_covs(epoch):\n", - " features, meta_info = coffeine.compute_features(\n", - " epoch, features=('covs',), n_fft=1024, n_overlap=512,\n", - " fs=epochs.info['sfreq'], fmax=35, frequency_bands=frequency_bands)\n", - " features['meta_info'] = meta_info\n", - " return features\n" + "In the following, we compute covariances based on pre-defined frequencies and show how to make a coffeine data frame from them. This was previously complicated, now coffeine provides the API for it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "As this is event-related data and not subject-level data as in [Sabbagh et al 2020](https://www.sciencedirect.com/science/article/pii/S1053811920303797), we need to loop over epochs." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "labels = []\n", - "features = []\n", - "for i in range(len(epochs)):\n", - " epoch = epochs[i]\n", - " labels.append(list(epoch.event_id.keys())[0])\n", - " feature = extract_fb_covs(epoch)\n", - " features.append(feature['covs'])" + "As this is event-related data and not subject-level data as in [Sabbagh et al 2020](https://www.sciencedirect.com/science/article/pii/S1053811920303797), we need to loop over epochs. Luckily, coffeine does this for us. We now get the pandas data frame where each columns is an object array of covariances, which is represented as a list of covariances, leading to an object array type." ] }, { @@ -147,13 +111,88 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
alpha1alpha2
0[[9.899550941533323e-11, 1.0150193223596802e-1...[[1.0496460732612284e-10, 1.1822827054921826e-...
1[[9.709858344182252e-11, 8.928610694895678e-11...[[9.006992581133798e-11, 8.001210027471314e-11...
2[[1.6005797216165005e-10, 1.7120265854899606e-...[[1.293161103688762e-10, 1.4271783164176115e-1...
3[[1.0282494751586467e-10, 1.0768228603843818e-...[[1.7453066588408235e-10, 2.1678207719155826e-...
4[[2.029473693821182e-10, 2.0201658837032425e-1...[[1.9550977509808572e-10, 1.979325286585598e-1...
\n", + "
" + ], + "text/plain": [ + " alpha1 \\\n", + "0 [[9.899550941533323e-11, 1.0150193223596802e-1... \n", + "1 [[9.709858344182252e-11, 8.928610694895678e-11... \n", + "2 [[1.6005797216165005e-10, 1.7120265854899606e-... \n", + "3 [[1.0282494751586467e-10, 1.0768228603843818e-... \n", + "4 [[2.029473693821182e-10, 2.0201658837032425e-1... \n", + "\n", + " alpha2 \n", + "0 [[1.0496460732612284e-10, 1.1822827054921826e-... \n", + "1 [[9.006992581133798e-11, 8.001210027471314e-11... \n", + "2 [[1.293161103688762e-10, 1.4271783164176115e-1... \n", + "3 [[1.7453066588408235e-10, 2.1678207719155826e-... \n", + "4 [[1.9550977509808572e-10, 1.979325286585598e-1... " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "X_cov = np.array(features)\n", - "X_df = pd.DataFrame(\n", - " {band: list(X_cov[:, ii]) for ii, band in enumerate(frequency_bands)})" + "X_df, feature_info = compute_coffeine(epochs, frequencies=('ipeg', ['alpha1', 'alpha2']))\n", + "X_df.head()" ] }, { @@ -168,12 +207,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW4AAAE0CAYAAAAMt9keAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8o6BhiAAAACXBIWXMAAA9hAAAPYQGoP6dpAABqiklEQVR4nO29eXwURf7//+q5JzeEJJNAgBhuAUVwEVTAA1x0XY9VVBQVXRWBXQFdV0TXeAVlhW90FVBXEZTr5yLq7qIQLzxARRRlwY8ioiAQI+FIyDXJTP/+COmp97szJ+AM4f18PObxmOrqrqqu7lR6Xv2qd2m6rusQBEEQjhks8W6AIAiCEB0ycAuCIBxjyMAtCIJwjCEDtyAIwjGGDNyCIAjHGDJwC4IgHGPIwC0IgnCMIQO3IAjCMYYM3IIgCMcYMnDHkRdeeAGapgX9vPfee8a+nTt3DrrfsGHDTGV/9dVXuPHGG1FYWAi32w23242uXbvilltuwWefffbrnWQc0DQNRUVF8W6GIBw1bPFugADMmzcPPXr0MG3v1asXSZ9++ul47LHHTPulpaWR9NNPP42JEyeie/fuuO2223DiiSdC0zR8/fXXWLx4MU499VR89913KCwsPLInkiCsXbsWHTp0iHczBOGoIQN3AtC7d28MGDAg7H4ZGRk47bTTQu7z0UcfYfz48bjgggvwr3/9Cw6Hw8g7++yzMWHCBLz88stwu92H3e5EQtd11NXVwe12h+0jQTjWEamklVFcXAyr1Yqnn36aDNoql19+OfLy8sKWtXPnTtx8883Iz8+Hw+FAXl4eLrvsMvz888/GPtu3b8c111yD7OxsOJ1O9OzZEzNnzoTf7wcANDQ0IDs7G2PGjDGVv3//frjdbkyZMgUAUFdXh9tvvx0nn3wy0tPT0bZtWwwaNAivvfaa6VhN0zBx4kTMnTsXPXv2hNPpxPz58408VSr55ZdfMH78ePTq1QspKSnIzs7G2WefjQ8++ICU+cMPP0DTNDz22GOYNWsWCgoKkJKSgkGDBuHjjz82teGTTz7BhRdeiMzMTLhcLhQWFmLSpElkny1btmD06NGkf5566qmwfS8IoZAn7gTA5/OhsbGRbNM0DVarlWzTdd20HwBYrVZomgafz4d3330XAwYMQG5u7mG1aefOnTj11FPR0NCAu+++G3379kVFRQVWrlyJffv2IScnB7/88gsGDx4Mr9eLBx98EJ07d8Z//vMf3HHHHdi6dStmz54Nu92Oa665BnPnzsVTTz1FZJ3Fixejrq4OY8eOBQDU19dj7969uOOOO9C+fXt4vV689dZbuPTSSzFv3jxce+21pI2vvvoqPvjgA/ztb3+Dx+NBdnZ2i+eyd+9eAMB9990Hj8eDgwcPYvny5Rg2bBjefvtt0zuCp556Cj169EBJSQkA4N5778X555+Pbdu2IT09HQCwcuVKXHjhhejZsydmzZqFjh074ocffsCqVauMcjZv3ozBgwejY8eOmDlzJjweD1auXIk///nP2LNnD+67777DukbCcYwuxI158+bpAFr8WK1Wsm+nTp2C7vvggw/quq7rZWVlOgD9yiuvNNXV2NioNzQ0GB+/3x+ybTfccINut9v1zZs3B93nrrvu0gHon3zyCdl+66236pqm6d98842u67r+1Vdf6QD0Z555huz3m9/8Ru/fv3/Q8pvbfOONN+r9+vUjeQD09PR0fe/evabjAOj33Xdf2HLPOecc/ZJLLjG2b9u2TQeg9+nTR29sbDS2f/rppzoAffHixca2wsJCvbCwUK+trQ1az3nnnad36NBBP3DgANk+ceJE3eVytdh2QYgEkUoSgAULFmDdunXk88knn5j2O+OMM0z7rVu3DjfeeGPYOvr37w+73W58Zs6cGXL/N954A2eddRZ69uwZdJ933nkHvXr1wm9+8xuy/frrr4eu63jnnXcAAH369EH//v0xb948Y5+vv/4an376KW644QZy7Msvv4zTTz8dKSkpsNlssNvteO655/D111+b6j/77LPRpk2bsOcOAHPnzsUpp5wCl8tllPv222+3WO4FF1xAfu307dsXAPDjjz8CAL799lts3boVN954I1wuV4v11dXV4e2338Yll1yCpKQkNDY2Gp/zzz8fdXV1LcovghAJIpUkAD179ozo5WR6enrI/dq1awe3220MMCqLFi1CTU0Ndu/ejd///vdh6/rll1/COjMqKirQuXNn0/Zm/byiosLYdsMNN2DChAn4v//7P/To0QPz5s2D0+nEVVddZezzyiuvYNSoUbj88svxl7/8BR6PBzabDXPmzMHzzz9vqidSOWjWrFm4/fbbMW7cODz44INo164drFYr7r333hYH7szMTJJ2Op0AgNraWgBNfQMgZP9UVFSgsbER//jHP/CPf/yjxX327NkTUfsFgSMDdyvCarXi7LPPxqpVq7B7924ysDVbC3/44YeIysrKysJPP/0Ucp/MzEzs3r3btH3Xrl0Amv6RNHPVVVdhypQpeOGFF/Dwww/jxRdfxMUXX0yemF966SUUFBRg6dKl0DTN2F5fX99i/eo+oXjppZcwbNgwzJkzh2yvqqqK6HhOVlYWAITsnzZt2sBqtWLMmDGYMGFCi/sUFBTEVL8giFTSypg6dSp8Ph/GjRuHhoaGmMsZOXIk3n33XXzzzTdB9znnnHOwefNmfP7552T7ggULoGkazjrrLGNbmzZtcPHFF2PBggX4z3/+g7KyMpNMomkaHA4HGZDLyspadJVEg6ZpxlNzM1999RXWrl0bU3ndunVDYWEhnn/++aD/VJKSknDWWWfhiy++QN++fTFgwADThz/ZC0KkyBN3AvC///2vRbdIYWGh8XQHNNnnWtJFnU4n+vXrB6Bpks5TTz2FP/3pTzjllFNw880348QTT4TFYsHu3buxbNkyAOZJO5wHHngAb7zxBoYMGYK7774bffr0wf79+/Hmm29iypQp6NGjByZPnowFCxbgggsuwAMPPIBOnTrhv//9L2bPno1bb70V3bp1I2XecMMNWLp0KSZOnIgOHTrg3HPPJfm/+93v8Morr2D8+PG47LLLsGPHDjz44IPIzc3Fli1bIuvMFvjd736HBx98EPfddx+GDh2Kb775Bg888AAKCgpa7PdIeOqpp3DhhRfitNNOw+TJk9GxY0ds374dK1euxMKFCwEAjz/+OM444wyceeaZuPXWW9G5c2dUVVXhu+++w7///W/jHYAgRE28344ez4RylQDQn332WWPfUK6S9u3bm8resGGDPnbsWL2goEB3Op26y+XSu3Tpol977bX622+/HVH7duzYod9www26x+PR7Xa7npeXp48aNUr/+eefjX1+/PFHffTo0XpmZqZut9v17t2763//+991n89nKs/n8+n5+fk6AH3atGkt1vnII4/onTt31p1Op96zZ0/92Wef1e+77z6d36oA9AkTJrRYBpirpL6+Xr/jjjv09u3b6y6XSz/llFP0V199Vb/uuuv0Tp06Gfs1u0r+/ve/hy1T13V97dq1+siRI/X09HTd6XTqhYWF+uTJk8k+27Zt02+44Qa9ffv2ut1u17OysvTB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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAW4AAAE0CAYAAAAMt9keAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABqiklEQVR4nO29eXwURf7//+q5JzeEJJNAgBhuAUVwEVTAA1x0XY9VVBQVXRWBXQFdV0TXeAVlhW90FVBXEZTr5yLq7qIQLzxARRRlwY8ioiAQI+FIyDXJTP/+COmp97szJ+AM4f18PObxmOrqrqqu7lR6Xv2qd2m6rusQBEEQjhks8W6AIAiCEB0ycAuCIBxjyMAtCIJwjCEDtyAIwjGGDNyCIAjHGDJwC4IgHGPIwC0IgnCMIQO3IAjCMYYM3IIgCMcYMnDHkRdeeAGapgX9vPfee8a+nTt3DrrfsGHDTGV/9dVXuPHGG1FYWAi32w23242uXbvilltuwWefffbrnWQc0DQNRUVF8W6GIBw1bPFugADMmzcPPXr0MG3v1asXSZ9++ul47LHHTPulpaWR9NNPP42JEyeie/fuuO2223DiiSdC0zR8/fXXWLx4MU499VR89913KCwsPLInkiCsXbsWHTp0iHczBOGoIQN3AtC7d28MGDAg7H4ZGRk47bTTQu7z0UcfYfz48bjgggvwr3/9Cw6Hw8g7++yzMWHCBLz88stwu92H3e5EQtd11NXVwe12h+0jQTjWEamklVFcXAyr1Yqnn36aDNoql19+OfLy8sKWtXPnTtx8883Iz8+Hw+FAXl4eLrvsMvz888/GPtu3b8c111yD7OxsOJ1O9OzZEzNnzoTf7wcANDQ0IDs7G2PGjDGVv3//frjdbkyZMgUAUFdXh9tvvx0nn3wy0tPT0bZtWwwaNAivvfaa6VhN0zBx4kTMnTsXPXv2hNPpxPz58408VSr55ZdfMH78ePTq1QspKSnIzs7G2WefjQ8++ICU+cMPP0DTNDz22GOYNWsWCgoKkJKSgkGDBuHjjz82teGTTz7BhRdeiMzMTLhcLhQWFmLSpElkny1btmD06NGkf5566qmwfS8IoZAn7gTA5/OhsbGRbNM0DVarlWzTdd20HwBYrVZomgafz4d3330XAwYMQG5u7mG1aefOnTj11FPR0NCAu+++G3379kVFRQVWrlyJffv2IScnB7/88gsGDx4Mr9eLBx98EJ07d8Z//vMf3HHHHdi6dStmz54Nu92Oa665BnPnzsVTTz1FZJ3Fixejrq4OY8eOBQDU19dj7969uOOOO9C+fXt4vV689dZbuPTSSzFv3jxce+21pI2vvvoqPvjgA/ztb3+Dx+NBdnZ2i+eyd+9eAMB9990Hj8eDgwcPYvny5Rg2bBjefvtt0zuCp556Cj169EBJSQkA4N5778X555+Pbdu2IT09HQCwcuVKXHjhhejZsydmzZqFjh074ocffsCqVauMcjZv3ozBgwejY8eOmDlzJjweD1auXIk///nP2LNnD+67777DukbCcYwuxI158+bpAFr8WK1Wsm+nTp2C7vvggw/quq7rZWVlOgD9yiuvNNXV2NioNzQ0GB+/3x+ybTfccINut9v1zZs3B93nrrvu0gHon3zyCdl+66236pqm6d98842u67r+1Vdf6QD0Z555huz3m9/8Ru/fv3/Q8pvbfOONN+r9+vUjeQD09PR0fe/evabjAOj33Xdf2HLPOecc/ZJLLjG2b9u2TQeg9+nTR29sbDS2f/rppzoAffHixca2wsJCvbCwUK+trQ1az3nnnad36NBBP3DgANk+ceJE3eVytdh2QYgEkUoSgAULFmDdunXk88knn5j2O+OMM0z7rVu3DjfeeGPYOvr37w+73W58Zs6cGXL/N954A2eddRZ69uwZdJ933nkHvXr1wm9+8xuy/frrr4eu63jnnXcAAH369EH//v0xb948Y5+vv/4an376KW644QZy7Msvv4zTTz8dKSkpsNlssNvteO655/D111+b6j/77LPRpk2bsOcOAHPnzsUpp5wCl8tllPv222+3WO4FF1xAfu307dsXAPDjjz8CAL799lts3boVN954I1wuV4v11dXV4e2338Yll1yCpKQkNDY2Gp/zzz8fdXV1LcovghAJIpUkAD179ozo5WR6enrI/dq1awe3220MMCqLFi1CTU0Ndu/ejd///vdh6/rll1/COjMqKirQuXNn0/Zm/byiosLYdsMNN2DChAn4v//7P/To0QPz5s2D0+nEVVddZezzyiuvYNSoUbj88svxl7/8BR6PBzabDXPmzMHzzz9vqidSOWjWrFm4/fbbMW7cODz44INo164drFYr7r333hYH7szMTJJ2Op0AgNraWgBNfQMgZP9UVFSgsbER//jHP/CPf/yjxX327NkTUfsFgSMDdyvCarXi7LPPxqpVq7B7924ysDVbC3/44YeIysrKysJPP/0Ucp/MzEzs3r3btH3Xrl0Amv6RNHPVVVdhypQpeOGFF/Dwww/jxRdfxMUXX0yemF966SUUFBRg6dKl0DTN2F5fX99i/eo+oXjppZcwbNgwzJkzh2yvqqqK6HhOVlYWAITsnzZt2sBqtWLMmDGYMGFCi/sUFBTEVL8giFTSypg6dSp8Ph/GjRuHhoaGmMsZOXIk3n33XXzzzTdB9znnnHOwefNmfP7552T7ggULoGkazjrrLGNbmzZtcPHFF2PBggX4z3/+g7KyMpNMomkaHA4HGZDLyspadJVEg6ZpxlNzM1999RXWrl0bU3ndunVDYWEhnn/++aD/VJKSknDWWWfhiy++QN++fTFgwADThz/ZC0KkyBN3AvC///2vRbdIYWGh8XQHNNnnWtJFnU4n+vXrB6Bpks5TTz2FP/3pTzjllFNw880348QTT4TFYsHu3buxbNkyAOZJO5wHHngAb7zxBoYMGYK7774bffr0wf79+/Hmm29iypQp6NGjByZPnowFCxbgggsuwAMPPIBOnTrhv//9L2bPno1bb70V3bp1I2XecMMNWLp0KSZOnIgOHTrg3HPPJfm/+93v8Morr2D8+PG47LLLsGPHDjz44IPIzc3Fli1bIuvMFvjd736HBx98EPfddx+GDh2Kb775Bg888AAKCgpa7PdIeOqpp3DhhRfitNNOw+TJk9GxY0ds374dK1euxMKFCwEAjz/+OM444wyceeaZuPXWW9G5c2dUVVXhu+++w7///W/jHYAgRE28344ez4RylQDQn332WWPfUK6S9u3bm8resGGDPnbsWL2goEB3Op26y+XSu3Tpol977bX622+/HVH7duzYod9www26x+PR7Xa7npeXp48aNUr/+eefjX1+/PFHffTo0XpmZqZut9v17t2763//+991n89nKs/n8+n5+fk6AH3atGkt1vnII4/onTt31p1Op96zZ0/92Wef1e+77z6d36oA9AkTJrRYBpirpL6+Xr/jjjv09u3b6y6XSz/llFP0V199Vb/uuuv0Tp06Gfs1u0r+/ve/hy1T13V97dq1+siRI/X09HTd6XTqhYWF+uTJk8k+27Zt02+44Qa9ffv2ut1u17OysvTBgwfrDz30UIttF4RI0HRdVnkXBEE4lhCNWxAE4RhDBm5BEIRjDBm4BUEQjjFk4BYEQTjGkIFbEAThGOOoDdyzZ89GQUEBXC4X+vfvbwqhKQiCIMTGUZmAs3TpUkyaNAmzZ8/G6aefjqeffhojR47E5s2b0bFjx5DH+v1+7Nq1C6mpqRFPaRYEIXHRdR1VVVXIy8uDxRJ4Vqyrq4PX642qLIfDETSw13HF0TCH/+Y3v9HHjRtHtvXo0UO/6667wh67Y8eOkJNS5CMf+Rybnx07dhh/57W1tXoSrFGX4fF4QobSPV444k/cXq8X69evx1133UW2jxgxAmvWrDHtX19fT+I96IfmA/33nNORbGtqXmMdnZZsTw6s7JKclUzyHOk0nexpS9NdupD0dwtXkLTfpwfKSqbd48hIIemkdhm07DwWVS6frum4fdl/EAyLi65W42Tn4W5Lp6g70mlb7LmBXzJlpavpsVm0nbyPyteZI+SRtrQJ1J12Ao3I58rJIemdpfQa11TUkHRK+0Bb6vfSIE+OVLqcmrNtash2Zfal63TaOwdC0G5f8BLJ6/RHGvr2pxdfJOmON95M0nv++zJJZ4z+k/H95znTSV770WNJ+udli0jax2LGqE+dAGBLDjxB2pzsPmhHw9ZqriSStma0Y+kskq788C3ju35oVSKjbNa/tuz80GV9TO8r9XhbWw/J81XuNb5X1daj+4RHkZoa2N/r9aIGPlyL9nBEqNh64ceCsp3wer3H/VP3ER+49+zZA5/Phxz2B52Tk4OysjLT/tOnT8f9999v2p5ssyHF3tS8BhZOwmEPNDvZYSd5TnbjJ7tocKGUJDo4pNhpF/gtysDNy2bpJDbYprhpXc5kVhc7XsUa5jzc7DycrC67Ule1k5bl5v8U2LE1IdoFAC6lvDR2rCuJ/gEdYGVZWP+mKvl2O92X97fL2fLSa0ZbWN32lMCgxvs6LYX+s0plfZSWSvPrWX+nKYNODWsXP7aG9bfPQiU/i5UN3EpdNnYs71+NDVjWZDaQs/PUleul++jA7XLTsmzsfrWm0LJ11ifq8fxYX6N5YG1J+nRrVji0yAZuq641PXcLRy/IFL9Iuq63eOGmTp1qrDkIAJWVlcjPz0djXaMxYO/7fj85Rr3xq3+uJnlJ7SpJurGOamj86bO+kuZXlwfKs9jpDeVuQ58e6/cfJGnd5yNpWwZ92q+vrFO+06hyFivtG1cbWnZDFa3bnUWfxNKSAn9kPvafrqG6lqQ1NnD42R80p3J7IG60I43+MTtSaZoP1A3V9GmzcrvyJLaLPXEn00ErNY+3m/ZRSnv6RGjLpfeCil5D6zL1QTW9b/gACj14H/lrab38PmisriNpfn1sSj5vFx9sef9rNtpOi5sO3H6lrsba0HpykruCpC0uWhb/W2pQ2m1x0/7TGwL76o3B67VogDXCV1kWQAbuQxzxgbs5SD1/ui4vLzc9hQNNke14yE1BEI4PrJoGa4QmBCvErNDMEbcDOhwO9O/fH6WlpWR7aWkpBg8efKSrEwThGMaqRfcRmjgqPu4pU6bgn//8J55//nl8/fXXmDx5MrZv345x48YdjeoEQThGaX7ijvQTDe+//z4uvPBC5OXlQdM0vPrqq0ekzatXr0b//v3hcrlwwgknYO7cuSS/oaEBDzzwAAoLC+FyuXDSSSfhzTffPCJ1N3NUNO4rrrgCFRUVeOCBB7B792707t0bK1asQKdOnSIuw57sMF5C8pc5dVUBfZg7Tnxeqi8606gM42VasTONaoS1+wK6Ktdn/Q2htWB3JtO866j2qWq4DdVU9/N5adlce7faabutTIPV66mOquJnmqrfyzRWXhbTVat/DtTtraTt4Lon12BtbnqL1R8IXDt+jvxaWh1Wlqb3AW+LXhdI83aommtTPnuJ10ivNdfuNUXjdqTyY2nZphd1/O06Q+1v3ve8fy0O2p82L73uXF9X3zlYWNncZaL7fSHTVkfkw4VmD9xTWoi/m2iepK3hdyFUV1fjpJNOwtixY/GHP/whyqNbZtu2bTj//PNx00034aWXXsJHH32E8ePHIysry6jjnnvuwUsvvYRnn30WPXr0wMqVK3HJJZdgzZo1xoInh8tRezk5fvx4jB8//mgVLwhCK+BoatwjR47EyJEjg+Z7vV7cc889WLhwIfbv34/evXvj0UcfxbBhw4IeM3fuXHTs2BElJSUAmhb6/uyzz/DYY48ZA/eLL76IadOm4fzzzwcA3HrrrVi5ciVmzpyJl156KVjRUSGxSgRBiBsamgahSD5HWuIeO3YsPvroIyxZsgRfffUVLr/8cvz2t78NuUze2rVrMWLECLLtvPPOw2effWas8VpfX2/ymbvdbnz44YdHrO0Ju+Zkclay4dHmlj/1J3VNPfvZz35+c9tdA7NmudvRiSxeRR6p9tF6fQ3M5lXXwNK0br+X5rsyAxNZ+M9nLhtozPtr+lnLfvaqcog9md403KLHLWdcFuD4f9xvfOftNnmDM9NJOilzP0l7DwbO085klIZaWjbvX81KJR0uAamSBW8Hl0LUa9FUGJMF0jIQDCebiBUun/eRj88dUPL5OfFrZcISOl+9tvw+4PeUZrGGTNuYp5xIbDbqi9eUtOYP3sZYnrgrK6n1MBZn2tatW7F48WL89NNPyMvLAwDccccdePPNNzFv3jwUFxe3eFxZWVmLc1QaGxuxZ88e5Obm4rzzzsOsWbMwZMgQFBYW4u2338Zrr70GH5OxDgd54hYEIW7E4irJz89Henq68Zk+fXroSlrg888/h67r6NatG1JSUozP6tWrsXXrVgAg21VjRUtzVNTtjz/+OLp27YoePXrA4XBg4sSJGDt2LKzWaFX64CTsE7cgCK2fpgE50ifuJnbs2IG0tMAvpljmgfj9flitVqxfv940oKakNP1i2rBhg7GtuT6Px9PiHBWbzYbMzKaQF1lZWXj11VdRV1eHiooK5OXl4a677kJBQUHU7QyGDNyCIMQNh0WDI8KB26837ZeWlkYG7ljo168ffD4fysvLceaZZ7a4TxcW1wgABg0ahH//+99k26pVqzBgwABTCAeXy4X27dujoaEBy5Ytw6hRow6rzSoJO3A70pONeB18Grtq+eOaNreMqUGjALMVjuuR7sqAHZBbC7ldzWKn/6l52VzzVrXncLqyztqtWUJPhVZ1Um7v08L8ROPWOT4F3pESPGYI12S5vs7LtrsDlkk9g2vxzPpm53ZAmm6so+8vdCWYE2+HzmxzdqbXcrug5mCxNhQ7IC8bTD/n/W+aPs/QwtgFQ8Lq5lq9RYnZYmWato/dr9HaAUPp76o+zu9d0r5op7xHwcGDB/Hdd98Z6W3btmHDhg1o27YtunXrhquvvhrXXnstZs6ciX79+mHPnj1455130KdPH8MRwhk3bhyefPJJTJkyBTfddBPWrl2L5557DosXLzb2+eSTT7Bz506cfPLJ2LlzJ4qKiuD3+3HnnXdGeQbBSdiBWxCE1s/RtAN+9tlnOOuss4x0c0yk6667Di+88ALmzZuHhx56CLfffjt27tyJzMxMDBo0KOigDQAFBQVYsWIFJk+ejKeeegp5eXl44okniE+8rq4O99xzD77//nukpKTg/PPPx4svvoiMjIyo2h8KGbgFQYgbR3MCzrBhw4wXhy1ht9tx//33txidNBRDhw7F559/HjJ/8+bNUZUZLTJwC4IQN47mwN2aSdiBO9nT1oilzbVidRo792lzTdvdhsUzZrpcsocufqDiSGNTl7lPO0zITa4JJil1WdiLDG9V8JCkLWHnsZMVj647m4Z85Xq4SZtMC62311UE3jGYzpHpt/Z0+tIomfnmuY9eRQ17C5jfV5i1Y+omULV8ZzsaUpd7kq0s5C6Y/mtJzaD5SsxoUx7zMPN8N3vH4GPavKo183cGvH+t3JPPtHh1qjkAWFICbdFcVA+3Mt2fh3HlZdvSqDdePW8eThaqxn2EfdxCAg/cgiC0fqyI4olbYnEbyMAtCELcsETxxG2RxcMNZOAWBCFuRKVxy7htkLADd3KXLsb6kHy5MTU0K9dMuZfarGlTbdOe056k3Z7A8k2+Gho2lPtew+mRtrZ0IVeHogM6PWy5K29w7ReA2a/LdFVrakDXtjFPMvfjcixOd8h81YfLdXu+PJsti/ZnKtNJVQ809/fydwimdvK6uV9dWUjXnsY0bIYtiS6Uy73uXO/1Kxq3Pa8g5L48ny9tZmPXklyfMNfZFE+EnYeqaQOALS+wP/eqc893KH28pf2Jju1kWruSZ3MHf38TlcYtT9wGCTtwC4LQ+pEn7tiQgVsQhLghT9yxIQO3IAhxw6JpEb90lJeTARJ24P5u4QqkHPKs8ljV6nJjPJ42jz3Cfdpc0/7q/y0haTU+iYt5wJPaUS3TnZ1B0ints0iae1s3/YPWRdqVTPVFdyY9jyRWlynutaKzHtj8DduXeqvtqbTsso/WB21XU9sC/ZBeSPvPkkw11p3LXyfp+v10OTe1LTyPxwDh58jJ6NODpK2Zucb3bXOfJnkF428l6W2z55D0CRMnknT58qUknXnTXwPHPr+AHTuBls3yuXbPtX3VG29jfZCURT35/P62tfMgFLteWW58535+7vdPPaEDLVvpTwDY9d9VQY9P7UhjVNdVHDC+V9VS37qKZtVMseeD7isDt0HCDtyCILR+LFYNlggHbnniDiADtyAI8cNqCRk9kKDJDJxmZOAWBCFuaBYNWoR2EU2mvBsk7MDt9+nwW5r+w1aXUx9o7b5AzGx1jUiAxtNuCdWnDZhjblftDuiudfupt7puH02nVlPtjj85uLKp5q2uqchjrFistN08n+ukpvgtivZpWuOQ7Wu1h/GMM1QtmuvS1nQW74J5rfm6hmrck5oK6pO3uZgnn52HhXny/VX7aV2KF577zblPPly+zc1iaCvxuE1rN9bR8+DwtTTNcd4D97DVQfuXw9f8TGGL0vJ3DupcA37PoHwfSXL9nPvT+fFqfJ36/VVB6/U3Bo83brFqsEQ4cFtk4DZI2IFbEITWj2aJXCrRQoRoPd6QgVsQhLghT9yxkbADtyPZBsehZZcsdvofuUGRR6p9VEbhP0NNoVnZNHZu+VPlEe9BKsPwn7xcm3Nl0p+5fKqzGo6WL4PWwCQfLsvYXPRScUlCnfofakkpwCxf8Kn6PF+VR/jPZS4xOFLpz2tVGuHHN4aREOxueq24RMHb4lCmdNv50nBsKjmXBfQw+ZoilZiOZVPJ+bJ04abyq+dt6oNK2gemMAHsfray81CvLZeeuOzSWEOvJe8Tfl+pkpwp1ITSzpBLlzkssES4+rnFJ0/czSTswC0IQutHnrhjQwZuQRDihqZFMQHHLwN3M9EunIz3338fF154IfLy8qBpGl599VWSr+s6ioqKkJeXB7fbjWHDhmHTpk1Hqr2CILQiLFZLVB+hiaifuKurq3HSSSdh7NixZGXjZmbMmIFZs2bhhRdeQLdu3fDQQw9h+PDh+Oabb5CamtpCiS3jyEiB85DG7W5DdTx/Q0Bb8zVwaxXTTZm+yEOz8mnsqrbMNW1edri6eNhXd5uA3s41ba5tcj0y7HkpaR7ulGvDXHPky6BxuE4dCr60GdeDG8v2Btrppu0K1wcWGuHU1L9q2FFXG3qvmXTotOSQ+dak4Mu58WN5uFOeb7LhgYcLDhzP7zl+jjzN72fellDXNtxSfLwsUxhdZSDl70XUey6Uxq1Zo/Bx6/LE3UzUA/fIkSMxcuTIFvN0XUdJSQmmTZuGSy+9FAAwf/585OTkYNGiRbjlllsOr7WCILQqZOCOjSP622Pbtm0oKyvDiBEjjG1OpxNDhw7FmjVrWjymvr4elZWV5CMIwvGBSCWxcUR7oqysDACQk0MjheXk5Bh5nOnTpyM9Pd345OfnH8kmCYKQyBx64o7kIyspBDgqrhIeflHX9aAhGadOnYopU6YY6crKSuTn5yOpXQaSDmlqfJq1ijpdGAAsduoJ5bqdSXdm4VLVaez8JxzXmTmmqeZcT88NvpwW13t5WSYfN592rWiM3MPMn1S4H5fr0qa2MW0zFFzT9jIfsrrsHIf7uq32MOfM+kj1HYfzabva0lC33OdtWrZLwc3C5ILpuzyMLsfL+lPVwO1Md7YnsSnt/H1FmKdQtR/4sQ3VNMwC72+wZdKcGXy5N2VJO3ZOarvttuA+bYsm0QFj4YgO3B5PU2zgsrIy5OYGYvmWl5ebnsKbcTqdcDqdLeYJgtC60ayWsP98jH39IpU0c0R7oqCgAB6PB6WlpcY2r9eL1atXY/DgwUeyKkEQWgHNE3Ai/QhNRP3EffDgQXz33XdGetu2bdiwYQPatm2Ljh07YtKkSSguLkbXrl3RtWtXFBcXIykpCaNHjz6iDRcE4dgnKleJTMAxiHrg/uyzz3DWWWcZ6WZ9+rrrrsMLL7yAO++8E7W1tRg/fjz27duHgQMHYtWqVVF5uAEgOS8TKe4mCUX3UT+pOzN47AweM4Hrt1yL48uNqZ5THnuE+15NOjRbdor/BFTr4nqiM4Nqv9wXy7V6frzabkdmO4SEh59lS6zpzL+brMRBMcXwYKE/rSydwnVo5bz4deXXkmuyVgc1cvOlzjRbIN/ejkpzGtNrbW3pdefnbEnNANtBOTZ0/zrb0XcZ/Dx4LBP1vH11LFQwi+PBywrntHBlBdriSKWxSPj7Bl42v0/4+yAVfj9aUwJ/71ZuwFcQqSQ2oh64hw0bBj1EeEVN01BUVISioqLDaZcgCMcBFisij1XiD7/P8YLEKhEEIW5olihilUS43/GADNyCIMQNiyXyiTUWn0glzSTswO3ML4TzUJwFWwbVDPW6QJxrv5f6b7lOypeo4vqkhem76nJjPJ52uDgRJn90mza0ruSAv9floWXzuNY8doYpLgfDmhLQnm05R3YSU6ojoCVbnDT2hSWNXhuN9SdfSitD0T65T5j3AddYuU7N9XW1bpunI0LB8/V6tgRbG6qB+y2B+8iWQ4/VnFRrt+cWkLS1Db3W3DOuXmtTH4SB94ElLTN4PqvXHqYu7mXnfyuRtstaHdy7H9XLSXGVGCTswC0IQusnqpeTMuXdQAZuQRDiRlRrTka43/GADNyCIMSNaIJHSZCpAAk7cG9f9h+kHPLt1leydQ2TA15sHheCe3uTPFTzczCdbtM/lpC0Gg9ZXSMSoPG0AXPsEe4JVzVtAFh3/3zju9XBY2JTf3lSO1pXsofW5cpMJ+lUReOu2fwFLTudtsOSRNMH/rcZoVBjlSR1yCV5WhLVsPf893WS5vEw1DUpvVVU++UxUXhsDE5K9+4kbVF01R3z/kny8sf+kaS3PvEESZ8wcQJJ7166kKRzJt5jfP+/kmdJXs+//omkvyx+mqRNMVgcLAZImkP5zu5fdo+52XVPyssmaa63b35yMYKRkkvvg8wTqTbvzqVe+E3PvUHS6Z0C73DSOtP7oq7igPG9qj7EmptRSCWQgdsgYQduQRBaPxabzTzxJ9i+flksuBkZuAVBiBtNLycjW+Vds/rC73SccEwM3PWVdBpwQ7UyRZjZ5Ph0YoudTrd1MhteqLp4GFe+3BiHT/vllj9VHqmvpD8f+ZJVfBkvDp9un6RMR+Z5JvtZlJYzdWq0i1kkrTwcKusDHoJAlUd4uN6GME9e/A+c2zXV0K0WZgPlYV15uFTeR3zpMxUuZ/BjucTGryUPRayGM/A1sCXAHKH7hIfwtabTstVwwPx+9lbWsjS17bkymUWS2fHUa2ueqm9p8TtHXCWxcUwM3IIgtE4sFgssEbpFIt3veEAGbkEQ4oY8cceGDNyCIMQNGbhjI2EHbovLYYTx5NqazxvQAblWzOGWM67vchuexRrQ/bimzbVKvtyYKTRriLq4ph1uWTRHCm2nzUXralBCr/LQteHgYQE4qqWPT73XG2n/c0sf12hVXZTr31yb5+EL+B8ur1tN25PcIffl4X65Bm7jGrh6LNOVeXgCB7un1HcyAMDflOi+gFvCe5Duy3Vo3r+mUMOsLXblHuX9y+/BhhpaVyjdGqDvl/i1ihRNi2ICjiYDdzMJO3ALgtD6kSfu2JCeEAQhbjQP3JF+oqGoqAiappFP87q4sbJ7926MHj0a3bt3h8ViwaRJk1rcb9myZejVqxecTid69eqF5cuXH1a9HBm4BUGIG81T3iP9RMuJJ56I3bt3G5+NGzceVnvr6+uRlZWFadOm4aSTTmpxn7Vr1+KKK67AmDFj8OWXX2LMmDEYNWoUPvnkk8OqWyVhpRJnejKcziY9z9WG+n1VXZsHV1f1wkhwZ9KluFQfd90+qlHz5cO4ZsiXG+N6ozqNPZxPm8P351qzmubT4WFjS0cxTZF7gU1LstWq/c3+eFioVa4dq9o7QN85hNPi+RMW98mb9lfawtvBMU2nZ0uXOTLodHAVU/+y687DMPC5BhY7VbnVdyn8HvOz+5mHEja/c2B+deXa8mvHQ0nwdw68LkcyvY/UgZTfM+q1tfiDL13TtJBCpEGmog/rarPZgj5le71e3HPPPVi4cCH279+P3r1749FHH8WwYcOClte5c2c8/vjjAIDnn3++xX1KSkowfPhwTJ06FQAwdepUrF69GiUlJVi8OHgIgmiQJ25BEOJGLFJJZWUl+dTX1wctf8uWLcjLy0NBQQGuvPJKfP/990be2LFj8dFHH2HJkiX46quvcPnll+O3v/0ttmzZcljntHbtWowYMYJsO++887BmzZrDKldFBm5BEOJGLAN3fn4+0tPTjc/06dNbLHvgwIFYsGABVq5ciWeffRZlZWUYPHgwKioqsHXrVixevBgvv/wyzjzzTBQWFuKOO+7AGWecgXnz5h3WOZWVlSEnhwboysnJQVlZ2WGVq5KwUokgCK2fWOyAO3bsQFpaQI5yOp0t7j9y5Ejje58+fTBo0CAUFhZi/vz5yM/Ph67r6NatGzmmvr4emZlNEUVTlIib11xzDebOnRvZSaFp0XQVXddN2w6HhB243W3T4HY1XZCGKupZttoDaa4rh70JmAaoxvgAqC9WjfMAmL3WPN+kTzL9kYdmVeE+ba5p81CgvC5Vj9QczIPMNG7NRuuyp1Kdn+u9jTUBLdTiYGUxjduWRvVfF/dqK9eLa9hcY7W56B9kuChyutJukw7N44lk0HPm7yMsLFytpgfazTVs7hE31c2ws/tZ9WpzbzWfw8Dv98ba4F52AHArbW0I806B69T8/nVl0j4xxcRRsCcH3ufYQwSR0qxWWCIOMtW0X1paGhm4IyU5ORl9+vTBli1b0L59e1itVqxfvx5WVn/zgL1hwwZjWzT1eTwe09N1eXm56Sn8cEjYgVsQhNbPr+njrq+vx9dff40zzzwT/fr1g8/nQ3l5Oc4888wW9+/SpUtM9QwaNAilpaWYPHmysW3VqlUYPHhwTOW1hAzcgiDEjaM5cN9xxx248MIL0bFjR5SXl+Ohhx5CZWUlrrvuOnTq1AlXX301rr32WsycORP9+vXDnj178M4776BPnz44//zzg5bb/CR+8OBB/PLLL9iwYQMcDgd69eoFALjtttswZMgQPProo7jooovw2muv4a233sKHH34YVftDIQO3IAhx42iuOfnTTz/hqquuwp49e5CVlYXTTjsNH3/8MTp16gQAmDdvHh566CHcfvvt2LlzJzIzMzFo0KCQgzYA9OvXz/i+fv16LFq0CJ06dcIPP/wAABg8eDCWLFmCe+65B/feey8KCwuxdOlSDBw4MKr2hyJhB25Hegqc7iaN053VhuSpHlGTl5qlVa0NgEnv5XqkGnOBx9ngcSG45hrOZ6zWZfJKs9gjJp8298myutTy+JJp3LfNNW6uaessbU8NaLDh9HNet4Npy2of8mXmuG84XNwTfh6q3s6XVONY0zLoBv6uhC1xB0XjdqSxPHasST9n146fh3of2cPE/Ag7eLG2qG3lsen5PRbuiZZ749V3Evyc1GtnQ/C5FUfziXvJkiUh8+12O+6//37cf//9UZWr6+Hnilx22WW47LLLoio3GhJ24BYEofWjWbTIB+4YJuC0VqL6FzZ9+nSceuqpSE1NRXZ2Ni6++GJ88803ZB9d11FUVIS8vDy43W4MGzYMmzZtOqKNFgShddAslUT6EZqIqidWr16NCRMm4OOPP0ZpaSkaGxsxYsQIVFcHpjHPmDEDs2bNwpNPPol169bB4/Fg+PDhqKqqOuKNFwTh2EazOaL6CE1EJZW8+eabJD1v3jxkZ2dj/fr1GDJkCHRdR0lJCaZNm4ZLL70UADB//nzk5ORg0aJFuOWWWyKuy57b0dCn05JYLI36gK84Wi3Ymkr18iQX1StVfZLH2TDFPg7jIbemUK0zVUlz/zivi58X13+5bqp6iy0ZWbRd3CfLvNeaK3RcD4sz8J6A72tJzaA7M42b75/ENXIF7kE2/aHy/mXXUtXfbVntg+a1lG8qu002zVdiQdtyOtI8/t4kj5btaJtB0ur9C9Brz+8xU5wTJivwODPcf57cOXDePD4896Obfdv0/Q+PQx4qBrd6zg01IdY4tVhMfR9yXwHAYU55P3DgAACgbdumiSXbtm1DWVkZmafvdDoxdOjQoPP06+vrTbEHBEE4PtCs1qg+QhMxD9y6rmPKlCk444wz0Lt3bwAwZgtFM09/+vTpJO5Afn5+rE0SBOFYw2KN7iMAOAxXycSJE/HVV1+1aCqPZp7+1KlTMWXKFCNdWVmJ/Px8lJWuRrWz6Sco/7mowi1l3ELmzqY/p21savOBzezlqi/4lGxeNv+Z6shsR/fPof+EajZ/0WI9gDnEKf+Zyn/qc9udKo+svPRekteueyYtuw0tq+KbCloXm2atHp/agU7b5+2uq6C/mGr20KXjknMCP+Xr9lELpJ0tBWeSAdj1yOhG+1cVvfZ8QO/LnIupNevgxvW0rOGXkHTturdoWzoFYi97d2wleUlDfk/S9b+8i1BoTtr/TkVu4iEEuBTF5SNTPpOPGr5V7jl2DyWx+5PLQ1oKvQcbtm2m7VZkGQur11+1z/hur6bXmWCxRD4gi1RiENPA/ac//Qmvv/463n//fXTo0MHY3hz3tqysDLm5ucb2UPP0nU5n0CAxgiC0bo7mBJzWTFQ9oes6Jk6ciFdeeQXvvPMOCgoKSH5BQQE8Hg9KS0uNbV6vF6tXrz6i8/QFQWglaFHIJJpIJc1E9cQ9YcIELFq0CK+99hpSU1MN3To9PR1utxuapmHSpEkoLi5G165d0bVrVxQXFyMpKQmjR48+KicgCMIxTDTatWjcBlEN3HPmzAEA09I+8+bNw/XXXw8AuPPOO1FbW4vx48dj3759GDhwIFatWoXU1NBTkDnurAy4D+mnDdW1JE+1LfFp5/zNs3l5MTqd27TMVAiLE68r2jXw7OlKXWwquAm+3FiY5cfU8+aatjOdSlFcS85k+/NQojZlf/5zlb8HSO1IJTGrax9Jq33mTAseFpTvC5j7P9S15e82+JJeTmbRM9WdwvKVKe/WjODheQHz+wfdF3qZOo1NRSd53BIZ7r7Q2PVRdGiN3fvhwhfAwu53Zp3VVJsoK0sNGaD5gs94FKkkNqIauCOZo69pGoqKilBUVBRrmwRBOF6QJ+6YkFglgiDED3GVxIQM3IIgxI1oJtbIBJwACTtwO9KTjbCuoZa4ChdZLFw+X7bLag9Mzw03pd1UdpgnAktSQPvk04/NO4cOxWqeDh64qblPm2vafh+VvJLaMe0yCu3ex5bOSvZQvdznpdqy+n6C9yfvb+4R5+0yadzKVHJnBnunwvRdPjWc69Cm0Lih8kLoygCghXufEeq+4cvO2YOHsm2xLar2zDVuJw15zMvSmcbN/eekbFvwkLuaLcT5y5T3mEjYgVsQhOMA0bhjQgZuQRDihmaxmn81hNhXaEIGbkEQ4ocWhVSiiVTSTMIO3OXrvkaNo0nf46Fa1ZghPNQkX14JLG1hul7ZRzRmhQrXWPkyaLwuF1/uinHgf5uD5lkdoeN0cC3epFcq4VN57BHu0+aa9vdvfc/aQp9s8vp7jO/c98615B/f+pKk6/ZRD35m90BMleryg7SsNNrffAkw7ut2FNI+srYJlL3jP2+TvBN6DyLpvZ9/RdKeXqeSdNVGeh5pfc9W8uixbQv7knTtt/8jaa7Fh4qBwzVsazq9dibvNcPKjm/Y8W0gwd4hcK+6LZuGo+XDpPcnGqNFjZPC45z49pUb3xvZPAwVeeKOjYQduAVBOA4QO2BMyMAtCEL8EFdJTMjALQhC3BAfd2wckwM31wxVuB5+WPX4oyuLx0E5rLr5ebCyQ9XF42nz2CNcY+WaNt8/GvhK3Cav9mFcn2iubbi4FnwQ0Fg4h1BedlPZOtOO+byDkC35FQekX/GJVdWjQ2rTNkfTJxJC+cGPM47JgVsQhNaBBJmKDRm4BUGIH1oUE3AkHreBDNyCIMQPTYvcnx1k+cPjkYQduJ1t0uA6tOZk5fY9JK/658Aadv4f95M8R0roNRD5zy2+ZmX9/oMtfm+pLL4GZXI1jT+S6gi+Hqa3iq7Dx2OO21gMkMYaWrY9le6v+tN5PG6bO/RlVn3aLbHv+/3Gd66fW1mM7OyTOtFjv91J0pU/Bfqwlnm8D/xI1WBXRhVJO1Jo3A7uo89qF4gFzuOCq75iAEjy0JjavioaN9zdPo+k4Q/EWOFedtTT87CmUP+5VkOvNV9D1a/Ec9H99fRYHquErZnKfd1+F5u3oMTQ5jHJTe9N6uk9pieFid+t7svaRWKshNKmNUsUA7dIJc0k7MAtCELrR9cs0CMckCPd73hABm5BEOKHPHHHRMIO3Gkn5CLtUFhX/pPYWxn46cl/dnL4sXxqeXohnearyiONIZYxawnTFG02vT6pQ67x3VVbTfL87Dy4pGNxsJ/MfKko5SdyagcqA4R7G2/66c9Q5REuLXGLXnpBLkLhSNsb2Jcdy/ub2+pMYV651VCRAlI7M6mD4cwJ3U5rZnD5iE8N59PUbZm0bD2VShA2LiuoL+d4KAMWRsEknfB8Fw8DEJiKrjeGqBeAlszC0bpZyGMlpABAz5uHslXDFlu0EHY/TYtcuxaN2yBhB25BEI4DZOZkTMjALQhC3BCNOzZk4BYEIX6Ixh0TCTtwu3Jy4Epq0lN56FZVC+VTqLlWzHVRWwbVfy1M17OmK0uXhVtejKG5qN5oSWNas6IDWpk1K6z+yCcpMK2ThNgMs+QXX27MtMwXQ7X8cU27kVkgbW3bkXQyD8nLQuOqqEvStYSFvZ/gVkT1pzTXqLk2zMOQWlyhQ/KqT3v8WN3mpGUxLRj8WvsiD41gWi6M3xes3bqN7m9Rw8LyMAm8rCSqaYcsC/QdjqkPnAFboxWhNG4ZuGMhYQduQRCOA2TgjgkZuAVBiBu6pkWhcYurpBkZuAVBiB/yxB0TCTtw7yxdgwOHvMsWpmWq3mxXZjrJ4z5jezr1KNuyqAd35/LXSVrVUR2pVD/knnDu27YyvZF7bPf8N1AXPyc+fZ7XZUuj52lJZt5rJc2n5vPp38keqlXy5cZ4aFZ1Gjv3aXNN+7vFK0mav4No27OD8Z2HFDD3b2jtPblLF5K2d+5hfN/6+D9IXtc77yTp7c/MJun8W28j6T3Ll5J05i0nGd9/WfkGycu55maSPvD+W6GabdLq1Xc4YZcu41PaWb6VhYit+fJD4zu/Fra2VIu3sr8NXnfd/z4Omm/JoGX5KsqM7/U1wZcuEx93bCTswC0IwnGAPHHHRFQ9MWfOHPTt2xdpaWlIS0vDoEGD8MYbgacPXddRVFSEvLw8uN1uDBs2DJs2bTrijRYEoXXQ7OOO9CM0EVVPdOjQAY888gg+++wzfPbZZzj77LNx0UUXGYPzjBkzMGvWLDz55JNYt24dPB4Phg8fjqqqqjAlC4JwXKJZArMnw31k4DaISiq58MILSfrhhx/GnDlz8PHHH6NXr14oKSnBtGnTcOmllwIA5s+fj5ycHCxatAi33HJLVA2rqagxdOCGauqDVcOUJmXuJ3lcJw0XapXrrOpyZVwr5pq2GjMFAFKYhsg94mroVu5Z5rpnA2u3i+3vYN5gVfus2UPjoFhdNGSpz0uPrWPhVXkMEB6aVYX7tLmOuuebCtoWZZm0ql20711t6LVJahfaW+1mMVbUWBomf381C+/LlyZjnn2bm3mP9RALkPlCx7QxxbxhabWtpvc5PGZNmLCuOnvPos5r4B58S111yLTO3qPw0K0kzUPGRopIJTERc0/4fD4sWbIE1dXVGDRoELZt24aysjKMGDHC2MfpdGLo0KFYs2ZN0HLq6+tRWVlJPoIgHCc0D9yRfgQAMQzcGzduREpKCpxOJ8aNG4fly5ejV69eKCtreouck0MdDDk5OUZeS0yfPh3p6enGJz8/P9omCYJwjKJbrNAttgg/snRZM1EP3N27d8eGDRvw8ccf49Zbb8V1112HzZs3G/kas+zoum7apjJ16lQcOHDA+OzYsSPaJgmCcKwiT9wxEbUd0OFwoMsh/+yAAQOwbt06PP744/jrX/8KACgrK0NubsDrW15ebnoKV3E6nXA6nabtKe0zkOpoXrpsL8mrPxCIg+A9SHU3u5vqplwr5j5vHota1bW5NtlYRtvBlx9T9XEAyEihGrfqC/dWsXjcTMPm+bxsH2tbkqJ1JufQenlcax7PJbM79eByfVhdbkyNpw2YY4+oPm2AatoAULMnoKc31tF2qPUA5ncbVgc9j/1bqfauLl3G46zzpctS2tNz9ldSLT6pA4vHrSxdxpc902voPWeKy86WnQsVk4VfVz9b9gzsPuBzBbi/X11GzcKWJuNl8dg8PH6OxR38nYPO44grMVa0Rj3ocb+Gj3v27Nn4+9//jt27d+PEE09ESUkJzjzzzJjKioRly5bh3nvvxdatW1FYWIiHH34Yl1xyyRFt02H/C9N1HfX19SgoKIDH40FpaamR5/V6sXr1agwePPhwqxEEoTVylJ+4ly5dikmTJmHatGn44osvcOaZZ2LkyJHYvn17TM194YUXMGzYsKD5a9euxRVXXIExY8bgyy+/xJgxYzBq1Ch88sknR7RNUfXE3XffjQ8++AA//PADNm7ciGnTpuG9997D1VdfDU3TMGnSJBQXF2P58uX43//+h+uvvx5JSUkYPXp0NNUIgnCccLR93LNmzcKNN96IP/7xj+jZsydKSkqQn5+POXPmAGh6uLzzzjvRvn17JCcnY+DAgXjvvfdiPp+SkhIMHz4cU6dORY8ePTB16lScc845KCkpibhNkRCVVPLzzz9jzJgx2L17N9LT09G3b1+8+eabGD58OADgzjvvRG1tLcaPH499+/Zh4MCBWLVqFVJTQ09dbon6vVWw25ukkqpd1AdeXxn4CWdnK5jrGcFXogbMVjduB6ypCPw0baylP2nDrZZuCtfJXqao8gevl/98DhealUs+KnX76M9rZxr7ec36oLqctoWjrsbOlxvj8PPilj9VHqn8iV5Xi50tVcZkFquXpZl1Tp0uXldxgDaMXQveTp7vO0jz1aCw/FgqjAANTBqp38eudQOVgCz2QOlcEuP3gZ3bGPlK7SytSi1c+rM6mCU1hVn6mMXPz5bbs4TYV10xPmR45BjsgNx5Fkxu9Xq9WL9+Pe666y6yfcSIEYbTbezYsfjhhx+wZMkS5OXlYfny5fjtb3+LjRs3omvXrpG1S2Ht2rWYPHky2XbeeecZA3ckbYqEqAbu5557LmS+pmkoKipCUVFRNMUKgnCc0hQdMDLtunk/7jy77777Whxz9uzZA5/PF9TptnXrVixevBg//fQT8vKa1ii944478Oabb2LevHkoLi6O+nzKyspCOuvCtSlSJFaJIAhxQ9ebPpHuCwA7duxAWlrgJWxLT9sqwZxun3/+OXRdR7du3Uh+fX09MjObAmht374dvXr1MvIaGxvR0NCAFOWl7zXXXIO5c+eGrS+SNkWKDNyCIMQNv67DH+HI3bxfc6ykcLRr1w5Wq9X0JNvsdPP7/bBarVi/fr0pqmLzwJyXl4cNGzYY21955RUsW7YMCxcuNLapbfF4PEHri6RNkZKwA7cj1Q3HITugI5nqfKpO2sB0aIud6nj1lVRf43YrrhXbXIH9fV6qF/I018C5hsi1PTV0awPTZ7kFj8M1cB9Lq9YtrvtzuI7qTAuxtBSAAz8G9ufnyNvFQw7waeyq5Y9r2tweyO2AYG40bvVUp2DzdnANli+Hx6dzW5NovqZMeTe9X2C6Mg/R62PT531cp44C033iD522OAL6uZVbCaNcNZ2HnOXvBei+gXo1W3D7o37oEwmR7teMw+FA//79UVpaSux4paWluOiii9CvXz/4fD6Ul5cHteLZbDbD/gwA2dnZcLvdZJvKoEGDUFpaSnTuVatWGc66cG2KlIQduAVBaP349aZPpPtGy5QpUzBmzBgMGDAAgwYNwjPPPIPt27dj3Lhx6NSpE66++mpce+21mDlzJvr164c9e/bgnXfeQZ8+fXD++edHXd9tt92GIUOG4NFHH8VFF12E1157DW+99RY+/DAQFz1UmyJFBm5BEOKGruvQI5RKIt1P5YorrkBFRQUeeOAB7N69G71798aKFSvQqVPT4iDz5s3DQw89hNtvvx07d+5EZmYmBg0aFNOgDQCDBw/GkiVLcM899+Dee+9FYWEhli5dioEDB0bcpkiQgVsQhLhxtJ+4AWD8+PEYP358i3l2ux33338/7r///ojKuv7663H99deH3Oeyyy7DZZddFnObIiFhB25n21S4nE2aWmoeDTuq+nsb67gnlnl9HaF1PL70mRr60u6uCZoHmH3EPCQnmIYYaikurh1z37bN5WRp5vO2BdJ2pt/yKe/cG8ynaHNcGQG/NS+Lw8+Rh2ZVdWvu0+aaNtfebS47SXO9V/Uw83Zwf7NJA2fwJcLIsax/udbL9XHueTCFeVUwLS/GrpXFxfR1G+0TjaeVMK9WlsdRdekWy+bLpjkD4Q54eFn13tcaQo+4MY7HxzUJO3ALgtD6+TWeuFsjMnALghA3jrbG3VqRgVsQhLjhP/SJdF+hiWNi4NasdEaRqltrVgfLo3qjSSN0hD5lVcPlmrWFSYA83+pgmmAonysz/HNNO5x+bjoPRVPkOjQ/ltdlCvvKdFZHiuIFjrI/Oeq147FHuE+ba9o8VoyV+aPV/uZeda79cvj14IQMcMT90NH6o0Psb3Hwm47uG+oeC18vO5alD6fsSIll5qRwjAzcgiC0TkTjjg0ZuAVBiBuicceGDNyCIMQN0bhjI2EH7sy+PZCW1OQN5ctMeSsD/mq+DFdjXT1Jh/M/Z/TpQdL+qv1KWSwuB6uLe255DAvVQwsAKd27B8pisY35MlHhUH3bAGBNbWN8z+hGw16a/M5cwy4M7WlWPc9cj+VafDKL4eBmS8Opy43xY02xR7hv3qRp07boSjyS1J49SR6P4eEs6I5Q2PMKaNlqXkcaTU71MwOAvX0hSdvq6HwAR6hrzbX5EP5oALAo1x0wL11my+2slM3ixTP4MmhaCp3jwPtE9Xlb2L2u+uatbnqvq/h0Hb4INRCfPHEbJOzALQhC6+doBplqzcjALQhC3JCXk7EhA7cgCPEjCjugPHIHSNiB2965J+wpTdqqLZfpwYpmyLVhna3nZ/JLs3gL1sxcerwSQ9vBYjSb1vdjMZ5NcSKYZqjqgPxYfh7cQ8tjbfB8VQtldmjTsep6gABgbUPfIXCy2gUCvPN2c83V3pm+M+Blq2Xx+M48Jna4c+ZtsSQH4pPY86kO7a+h61ta0zND1g2m2foUH7et/Qm0bDu7pzw0ypsWRlsma5Xyc+YxsPmxVnrPmdqSE9q/Tsqy0OHAb6favSWLXS9lf34s/Or7oODro/qhwx/hiBzpfscDCTtwC4LQ+pEJOLEhA7cgCHFDNO7YSNiBe/uCl5DCp/seQrWn8bCs3JLnbNeW5qfR9La5T5O0VZnCzcOjutrQUKE8HKq9HV0zzubpSNI75v3T+M6nituT6M9S0xJg7Dy1JNoWW1Z74/ueDz4kee5sahnjIU93/OdtWjaTP1I7Bs4rtXMeybNmekh66+P/IGlu6UsvDLSzruIAyePnbA7NSsvilj9VHtny2CyS123qXbSd/4/mnzDldpLe+dxTJO2Z/JDxfftseo4dJ9xG0rteoPcUh1tU1XvWxu5fR5vQdj8Lu58tTALau+r1oO1I8tB9bTn0fuVlHfj0fZJW/7ZsTHJs/CVg+6yvodKcijxxx0bCDtyCILR+ROOODRm4BUGIG/LEHRsycAuCEDf8ug5/hCNypPsdD2h6gkVuqaysRHp6Oio+/jfSUposWTqzcqnWLZOtzkv1NJNtji+/xG1h6vG8bG5X43ZAXpeT6pWWlIzg7Q435Z3b8BimqdGkbHYst5y5uIGQ4ttXHrxeZoG0ZXegVVVXBi+Lhw3lfcLbyUOzMs1bvZbc7uc7UEH3zWhHi6rcy/Kz6fGpAZ3femAn6M6hrHAAGlk6hD0wnN2Sw0MfwMnCF6ht0dl0evanr2s0fLJuYyEcfCHuUd4HCpVVB9G27xAcOHAAaWlNGn3z3/l7m35ESmpa0GNVDlZVYtiJnUg5xyvyxC0IQtyQJ+7YiC7iO2P69OnQNA2TJk0ytum6jqKiIuTl5cHtdmPYsGHYtGnT4bZTEIRWiF/XmwJNRfCRgTtAzAP3unXr8Mwzz6Bv375k+4wZMzBr1iw8+eSTWLduHTweD4YPH46qqqogJQmCcLzS5OPWI/zEu7WJQ0xSycGDB3H11Vfj2WefxUMPBfytuq6jpKQE06ZNw6WXXgoAmD9/PnJycrBo0SLccsstEdfx04svItXZpGnypbYcaQFN1sXChtqTqC5nzaA+VxvzP2+bPYfur/iruU9brRcAXG1ZCM22dHo393FvfeKJoO0M52HmbbGmZdC6FB/3wY3r6bFt6b4W1gd7P/+KpHmYgCRPoA+dOdSva21DteDtz8xmZdFrp4bord9/kOQ5mG+e9wmHh2ZVde1wPu3/u/9Bku5x370k/eMTM0m6w7QZxvctxdNJHveIfzfzMZLmvng+10C9r3gfcA8+9+9zLZ+/s9m5eHHgWGtwfz4AuDt2Dln2L2+/FbRtrjzq76/btcv4XllLQy2r+PxNn0iIdL/jgZieuCdMmIALLrgA5557Ltm+bds2lJWVYcSIEcY2p9OJoUOHYs2aNYfXUkEQWh2RP22LVKIS9RP3kiVL8Pnnn2PdunWmvLKyMgBATg79T56Tk4Mff/yxxfLq6+tRXx/4j1xZWdnifoIgtD6a9etI9xWaiOqJe8eOHbjtttvw0ksvweUKbj/TuK1I103bmpk+fTrS09ONT35+fov7CYLQ+vAjEK8k7CfejU0govJxv/rqq7jkkktgVTRQn88HTdNgsVjwzTffoEuXLvj888/Rr18/Y5+LLroIGRkZmD9/vqnMlp648/Pzse/zt5CW2qT9cS8w8brykKWmUKzMuxrCWw1QH7fJa83LDuc7Zj5lixri1OTjDu21Dndeqt+Xe6k5JIwoANjoDy/u7/VV7QtaFl+yiodDBfPV+ysVPzUP08rPkcG1d1Nb1GvpoPFATD5tFuOj7rN3SNr1mxEk3dgm8L7CvmcryeP+Z+7bNnn0+bVTrnXY+8AXOuwrv59J2dw/HqIdQOi5Abw8fq+r17byYDXaDjivRR/3ss++Q3IK1e2DUX2wCn8Y0EV83IhSKjnnnHOwceNGsm3s2LHo0aMH/vrXv+KEE06Ax+NBaWmpMXB7vV6sXr0ajz76aItlOp1OOJ3OFvMEQWjdNPp1NERoF2kUW4lBVAN3amoqevfuTbYlJycjMzPT2D5p0iQUFxeja9eu6Nq1K4qLi5GUlITRo0cfuVYLgtAqkAk4sXHEZ07eeeedqK2txfjx47Fv3z4MHDgQq1atQmpqZD+HBEE4fvD5o1jlXZ64DQ574H7vvfdIWtM0FBUVoaio6LDK3fPfl1F/KG6xzUV1PNXryv3MXJezpNJ8rsmWL19K0jZ3oC6TdzqJxTlheqKpLrZs1+6lC43vPLa3jfu6M1jcZebf5cuiqX7q2nXUb2tqJ4vpXLXxS1o28/u62wc8ujz+NmdPiP4EgKQOgeN9B6mPm/cvjyvDsecV0A3KteXxtNvfOIGkuU+705+pz3vrDOrV7vxgSSCPe8Rv/wstey6tm8d15/MB1PuZe7y5l9q0HB67L3QWz2X3sv/P+M7jgKd2pB58Pu/A5Pf/YDVJJ2VnBNqdTX3cNdu+N75XhfBxyxN3bEisEkEQ4oZPb/pEuq/QhAzcgiDEDXnijg0ZuAVBiBt+vw5/hNp1pPsdDyRsPO5ftv4Pac0vNE1xhENY8XmeRvVanaV5vnp8yHoiqFsPEaM4WkxtCXGeutURel9T4WHmYfH40qGO5efM6w5RVrj+Nl27UG0J1w5eto3qv1oj1WUttYH1Mf0u9qI9zD0XFWHaGXUfRdOWaO/3CKmsqkJWl74t+rifXr0Z7gh93LUHq3DL0F7i44Y8cQuCEEdEKokNGbgFQYgbEqskNhJ24P55znTUOB0t5jlSA5Yobtnjdipu0eMWsm3PL6D72yMP6+pmIWVtbelyWLYcaq/6v5JnA2WnMfsfs4y5MtNZmtbF26LW5d1Bp2Tz0LZmOyAL68rCkKp127Lbkzwe1vWXlW8gFGqIWB7W1RTuNDWMHbBjN5K2tT/B+L599j9IXsfxfyLpcKFZueWvU1EgVOumW24ieX0epMd+edfDJG2x0+ngrnQqy6j3Gb/neFhX3ie8/7l98Ns5gTATmpVOzc8opBa+jG7MDphGy9r+WilJp7QP3O88RGzV9p8D3+uChzIQjTs2EnbgFgSh9eNDFHbAo9qSYwsZuAVBiBuicceGDNyCIMQN0bhjI2HtgCSsa2012ccUJlOFh8VkU4D5lHce6lKvqwl8N4VSDRMWk6Elh7A5hQsZy8oOGxpUOU9bPtV+zQ0LboFsMV1fGziUhRHlNjoTPtpuveZgkB1h7l9TqFDabovTTQ93BK6t1kjDyfJz1nys/3loVra/LyUQvsDyyzZa74EKkubT0k3XmofVVfL5ddZZWFwTrI9MIR+UtvB69Tr2d8Xr4mGJ+d+O0lYejladLl9ZXYOsEde1aAd8ZOUGuEL9nSjUVVfhrvNOFjsg5IlbEIQ4IkGmYkMGbkEQ4oYM3LFxGFO8BEEQDo+mVd71CD+HV9f1118PTdPI57TTTjvsc9i0aRP+8Ic/oHPnztA0DSUlJS3uN3v2bBQUFMDlcqF///744IMPYq4zYZ+4f162CDWHwrlybc6WHNA2ue+Vh4CN1setwj2z3DvNvdXOdtQvbc+ldX1Z/HRg3zSqDTuSabt52dzXzc/blRfwV9f/8i7J475tjYXrrP32f3R/FtbVmhKoy5aZS/dloWsPvE9DynLUdjfUUE2VXzse5pVr3Pb2hXR/Tyfj+64XniZ5eddR7/V3Mx8j6cJJk0mah2btcPcjxnfu0+77AA0J+/51fyNpm4v+mfFrr6aT2rG5AkroVABwZtBrl+yh95ytHb0+708M+NGtzE/ergf1abfrewJJ83tww5y3SbrNCYG2telOPeFV28uN7we97L2Twq/9xP3b3/4W8+bNM9IOR8tzRaKhpqYGJ5xwAi6//HJMnjy5xX2WLl2KSZMmYfbs2Tj99NPx9NNPY+TIkdi8eTM6duzY4jGhkCduQRDiRuRP25EP8KFwOp3weDzGp21b+o/vwIEDuPnmm5GdnY20tDScffbZ+PLLL4OU1sSpp56Kv//977jyyiuDLsM4a9Ys3HjjjfjjH/+Inj17oqSkBPn5+ZgzZ05M5yEDtyAIccMfxaDdPHOysrKSfNTFxsPx3nvvITs7G926dcNNN92E8vLALwNd13HBBRegrKwMK1aswPr163HKKafgnHPOwd69e0OUGhqv14v169djxAi6APWIESOwZs2amMqUgVsQhLjh9fnhbYzwc0jkzs/PR3p6uvGZPn16mFqaGDlyJBYuXIh33nkHM2fOxLp163D22WcbA/+7776LjRs34uWXX8aAAQPQtWtXPPbYY8jIyMC//vWvmM9xz5498Pl8yMmhYQFycnJQVlYWU5kJq3H7GhrgszR5axur61heIDSozt5YcJ3UbaW6HveE+1gchYbaxqB5jSFiLgA0zgkAWNvQuhrVsr1Ut2+opmWr59gS/LwdbTNC7Evr0ky+YloWfwek1Sje9lTm9eW+eQbvM4uia9fvo55uH1vmLIxDHDbFcw8AGveBk4bQ/uTxWLh/mi83psJjj/A+4Jp2QzXN9zfQHm6sa1TyopvYbY7NU0vSujKf3Mu05po9dN/6/VUhy/axtqnt5n+j6nsS/s6ElBmDxr1jxw7i425Jnli4cCFuueUWI/3GG2/giiuuMNK9e/fGgAED0KlTJ/z3v//FpZdeivXr1+PgwYPIzKTaf21tLbZu3Yrt27ejV69exva7774bd999d0RtB5qWdVTRdd20LVISduAWBKH10+jXYY1w4G48tF9aWlrYCTi///3vMXDgQCPdvn170z65ubno1KkTtmzZAgDw+/3Izc01raMLABkZGcjIyMCGDRuMbVwfD0a7du1gtVpNT9fl5eWmp/BIkYFbEIS4cbRcJampqUhNDT0js6KiAjt27EBubpMT55RTTkFZWRlsNhs6d+7c4jFdunSJuA3NOBwO9O/fH6WlpbjkkkuM7aWlpbjooouiLg+QgVsQhDjij2LgPpywrgcPHkRRURH+8Ic/IDc3Fz/88APuvvtutGvXzhhMzz33XAwaNAgXX3wxHn30UXTv3h27du3CihUrcPHFF2PAgAEtlu31erF582bj+86dO7FhwwakpKQYA/2UKVMwZswYDBgwAIMGDcIzzzyD7du3Y9y4cTGdT8IO3BaLxdDGQum9PnvoU/DV0TfONqZHcq2Ta88Uqql6mZ5uih/N6rI6AtpoYx3N40qxxU632Kto3RYHPW+9PqAxak6qTYZDC6FBArT/bSymCtfPebvANG6/V9Vz6Tn6WDvCvVNwhIhZY3Mx3ZPp31y/5bFfuGdfhcfT5n3Afdpc0/azdwqqBm5hMbPtyVQ7trrofeDPYn8b7J6zJwdi2KiaNAB42XuVBqZT+9nfHfeB+xX9nJ+T+r7HEiIc0q8VZMpqtWLjxo1YsGAB9u/fj9zcXJx11llYunSp8WSuaRpWrFiBadOm4YYbbsAvv/wCj8eDIUOGhJQ0du3ahX79+hnpxx57DI899hiGDh1qyC5XXHEFKioq8MADD2D37t3o3bs3VqxYgU6dOgUpNTQJO3ALgtD6+bUm4LjdbqxcuTLsfqmpqXjiiSfwxBNPRFx2586dEUmsvvHjx2P8+PERlxsKGbgFQYgbEqskNmTgFgQhbsjAHRsJO3Dbkl2GTmlj2pvqO+bamsZ0OZ+Xpnn8bUca1aVV7Znr3TzNNVie5jG2nWkBTZy3W2frN3Hvr7eSem65Z1zVJ50sPotmpzHJecwP7n3XuPdd9f/yGNkMrvNzjzhpBm9XGPj7CI6qNZs0bIZJw+b3RQgfN48Tw3VlrnFzbZlfW/W+8h6keXX7mMbtoH3gZe8+3F6+f+B6ca2dl11XQX3c/Dx1NnDWVwbeH/Fjab0h3lHpfvjCxLVX9xWaiGrmZFFRkSm6lsfjMfJ1XUdRURHy8vLgdrsxbNgwbNq06Yg3WhCE1kEsU96FGKa8n3jiidi9e7fx2bhxo5E3Y8YMzJo1C08++STWrVsHj8eD4cOHo6qqKkSJgiAcr/zaQaZaC1FLJTabjTxlN6PrOkpKSjBt2jRceumlAID58+cjJycHixYtItNPI6rH6TB+wnO7GpFKwkwNN+Xz6cnsJ7XVEZiGbZqWXkvLsjNphFsP+VJQzrRAXT72s9V7kNnmuGUsbN2BtBZGzuDw5cg4ul85r1DTylsoi0s6ajv1MD+RQ8ksTW1h+Urb+HXlS2uZJB2TjY5JLcrPdJOEwGyJPDQrn8bOLX+qPMLlCG4bbWT3QSO75/xsWntydqAtqrQBALUVVH7j9xj/23Fn0qXiQmFV5DerJfi07kY/oEU8czLi6ls9UT9xb9myBXl5eSgoKMCVV16J77//HgCwbds2lJWVkQhYTqcTQ4cOjTkCliAIrRt54o6NqJ64Bw4ciAULFqBbt274+eef8dBDD2Hw4MHYtGmTMQ+/pQhYP/74Y9Ay6+vrSVjGysrKaJokCMIxjM+vwyKukqiJauAeOXKk8b1Pnz4YNGgQCgsLMX/+fGMJoGgjYE2fPh33339/NM0QBKGVIAN3bByWHTA5ORl9+vTBli1bcPHFFwMAysrKjKAtQPgIWFOnTsWUKVOMdGVlJfLz8+Fs1waupCadkWudqu0u3HRtK7O6wUYtaElZbYIea69k04uZ5mdPojoot9FxknID0cT41HBu9/MzeyDXRTnqtHS+XJtmC90H1nQaxpKjKftrbqrf8un1vCwHs/D5lRCxpmvDMC1D56Dt1hys/xV93dGGXVfWDnc2y2fafag+4cfydxl8uTEOn8au2vK4ps3vA9O0dXaPcnugqrfb3fSe45o3twfWlNHFAxwp9HrUHwgcz0PEOtIi08N/rVglrY3DWkihvr4eX3/9NXJzc1FQUACPx4PS0lIj3+v1YvXq1Rg8eHDQMpxOpxGmMZJwjYIgtB5E446NqJ6477jjDlx44YXo2LEjysvL8dBDD6GyshLXXXcdNE3DpEmTUFxcjK5du6Jr164oLi5GUlISRo8efbTaLwjCMYyu6yYnTah9hSaiGrh/+uknXHXVVdizZw+ysrJw2mmn4eOPPzYiXN15552ora3F+PHjsW/fPgwcOBCrVq0KGxdXEITjE38UE2tEKgkQ1cC9ZMmSkPmapqGoqAhFRUWH06amslxJ0FxNGiaflm4KHRoCK/MRc48z9+SqWjGfYs01bu5R5mmOOzM9aB7Xc81T9dnUftY2dXmocJo291pzrZijKVP3NV4W60/Nxa4Vm/aveq/tIfz5AGBxsXbxKe8hpsBbkkNLbloSfZgwLe/GtXzFxx1qOjwAODNCP6jw0KzqNHazT5um+bJooZYFAwBXZqAf7Mn0WnjZ1HtT/7P7OSWX9qmNnYeK+nflrQ8eftfv85vmLITaV2giYWOVCILQ+pEn7tiQgVsQhLih+8mk1LD7Ck3IwC0IQtzQdT3il47ycjJAwg7c1ox2sCY3aYlcs7Wpvlmuc/KlybjXl2mbtnY07kqKoqv6aqiGx3Vn7iHneqPmojppUl628d3OdFIfX+KL6emNtaGX8VLL4z5uk8YdbSwTpQ9N2i87RwvzP5v6Xz2exz3hsUfCtNuSyvzU1sD+ljS6Aje/h7hP2xRjJSm4Tm1tk003sHYle2jdPO4JX25M9V7z2CPcp83vMX4f8XsypX1WoN4wcX14Xdxnn8T86/akQPA4HtLYpbzPaWDnpCJSSWwk7MAtCELrR/dHYQeUgdtABm5BEOJHFAM3ZOA2kIFbEIS44dd1aBFq137RuA0SduC2ZmTBmtKkh1qYrso9twSmm5q0y5SMkPVakgPappXp5eFiUZvKSmM6qhLXw5rOPLTM78zjQ/OYz1wPVjVZjWm/0Cwh09Yw8bj9ijeb+7R1G4tVwuK16FwDV/zVfBk5fk7cM87hXm2/XdH5eawRJ/OXs3xLEi1LZ3X7lT7j+jg/D1u7XJK2pNI4Hvw9jLrcGI+nzWOPcLimzT3mJJYM61+uYddV0Mic/O8spX27oHWZllBT/OMNtcE1bpk5GRsJO3ALgtD6EY07NmTgFgQhbvijWAEnwjWFjwtk4BYEIW6Ijzs2EnbgrvzwLehuJ4DQMUK4psdjNnNN25ZHNdhdrywnabUurgHak2mMYR7nxJXFvMNM39385OJAO1jMCR4rmftzVc0QABxptOzkzgEts+HbL2g7mCeZe6sbdnyLUFiU8+AeZq4V13z5IUnza2dNCfSZn/nkTfG2Wf9xbLmdadk5geP3rnqd5LW9iEao3Ll4MUnnj/0jSe9e9v+RdM6f/mZ8/3bOfJLXfRJdT/X9ibNIWmcxte3JLB66I3BPqmtEAub1K13sPlB92oA5PvqKCYG2Otjaj20LMkg699R8kub33Mq/LiPprPxAftaJVP/e/t7XxvfqxuD+cZk5GRsJO3ALgtD68fv1KKQSeeJuRgZuQRDihrycjI2EHbh1v98IM8mne1uU8I489KSVW8pcYWx3IZZFCxdGktftSKVLP3HbF62HhW1ldfGwrQ18GS87/bmtLp+l82nmJttdmKnmrG7Vmmi2JdKy+HnwPrTUq8t00bL4tbOGsQNGZc9kv7O5jc5k6XM5gxalsWXkuG3OaqdynJdZ/Pi19zcE2saXEzNJaMmhQyPwa8nlEdKualqWKewCu3ZWvp6sMpByOUiVfyxa8AFXBu7YSNiBWxCE1o9MwIkNGbgFQYgb8sQdGzJwC4IQN2TmZGwk7MDtbJsKl7vlJbXUZbz4kl489KrVy3RnpmW6WahKlO8LlMX0Q64BNlTTqcx82q+d1a0u/eStpMc2sCWr6itZuxlc21RtYkk51NZlCq3qpLbGcGEASJ/xkLAsbWtL7WmWumpWVuB6WR0sTG6Ipcia8iMPR5vkYeEG2B99asecoO1qymehWxUyCvNIWmfn2K4Hs0juYfcJ05br9gWudW0F3Zdr3ny5MQ63sKqWP17vgZ/p/erY+DNJt6mmdbuZjVE9r4ote+m+bQL3WKiBWY8irKs8cQdI2IFbEITWj0zAiQ0ZuAVBiBu+Rj90S4SLBTfKDJxmZOAWBCFu6H6fOUpkiH2FJhJ24LZl58N2aIp5kruC5KkXkOue/OJa2LRpHuY19YQOJK1OY2+soTqzydfKfNzc183JPLHA+M6XiWqoodqm3xvG5818yGSqPl9aK8wSYLbs9iFaDeiK91pLZtPnk+i0f2sWLYtr3Krf3JISWq/VmFed6+l8GTXdEuh/W05Hmsc8yO6OnWnZ3MftocerPvCMbqxs9i6jXd8TSLp+fxVJN1TT/esqAvn8XYeqfwPm+4DfRzw0qzqNnb+j4Zo219P3/3iApD0n0/cCB3cfDHqsqvPr3uDXWQbu2EjYgVsQhNaP7vdHMXCLVNKMDNyCIMQN3ecLvTAK21doQgZuQRDihq5HIZXoMnA3k7ADd9PSZU2hTblOHY3GzT3MpjCvmWyZKaUuvnyYKTaGydNMdWdelzs3oBG6Mql26aujGiH3o5tiUjBcmenGdy0lnWZa6GXWWTq0exrQk5T+dlNN27R0GV/Wiy0vRmKdhIjlAiCsNs/P028PeId5uNlw7TTdJywULsljS9Lx+4CHXrUn07L5tVTfq/C8mjLqjzbF5mG+bf5UqoZm5e9ouE+ba9pcX8/u4yFpNeYK94hblHcwFmvwO0w07thI2IFbEITWjwzcsRHuYcvEzp07cc011yAzMxNJSUk4+eSTsX79eiNf13UUFRUhLy8Pbrcbw4YNw6ZNm45oowVBaB00D9yRfoQmohq49+3bh9NPPx12ux1vvPEGNm/ejJkzZyIjI8PYZ8aMGZg1axaefPJJrFu3Dh6PB8OHD0dVVVXwggVBOC5pdpVE9hFXSTNRSSWPPvoo8vPzMW/ePGNb586dje+6rqOkpATTpk3DpZdeCgCYP38+cnJysGjRItxyyy28yKBUfrwa+qGYyKa4zQ7Fr5vkCpoHALY0pvey/9q7/ruKpNW6uFfaxvREZwbVQd3ZGSRtYT7jTc+9EchjMZ15XQ4WF8KVSetypNGlzdQl3Bq2babt4F52tryV96etCIWq/1rbsFgkTCuu+9/HJM3jn6t94q+lHm/usddc9Bw59rwCkrZkBY4/8On7JC/9vMtI+pe33yJpz6hrSHrvB6tJum2XAcb37a+VkryCa68k6Q1z3iZpX0PoeN1qDA53Jo0j40ihfaLGuwGAJBZrJ6U9XUJMXW6Mx9PmsUe4T5tr2v/85+ck3V6JFd6tHb1Wn/97i/G9JsSTst/viziuuv8wn7hfeeUVPP3001i/fj0qKirwxRdf4OSTTz6sMptZtmwZ7r33XmzduhWFhYV4+OGHcckllxj5VVVVuPfee7F8+XKUl5ejX79+ePzxx3HqqafGVF9UT9yvv/46BgwYgMsvvxzZ2dno168fnn32WSN/27ZtKCsrw4gRI4xtTqcTQ4cOxZo1a1oss76+HpWVleQjCMLxwa8plVRXV+P000/HI488coRa38TatWtxxRVXYMyYMfjyyy8xZswYjBo1Cp988omxzx//+EeUlpbixRdfxMaNGzFixAice+652LlzZ0x1RjVwf//995gzZw66du2KlStXYty4cfjzn/+MBQsWAADKysoAADk59D93Tk6OkceZPn060tPTjU9+fn6L+wmC0Pr4NQfuMWPG4G9/+xvOPffcoPscOHAAN998M7Kzs5GWloazzz4bX375ZchyS0pKMHz4cEydOhU9evTA1KlTcc4556CkpAQAUFtbi2XLlmHGjBkYMmQIunTpgqKiIhQUFGDOnDkxnUtUA7ff78cpp5yC4uJi9OvXD7fccgtuuukmU+UaX+JI103bmpk6dSoOHDhgfHbs2BHlKQiCcMxyaAJOJB8c5Qk4uq7jggsuQFlZGVasWIH169fjlFNOwTnnnIO9e/cGPW7t2rVEZQCA8847z1AZGhsb4fP54HJRidLtduPDDz+Mqa1Rady5ubno1asX2dazZ08sW9ako3k8TZpYWVkZcnMD/ujy8nLTU3gzTqcTTqd5fT81HjeP7UBOgOnOXCvmXmDuueXxuL1VAd01XHwQU11hSO8UqIvHIuGxv7n31bSWIzte1eadzIPM42+bPMupGSFaTeE6tIWVbfJxM42bHGvaQK8NL9sEu7aqP93Zrm3IQ/l1509zSex9hQrXkfk6nG1OoMea1phk6zPyOB8k7wDNs7lYzPck+tJffdcBAFn5AU2cx7PmccLV2COAud3t2fqXe72BPtvK4oi7lLUu60KEY9X1yDXu5gk4XE4NNoZEy7vvvouNGzeivLzcKO+xxx7Dq6++in/961+4+eabWzyurKwspMqQmpqKQYMG4cEHH0TPnj2Rk5ODxYsX45NPPkHXrl1jamtUI8/pp5+Ob775hmz79ttv0alTJwBAQUEBPB4PSksDL2+8Xi9Wr16NwYMHx9RAQRBaL7G4SvLz84m8On36dFO5CxcuREpKivH54IMPwrZl/fr1OHjwIDIzM8mx27Ztw9atW7F9+3ayvbi42Dg2nMrw4osvQtd1tG/fHk6nE0888QRGjx4NqzXyxUFUonrinjx5MgYPHozi4mKMGjUKn376KZ555hk888wzRuMnTZqE4uJidO3aFV27dkVxcTGSkpIwevTomBooCELrRY/CVdL8q2jHjh1ISwv8kmjpafv3v/89Bg4caKTbtw8dARNokoJzc3Px3nvvmfIyMjKQkZGBDRs2GNvatm36VefxeEzv8LjKUFhYiNWrV6O6uhqVlZXIzc3FFVdcgYIC6oyKlKgG7lNPPRXLly/H1KlT8cADD6CgoAAlJSW4+uqrjX3uvPNO1NbWYvz48di3bx8GDhyIVatWITU1+BTiFhvW1mOEdbW4QzhNuBTC4JY8boXjS1ipIThNoVWZj5RPN+ZhXjlpnQPyEZ/izi2PXBrhWBzB67KkUhmASyOwsWnTPAwsQ5U7NCbD6Db6R2PJoHZBPq2dSBJhpryb2s0whUJQw7qyUAZ82r8rjy4/xqfT27Npvgq/Z3hohDbd6bGNTOrjU8/VsK4cLmdw+H3Dl8/LOjEg6+hMouHLjZmXSaNlc8ufKo/8jx17TlZgX3vIpcv8pmXjQu4LIC0tjQzcLZGamhr1mHPKKaegrKwMNpuN2JxVunTpYto2aNAglJaWYvLkyca2VatWtagyJCcnIzk5Gfv27cPKlSsxY8aMqNrYTNRT3n/3u9/hd7/7XdB8TdNQVFSEoqKimBokCMLxQyxP3LGyd+9ebN++Hbt27QIAQ/b1eDzweDw499xzMWjQIFx88cV49NFH0b17d+zatQsrVqzAxRdfjAEDBrRY7m233YYhQ4bg0UcfxUUXXYTXXnsNb731FnnxuHLlSui6ju7du+O7777DX/7yF3Tv3h1jx46N6VyinvIuCIJwpPg17YCvv/46+vXrhwsuuAAAcOWVV6Jfv36YO3cugKaHzhUrVmDIkCG44YYb0K1bN1x55ZX44YcfgporAGDw4MFYsmQJ5s2bh759++KFF17A0qVLiVRz4MABTJgwAT169MC1116LM844A6tWrYKdLxYSIRJkShCEuOH3+6D9Sk/c119/Pa6//vqQ+6SmpuKJJ57AE088EVXZl112GS677LKg+aNGjcKoUaOiKjMUCTtw+yr3wtfYpHFyS5lqSdPChP40LXfF0nUVNJSlGlZT42FamYZt59PtU5gNj2mwal3hrIRcP7cnU2sct0E62mYY3/1V+2g7uM5vo8f69pXTfN6HSh/zZbosThaOtqLliVZG2co7BnVJNKClpcpC95HpD9kfuHaNv9AZabYT+pB03aGfy804e9CfwTXbvifpVGVmctV2uuRXVveTSLpqO+1Pbu00hWZ1BPqbX3dHGr3uaghYgIbzBWgYVwDY/t7XLdYDAO42tGx1ubGW2q1OYweo5U/VtAHg66rA32ydHlzD9jc2QNNbnuPB0X1hwgAfRyTswC0IQutH9/sATcK6RosM3IIgxA0ZuGMj4QZu/dAsq6rawE9wPjNNawj89NL8bDYj+3nN821uGpFOrQcA/I3BpRKettvoT0+rhf7Ut1ZTa1ZVffDIgxwLs0jZmVHfBmqxalBWpLezejUfi0Rooz85G6up5cwslQT2t2jMAgmarq8JbV/TGgPt5rKLZqP2S60huI0MAKzsWgIBGaa+hpbtraKzAivZddcOhr4vdCUscRWz4DlZfx9kq5qbpBI2k1CV56yW0LKBt57W3cBspQ2s3dXK/WzRaL18JiVfjZ23m0f5U2dEcsufKo/UH/qutzCDUm+oi3xAFqnEQNNb6s048tNPP0mgKUFohezYsQMdOnQAANTV1aGgoCBo8LlgeDwebNu2zRT343gj4QZuv9+PXbt2Qdd1dOzY0TRLSghOZWUl8vPzpc8iRPorOmLtL13XUVVVhby8PFiUX611dXXweoPHsmkJh8Nx3A/aQAJKJRaLBR06dDACyUQyS0qgSJ9Fh/RXdMTSX+np6aZtLpdLBuEYkQk4giAIxxgycAuCIBxjJOzA7XQ6cd999x2ROLvHC9Jn0SH9FR3SX4lDwr2cFARBEEKTsE/cgiAIQsvIwC0IgnCMIQO3IAjCMYYM3IIgCMcYCTtwz549GwUFBXC5XOjfv39Ei30eD0yfPh2nnnoqUlNTkZ2djYsvvti0gLOu6ygqKkJeXh7cbjeGDRuGTZs2xanFicX06dONtVGbkf6i7Ny5E9dccw0yMzORlJSEk08+GevXrzfypb/iT0IO3EuXLsWkSZMwbdo0fPHFFzjzzDMxcuRIbN++Pd5NizurV6/GhAkT8PHHH6O0tBSNjY0YMWIEqqsDQZJmzJiBWbNm4cknn8S6devg8XgwfPhwVFUFX9vweGDdunV45pln0LdvX7Jd+ivAvn37cPrpp8Nut+ONN97A5s2bMXPmTGRkZBj7SH8lAHoC8pvf/EYfN24c2dajRw/9rrvuilOLEpfy8nIdgL569Wpd13Xd7/frHo9Hf+SRR4x96urq9PT0dH3u3Lnxambcqaqq0rt27aqXlpbqQ4cO1W+77TZd16W/OH/961/1M844I2i+9FdikHBP3F6vF+vXr8eIESPI9hEjRmDNmjVxalXicuBA06o6bdu2BQBs27YNZWVlpP+cTieGDh16XPffhAkTcMEFF+Dcc88l26W/KK+//joGDBiAyy+/HNnZ2ejXrx+effZZI1/6KzFIuIF7z5498Pl8psU5c3Jyog4B2drRdR1TpkzBGWecgd69ewOA0UfSfwGWLFmCzz//HNOnTzflSX9Rvv/+e8yZMwddu3bFypUrMW7cOPz5z3/GggULAEh/JQoJFx2wGU2jAeV1XTdtO96ZOHEivvrqK3z44YemPOm/Jnbs2IHbbrsNq1atChmJTvqrCb/fjwEDBqC4uBgA0K9fP2zatAlz5szBtddea+wn/RVfEu6Ju127drBarab/3uXl5ab/8sczf/rTn/D666/j3XffNYLTA02B5gFI/x1i/fr1KC8vR//+/WGz2WCz2bB69Wo88cQTsNlsRp9IfzWRm5uLXr16kW09e/Y0jAFyfyUGCTdwOxwO9O/fH6WlpWR7aWkpBg8eHKdWJQ66rmPixIl45ZVX8M4776CgoIDkFxQUwOPxkP7zer1YvXr1cdl/55xzDjZu3IgNGzYYnwEDBuDqq6/Ghg0bcMIJJ0h/KZx++ukme+m3336LTp06AZD7K2GI55vRYCxZskS32+36c889p2/evFmfNGmSnpycrP/www/xblrcufXWW/X09HT9vffe03fv3m18ampqjH0eeeQRPT09XX/llVf0jRs36ldddZWem5urV1ZWxrHliYPqKtF16S+VTz/9VLfZbPrDDz+sb9myRV+4cKGelJSkv/TSS8Y+0l/xJyEHbl3X9aeeekrv1KmT7nA49FNOOcWwux3vAGjxM2/ePGMfv9+v33fffbrH49GdTqc+ZMgQfePGjfFrdILBB27pL8q///1vvXfv3rrT6dR79OihP/PMMyRf+iv+SFhXQRCEY4yE07gFQRCE0MjALQiCcIwhA7cgCMIxhgzcgiAIxxgycAuCIBxjyMAtCIJwjCEDtyAIwjGGDNyCIAjHGDJwC4IgHGPIwC0IgnCMIQO3IAjCMYYM3IIgCMcY/z/r+0w123XZnAAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -183,7 +222,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -197,7 +236,7 @@ "(
,
)" ] }, - "execution_count": null, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -208,12 +247,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ - "fb_model = coffeine.make_filter_bank_classifier(\n", - " names=frequency_bands.keys(),\n", + "fb_model = make_filter_bank_classifier(\n", + " names=list(X_df.columns),\n", " method='riemann',\n", " projection_params=dict(scale=1, n_compo=60, reg=0),\n", " estimator=LogisticRegression(solver='liblinear', C=1e7)\n", @@ -222,7 +261,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -231,7 +270,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -240,14 +279,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Mean classification accuracy: 0.89\n" + "Mean classification accuracy: 0.84\n" ] } ], @@ -258,9 +297,21 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "coffeine", "language": "python", - "name": "python3" + "name": "coffeine" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" } }, "nbformat": 4, diff --git a/notebooks/filterbank_kernel_classification_bci.ipynb b/doc/tutorials/filterbank_kernel_classification_bci.ipynb similarity index 73% rename from notebooks/filterbank_kernel_classification_bci.ipynb rename to doc/tutorials/filterbank_kernel_classification_bci.ipynb index 3d6753d..42c2926 100644 --- a/notebooks/filterbank_kernel_classification_bci.ipynb +++ b/doc/tutorials/filterbank_kernel_classification_bci.ipynb @@ -20,7 +20,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -30,7 +30,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -49,12 +49,12 @@ "from mne.io import concatenate_raws, read_raw_edf\n", "from mne.datasets import eegbci\n", "\n", - "import coffeine" + "from coffeine import compute_coffeine, make_filter_bank_transformer" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -78,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -112,67 +112,101 @@ "source": [ "## Building a coffeine data frame of covariances per frequency\n", "\n", - "In the following, we compute covariances based on pre-defined frequencies and show how to make a coffeine data frame from them." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "frequency_bands = {\n", - " \"theta\": (4.0, 8.0),\n", - " \"alpha\": (8.0, 15.0)\n", - "}\n", "\n", - "\n", - "def extract_fb_covs(epoch):\n", - " features, meta_info = coffeine.compute_features(\n", - " epoch, features=('covs',), n_fft=1024, n_overlap=512,\n", - " fs=epochs.info['sfreq'], fmax=35, frequency_bands=frequency_bands)\n", - " features['meta_info'] = meta_info\n", - " return features\n" + "In the following, we compute covariances based on pre-defined frequencies and show how to make a coffeine data frame from them. This was previously complicated, now coffeine provides the API for it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "As this is event-related data and not subject-level data as in [Sabbagh et al 2020](https://www.sciencedirect.com/science/article/pii/S1053811920303797), we need to loop over epochs." + "As this is event-related data and not subject-level data as in [Sabbagh et al 2020](https://www.sciencedirect.com/science/article/pii/S1053811920303797), we need to loop over epochs. Luckily, coffeine does this for us. We now get the pandas data frame where each columns is an object array of covariances, which is represented as a list of covariances, leading to an object array type." ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "labels = []\n", - "features = []\n", - "for i in range(len(epochs)):\n", - " epoch = epochs[i]\n", - " labels.append(list(epoch.event_id.keys())[0])\n", - " feature = extract_fb_covs(epoch)\n", - " features.append(feature['covs'])" - ] - }, - { - "cell_type": "markdown", + "execution_count": 6, "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
alpha1alpha2
0[[9.899550941533323e-11, 1.0150193223596802e-1...[[1.0496460732612292e-10, 1.182282705492182e-1...
1[[9.709858344182261e-11, 8.928610694895676e-11...[[9.006992581133795e-11, 8.001210027471314e-11...
2[[1.6005797216165005e-10, 1.7120265854899606e-...[[1.2931611036887622e-10, 1.4271783164176122e-...
3[[1.0282494751586464e-10, 1.0768228603843814e-...[[1.7453066588408227e-10, 2.1678207719155818e-...
4[[2.029473693821182e-10, 2.0201658837032425e-1...[[1.955097750980857e-10, 1.9793252865855997e-1...
\n", + "
" + ], + "text/plain": [ + " alpha1 \\\n", + "0 [[9.899550941533323e-11, 1.0150193223596802e-1... \n", + "1 [[9.709858344182261e-11, 8.928610694895676e-11... \n", + "2 [[1.6005797216165005e-10, 1.7120265854899606e-... \n", + "3 [[1.0282494751586464e-10, 1.0768228603843814e-... \n", + "4 [[2.029473693821182e-10, 2.0201658837032425e-1... \n", + "\n", + " alpha2 \n", + "0 [[1.0496460732612292e-10, 1.182282705492182e-1... \n", + "1 [[9.006992581133795e-11, 8.001210027471314e-11... \n", + "2 [[1.2931611036887622e-10, 1.4271783164176122e-... \n", + "3 [[1.7453066588408227e-10, 2.1678207719155818e-... \n", + "4 [[1.955097750980857e-10, 1.9793252865855997e-1... " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "We can now make the pandas data frame where each columns is an object array of covariances, which we can represent as a list of covariances." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "X_cov = np.array(features)\n", - "X_df = pd.DataFrame(\n", - " {band: list(X_cov[:, ii]) for ii, band in enumerate(frequency_bands)})" + "X_df, feature_info = compute_coffeine(epochs, frequencies=('ipeg', ['alpha1', 'alpha2']))\n", + "X_df.head()" ] }, { @@ -187,7 +221,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -216,7 +250,7 @@ "(
,
)" ] }, - "execution_count": null, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -227,21 +261,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ - "filter_bank_transformer = coffeine.make_filter_bank_transformer(\n", - " names=list(frequency_bands),\n", + "filter_bank_transformer = make_filter_bank_transformer(\n", + " names=list(X_df.columns),\n", " method='riemann',\n", " kernel='gaussian',\n", + " vectorization_params=dict(metric='logeuclid'),\n", " projection_params=dict(scale=1, n_compo=60)\n", ")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -255,20 +290,20 @@ " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'theta'),\n", + " 'alpha1'),\n", " ('pipeline-2',\n", " Pipeline(steps=[('projcommonspace',\n", " ProjCommonSpace(n_compo=60,\n", " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'alpha')])),\n", + " 'alpha2')])),\n", " ('kernelsum', KernelSum())])In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + " 'alpha2')])
alpha1
ProjCommonSpace(n_compo=60, reg=1e-05, scale=1)
Riemann(metric='logeuclid')
GaussianKernel()
alpha2
ProjCommonSpace(n_compo=60, reg=1e-05, scale=1)
Riemann(metric='logeuclid')
GaussianKernel()
passthrough
KernelSum()
" ], "text/plain": [ "Pipeline(steps=[('columntransformer',\n", @@ -320,24 +357,24 @@ " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'theta'),\n", + " 'alpha1'),\n", " ('pipeline-2',\n", " Pipeline(steps=[('projcommonspace',\n", " ProjCommonSpace(n_compo=60,\n", " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'alpha')])),\n", + " 'alpha2')])),\n", " ('kernelsum', KernelSum())])" ] }, - "execution_count": null, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -348,7 +385,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -357,22 +394,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": null, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaMAAAGkCAYAAACckEpMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAABEsElEQVR4nO3df3TU9Zk3/Pf8nkwyGQwkmYkJEeSHhQBWoEhqBVFym209Wrx3afXuwtmud63oLYfucRd8do17WuLaW27aB8uWrofiqSzuXaV1Hy2QfZRQH266AeGQAkWUAEHyAwiZmfyan9/nD5qpkcx1zUDwO8D7dc6c1lyTmU8+8525MuT7nstiGIYBIiIiE1nNXgARERGbERERmY7NiIiITMdmREREpmMzIiIi07EZERGR6diMiIjIdGxGRERkOjYjIiIyHZsRERGZLueb0U9+8hOMGzcObrcbM2fOxG9/+1uzlzREXV0dLBbLkIvf7zd1Tbt27cIDDzyAsrIyWCwW/OpXvxpSNwwDdXV1KCsrQ15eHubPn49Dhw7l1BqXLl16yb7eeeedn+sa6+vrMXv2bHi9XpSUlOChhx7C0aNHh1zH7L3MZI25sJfr16/H9OnTUVhYiMLCQsydOxe/+c1vUnWz9zGTNebCPn5WfX09LBYLli9fnvpaLuzl5cjpZvT6669j+fLlePbZZ7F//3585StfQW1tLU6dOmX20oaYOnUq2traUpfm5mZT19Pb24sZM2Zg3bp1w9ZffPFFrFmzBuvWrUNTUxP8fj8WLlyIcDicM2sEgPvvv3/Ivr7zzjuf2/oAoLGxEcuWLcOePXvQ0NCAeDyOmpoa9Pb2pq5j9l5mskbA/L0sLy/HCy+8gL1792Lv3r1YsGABHnzwwdSLpNn7mMkaAfP38dOampqwYcMGTJ8+fcjXc2EvL4uRw770pS8Zjz/++JCv3Xbbbcbf/d3fmbSiSz333HPGjBkzzF5GWgCMrVu3pv47mUwafr/feOGFF1JfGxgYMHw+n/HP//zPJqzw0jUahmEsWbLEePDBB01ZTzqdnZ0GAKOxsdEwjNzcy8+u0TBycy8NwzBuuukm41/+5V9ych8HDa7RMHJrH8PhsDFx4kSjoaHBmDdvnvH0008bhpGbx2SmcvadUTQaxb59+1BTUzPk6zU1Ndi9e7dJqxresWPHUFZWhnHjxuEb3/gGjh8/bvaS0mppaUF7e/uQfXW5XJg3b17O7evOnTtRUlKCSZMm4bHHHkNnZ6ep6wkGgwCAoqIiALm5l59d46Bc2stEIoEtW7agt7cXc+fOzcl9/OwaB+XKPi5btgxf/epXcd999w35ei7uZabsZi8gnXPnziGRSKC0tHTI10tLS9He3m7Sqi41Z84cvPrqq5g0aRI6Ojrw/e9/H9XV1Th06BBGjx5t9vIuMbh3w+3ryZMnzVjSsGpra/Hnf/7nqKysREtLC/7+7/8eCxYswL59++ByuT739RiGgRUrVuCuu+5CVVUVgNzby+HWCOTOXjY3N2Pu3LkYGBhAQUEBtm7diilTpqReJHNhH9OtEcidfdyyZQs++OADNDU1XVLLtWMyGznbjAZZLJYh/20YxiVfM1NtbW3q/0+bNg1z587Frbfeik2bNmHFihUmrkyW6/u6ePHi1P+vqqrCrFmzUFlZibfffhuLFi363Nfz5JNP4uDBg3j//fcvqeXKXqZbY67s5eTJk3HgwAF0d3fjjTfewJIlS9DY2Jiq58I+plvjlClTcmIfW1tb8fTTT2PHjh1wu91pr5cLe5mtnP1nujFjxsBms13yLqizs/OSrp9L8vPzMW3aNBw7dszspQxr8Ey/a21fA4EAKisrTdnXp556Cm+99Rbee+89lJeXp76eS3uZbo3DMWsvnU4nJkyYgFmzZqG+vh4zZszAj370o5zax3RrHI4Z+7hv3z50dnZi5syZsNvtsNvtaGxsxI9//GPY7fbUfuXCXmYrZ5uR0+nEzJkz0dDQMOTrDQ0NqK6uNmlVukgkgiNHjiAQCJi9lGGNGzcOfr9/yL5Go1E0Njbm9L6eP38era2tn+u+GoaBJ598Em+++SbeffddjBs3bkg9F/ZSW+NwzNjL4RiGgUgkkhP7mM7gGodjxj7ee++9aG5uxoEDB1KXWbNm4dFHH8WBAwcwfvz4nN1LlUknTmRky5YthsPhMF555RXj8OHDxvLly438/HzjxIkTZi8t5Xvf+56xc+dO4/jx48aePXuMr33ta4bX6zV1jeFw2Ni/f7+xf/9+A4CxZs0aY//+/cbJkycNwzCMF154wfD5fMabb75pNDc3G9/85jeNQCBghEKhnFhjOBw2vve97xm7d+82WlpajPfee8+YO3eucfPNN3+ua/zud79r+Hw+Y+fOnUZbW1vq0tfXl7qO2XuprTFX9nLlypXGrl27jJaWFuPgwYPGqlWrDKvVauzYscMwDPP3UVtjruzjcD59Np1h5MZeXo6cbkaGYRgvv/yyUVlZaTidTuOOO+4YcspqLli8eLERCAQMh8NhlJWVGYsWLTIOHTpk6pree+89A8AllyVLlhiGcfH0z+eee87w+/2Gy+Uy7r77bqO5uTln1tjX12fU1NQYxcXFhsPhMMaOHWssWbLEOHXq1Oe6xuHWB8DYuHFj6jpm76W2xlzZy7/6q79KPY+Li4uNe++9N9WIDMP8fdTWmCv7OJzPNqNc2MvLYTEMw/j83ocRERFdKmf/ZkRERDcONiMiIjIdmxEREZmOzYiIiEzHZkRERKZjMyIiItNdE80oEomgrq4ubRI6F3CNI+daWCfXOHKuhXVyjVffNZEzCoVC8Pl8CAaDKCwsNHs5w+IaR861sE6uceRcC+vkGq++a+KdERERXd/YjIiIyHQ5N88omUzizJkz8Hq9qfkboVBoyP/mIq5x5FwL6+QaR861sE6u8fIYhoFwOIyysjJYrcp7n6v1oXcvv/yyccsttxgul8u44447jF27dmX0fa2trWk//JEXXnjhhZdr79La2qq+9l+Vd0avv/46li9fjp/85Cf48pe/jJ/+9Keora3F4cOHMXbsWPF7vV4vAODkB7egsGD4TtqTHFDXcDwmTzXsMxxi/W9e/u9i/Rf/Y626hvaER6zfYu8T6xeSNrGeZ0moazgRl/+QmTDk31ZudwXF+oWkugQcjMjzXu5wnRHrN9nkfQCAuCEvJJQ0xHp30inWPZa4uga/XT7m+pPy4/VJQh5dPcGhryGq7MPufr9Yb4+PEutf9uiD5PqT8nMrzxoT60lDn0jqVW5DeSjQqez1LfaougbNqbi8D13K60NEeY0CgN8PyIMUFxUeEOs2yM+LvAyGwzqECbLhniS+OPts6nVdclWa0Zo1a/Dtb38bf/3Xfw0AWLt2LbZv347169ejvr5e/N7Bf5orLLCi0Dv8C6U1qf+pq0BpRhblRdjmTD/SFwC8adb2aeGEfB2vXa7HlJ/TY5EPJADIj8sv5Foz8rq0NapLgMcpr0G7j0KbvtcxZSuSSjOKq3utr6FQeQW0K2vIV46XQoe+hoiyDx67/Fi4Y/JLQkG+vgbt+elR/rkmk2ZUoNyGQ7mJ3it8bmaiIC7fRiQhPxY2Q/8lzG2XG1aB8jqlNSPPFTajQZmMPB/xExii0Sj27duHmpqaIV+vqanB7t27L7l+JBJBKBQaciEiohvLiDejc+fOIZFIXDJvvbS09JK57ABQX18Pn8+XulRUVIz0koiIKMddtVO7P/u2zDCMYd+qrVy5EsFgMHVpbW29WksiIqIcNeJ/MxozZgxsNtsl74I6OzsvebcEAC6XCy6X/MdEIiK6vo34OyOn04mZM2eioaFhyNcbGhpQXV090ndHRETXgatyNt2KFSvwrW99C7NmzcLcuXOxYcMGnDp1Co8//njGt9GTHEh7Vk6BVT7TDQBCyllFo639Yj3vrHyamNeqnx3ih3zqdkdCPhPGp5y+GkMGp7oo8q3yhypqJ8uNyuDXmUKrfCq+W/kx+pRTogHAZ5VPze6CvJfnE/livchxQV1Dn7JZbuWMvMORm8X6FMcpdQ0u5T6ODJSJ9faIT6wvLjysrqFVOUNzQDlLzGuRHysAKLXJL11nEvIx41SO7AxOElV/kx9llU8P7zXkY7YQeoRlQDmNvkhZ5FnlrMLSDM5klUQzOItu0FVpRosXL8b58+fxj//4j2hra0NVVRXeeecdVFZWXo27IyKia9xV+zigJ554Ak888cTVunkiIrqO8INSiYjIdGxGRERkOjYjIiIyHZsRERGZjs2IiIhMx2ZERESmy7lJr4OOxyxpx0BogVYAuFvJxf6qt1isdz4oB866MkjFbe+ZKta1AOGJuPwxSZMzmG/jtcjziI7G5HlH2m8rHUpoDgBGWeXwrxZp1T9IH/goLj8gRVb5oJmtzG0KZ3DMaY7H5adbV7xArL8/IAdSAcCjhJjvKzgk1h1e+dHYPXDpR3p9VrW7Q6xrwdyWmP6Iv9t/k1if7eoU6zGLfLwkDP0B71Wu0hyVZ0d1K/OMDvXJIWgAcFnl14CTykylCrscMD6uv8TALcxV60lkEh++iO+MiIjIdGxGRERkOjYjIiIyHZsRERGZjs2IiIhMx2ZERESmYzMiIiLT5WzOqM9wwJJmSJc2GA/Qc0QP5feI9bW/kM/PH6jWsxD/rfCIWP/3Xnm+05fzToj1ozF9XHt7fLRYr3afFevBpBym8AgZg0FFdvnx0oYMtifkLBQAzHCeF+u/i8iZj/aYnOEZ75RzK4A+RHCyQ84A1V8YL9a/NrZZXYPHIj9eSz58RKx39crZl+13vKKuoaFvrHwfSp5Ky0oBwKKC42L9aCxPrH8cKxHr1e6T6hqCymC7yQ75mMl3yRmc25xt6hoae28T66U2ecDfb/vlYYtTnO3qGtzCMRdTjsdP4zsjIiIyHZsRERGZjs2IiIhMx2ZERESmYzMiIiLTsRkREZHp2IyIiMh0FsPIYHDH5ygUCsHn82Hqd1bD5hx+KFHeWX1GhjaPqFzJEe38l5+J9dvrn1DXcPMv5SzE4efkPMaoZjkGFpysZ3yMPHmvCo7K+xApkg8P97nhZ04NWYOSZot6lUMwg1+ZfMfk+oUpcr3wC3JOqf93Y9Q1GEr0LP+M/HMmle8f9ZGcGQGAvlLl8fyLbvk+PHImzP6PReoaPv6vcv7NKJCH5HgPO9X7KN4vZ5FO1ci3kf+JfNwm5JjSRcrL0Ogj8qygmEc+sAv+9+/UJXT/5VyxblFygp1fkuujD+hPvrg7/V4mogM49LNVCAaDKCy8stlpREREVx2bERERmY7NiIiITMdmREREpmMzIiIi07EZERGR6diMiIjIdDmbM9p/qARe7/C90mvVsy1dSgZgQAmF/OVLK8T6gZU/UddwJNon1vuUAM5kh/xDxAw9b9WrXOecMktonLIGt0UfiXUkKt/GJIf8eAaTer7GZ5VzJRFDzracSchrmODQf05tnQ7I9/H9zrvE+nfG/FZdg1eZH/OL0Ayx3pMYPts3aHlRk7qGGOQ1dCuHrfYzAIDDor8GSAaUlz2vVZ9XZlMezwFDzgGejsvHVK8hPzcB4FhUntP1FwWnxXqXcswW2/SZaQlhL0PhJG6+7bQ5OaO6ujpYLJYhF79f3jAiIrqxXZVJr1OnTsV//Md/pP7bZtN/yyAiohvXVWlGdrud74aIiChjV+UEhmPHjqGsrAzjxo3DN77xDRw/nv4z2iKRCEKh0JALERHdWEa8Gc2ZMwevvvoqtm/fjp/97Gdob29HdXU1zp8f/oMo6+vr4fP5UpeKioqRXhIREeW4EW9GtbW1ePjhhzFt2jTcd999ePvttwEAmzZtGvb6K1euRDAYTF1aW1tHeklERJTjrsrfjD4tPz8f06ZNw7Fjw3/Gv8vlgsulnz5IRETXr6seeo1EIjhy5AgCgcDVvisiIrpGjfg7o7/5m7/BAw88gLFjx6KzsxPf//73EQqFsGTJkqxupz3hQTgxfK/0Qw6TAsD2nqli/b8VHhHr2mC8I9/T1/AFp0esr+kaL9bdBYfE+scxfeBbd0Jew22uNrHeIs8Hg9cqDzm7SA7v7Y3KgdVwUg7LAcBslzwcb2d/mVg/2CcPOrzHe1hdQ8KQ93qa84JYPxSUf2FzjNHDoGFDDmJuaZkp1kNh+Wf427v3q2t4p1f+OU5H5QF9AYe8TwCw2Csft9v7fOptSG51yMcTAIST8nFdbJOD1gNK6L3Crr/GvBWUj+suj/w69k7vJLG+0POhugYpsx5O6sH8QSPejE6fPo1vfvObOHfuHIqLi3HnnXdiz549qKysHOm7IiKi68SIN6MtW7aM9E0SEdF1jh+USkREpmMzIiIi07EZERGR6diMiIjIdGxGRERkupwdrnfkcPrheh3KQDgAKLPL5/hv65VPNX9u5yKx/sv/sk5dQ2PvbWJ9RZGcAdjRJ/+cWm4FAI7H5dxIa2y0WJ+XJ38809GYngH6OFoi1u/MaxHrZTb9ED0Zl8eUFNnkwJT2W1kwqY9BKbXJmYqPYvLguoQyrM1tkY9pALApg+2syuC6mCHvxKGInGsBgNvd8kA3v00eOtca15/fn8RHifVpzk6xHlYyPkVWfa+1BM0HEXlyQWdcfu6ci3kzWIN8zMzNH/6TbwZNcQTFeiavtR5hr3rCScye2mHOcD0iIqJssRkREZHp2IyIiMh0bEZERGQ6NiMiIjIdmxEREZmOzYiIiEx31Se9Xq4LSRtiyeF7pc+qDNkBcCIuT4/9ct4JsT6qWd6ayV/T53Ro84h29Mnn3dd45J+zTY9CoNjWL9Yr7HKOyGZRcgxufZ5RsU3OEVXa5fs4HpfrAFCu5Mq6kvJtaLNpKu36MTegRPamO+V8zVOnF4j1Ff4GdQ0+q3wf/+vs3WK9Oybn0v7nzTvUNbTLS8DhqJyfKbb1qvdxp/uscg358e6IKbOIMsgZea1y9uwud4dYjxntYv1YvEBdgzav7C73gFg/qTy3tLymxpbF2x2+MyIiItOxGRERkenYjIiIyHRsRkREZDo2IyIiMh2bERERmY7NiIiITJezOaM8SwKeNLNXYkqGAAAmO+Tz44/G5BxScLIclogZes7o49gYsT7bJc9c0XJEAbueQ0jEe8S6NqdnjF2uB5NRdQ0DhjYTRd7LCmVOEAD0KhmfYqv8e1eRkl2zZXDMeZX76FL2appXngM0Eqq9H4l1hzIzqTWh//6qZXRG28JiXctrAUB7QskBOuTjVsvfea1X/tJ4WtmrXmWm0uGBm9X7cCvH7dmE/BpTZpPXEE7qOSOHkEXM5t0O3xkREZHp2IyIiMh0bEZERGQ6NiMiIjIdmxEREZmOzYiIiEzHZkRERKZjMyIiItNlnezatWsXfvjDH2Lfvn1oa2vD1q1b8dBDD6XqhmHg+eefx4YNG3DhwgXMmTMHL7/8MqZOnZrV/ZyIFyI/LgfXJF5LUKy3x0eLdSNPDlr2ZhB61QZfHY/LdS2YpwVaAaBcCcZ+1C//PuKxhMS6Tc+Cwm2RA8RnE3I9rIQDAT2UGlHW4LXK3z+QweMdTGjHq1xvDpeL9SKb/niX2OVAqc0i/xzaMdtllYe1AYBfCbWeT8h73Rofpd6Hxm3pFutdiTyxnoD+c8YM+blzNpEv1kNJt1jvymC4ntcmrzOcZkDpoHPKYxGF/OEAAOC1pA/e9ii3/2lZvzPq7e3FjBkzsG7dumHrL774ItasWYN169ahqakJfr8fCxcuRDgsH6BERHTjyvqdUW1tLWpra4etGYaBtWvX4tlnn8WiRYsAAJs2bUJpaSk2b96M73znO1e2WiIiui6N6N+MWlpa0N7ejpqamtTXXC4X5s2bh927dw/7PZFIBKFQaMiFiIhuLCPajNrb2wEApaWlQ75eWlqaqn1WfX09fD5f6lJRUTGSSyIiomvAVTmbzvKZT3E1DOOSrw1auXIlgsFg6tLa2no1lkRERDlsREdI+P1+ABffIQUCgdTXOzs7L3m3NMjlcsHl0s/YICKi69eIvjMaN24c/H4/GhoaUl+LRqNobGxEdXX1SN4VERFdR7J+Z9TT04OPPvrTgK6WlhYcOHAARUVFGDt2LJYvX47Vq1dj4sSJmDhxIlavXg2Px4NHHnkkq/tJGFYk0pzHn2+NqN9/NFYo1qvdZ8V6wVF5INy5+7SBccBtrjaxfjxaItYr7PI/WWqD8QA9RzRfyVO1yLO7MlKqDMfrSspZhBOxIvU+bnWcF+sfx24S6zElA5Rv0YcIepTjsswm19v65WN2bHGXuoYyJWe06tSDYj0YlfM3P771dXUNuweG/1eQQVqWyaFkwgBgtvuUWB8w5MfzUEQeXPcVz8fqGjRFtj6xPsEhn6wVTsqPBQAMJOXXIaeSK+tIyFkmbwa5sqSQ8ZNqn5V1M9q7dy/uueee1H+vWLECALBkyRL8/Oc/xzPPPIP+/n488cQTqdDrjh074PV6s70rIiK6QWTdjObPnw9DGAtssVhQV1eHurq6K1kXERHdQPjZdEREZDo2IyIiMh2bERERmY7NiIiITMdmREREphvRT2AYSbe7gvC6hu+V+mQZvcsGk+nPCASASJFcH+fQV6FldOblyTkiW5qPUBo0xq7njLR5RNoaxznkHEIwKc9cAoCOhLxX5TY5K1GWp+droOQZyu3yPgSTcrbFozwWAOCwyEddUpl/U1NyWKxPVnIpF9cgr/NrxQfFelSZHeW16sd9tbtDrCeEs3EBIJNom5byK1OeGkX5H4n1Ypv+qTAxQz5mupJxpS7v9egM5ld1GnJkxqfM6Rrj6hXr2pwwAHBY0v8coQxeJwfxnREREZmOzYiIiEzHZkRERKZjMyIiItOxGRERkenYjIiIyHRsRkREZLqczRldSAKxNKeoj8qghXYk5Ct5lJkp7nPy+fVu4dz6QV5lvo02c2muW/7+YFKfsWPLfJxImvuQc0Q+qz5z5VxCzktoeaqOuJzXAIBSm1Osdyl71a1kPrzKTCZAzyqNscpr/CA0Vqz/l3w5hwToOaAj/WVivTcu52sWe/U5P2FlHzoS8j54rXrSyGeTn9/dSsbnXEJOKrkzmF+lZXDcynFtg5y3clv0fRgw5L30Wd1i/XRcfn4X2/TXOSlvFTOYMyIiomsImxEREZmOzYiIiEzHZkRERKZjMyIiItOxGRERkenYjIiIyHRsRkREZLqcDb0ejATgcQ4/IavQOqB+/yhrn1gvssthL2XGGI5EMwlzycG6j6MlYr3Y1iLWBwxtxBjgVsK9pUqYUxuMpwVaAeBWZUDfvogcMGyN+9X7mOg4K9ZPxMeI9YQy+C6c1H9O7fGI2YNi/XhQXuPh0fo+jLLJw9Ja+24S6+cH8sX6mWI5qAkAHQk5zP1JXF5Dd8Kj3sd8z4di/XxSPuba4z6x7rK0qWvoSMj3YbXIzx0n5Oemtk8AEEzIofOWuPxa2RyRQ9B+e7e6hlFCuL8nrh8vg/jOiIiITMdmREREpmMzIiIi07EZERGR6diMiIjIdGxGRERkOjYjIiIyXdY5o127duGHP/wh9u3bh7a2NmzduhUPPfRQqr506VJs2rRpyPfMmTMHe/bsyep+7nCdgdc1fK90ZzAwTj6DH+hQhmtFvfL58ZMc+iL2RuXBV3fmyTmiSrt2H3rW6WxC3omupHwf5TZ5n7TBeICeI5rpkvepwt6h3ofLIv9eVWo7L9b7DPnx9lmHz7x9WsSQs2sO5Xe/uSXy8TDNpWdfvBb55/jSKPk+1NtXhvcBwGhbWKyPd4TEujaUDgCiyuNVruQIi5UcYpn63AMq7PJtnE3IA/66kvJxb8vg+e1VMpdlNvm4LfXIzy1tgCAgv9aGsugwWb8z6u3txYwZM7Bu3bq017n//vvR1taWurzzzjvZ3g0REd1Asn5nVFtbi9raWvE6LpcLfr+eFiciIgKu0t+Mdu7ciZKSEkyaNAmPPfYYOjs70143EokgFAoNuRAR0Y1lxJtRbW0tXnvtNbz77rt46aWX0NTUhAULFiASGf7zi+rr6+Hz+VKXioqKkV4SERHluBH/oNTFixen/n9VVRVmzZqFyspKvP3221i0aNEl11+5ciVWrFiR+u9QKMSGRER0g7nqn9odCARQWVmJY8eODVt3uVxwuVxXexlERJTDrnrO6Pz582htbUUgELjad0VERNeorN8Z9fT04KOPPkr9d0tLCw4cOICioiIUFRWhrq4ODz/8MAKBAE6cOIFVq1ZhzJgx+PrXv57V/dxks6HQNnyv7EtqKSJAS4W0KzNXtDYdTMrZGQAIJ+X7mOaQcwrH4/I5/hXKLCIACCuDmU7EisR6WV6XWO+Iy1kKQJ9HpOWISmzyjB0A6EzIc3y0HFJMOaYyOeYcSj6mKyk/XncWfCzWPUqGCAD6lKuMd6Y/mQgAbMoMno6EnI0BgFKb/NzwKo9Fr6Ef18Gk/Ay3KUnDUcrzO6nMtwKAmJID0nJEx6KlYj2RwXuFoDL76YySMyxN8xo7aMDI5LU2/XFvKHmwT8u6Ge3duxf33HNP6r8H/96zZMkSrF+/Hs3NzXj11VfR3d2NQCCAe+65B6+//jq8Xm+2d0VERDeIrJvR/PnzxW63ffv2K1oQERHdePjZdEREZDo2IyIiMh2bERERmY7NiIiITMdmREREpmMzIiIi0131jwO6XHEjiViaM8h9Vj1491FcDqTNcMrD1nzDf3pRVmuY7ZLv42Rc3v5yuxwo7c0gUKYNx7rVIa8RyveX2vR9mOg4K9a1QKoWaAX0YOzHsR6x3q6EB8crg9QAfdRhuV3+2KtfhuQQ5H3KIDQAyFeOif19t4j1s1E5D/hCoFFdw5mEfMx0JOTj3m3Rg5YTHPJtdChhz7ASmtUHWwJQwrla+BdObbCd/vw+HZVD65V2+fl5Mi6vURuuCQAOS/q9TGYwjHEQ3xkREZHp2IyIiMh0bEZERGQ6NiMiIjIdmxEREZmOzYiIiEzHZkRERKbL2ZxRKGkgmRz+PPsuxNTvL7LK5+j/LiIPfLswRb79iKEPldvZXybW73R/Ita7knLWodiq/y4RUTIbH8duEuvl9pBY78pgyOCJ+BixXmqTs05aDgnQc0S3OgqU+5C/32PVxjUCQWUAX3tMyb4k3GL9aEx/unot8nNjsrtNrH/Rc0KsH47p+zDRruVv9ByR5vdR+fmt5YR8ylaGk/rz260clxElJnQ2IWe6zifkYxYAJrjkrJKWI9KG6/UZ+mttTHgNCCeYMyIiomsImxEREZmOzYiIiEzHZkRERKZjMyIiItOxGRERkenYjIiIyHQ5mzPqTjoRTw7fK88n5Nk1ADDbFRTr7TGfWC/8gpx90Wa2AMDBvrFivVrJGYWT8iyRIqueAfBa5XXGIOdGtOxMd1I/hBKGlmWQAxkxZQ2APo9IyxGV2+VMh5Zjungfcn3AkPfap8xMOhaVs3EAUGyTc2EzXPIxl1TmV+0bqFDX4LedEOtu5T5OxPUZWX+IBMR6qbKGozF5tlSxrV9dQ58yz6hZebx6k/IadgUnqWuYXnBarI+2ycet1yIfL8fj8vMKANyW9JmsHuaMiIjoWsJmREREpmMzIiIi07EZERGR6diMiIjIdGxGRERkOjYjIiIyXc7mjDyWODxp5oUUOS6o3x9WZomMd3aK9f7fyTN4Jtyhb9093sNiPZiUcyeVdjlHZFPyGgAwoGQh8i3yvBOPRb4Pr03PEYSTctbBp8wK6ssgZzReyeho84iudB4SALTF5dsotkbE+rmYPN9mQf4RdQ0eIfMBALv7x6u3IZnv+Ui9TpFVfm5os4ImKsc9AIyynhTrTuW4neyQc0SZpGMcyu/yM5ztYv2YMkusZtQhdQ3hpDwDq8oZFutarqzKKR+zAJAUcoJhZbbVp2X1zqi+vh6zZ8+G1+tFSUkJHnroIRw9enTIdQzDQF1dHcrKypCXl4f58+fj0CF9U4mI6MaVVTNqbGzEsmXLsGfPHjQ0NCAej6Ompga9vb2p67z44otYs2YN1q1bh6amJvj9fixcuBDhsNyhiYjoxpXVP9Nt27ZtyH9v3LgRJSUl2LdvH+6++24YhoG1a9fi2WefxaJFiwAAmzZtQmlpKTZv3ozvfOc7I7dyIiK6blzRCQzB4MXPfysqKgIAtLS0oL29HTU1NanruFwuzJs3D7t37x72NiKRCEKh0JALERHdWC67GRmGgRUrVuCuu+5CVVUVAKC9/eIf7EpLS4dct7S0NFX7rPr6evh8vtSlokL/IEYiIrq+XHYzevLJJ3Hw4EH867/+6yU1y2fOZDEM45KvDVq5ciWCwWDq0traerlLIiKia9Rlndr91FNP4a233sKuXbtQXl6e+rrff/Ej09vb2xEI/Okj3js7Oy95tzTI5XLB5ZI/Sp2IiK5vWb0zMgwDTz75JN588028++67GDdu3JD6uHHj4Pf70dDQkPpaNBpFY2MjqqurR2bFRER03cnqndGyZcuwefNm/PrXv4bX6039Hcjn8yEvLw8WiwXLly/H6tWrMXHiREycOBGrV6+Gx+PBI488ktXC/HYLCu3D/9NeX+Y5qrQKrQNiXZmDhmBSDosCQMKQB1OVKoHRAWXonNeq/y4RTMg/iEcJYjrSBI9Tt59BIHXAkIcERgw5gOhQAoyAHlLU1qkNxtMCrQAQUAb0nUv0ivXawoNivdSmH3PKYYtblbB3Z0IO3vYa+ktGa1x+NJzKXncl9cdbO/JdyjHTEpNvYYJDSc1nQAu15yvPvbOJQvU+tAF92uBK+ZkJhA39+e0W9jqBzPcxq2a0fv16AMD8+fOHfH3jxo1YunQpAOCZZ55Bf38/nnjiCVy4cAFz5szBjh074PXKBzkREd24smpGhtJlgYsnL9TV1aGuru5y10RERDcYflAqERGZjs2IiIhMx2ZERESmYzMiIiLTsRkREZHpcna4Xn8yAXty+LP33Er2BQCOx+UfbbJDPsc//4x2fr6ehZjmlIcAfhTLE+vTnfI5/l0ZZJ205EmZTd6HpCHv9RirU11BzB4U69qQsq6kHiwrt8t5i/aYvJcDSrBMG4wH6DmiMbZ8sf5+7ySxPuWmfeoatGfGez1fEOun++WBb39W3qGu4WhMfu6dScjHvduiD9eb4ZSP/S5lgF/IkNcQM+RhjYCeoRljk+tFkH9Oh0UezgcABwYq5TUoz8+PlEyY35ZJzij9cyeaQUZwEN8ZERGR6diMiIjIdGxGRERkOjYjIiIyHZsRERGZjs2IiIhMx2ZERESmy9mc0ScJF/ITw/fKw5Gb1e/visuzZeovjBfryigSfL/zLnUNh4IBsf73t/y7WH/q9AKxPs17Wl1Dc7hcrLf1yzNTakoOi/UPQmPVNRwPjhHrc0taxPqdBR+r9/HL0PCThAeFE26x7rPLuZJzMX0EijaPSMsR/V9j/iDWXwvre30mNkqsfzn/Q7F+2C4/t5a2fE1dg88hzwqbWnBGrB/plZ83AGC1yPmYL+S3XdF9fLHglLqGhPK7/PazU8V60pAzOKGIfMwCwLmwnF3bN1Z+7kz2yLmxtqhPXUPAmT5HONATByA/3oP4zoiIiEzHZkRERKZjMyIiItOxGRERkenYjIiIyHRsRkREZDo2IyIiMp3FMAx56MbnLBQKwefz4cQfAij0Dt8rbRnMEnp/QD4/fryjS6w//u3/Idb/+ZUfq2twKPNOupLyrBG3RZ8lotk3UCHWxyr7MNkREuvdSf33mcNRv1if5pIzIR6Lfoh6rXIwTJuxc0xZ421OeY0AUGqTZ+w4ldkuDX1yjuhR73l1DcFkv1h/tm2+WO9WZmytLv9/1DU0R+VcmU15Xoyy6rOEJihZpo40GcVB3Ul5/tVkh7yPABBTXjq7lLDi2YScEfJkMEPrje7ZYv2p0e+L9XMJh1gvs8tzoQB5tls4nMS4L7QjGAyisFDONPKdERERmY7NiIiITMdmREREpmMzIiIi07EZERGR6diMiIjIdGxGRERkOjYjIiIyXVbD9err6/Hmm2/iD3/4A/Ly8lBdXY1/+qd/wuTJk1PXWbp0KTZt2jTk++bMmYM9e/ZktbCokUQkTabMZdF7qBYY04KUfaVyGMybQRAzrAzP0sJ/PuuVh15L7GGxXqbUHUpQ02uVh5wBwChbr3wb2mORQSw7Xwkgei0xsV5sk8O9Hose/lPmMaq/+WmD8YJJfZiizyqHVrWhdGpdXQHggHzc2pT78FjlxwrQg+/FNvk+wskrz/p7rfLLZwLyMeOxyMfcmYRHXUO584JY14LWLiVYLwVaR1pW74waGxuxbNky7NmzBw0NDYjH46ipqUFv79AXm/vvvx9tbW2pyzvvvDOiiyYioutLVu+Mtm3bNuS/N27ciJKSEuzbtw9333136usulwt+v/zxKkRERIOu6G9GweDF2edFRUVDvr5z506UlJRg0qRJeOyxx9DZ2Zn2NiKRCEKh0JALERHdWC67GRmGgRUrVuCuu+5CVVVV6uu1tbV47bXX8O677+Kll15CU1MTFixYgEhk+L/h1NfXw+fzpS4VFfIHexIR0fUnq3+m+7Qnn3wSBw8exPvvD/1U2MWLF6f+f1VVFWbNmoXKykq8/fbbWLRo0SW3s3LlSqxYsSL136FQiA2JiOgGc1nN6KmnnsJbb72FXbt2oby8XLxuIBBAZWUljh07Nmzd5XLB5ZI/zp2IiK5vWTUjwzDw1FNPYevWrdi5cyfGjRunfs/58+fR2tqKQCBw2YskIqLrW1bNaNmyZdi8eTN+/etfw+v1or29HQDg8/mQl5eHnp4e1NXV4eGHH0YgEMCJEyewatUqjBkzBl//+tezWtjufj889uGTG0cGytTvv6/gkFhf8uEjYj3yF91i/RehGeoatrTMFOsbp70q1v/X2bvFerX3I3UNWqZj1akHxfrXig+K9SP9+mPR2neTWP/SqBaxPt6Z/gSYQfv7bhHrk93ycLwZrk/E+u7+8eoablXW+V7PF8T6l/M/FOvaYDxAzwn9uKxJrJ+O94j1x4//ubqGbwb+U6xXOOQhgW8E5ecNADQH5ePuoZL9Yv10dLRYP+iQ83cAkFRyhDvOTRHrvTH5X4RaL4xS11BSKD9eR/vks5rvKpSPuZ/3VaprKLKnzxEO9MQAtKu3AWTZjNavXw8AmD9//pCvb9y4EUuXLoXNZkNzczNeffVVdHd3IxAI4J577sHrr78Or9ebzV0REdENJOt/ppPk5eVh+/btV7QgIiK68fCz6YiIyHRsRkREZDo2IyIiMh2bERERmY7NiIiITHfZHwd0tbXHR8EdG3557RGf+v0Orzyno6tXnhUyytMv1nsSbnUNobB8HzFD/l2gOyZ/vyODGTvdykyUYFSefxM15EOkN65/esb5gXz1OhItKwUAZ6NydOCLnhNiPTkCc1s6E/IaTvfLeavD9pvFendMfqwAPWek5YjK7QXyGgb0NeQrs8SKrX1iPeDoVu9jV2SCWE8qv2cX2eV9iCTleWaAvtcDCfk2Lih72R/Wn1vxAnkvQ8rzs9gufzC1lqUCgL6kM20tksz8ecV3RkREZDo2IyIiMh2bERERmY7NiIiITMdmREREpmMzIiIi07EZERGR6SyG9lHcn7NQKASfz4ff/r4MBd7he6XfJmeIAGD3QKlYr3Z3iPVHH3lSrP/b5pfVNbgsckbnlz3yTJYH8k+J9daE/rtEl5IzKrXJeQuvVc5SeK3Dz5z6tDNx+RDT7qMjkT7HMGiyQ76NwzF5nX+IyMMfv5x3Ql1Dr5LJGq+k+pa2fE2sr6n8lboG7YjQ5hFpOaL3p7+prmHPgPz8PBUvEutj7V3qfcxUIjhHYjGx3qfkiMrtcs4QAGLKK6fXKmdsupT4nA36S/O/91SJ9e+OGn7C9qD/MyBv5Ayn/PoAAFZL+p8zFE7iltvaEAwGUVhYKN+Oek9ERERXGZsRERGZjs2IiIhMx2ZERESmYzMiIiLTsRkREZHp2IyIiMh0bEZERGS6nB2u1590wJocvle2KkPpAD3U2tA3Vqx//F/lMFgsg0DaO71ykPJ292mx3q5ke4ut+nA9vy0s1q80HBxO6gHkjoQcdhutrLHUFlXv40xCDhhOtMsJQ7/thFgvsupPlda4fB9H0wyLHORzDIj15ugYdQ0OyI/HNwP/Kda1wXhaoBUA7nTLAeMvJNvFel8Gx9R/RuQwd7ESjPc75HqvPs8R2lWOx+Ww9oGBSrEuDa0bFDPkvT4dlx/PyQ653pvJRyII1+lJZrCRf8R3RkREZDo2IyIiMh2bERERmY7NiIiITMdmREREpmMzIiIi07EZERGR6bLKGa1fvx7r16/HiRMnAABTp07FP/zDP6C2thYAYBgGnn/+eWzYsAEXLlzAnDlz8PLLL2Pq1KlZLyzPGoPHOnyvHFDOrQcAl0Xus13xArFuFMgZnu4MTp8/HZWHiC30yMPzDke9Yl3L5wDAeSV/060M30sosxczGXz3SfwmsT7eERLrXuWxvLgO+VAuVXInbsj7FE7qmS6nfBM4k5AH100tOCPWMxm2ZrPIB2aF47xYL7b2ifXmqJydA/Qckc8q70NfUh/odlbJrvlt8s8B5fEeCWcT8vP3QjxfrJ+Lya9RAOBSsobtyvO7yinnjM4l9MxXQtjLfiPzfc7qnVF5eTleeOEF7N27F3v37sWCBQvw4IMP4tChQwCAF198EWvWrMG6devQ1NQEv9+PhQsXIhzWXzSJiOjGlVUzeuCBB/Bnf/ZnmDRpEiZNmoQf/OAHKCgowJ49e2AYBtauXYtnn30WixYtQlVVFTZt2oS+vj5s3rz5aq2fiIiuA5f9N6NEIoEtW7agt7cXc+fORUtLC9rb21FTU5O6jsvlwrx587B79+60txOJRBAKhYZciIjoxpJ1M2pubkZBQQFcLhcef/xxbN26FVOmTEF7+8V/Jy4tHfpZZ6WlpanacOrr6+Hz+VKXioqKbJdERETXuKyb0eTJk3HgwAHs2bMH3/3ud7FkyRIcPnw4VbdYhv7ByjCMS772aStXrkQwGExdWltbs10SERFd47L+1G6n04kJEyYAAGbNmoWmpib86Ec/wt/+7d8CANrb2xEI/OmMm87OzkveLX2ay+WCyyV/QjYREV3frjhnZBgGIpEIxo0bB7/fj4aGhlQtGo2isbER1dXVV3o3RER0HcvqndGqVatQW1uLiooKhMNhbNmyBTt37sS2bdtgsViwfPlyrF69GhMnTsTEiROxevVqeDwePPLII1kvLGlYkExzjrrXElO/vyUmZ5E8ytwW72E5P+NdqGc+Ao4LYr017hDrxbZesT6gZIAu3scose6wyDkCbae9Vv2x0LJMbuGfcQGg19BDXW7l59CcUGbPTLTrP2dXUv453Mpxe0SZf1XtOaauwaM8Hm8EZ4r1gKNbrN/ulrNxgD6PSMsRBex6vqYsIT+3tN+ytXosgxzSKOVGJiqZru6EnDO6yS4//wF9nlGRVZ6RpeWtitJkPT+tW5hZZM8gG/en62aho6MD3/rWt9DW1gafz4fp06dj27ZtWLhwIQDgmWeeQX9/P5544olU6HXHjh3weuXwFxER3diyakavvPKKWLdYLKirq0NdXd2VrImIiG4w/Gw6IiIyHZsRERGZjs2IiIhMx2ZERESmYzMiIiLTsRkREZHpsv44oM+L1xpDQZrAValNX/a7/fJAt0UFx8X65v1yKNahBDUBYLG3Taxv7xsl1u90nxXr7cpAuUzMVkKMciwX8Nn032fmez4U61ElvBtM6sMUJzjkvfh9VL6PP0TkwOko60l1DdpOzHBG5e9XBuNNcGgBRsCmhBibg2VifVdkglj/9hQ99PqfETnkrA3G0wKtAPAll3xkHojIe3k2KT9at9jlxwrQQ+dFVvmxuN11Wqx7Mghy/1voi2K90i4/L/ZH5bp2zALy63GeLYMppH/Ed0ZERGQ6NiMiIjIdmxEREZmOzYiIiEzHZkRERKZjMyIiItOxGRERkelyNmdktwCONKfpn0no59/PdnWK9aOxPLF+qkYetpaJ7X0+sT7NKa9RG3w12aHnb9yWbrE+oAznKlPuojsZV9dwPikPSyu394t1G/THu0M5Jirt8l6W2k6IdWcGuTKXcp0uZa++kC/n0joS+u+OxUqu46GS/WI9qfx+eiSmDxkstsmPhd/WJ9Yz+Q1ZyxHd7nKJ9UNR+ZhzZDBcr8AqZ51OJ+S9siqD5xr7x6trGKe8zp1LyjmhyQ55jd1JfTie9BIRFgbvfRbfGRERkenYjIiIyHRsRkREZDo2IyIiMh2bERERmY7NiIiITMdmREREpsvZnFFnwoXeNLkKJ/Rz12PKbJiPYyViPf8TOWegzTLJRNiQt78jJucYim1yVgIAuhJynupQ5GaxXpT/kVg/l9AmHgHtcTlvVWyVcyejMviVKazMPPIpR/rRmJxLmezQ97olJi80ZMiPxZFeeabS7Dx5BhcAhJVcyOnoaLFeZO8R631J/fH2O7RcmPzcyuQ3ZG0ekZYjmuqUH4uWmLwPF8kZnoQhr3G3kiMqtofUFbTHR4n1LuX5mbDKOaN8ZSYTIM8j0xOCf8J3RkREZDo2IyIiMh2bERERmY7NiIiITMdmREREpmMzIiIi07EZERGR6XI2Z3SLPQqvffhemcmEjISSA6p2n5S/X44hwGvVZwnd6jgv1n1W+Sz8Yqs8/8Zr1R++BAbE+lc8H8trsMn5G7dFzloAgMsiz+kpU2YNJZW8BqDPKwors4S0zFYmx9wEh3zMxQw5T/XFglNiPZOsk+agIyzWI0qOSJs9BQC9mY+wGVYsg1lCt9jl406bR6TliMY55BlcANCnzApqS8j1293y43024VXXEFPmkVXa5deYhLJPDov+3CuwpF+D3XqV5hmtX78e06dPR2FhIQoLCzF37lz85je/SdWXLl0Ki8Uy5HLnnXdmcxdERHQDyuqdUXl5OV544QVMmDABALBp0yY8+OCD2L9/P6ZOnQoAuP/++7Fx48bU9zidVz4xlYiIrm9ZNaMHHnhgyH//4Ac/wPr167Fnz55UM3K5XPD7/SO3QiIiuu5d9gkMiUQCW7ZsQW9vL+bOnZv6+s6dO1FSUoJJkybhscceQ2enPKM9EokgFAoNuRAR0Y0l62bU3NyMgoICuFwuPP7449i6dSumTJkCAKitrcVrr72Gd999Fy+99BKampqwYMECRCKRtLdXX18Pn8+XulRUVFz+T0NERNekrM+mmzx5Mg4cOIDu7m688cYbWLJkCRobGzFlyhQsXrw4db2qqirMmjULlZWVePvtt7Fo0aJhb2/lypVYsWJF6r9DoRAbEhHRDSbrZuR0OlMnMMyaNQtNTU340Y9+hJ/+9KeXXDcQCKCyshLHjh1Le3sulwsul3z6MBERXd+uOPRqGEbaf4Y7f/48WltbEQjIc1qIiOjGltU7o1WrVqG2thYVFRUIh8PYsmULdu7ciW3btqGnpwd1dXV4+OGHEQgEcOLECaxatQpjxozB17/+9RFddCYdtFeZfRfUhoQpWS1bBsG8sHIfXqscIMwkWKuJZRAYlb9fDs1lsg8dCTlAWGGXw6CxTCKnhnwdtxLe61O+3zECH1aSgHxQJpT7iGUw0FELQicNZbCdMpQylsFMySvMvGY0TFEbbllg1YYAyoFULdAKAB6rHFvxaLdhlevnE/pO+u1B9TqSTEKtmpgwQi+j5+4fZdWMOjo68K1vfQttbW3w+XyYPn06tm3bhoULF6K/vx/Nzc149dVX0d3djUAggHvuuQevv/46vF49SUxERDeurJrRK6+8kraWl5eH7du3X/GCiIjoxsMPSiUiItOxGRERkenYjIiIyHRsRkREZDo2IyIiMl3ODtc7FXegID58rxylnJ8PAM1R+ZPDJzvkD3AdfSQm1geU/A0AFNvkgW4fROQ13uXuEOunE/rvEmcT+WK9yCZnfLqUoXRui54z0rIrZxPyfXQl9TEkpTb5mIgo+RjteJnhbFfXEEzKubAxNnkR289OFevzPR+qa0hA3ssd56aI9YGEnM9ZPOEP6hqOx+XHSxsaN1EZSgkARVb5uDudkJ+/CSV/pw3GA/QcUcAu5+tOxeUBf1OcF9Q1nIyn/9xPAIgp2bYTMfnxHq8MMQTk/Ft/8ioN1yMiIroa2IyIiMh0bEZERGQ6NiMiIjIdmxEREZmOzYiIiEzHZkRERKbL2ZxRV8KDSGL43EavoedOuhMesZ7vUua2eOQ+fTqub92AIV+nM14or8GQsy29yu0DQCjpFusTHCGx3pWU78Om5BgAwCnMO7l4H/LjeSxaqt4HnHImS8u29CblacPHYjepS8i3ypmPIsjZF23WkJYZAwCPRX48e2Pyz3lhIE+sd2UQGzkwUCnfR1z+Oboz+Dlvd50W61bluNzdP16+ffcpdQ3aPCItRzRWySH9v/36PDOHRX5udSuPV3vcJ9aTRviK1tCTwUymQXxnREREpmMzIiIi07EZERGR6diMiIjIdGxGRERkOjYjIiIyHZsRERGZLmdzRhHDAZsx/Hn2hRhQv/9Q381i/TZnm1gv+N+/E+u9/yTPAQGACrs8K+jdHjn7ciwu5xAOD8g/IwB0KbcRTsq5ktE2OSvhtsjZGQD4JC5ndGyQswiJDH5n0vJO5xPyPuwKThLrNaMOqWs4m5BzYw6LnBsLReRMmEfJMQHAGSVf13phlFjvD8s5pExyZX1KbuxcTH4sbrL3qvfhUfI1jUqOqNgu57G0XBoAnFcyNNo8Ii1HdG+ePjNtQ7BMrOe7T4j1I8priL/gsLqGBNLn45JC7bP4zoiIiEzHZkRERKZjMyIiItOxGRERkenYjIiIyHRsRkREZDo2IyIiMh2bERERme6KQq/19fVYtWoVnn76aaxduxYAYBgGnn/+eWzYsAEXLlzAnDlz8PLLL2Pq1KlZ3fbvB8rhtg8fLB1I6oFTlzUu1ht7bxPr3X85V6wfi55R1/CWEkjz2uTwrjYg0G3VA6fafWh72WnI4b+BDAYdBhNysNZrldcYVPYBAE5Hi8T6BJc8fG96gTysLawMKQT0AX3a0LlzYXmo3Bvds9U1lCtBy5JCOcQcL5CD2v/eU6WuIZYmrD5Ie25q3w8A/xb6olgf5+oU6+3xUVe8Br89KNZPxuWQsjYYTwu0AsB/98mvQ//3hYlivUB5ffhd3wR1DZKB/jiA1oyue9nvjJqamrBhwwZMnz59yNdffPFFrFmzBuvWrUNTUxP8fj8WLlyIcFifGEhERDemy2pGPT09ePTRR/Gzn/0MN930p496MQwDa9euxbPPPotFixahqqoKmzZtQl9fHzZv3jxiiyYiouvLZTWjZcuW4atf/Sruu+++IV9vaWlBe3s7ampqUl9zuVyYN28edu/ePextRSIRhEKhIRciIrqxZP03oy1btuCDDz5AU1PTJbX29osfBFlaWjrk66WlpTh58uSwt1dfX4/nn38+22UQEdF1JKt3Rq2trXj66afxi1/8Am53+j/oWixDP6nVMIxLvjZo5cqVCAaDqUtra2Z/7CIioutHVu+M9u3bh87OTsycOTP1tUQigV27dmHdunU4evQogIvvkAKBQOo6nZ2dl7xbGuRyueByyWchERHR9S2rd0b33nsvmpubceDAgdRl1qxZePTRR3HgwAGMHz8efr8fDQ0Nqe+JRqNobGxEdXX1iC+eiIiuD1m9M/J6vaiqGpozyM/Px+jRo1NfX758OVavXo2JEydi4sSJWL16NTweDx555JGsFrao8AAKvMP3yqIMWujJuJyfKbVFxfrW5L1i/S+UXAoAdHmOi/WjMZ9Yv8stZwDOJuQsBQCEk/JmOS3ygDCfVR6O5bPq+ZuWuPxzlNnkTMeZhD5krNIu551OxuXHWxsiWOXUowl9hjx4boxVXuO+sR+L9adGv6+uwZnmn8MHHe3zi/VQXP5Xiu+OOqau4bSSr2lXcmNFSu4MACrt8kvXuaT8eHcl5NeHSrt+zGliyiDCbvmppw7GA/Qc0VM3Df+3+kEfxuRBhqW2TAZbpj/mQtYk/k69hYtGfNLrM888g/7+fjzxxBOp0OuOHTvg9eqTE4mI6MZ0xc1o586dQ/7bYrGgrq4OdXV1V3rTRER0g+Bn0xERkenYjIiIyHRsRkREZDo2IyIiMh2bERERmW7ET+0eKTYYsKU5T/9sQu+hFXZ51s9v++VZIZ1fkjMCXUqOAQDe6Z0k1h/I/1Csn4zLmZEym/7wnUvIt9GRKBDrY1xyDuF0vF9dQ3NE3utSjzxrKJOsg5Yj0m7Da5E/oDcpZCkGaVO2PorLwZLJyj6cU7IxAOBSZuTcVSgfc8V2eR/+z4D+aSmTHXLOqMop15HBXu+Pysf+ZIf8/E8os8ASmTzeFvmYOhGTH6/2uJwzPDJws7oGbR6RliOa5JBnaLXF5fwdAEhHXDiphKk+he+MiIjIdGxGRERkOjYjIiIyHZsRERGZjs2IiIhMx2ZERESmYzMiIiLT5WzOKM8CeNKc6p9J7uR4XK5PcbaL9dEH5PsofljPWyz0yJmODiU3UmaXf4hwUvkhAUQhr9OrzI6RZpUAQHEGWSe/vfuK7mPA0GfLlNvkvewz5FzJ8bg8Y0fPxgBhZZ1+m1xvi8q5kzKf/ng7lL38eV+lWE8a8vevKv7/1DX0yhE9nFPmUxVZ9ef3DKecK+tOyovIV+Z0aRmiTIy3y2tMGvKMLH/BYfU+ftc3Qaxrr5Vajihgl3OIABARnlsuG3NGRER0DWEzIiIi07EZERGR6diMiIjIdGxGRERkOjYjIiIyHZsRERGZjs2IiIhMl7OhV4fFAodFH3CVjlsZMua2yKG4uFu+74ShJPsAOJTle6x6iFG+fX1/vBY57KkNjXNY5EMklkEgdZRVDoxqt6CFYgHAYbGJ9ZgyDNFtkR+LZAaPt1t5PNzKGgPOoFjXAq2ZKLLLw9b6kk6xbs3kOalslTa4rjuDgWylStha3mkgqjyeBcpjBQAx5ciNKffhUF6jMhnwp9GeO9pzTwq0DnJZ0gfOXRaGXomI6BrCZkRERKZjMyIiItOxGRERkenYjIiIyHRsRkREZLqcO7Xb+OPpkOGe9KcERjM4vbQnIZ9SGFNO7U5E5Tk/obB+ymJYOUW1X5kdo41tyuQ3iZ6EfB/aqd0hh7KPhr4PPXF5r0PKUWhkcFp10iqvI6wcD9rxErbrP2dCOadZO24HepT5VcrPmImBHvlU3UhSOR6cGTzeV3jc27VzwwHkKXNytOeedkqzPYO9jkH5OZU1aMec9twEgIF++ZgJac8LZY2ZzCOSTt8O/fF1PJPnsMXI5Fqfo9OnT6OiosLsZRAR0QhpbW1FeXm5eJ2ca0bJZBJnzpyB1+uF5Y+/SYZCIVRUVKC1tRWFhYUmr3B4XOPIuRbWyTWOnGthnVzj5TEMA+FwGGVlZbAqE3xz7p/prFZr2g5aWFiYM5ucDtc4cq6FdXKNI+daWCfXmD2fz5fR9XgCAxERmY7NiIiITHdNNCOXy4XnnnsOLpfL7KWkxTWOnGthnVzjyLkW1sk1Xn05dwIDERHdeK6Jd0ZERHR9YzMiIiLTsRkREZHp2IyIiMh0bEZERGQ6NiMiIjIdmxEREZmOzYiIiEz3/wOvsP0yBuRkCgAAAABJRU5ErkJggg==\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -387,7 +424,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -399,7 +436,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -414,20 +451,20 @@ " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'theta'),\n", + " 'alpha1'),\n", " ('pipeline-2',\n", " Pipeline(steps=[('projcommonspace',\n", " ProjCommonSpace(n_compo=60,\n", " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'alpha')])),\n", + " 'alpha2')])),\n", " ('kernelsum', KernelSum())])),\n", " ('kernelridge',\n", " KernelRidge(alpha=1e-10, kernel='precomputed'))])In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" + " 'alpha2')])
alpha1
ProjCommonSpace(n_compo=60, reg=1e-05, scale=1)
Riemann(metric='logeuclid')
GaussianKernel()
alpha2
ProjCommonSpace(n_compo=60, reg=1e-05, scale=1)
Riemann(metric='logeuclid')
GaussianKernel()
[]
passthrough
KernelSum()
KernelRidge(alpha=1e-10, kernel='precomputed')
" ], "text/plain": [ "Pipeline(steps=[('pipeline',\n", @@ -507,26 +546,26 @@ " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'theta'),\n", + " 'alpha1'),\n", " ('pipeline-2',\n", " Pipeline(steps=[('projcommonspace',\n", " ProjCommonSpace(n_compo=60,\n", " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'alpha')])),\n", + " 'alpha2')])),\n", " ('kernelsum', KernelSum())])),\n", " ('kernelridge',\n", " KernelRidge(alpha=1e-10, kernel='precomputed'))])" ] }, - "execution_count": null, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -537,16 +576,16 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ - "y = [1 if ll == 'hands' else -1 for ll in labels]" + "y = epochs.events[:, 2]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -562,15 +601,14 @@ " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'theta'),\n", - " ('pipeline-2',\n", - " Pipelin...\n", + " 'alpha1'),\n", + " ('...\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'alpha')])),\n", + " 'alpha2')])),\n", " ('kernelsum',\n", " KernelSum())])),\n", " ('kernelridge',\n", @@ -589,15 +627,14 @@ " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'theta'),\n", - " ('pipeline-2',\n", - " Pipelin...\n", + " 'alpha1'),\n", + " ('...\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'alpha')])),\n", + " 'alpha2')])),\n", " ('kernelsum',\n", " KernelSum())])),\n", " ('kernelridge',\n", @@ -615,20 +652,20 @@ " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'theta'),\n", + " 'alpha1'),\n", " ('pipeline-2',\n", " Pipeline(steps=[('projcommonspace',\n", " ProjCommonSpace(n_compo=60,\n", " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'alpha')])),\n", + " 'alpha2')])),\n", " ('kernelsum', KernelSum())])),\n", " ('kernelridge',\n", " KernelRidge(alpha=1e-10, kernel='precomputed'))])
Pipeline(steps=[('columntransformer',\n",
@@ -639,39 +676,41 @@
        "                                                                                   reg=1e-05,\n",
        "                                                                                   scale=1)),\n",
        "                                                                  ('riemann',\n",
-       "                                                                   Riemann()),\n",
+       "                                                                   Riemann(metric='logeuclid')),\n",
        "                                                                  ('gaussiankernel',\n",
        "                                                                   GaussianKernel())]),\n",
-       "                                                  'theta'),\n",
+       "                                                  'alpha1'),\n",
        "                                                 ('pipeline-2',\n",
        "                                                  Pipeline(steps=[('projcommonspace',\n",
        "                                                                   ProjCommonSpace(n_compo=60,\n",
        "                                                                                   reg=1e-05,\n",
        "                                                                                   scale=1)),\n",
        "                                                                  ('riemann',\n",
-       "                                                                   Riemann()),\n",
+       "                                                                   Riemann(metric='logeuclid')),\n",
        "                                                                  ('gaussiankernel',\n",
        "                                                                   GaussianKernel())]),\n",
-       "                                                  'alpha')])),\n",
+       "                                                  'alpha2')])),\n",
        "                ('kernelsum', KernelSum())])
ColumnTransformer(remainder='passthrough',\n",
        "                  transformers=[('pipeline-1',\n",
        "                                 Pipeline(steps=[('projcommonspace',\n",
        "                                                  ProjCommonSpace(n_compo=60,\n",
        "                                                                  reg=1e-05,\n",
        "                                                                  scale=1)),\n",
-       "                                                 ('riemann', Riemann()),\n",
+       "                                                 ('riemann',\n",
+       "                                                  Riemann(metric='logeuclid')),\n",
        "                                                 ('gaussiankernel',\n",
        "                                                  GaussianKernel())]),\n",
-       "                                 'theta'),\n",
+       "                                 'alpha1'),\n",
        "                                ('pipeline-2',\n",
        "                                 Pipeline(steps=[('projcommonspace',\n",
        "                                                  ProjCommonSpace(n_compo=60,\n",
        "                                                                  reg=1e-05,\n",
        "                                                                  scale=1)),\n",
-       "                                                 ('riemann', Riemann()),\n",
+       "                                                 ('riemann',\n",
+       "                                                  Riemann(metric='logeuclid')),\n",
        "                                                 ('gaussiankernel',\n",
        "                                                  GaussianKernel())]),\n",
-       "                                 'alpha')])
theta
ProjCommonSpace(n_compo=60, reg=1e-05, scale=1)
Riemann()
GaussianKernel()
alpha
ProjCommonSpace(n_compo=60, reg=1e-05, scale=1)
Riemann()
GaussianKernel()
[]
passthrough
KernelSum()
KernelRidge(alpha=1e-10, kernel='precomputed')
" + " 'alpha2')])
alpha1
ProjCommonSpace(n_compo=60, reg=1e-05, scale=1)
Riemann(metric='logeuclid')
GaussianKernel()
alpha2
ProjCommonSpace(n_compo=60, reg=1e-05, scale=1)
Riemann(metric='logeuclid')
GaussianKernel()
[]
passthrough
KernelSum()
KernelRidge(alpha=1e-10, kernel='precomputed')
" ], "text/plain": [ "GridSearchCV(error_score='raise',\n", @@ -684,15 +723,14 @@ " reg=1e-05,\n", " scale=1)),\n", " ('riemann',\n", - " Riemann()),\n", + " Riemann(metric='logeuclid')),\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'theta'),\n", - " ('pipeline-2',\n", - " Pipelin...\n", + " 'alpha1'),\n", + " ('...\n", " ('gaussiankernel',\n", " GaussianKernel())]),\n", - " 'alpha')])),\n", + " 'alpha2')])),\n", " ('kernelsum',\n", " KernelSum())])),\n", " ('kernelridge',\n", @@ -704,7 +742,7 @@ " scoring='roc_auc')" ] }, - "execution_count": null, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -726,7 +764,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -735,7 +773,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -744,14 +782,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Mean classification accuracy: 0.93\n" + "Mean classification accuracy: 1.00\n" ] } ], @@ -761,17 +799,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{'pipeline__columntransformer__pipeline-1__gaussiankernel__sigma': 100.0,\n", + "{'pipeline__columntransformer__pipeline-1__gaussiankernel__sigma': 1.0,\n", " 'pipeline__columntransformer__pipeline-2__gaussiankernel__sigma': 1.0}" ] }, - "execution_count": null, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -782,12 +820,25 @@ } ], "metadata": { + "celltoolbar": "Raw Cell Format", "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "coffeine", "language": "python", - "name": "python3" + "name": "coffeine" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.16" } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/requirements.txt b/requirements.txt index 4295fe0..44fd1b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,6 @@ numpy>=1.18.1 scipy>=1.4.1 matplotlib>=2.0.0 pandas>=1.0.0 -pyriemann>=0.2.7 -scikit-learn>=0.24 -mne[data]>=0.24 +pyriemann>=0.4 +scikit-learn>=1.0 +mne[data]>=1.0 \ No newline at end of file