Skip to content

Commit

Permalink
Merge pull request #198 from MICA-MNI/development
Browse files Browse the repository at this point in the history
Version 0.2.2
  • Loading branch information
ReinderVosDeWael authored Jul 28, 2021
2 parents e58ba56 + d54ea1a commit b414527
Show file tree
Hide file tree
Showing 121 changed files with 3,666 additions and 752 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/python_unittests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,16 @@ jobs:
[[ -z $(git remote show origin | grep "Fetch URL:" | grep [email protected]:MICA-MNI/BrainStat.git) ]] && git config remote.upstream.fetch refs/heads/*:refs/remotes/upstream/* || git config remote.origin.fetch refs/heads/*:refs/origin/upstream/*
git fetch origin test-data-2.0
python -m pip install --upgrade pip
pip install pytest gitpython
pip install pytest mypy gitpython
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Test with pytest
shell: bash
run: |
python3 -m pytest
- name: Test with mypy
shell: bash
if: ${{ matrix.python-version == 3.9 }}
run: |
python3 -m mypy $(find brainstat -path "*tests*" -prune -false -o -name "*.py")
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@ __pycache__/

.idea

.mypy_cache

# test input data lives in a separate branch and will be pulled on demand
/extern/test-data/
6 changes: 5 additions & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
BSD 3-Clause License
BrainStat was released under the BSD 3-Clause License

Copyright (c) 2021, The BrainStat developers
All rights reserved.
Expand Down Expand Up @@ -27,3 +27,7 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The MATLAB implementation includes some toolboxes released under separate
licenses. Please refer to the license.txt and the function help string inside
the brainstat_matlab directory for these licenses.
10 changes: 10 additions & 0 deletions brainstat/_typing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import sys
from typing import Any

""" Python 3.6/3.7 compatibility for the ArrayLike type hint.
In these versions we simply accept anything. The tests in 3.8+
should catch all errors anyway. """
if sys.version_info[1] >= 8:
from numpy.typing import ArrayLike
else:
ArrayLike = Any
55 changes: 29 additions & 26 deletions brainstat/context/genetics.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,39 @@
"""Genetic decoding using abagen."""
from typing import List, Optional, Tuple, Union

import numpy as np
import pandas as pd
from abagen import check_atlas, get_expression_data


def surface_genetic_expression(
labels,
surfaces=None,
space=None,
labels: Union[List[str], np.ndarray],
surfaces: Union[List[str], Tuple[str, ...]] = None,
space: Optional[str] = None,
*,
atlas_info=None,
ibf_threshold=0.5,
probe_selection="diff_stability",
donor_probes="aggregate",
lr_mirror=None,
missing=None,
tolerance=2,
sample_norm="srs",
gene_norm="srs",
norm_matched=True,
norm_structures=False,
region_agg="donors",
agg_metric="mean",
corrected_mni=True,
reannotated=True,
return_counts=False,
return_donors=False,
return_report=False,
donors="all",
data_dir=None,
verbose=0,
n_proc=1
):
atlas_info: str = None,
ibf_threshold: float = 0.5,
probe_selection: str = "diff_stability",
donor_probes: str = "aggregate",
lr_mirror: Optional[bool] = None,
missing: Optional[str] = None,
tolerance: float = 2,
sample_norm: str = "srs",
gene_norm: str = "srs",
norm_matched: bool = True,
norm_structures: bool = False,
region_agg: str = "donors",
agg_metric: str = "mean",
corrected_mni: bool = True,
reannotated: bool = True,
return_counts: bool = False,
return_donors: bool = False,
return_report: bool = False,
donors: str = "all",
data_dir: Optional[str] = None,
verbose: float = 0,
n_proc: int = 1
) -> pd.DataFrame:
"""Computes genetic expression of surface parcels.
Parameters
Expand Down
53 changes: 32 additions & 21 deletions brainstat/context/histology.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,28 @@
import shutil
import urllib.request
from pathlib import Path
from typing import Callable, Optional, Union

import h5py
import numpy as np
from brainspace.gradient.gradient import GradientMaps
from brainspace.utils.parcellation import reduce_by_labels

from brainstat._typing import ArrayLike


def compute_histology_gradients(
mpc,
kernel="normalized_angle",
approach="dm",
n_components=10,
alignment=None,
random_state=None,
gamma=None,
sparsity=0.9,
reference=None,
n_iter=10,
):
mpc: np.ndarray,
kernel: Union[str, Callable[[np.ndarray], np.ndarray]] = "normalized_angle",
approach: Union[str, Callable[[np.ndarray], np.ndarray]] = "dm",
n_components: int = 10,
alignment: Optional[str] = None,
random_state: Optional[int] = None,
gamma: Optional[float] = None,
sparsity: Optional[float] = 0.9,
reference: Optional[np.ndarray] = None,
n_iter: int = 10,
) -> GradientMaps:
"""Computes microstructural profile covariance gradients.
Parameters
Expand Down Expand Up @@ -71,7 +74,7 @@ def compute_histology_gradients(
return gm


def compute_mpc(profile, labels):
def compute_mpc(profile: np.ndarray, labels: np.ndarray) -> np.ndarray:
"""Computes MPC for given labels on a surface template.
Parameters
Expand Down Expand Up @@ -102,12 +105,16 @@ def compute_mpc(profile, labels):
return mpc


def read_histology_profile(data_dir=None, template="fsaverage", overwrite=False):
def read_histology_profile(
data_dir: Optional[Union[str, Path]] = None,
template: str = "fsaverage",
overwrite: bool = False,
) -> np.ndarray:
"""Reads BigBrain histology profiles.
Parameters
----------
data_dir : str, None, optional
data_dir : str, pathlib.Path, None, optional
Path to the data directory. If data is not found here then data will be
downloaded. If None, data_dir is set to the home directory, by default None.
template : str, optional
Expand Down Expand Up @@ -140,12 +147,16 @@ def read_histology_profile(data_dir=None, template="fsaverage", overwrite=False)
return h5_file.get(template)[...]


def download_histology_profiles(data_dir=None, template="fsaverage", overwrite=False):
def download_histology_profiles(
data_dir: Optional[Union[str, Path]] = None,
template: str = "fsaverage",
overwrite: bool = False,
) -> None:
"""Downloads BigBrain histology profiles.
Parameters
----------
data_dir : str, None, optional
data_dir : str, pathlib,Path, None, optional
Path to the directory to store the data. If None, defaults to the home
directory, by default None.
template : str, optional
Expand Down Expand Up @@ -177,12 +188,12 @@ def download_histology_profiles(data_dir=None, template="fsaverage", overwrite=F
)


def partial_correlation(X, covar):
def partial_correlation(X: ArrayLike, covar: np.ndarray) -> np.ndarray:
"""Runs a partial correlation whilst correcting for a covariate.
Parameters
----------
X : numpy.ndarray
X : ArrayLike
Two-dimensional array of the data to be correlated.
covar : numpy.ndarray
One-dimensional array of the covariate.
Expand All @@ -200,7 +211,7 @@ def partial_correlation(X, covar):
return (r_xy - r_xz @ r_xz.T) / (np.sqrt(1 - r_xz ** 2) * np.sqrt(1 - r_xz.T ** 2))


def _get_urls():
def _get_urls() -> dict:
"""Stores the URLs for histology file downloads.
Returns
Expand All @@ -215,14 +226,14 @@ def _get_urls():
}


def _download_file(url, output_file, overwrite):
def _download_file(url: str, output_file: Path, overwrite: bool) -> None:
"""Downloads a file.
Parameters
----------
url : str
URL of the download.
file : pathlib.Path
output_file : pathlib.Path
Path object of the output file.
overwrite : bool
If true, overwrite existing files.
Expand Down
Loading

0 comments on commit b414527

Please sign in to comment.