Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .codespellrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[codespell]
skip = [setup.cfg]
ignore-words-list = Reson, DNE, ACI, FPT, sagital, saggital
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
python -m pip check
- name: Lint
run: |
flake8 --ignore N802,N806,W503 --select W504 `find . -name \*.py | grep -v setup.py | grep -v version.py | grep -v __init__.py | grep -v /docs/`
ruff check .
- name: Test
run: |
cd && mkdir for_test && cd for_test && pytest --pyargs AFQ --cov-report term-missing --cov=AFQ -m "not nightly and not nightly_basic and not nightly_custom and not nightly_anisotropic and not nightly_slr and not nightly_reco and not nightly_reco80" --durations=0
63 changes: 31 additions & 32 deletions .maintenance/update_zenodo.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,81 +7,80 @@
https://github.com/nipreps/dmriprep/blob/master/LICENSE

"""
import sys

import json
import shutil
import subprocess as sp
import sys
from pathlib import Path
import json

from rapidfuzz import fuzz, process
import subprocess as sp

# These ORCIDs should go last
CREATORS_LAST = ['Yeatman, Jason', 'Rokem, Ariel']
CREATORS_LAST = ["Yeatman, Jason", "Rokem, Ariel"]
# for entries not found in line-contributions
MISSING_ENTRIES = [
]
MISSING_ENTRIES = []

if __name__ == '__main__':
contrib_file = Path('line-contributors.txt')
if __name__ == "__main__":
contrib_file = Path("line-contributors.txt")
lines = []
if contrib_file.exists():
print('WARNING: Reusing existing line-contributors.txt file.',
file=sys.stderr)
print("WARNING: Reusing existing line-contributors.txt file.", file=sys.stderr)
lines = contrib_file.read_text().splitlines()

git_line_summary_path = shutil.which('git-summary')
git_line_summary_path = shutil.which("git-summary")
if not lines and git_line_summary_path:
print("Running git-line-summary on the repo")
lines = sp.check_output([git_line_summary_path]).decode().splitlines()
contrib_file.write_text('\n'.join(lines))
contrib_file.write_text("\n".join(lines))

if not lines:
raise RuntimeError(
"""Could not find line-contributors from git repository.%s"""
% """git-line-summary not found, please install git-extras. """
* (git_line_summary_path is None))
* (git_line_summary_path is None)
)

data = [' '.join(line.strip().split()[1:-1]) for line in lines if '%'
in line]
data = [" ".join(line.strip().split()[1:-1]) for line in lines if "%" in line]

# load zenodo from master
zenodo_file = Path('.zenodo.json')
zenodo_file = Path(".zenodo.json")
zenodo = json.loads(zenodo_file.read_text())
zen_names = [' '.join(val['name'].split(',')[::-1]).strip()
for val in zenodo['creators']]
zen_names = [
" ".join(val["name"].split(",")[::-1]).strip() for val in zenodo["creators"]
]
total_names = len(zen_names) + len(MISSING_ENTRIES)

name_matches = []
position = 1
for ele in data:
match = process.extractOne(ele, zen_names,
scorer=fuzz.token_sort_ratio,
score_cutoff=80)
match = process.extractOne(
ele, zen_names, scorer=fuzz.token_sort_ratio, score_cutoff=80
)

if match:
val = zenodo['creators'][zen_names.index(match[0])]
val = zenodo["creators"][zen_names.index(match[0])]
else:
# skip unmatched names
print("No entry to sort:", ele)
continue

if val not in name_matches:
if val['name'] not in CREATORS_LAST:
val['position'] = position
if val["name"] not in CREATORS_LAST:
val["position"] = position
position += 1
else:
val['position'] = total_names + \
CREATORS_LAST.index(val['name'])
val["position"] = total_names + CREATORS_LAST.index(val["name"])
name_matches.append(val)

for missing in MISSING_ENTRIES:
missing['position'] = position
missing["position"] = position
position += 1
name_matches.append(missing)

zenodo['creators'] = sorted(name_matches, key=lambda k: k['position'])
zenodo["creators"] = sorted(name_matches, key=lambda k: k["position"])
# Remove position
for creator in zenodo['creators']:
del creator['position']
for creator in zenodo["creators"]:
del creator["position"]

zenodo_file.write_text('%s\n' % json.dumps(zenodo, indent=2,
sort_keys=True))
zenodo_file.write_text("%s\n" % json.dumps(zenodo, indent=2, sort_keys=True))
18 changes: 18 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
default_language_version:
python: python3

repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.10
hooks:
# Run the linter
- id: ruff
args: [ --fix, --config, pyproject.toml ]
# Run the formatter
- id: ruff-format
- repo: https://github.com/codespell-project/codespell
rev: v2.3.0
hooks:
- id: codespell
additional_dependencies:
- tomli
54 changes: 23 additions & 31 deletions AFQ/_fixes.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
import numpy as np
import logging

from scipy.special import lpmv, gammaln
from scipy.linalg import pinvh

from tqdm import tqdm

import math

from dipy.reconst.gqi import squared_radial_component
import numpy as np
from dipy.data import default_sphere
from dipy.reconst.gqi import squared_radial_component
from dipy.tracking.streamline import set_number_of_points
from scipy.linalg import blas

from scipy.linalg import blas, pinvh
from scipy.special import gammaln, lpmv
from tqdm import tqdm

logger = logging.getLogger('AFQ')
logger = logging.getLogger("AFQ")


def gwi_odf(gqmodel, data):
gqi_vector = np.real(
squared_radial_component(np.dot(
gqmodel.b_vector, default_sphere.vertices.T)
* gqmodel.Lambda))
squared_radial_component(
np.dot(gqmodel.b_vector, default_sphere.vertices.T) * gqmodel.Lambda
)
)
odf = blas.dgemm(
alpha=1.,
a=data.reshape(-1, gqi_vector.shape[0]),
b=gqi_vector
alpha=1.0, a=data.reshape(-1, gqi_vector.shape[0]), b=gqi_vector
).reshape((*data.shape[:-1], gqi_vector.shape[1]))
return odf

Expand All @@ -44,7 +38,7 @@ def spherical_harmonics(m, n, theta, phi):


def in_place_norm(vec, axis=-1, keepdims=False, delvec=True):
""" Return Vectors with Euclidean (L2) norm
"""Return Vectors with Euclidean (L2) norm

See :term:`unit vector` and :term:`Euclidean norm`

Expand Down Expand Up @@ -131,9 +125,7 @@ def tensor_odf(evals, evecs, sphere, num_batches=100):
batch_size = math.ceil(num_vertices / num_batches)
batches = range(num_batches)

mask = np.where((evals[..., 0] > 0)
& (evals[..., 1] > 0)
& (evals[..., 2] > 0))
mask = np.where((evals[..., 0] > 0) & (evals[..., 1] > 0) & (evals[..., 2] > 0))
evecs = evecs[mask]

proj_norm = np.zeros((num_vertices, evecs.shape[0]))
Expand All @@ -157,8 +149,7 @@ def tensor_odf(evals, evecs, sphere, num_batches=100):
return odf


def gaussian_weights(bundle, n_points=100, return_mahalnobis=False,
stat=np.mean):
def gaussian_weights(bundle, n_points=100, return_mahalnobis=False, stat=np.mean):
"""
Calculate weights for each streamline/node in a bundle, based on a
Mahalanobis distance from the core the bundle, at that node (mean, per
Expand Down Expand Up @@ -203,9 +194,12 @@ def gaussian_weights(bundle, n_points=100, return_mahalnobis=False,

if n_sls < 15: # Cov^-1 unstable under this amount
weights = np.ones((n_sls, n_nodes))
logger.warning((
"Not enough streamlines for weight calculation, "
"weighting everything evenly"))
logger.warning(
(
"Not enough streamlines for weight calculation, "
"weighting everything evenly"
)
)
if return_mahalnobis:
return np.full((n_sls, n_nodes), np.nan)
else:
Expand All @@ -225,11 +219,9 @@ def gaussian_weights(bundle, n_points=100, return_mahalnobis=False,

# calculate Mahalanobis for node in every fiber
if np.any(cov > 0):
weights[:, i] = np.sqrt(np.einsum(
'ij,jk,ik->i',
diff[:, i, :],
pinvh(cov),
diff[:, i, :]))
weights[:, i] = np.sqrt(
np.einsum("ij,jk,ik->i", diff[:, i, :], pinvh(cov), diff[:, i, :])
)

# In the special case where all the streamlines have the exact same
# coordinate in this node, the covariance matrix is all zeros, so
Expand Down
Loading
Loading