Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Correlation heatmaps #1

Merged
merged 84 commits into from
May 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
aa44ae2
move stuff around
anibalsolon Apr 16, 2019
4406132
Updated the CircleCI pipeline config.
sgiavasis Nov 8, 2019
d3bcd55
Update pipe-test_ci.yml
XinhuiLi Nov 19, 2019
7f93261
Update pipe-test_ci.yml
XinhuiLi Nov 19, 2019
e09cfed
template based segmentation fix typo
HechengJin0 Dec 23, 2019
fd4054e
fix typo segmentation
HechengJin0 Jan 8, 2020
e11c03e
Changed "ndmg_mode" to "output_tree" key in configs.
sgiavasis Jan 8, 2020
1ad26c1
Merge branch 'master' of github.com:FCP-INDI/C-PAC into feature/erosi…
HechengJin0 Jan 10, 2020
be5036a
Merge branch 'develop' into feature/preconfigs
sgiavasis Jan 24, 2020
f91c7af
update configs
XinhuiLi Feb 20, 2020
3d7efcc
:newspaper: start w/ regressors
shnizzedy Mar 3, 2020
0bddf1b
:construction: :yellow_heart: :microscope: :newspaper: ≟ on Circle CI
shnizzedy Mar 3, 2020
c53d76e
:tractor: Port function definitions from notebook to script
shnizzedy Mar 3, 2020
39e74ef
:tractor: Port function definitions from notebook to script
shnizzedy Mar 3, 2020
b61b9c8
:construction: :yellow_heart: persist_to_workspace
shnizzedy Mar 3, 2020
42b4fa3
:tractor: Port remaining functions from notebook
shnizzedy Mar 4, 2020
6c18f13
:green_heart: :snake: PEP 263
shnizzedy Mar 4, 2020
ad6e5d0
:tractor: Finish abstracting from notebook
shnizzedy Mar 4, 2020
32a8b56
:green_heart: Fix imports
shnizzedy Mar 4, 2020
07509ee
🧙 Add autoreload magics
shnizzedy Mar 4, 2020
d194862
:sparkles: Handle lists of strings and no session specifications
shnizzedy Mar 4, 2020
cc5ded5
:sparkles: generate_heatmaps function + heatmaps CLI
shnizzedy Mar 5, 2020
95a636f
:construction: Begin CPAC config
shnizzedy Mar 5, 2020
7a983a8
:construction:
shnizzedy Mar 5, 2020
b2a3868
:construction:
shnizzedy Mar 5, 2020
1465618
:newspaper: Benchmarks index
shnizzedy Mar 5, 2020
0f5f66f
:construction: Prep to run current branch if not already run
shnizzedy Mar 6, 2020
3f27032
:handshake: Merge branch 'feature/auto-heatmaps' of github.com:FCP-IN…
shnizzedy Mar 6, 2020
e54c8fa
:construction: WIP automatic correlation heatmaps
shnizzedy Mar 6, 2020
b20b65f
:construction:
shnizzedy Mar 6, 2020
6d803df
:construction: Generalize fmriprep subject list
shnizzedy Mar 9, 2020
0ad15e3
:snake: Python 2 → 3
shnizzedy Mar 9, 2020
823091f
:comstruction: Generalize nuisance output paths
shnizzedy Mar 9, 2020
4fed348
:art: Functionalize compare.get_paths()
shnizzedy Mar 9, 2020
c91ccf2
:construction: path_lists to dicts
shnizzedy Mar 9, 2020
8a2f2bc
:construction:
shnizzedy Mar 10, 2020
f7bad99
:pencil: Import defaults
shnizzedy Mar 10, 2020
fecca59
:construction:
shnizzedy Mar 10, 2020
1f05966
:construction:
shnizzedy Mar 10, 2020
e6c1dfb
:tractor: read_feature
shnizzedy Mar 11, 2020
d30049f
:building_construction: classes for correlations
shnizzedy Mar 12, 2020
de48c26
:construction:
shnizzedy Mar 12, 2020
1e93392
:construction:
shnizzedy Mar 12, 2020
5b4eb84
:construction: WIP :art: More abstraction
shnizzedy Mar 13, 2020
3cf1caf
:snake: Python 2→3
shnizzedy Mar 16, 2020
a21bd7c
:recycle: Move heatmap scripts from C-PAC to CPAC_regtest_pack
shnizzedy Mar 16, 2020
07b68fb
:handshake: Merge 'C-PAC/feature/auto-heatmaps' into feat/heatmaps
shnizzedy Mar 16, 2020
33e28b6
:cucumber: R/w pickles as bitstreams
shnizzedy Mar 17, 2020
9109110
:fire: Remove static configs
shnizzedy Mar 17, 2020
55b113f
:microscope: Set up Circle CI
shnizzedy Mar 17, 2020
3d484bd
:building_construction: Integrate correlation matrix and heatmap scripts
shnizzedy Mar 17, 2020
4fc1156
:snake: Allow imports as either scripts or modules
shnizzedy Mar 17, 2020
67aeef3
:books: Add `--help`s to README
shnizzedy Mar 17, 2020
6093558
:books: Report only local coverage
shnizzedy Mar 17, 2020
f9af36d
:arrow_up: afni_python → afnipy
shnizzedy Mar 19, 2020
c636905
:children_crossing: Check Python version
shnizzedy Mar 30, 2020
101acd9
:heavy_plus_sign: tabulate
shnizzedy Mar 30, 2020
77ceea6
:zap: Broaden range of parsed subject formats
shnizzedy Mar 30, 2020
2ccff20
:zap: Handle "nuisance_[''/regressors]0_0" and separate `session` fro…
shnizzedy Mar 31, 2020
2ce9615
:tractor: split session from subject
shnizzedy Mar 31, 2020
08ed714
:mute:
shnizzedy Mar 31, 2020
88d25e2
:lipstick: Print filepaths without given directories
shnizzedy Mar 31, 2020
c9671a0
:ambulance: Check path for Nonetype
shnizzedy Mar 31, 2020
d5bb536
:art: '/' inside "run_path"
shnizzedy Mar 31, 2020
f7d9c70
:lipstick: Wrap long paths
shnizzedy Mar 31, 2020
5448b63
:speaker: "Not found"
shnizzedy Mar 31, 2020
0719989
🚑 Handle a variety of subject ID formats (#2)
shnizzedy Mar 31, 2020
88d1598
:fast_forward: Merge remote-tracking branch 'steve/master' into feat/…
shnizzedy Mar 31, 2020
13d0c46
:zap: Logs aren't subjects
shnizzedy Apr 1, 2020
be37011
:ambulance: Handle splitting sessions & users separately for separate…
shnizzedy Apr 1, 2020
0124b49
:lipstick: Don't format/wrap if not plaintext
shnizzedy Apr 2, 2020
6c2f33b
:zap: Logs aren't subjects
shnizzedy Apr 1, 2020
4bc4e25
:ambulance: Handle splitting sessions & users separately for separate…
shnizzedy Apr 1, 2020
bfa3fb7
:handshake: Merge remote-tracking branch 'origin/fix/fmriprep_file_no…
shnizzedy Apr 2, 2020
ed4450f
:pencil: Don't wrap header if not plaintext
shnizzedy Apr 2, 2020
d3ad1af
:construction: Find GS, CSF, aCompCor …
shnizzedy Apr 2, 2020
1d0317e
:hammer: Fix FD reading
shnizzedy Apr 3, 2020
a03c97d
:hammer: Fix aCompCor
shnizzedy Apr 3, 2020
87258ca
:pencil: 'WhiteMatter_mean'
shnizzedy Apr 10, 2020
b764fac
:pencil: Make glob for compcor more vague
shnizzedy Apr 13, 2020
41e6e4f
:rewind: Revert 3cf1caf94058ceec3fa2d5bd301c709badf1908c
shnizzedy Apr 13, 2020
3c88f63
:hammer: path → paths
shnizzedy Apr 17, 2020
cae19f0
:lipstick: bbox_inches="tight"
shnizzedy Apr 17, 2020
479739c
👷 Debug heatmaps (#8)
shnizzedy Apr 17, 2020
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
29 changes: 29 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
version: 2
jobs:
pytest:
docker:
- image: circleci/python:3.7.3
steps:
- checkout
- run:
name: pytest
command: |
export PATH=/home/circleci/.local/bin:$PATH
mkdir test-results
pip install --user -r requirements.txt
set +e
coverage run -m pytest --junitxml=test-results/junit.xml
coverage report --include="./*" --omit="/home/circleci/.local/*"
coverage html --include="./*" --omit="/home/circleci/.local/*"
- store_test_results:
path: test-results
- store_artifacts:
path: test-results
- store_artifacts:
path: htmlcov

workflows:
version: 2
unit_tests:
jobs:
- pytest
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,90 @@
# CPAC_regtest_pack

```bash
$ python cpac_correlations_wf.py --help
usage: cpac_correlations_wf.py [-h] [--old_outputs_path OLD_OUTPUTS_PATH]
[--new_outputs_path NEW_OUTPUTS_PATH]
[--s3_creds S3_CREDS]
[--replacements REPLACEMENTS]
[--corr_map CORR_MAP]
[--working_dir WORKING_DIR]
num_cores run_name

positional arguments:
num_cores number of cores to use - will calculate correlations
in parallel if greater than 1
run_name name for the correlations run

optional arguments:
-h, --help show this help message and exit
--old_outputs_path OLD_OUTPUTS_PATH
path to a CPAC outputs directory - the folder
containing the participant-ID labeled directories
--new_outputs_path NEW_OUTPUTS_PATH
path to a CPAC outputs directory - the folder
containing the participant-ID labeled directories
--s3_creds S3_CREDS path to your AWS S3 credentials file
--replacements REPLACEMENTS
text file containing strings you wish to have removed
from the filepaths if they occur - place one on each
line
--corr_map CORR_MAP YAML file with already-calculated correlations, which
can be provided if you only want to generate the box
plots again
--working_dir WORKING_DIR
if you are correlating two working directories of a
single participant to check intermediates
```

```bash
$ python correlation_matrix.py --help
usage: correlation_matrix.py [-h] [--old_outputs_path OLD_OUTPUTS_PATH]
[--old_outputs_software {C-PAC,fmriprep}]
[--new_outputs_path NEW_OUTPUTS_PATH]
[--new_outputs_software {C-PAC,fmriprep}]
[--save] [--no-save]
[--subject_list SUBJECT_LIST] [--session SESSION]
[--feature_list FEATURE_LIST]
num_cores run_name

Create a correlation matrix between two C-PAC output directories.

positional arguments:
num_cores number of cores to use - will calculate correlations
in parallel if greater than 1
run_name name for the correlations run

optional arguments:
-h, --help show this help message and exit
--old_outputs_path OLD_OUTPUTS_PATH
path to an outputs directory - the folder containing
the participant-ID labeled directories
--old_outputs_software {C-PAC,fmriprep}
(default: fmriprep)
--new_outputs_path NEW_OUTPUTS_PATH
path to an outputs directory - the folder containing
the participant-ID labeled directories
--new_outputs_software {C-PAC,fmriprep}
(default: C-PAC)
--save save matrices & heatmap (default)
--no-save do not save matrices & heatmap
--subject_list SUBJECT_LIST
(default: subjects in OLD_OUTPUTS_PATH sorted by
session, subject ID). TODO: handle path to file
--session SESSION limit to a single given session (integer)
--feature_list FEATURE_LIST
TODO: handle path to file (default: ['GS', 'CSF',
'WM', 'tCompCor0', 'aCompCor0', 'aCompCor1',
'aCompCor2', 'aCompCor3', 'aCompCor4', 'FD'])

The following features currently have available definitions to calculate Pearson's r between C-PAC and fmriprep:

key feature name documentation link
-------- ------------------------ ----------------------------------------------------------------------------------
aCompCor aCompCor https://fcp-indi.github.io/docs/user/nuisance.html#acompcor
CSF mean cerebrospinal fluid https://fcp-indi.github.io/docs/user/nuisance.html#mean-white-matter-csf
FD framewise displacement https://fcp-indi.github.io/docs/user/nuisance.html#regression-of-motion-parameters
GS global signal regression https://fcp-indi.github.io/docs/user/nuisance.html#global-signal-regression
tCompCor tCompCor https://fcp-indi.github.io/docs/user/nuisance.html#tcompcor
WM mean white matter https://fcp-indi.github.io/docs/user/nuisance.html#mean-white-matter-csf
```
Empty file added __init__.py
Empty file.
53 changes: 53 additions & 0 deletions configs/defaults.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
feature_headers = {
'GS': {
'name': 'global signal regression',
'link': 'https://fcp-indi.github.io/docs/user/nuisance.html#'
'global-signal-regression',
'C-PAC': ['GlobalSignalMean0', 'GlobalSignal_mean'],
'fmriprep': 'global_signal'
},
'CSF': {
'name': 'mean cerebrospinal fluid',
'link': 'https://fcp-indi.github.io/docs/user/nuisance.html#'
'mean-white-matter-csf',
'C-PAC': ['CerebrospinalFluidMean0', 'CerebrospinalFluid_mean'],
'fmriprep': 'csf'
},
'WM': {
'name': 'mean white matter',
'link': 'https://fcp-indi.github.io/docs/user/nuisance.html#'
'mean-white-matter-csf',
'C-PAC': ['WhiteMatterMean0', 'WhiteMatter_mean'],
'fmriprep': 'white_matter'
},
'aCompCor': {
'name': 'aCompCor',
'link': 'https://fcp-indi.github.io/docs/user/nuisance.html#acompcor',
'C-PAC': ['aCompCorPC', 'aCompCor'],
'fmriprep': 'aCompCor_comp_cor_0'
},
'tCompCor': {
'name': 'tCompCor',
'link': 'https://fcp-indi.github.io/docs/user/nuisance.html#tcompcor',
'C-PAC': ['tCompCorPC', 'tCompCor'],
'fmriprep': 'tCompCor_comp_cor_0'
},
'FD': {
'name': 'framewise displacement',
'link': 'https://fcp-indi.github.io/docs/user/nuisance.html#'
'regression-of-motion-parameters'
}
}
motion_list = ['FD']
regressor_list = [
'GS',
'CSF',
'WM',
'tCompCor0',
'aCompCor0',
'aCompCor1',
'aCompCor2',
'aCompCor3',
'aCompCor4'
]
software = ["C-PAC", "fmriprep"]
162 changes: 162 additions & 0 deletions configs/subjects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import os

from itertools import chain
from string import ascii_lowercase


def cpac_sub(sub):
"""
Function to convert a string from f"sub-{sub_number}{ses_letter}" to
f"sub-{sub_number}_ses-{ses_number}"

Parameter
---------
fmriprep_sub: str

Returns
-------
sub: str

Example
-------
>>> print(cpac_sub("sub-0025427a"))
sub-0025427_ses-1
"""
return(f"{sub[:-1]}_ses-{str(ascii_lowercase.find(sub[-1])+1)}")


def fmriprep_sub(sub):
"""
Function to convert a string from f"sub-{sub_number}_ses-{ses_number}" to
f"sub-{sub_number}{ses_letter}"

Parameter
---------
sub: str

Returns
-------
fmriprep_sub: str

Example
-------
>>> print(fmriprep_sub("sub-0025427_ses-1"))
sub-0025427a
"""
return(f"{sub.split('_')[0]}{ascii_lowercase[int(sub[-1])-1]}")


def generate_subject_list_for_directory(path, old_outputs_software="C-PAC"):
"""
Function to take a path and return a subject list.

Parameter
---------
path: str

old_outputs_software: str, optional, default="C-PAC"

Returns
-------
sub_list: list
"""
output = os.path.join(path, "output")
sub_ses_list = list(chain.from_iterable([[
d for d in os.listdir(
os.path.join(output, o)
) if all([
os.path.isdir(os.path.join(output, o, d)),
d not in ["log", "logs"]
])
] for o in os.listdir(output)]))
return(sessions_together([
cpac_sub(s) if s[
-1
] in ascii_lowercase else s for s in sub_ses_list
]))


def generate_subject_list_for_range(
subject_start_stop,
session_start_stop=None
):
"""
Function to create a subject list for a given range. All values are
inclusive.

Parameters
----------
subject_start_stop: 2-tuple of integers (start, stop) or list of specific
values

session_start_stop: 2-tuple of integers (start, stop) or list of specific
values or None

Returns
-------
List of strings

Example
-------
>>> generate_subject_list_for_range((25427,25428), (1,2))
['sub-0025427_ses-1', 'sub-0025428_ses-1', 'sub-0025427_ses-2', 'sub-0025428_ses-2']
"""
return([
f'sub-00{sub}{ses_string}' for ses_string in ([
f'_ses-{ses}' for ses in _expand_range(
session_start_stop
)
] if session_start_stop else [
''
]) for sub in _expand_range(subject_start_stop)
])


def sessions_together(sub_list):
"""
Function to sort by session then by subject

Parameter
---------
sub_list: list of str

Returns
-------
sub_list: list of str

Example
-------
>>> sub_list = [
... 'sub-0025427_ses-1', 'sub-0025427_ses-2', 'sub-0025428_ses-1'
... ]
>>> print(sessions_together(sub_list))
['sub-0025427_ses-1', 'sub-0025428_ses-1', 'sub-0025427_ses-2']
"""
sub_list.sort()
sub_list.sort(key=lambda x: x.split("ses-")[-1])
return(sub_list)


def _expand_range(tuple_or_list):
"""
Function to expand an inclusive tuple to a range or return a literal list

Parameter
---------
tuple_or_list: 2-tuple of integers or list

Returns
-------
list
"""
return(
list(
range(
tuple_or_list[0],
tuple_or_list[1] + 1) if all([
isinstance(tuple_or_list, tuple),
len(tuple_or_list)==2,
*[isinstance(v, int) for v in tuple_or_list]
]) else tuple_or_list
)
)
Loading