Skip to content

Commit

Permalink
Merge branch 'main' into documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
bclenet committed Oct 13, 2023
2 parents 7c3b6df + 91dc744 commit c10e3a4
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 7 deletions.
9 changes: 6 additions & 3 deletions docs/description.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@ It is a conversion into tsv format (tab-separated values) of the [original .xlsx

The file `narps_open/data/description/analysis_pipelines_derived_descriptions.tsv` contains for each team a set of programmatically usable data based on the textual descriptions of the previous file. This data is available in the `derived` sub dictionary (see examples hereafter).

The file `narps_open/data/description/analysis_pipelines_comments.tsv` contains for each team a set of comments made by the NARPS Open Pipelines team about reproducibility and exclusions of the pipeline. This data is available in the `comments` sub dictionary (see examples hereafter).

The class `TeamDescription` of module `narps_open.data.description` acts as a parser for these two files.

You can use the command-line tool as so. Option `-t` is for the team id, option `-d` allows to print only one of the sub parts of the description among : `general`, `exclusions`, `preprocessing`, `analysis`, and `categorized_for_analysis`. Options `--json` and `--md` allow to choose the export format you prefer between JSON and Markdown.
You can use the command-line tool as so. Option `-t` is for the team id, option `-d` allows to print only one of the sub parts of the description among : `general`, `exclusions`, `preprocessing`, `analysis`, `categorized_for_analysis`, `derived`, and `comments`. Options `--json` and `--md` allow to choose the export format you prefer between JSON and Markdown.

```bash
python narps_open/data/description -h
# usage: __init__.py [-h] -t TEAM [-d {general,exclusions,preprocessing,analysis,categorized_for_analysis,derived}]
# usage: __init__.py [-h] -t TEAM [-d {general,exclusions,preprocessing,analysis,categorized_for_analysis,derived,comments}]
#
# Get description of a NARPS pipeline.
#
# options:
# -h, --help show this help message and exit
# -t TEAM, --team TEAM the team ID
# -d {general,exclusions,preprocessing,analysis,categorized_for_analysis,derived}, --dictionary {general,exclusions,preprocessing,analysis,categorized_for_analysis,derived}
# -d {general,exclusions,preprocessing,analysis,categorized_for_analysis,derived,comments}, --dictionary {general,exclusions,preprocessing,analysis,categorized_for_analysis,derived,comments}
# the sub dictionary of team description
# --json output team description as JSON
# --md output team description as Markdown
Expand Down Expand Up @@ -91,6 +93,7 @@ description.preprocessing
description.analysis
description.categorized_for_analysis
description.derived
description.comments
# Access values of sub dictionaries
description.general['teamID']
# Other keys in general are: ['teamID', 'NV_collection_link', 'results_comments', 'preregistered', 'link_preregistration_form', 'regions_definition', 'softwares', 'general_comments']
Expand Down
40 changes: 38 additions & 2 deletions narps_open/data/description/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class TeamDescription(dict):
derived_description_file = join(
files('narps_open.data.description'),
'analysis_pipelines_derived_descriptions.tsv')
comments_description_file = join(
files('narps_open.data.description'),
'analysis_pipelines_comments.tsv')

def __init__(self, team_id):
super().__init__()
Expand Down Expand Up @@ -59,6 +62,11 @@ def derived(self) -> dict:
""" Getter for the sub dictionary containing derived team description """
return self._get_sub_dict('derived')

@property
def comments(self) -> dict:
""" Getter for the sub dictionary containing comments for NARPS Open Pipeline """
return self._get_sub_dict('comments')

def markdown(self):
""" Return the team description as a string formatted in markdown """
return_string = f'# NARPS team description : {self.team_id}\n'
Expand All @@ -69,7 +77,8 @@ def markdown(self):
self.preprocessing,
self.analysis,
self.categorized_for_analysis,
self.derived
self.derived,
self.comments
]

names = [
Expand All @@ -78,7 +87,8 @@ def markdown(self):
'Preprocessing',
'Analysis',
'Categorized for analysis',
'Derived'
'Derived',
'Comments'
]

for dictionary, name in zip(dictionaries, names):
Expand Down Expand Up @@ -175,3 +185,29 @@ def _load(self):
if not found:
raise AttributeError(f'Team {self.team_id}\
was not found in the derived description.')

# Parsing third file : self.comments_description_file
with open(self.comments_description_file, newline='', encoding='utf-8') as csv_file:
# Prepare first line (whose elements are second part of the keys)
first_line = csv_file.readline().replace('\n','').split('\t')

# Read the rest of the file as a dict
reader = DictReader(
csv_file,
fieldnames = ['comments.' + k2 for k2 in first_line],
delimiter = '\t'
)

# Update self with the key/value pairs from the file
found = False
for row in reader:
if row['comments.teamID'] == self.team_id:
found = True
row.pop('comments.teamID', None) # Remove useless 'comments.teamID' key
self.update(row)
break

# If team id was not found in the file
if not found:
raise AttributeError(f'Team {self.team_id}\
was not found in the comments description.')
5 changes: 4 additions & 1 deletion narps_open/data/description/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
'preprocessing',
'analysis',
'categorized_for_analysis',
'derived'
'derived',
'comments'
],
help='the sub dictionary of team description')
formats = parser.add_mutually_exclusive_group(required = False)
Expand Down Expand Up @@ -49,5 +50,7 @@
print(dumps(information.categorized_for_analysis, indent = 4))
elif arguments.dictionary == 'derived':
print(dumps(information.derived, indent = 4))
elif arguments.dictionary == 'comments':
print(dumps(information.comments, indent = 4))
else:
print(dumps(information, indent = 4))
71 changes: 71 additions & 0 deletions narps_open/data/description/analysis_pipelines_comments.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
teamID excluded_from_narps_analysis exclusion_comment reproducibility reproducibility_comment
50GV no N/A ? Uses custom software (Denoiser)
9Q6R no N/A
O21U no N/A
U26C no N/A
43FJ no N/A
C88N no N/A
4TQ6 yes Resampled image offset and too large compared to template.
T54A no N/A
2T6S no N/A
L7J7 no N/A
0JO0 no N/A
X1Y5 no N/A
51PW no N/A
6VV2 no N/A
O6R6 no N/A
C22U no N/A ? Custom Matlab script for white matter PCA confounds
3PQ2 no N/A
UK24 no N/A
4SZ2 yes Resampled image offset from template brain.
9T8E no N/A
94GU no N/A ? Multiple software dependencies : SPM + ART + TAPAS + Matlab.
I52Y no N/A
5G9K no N/A ? ?
2T7P yes Missing thresholded images. ? ?
UI76 no N/A
B5I6 no N/A
V55J yes Bad histogram : very small values.
X19V no N/A
0C7Q yes Appears to be a p-value distribution, with slight excursions below and above zero.
R5K7 no N/A
0I4U no N/A
3C6G no N/A
R9K3 no N/A
O03M no N/A
08MQ no N/A
80GC no N/A
J7F9 no N/A
R7D1 no N/A
Q58J yes Bad histogram : bimodal, zero-inflated with a second distribution centered around 5.
L3V8 yes Rejected due to large amount of missing brain in center.
SM54 no N/A
1KB2 no N/A
0H5E yes Rejected due to large amount of missing brain in center.
P5F3 yes Rejected due to large amounts of missing data across brain.
Q6O0 no N/A
R42Q no N/A ? Uses fMRIflows, a custom software based on NiPype.
L9G5 no N/A
DC61 no N/A
E3B6 yes Bad histogram : very long tail, with substantial inflation at a value just below zero.
16IN no N/A ? Multiple software dependencies : matlab + SPM + FSL + R + TExPosition + neuroim
46CD no N/A
6FH5 yes Missing much of the central brain.
K9P0 no N/A
9U7M no N/A
VG39 no N/A
1K0E yes Used surface-based analysis, only provided data for cortical ribbon. ? ?
X1Z4 yes Used surface-based analysis, only provided data for cortical ribbon. ? Multiple software dependencies : FSL + fmriprep + ciftify + HCP workbench + Freesurfer + ANTs
I9D6 no N/A
E6R3 no N/A
27SS no N/A
B23O no N/A
AO86 no N/A
L1A8 yes Resampled image much smaller than template brain. ? ?
IZ20 no N/A
3TR7 no N/A
98BT yes Rejected due to very bad normalization.
XU70 no N/A ? Uses custom software : FSL + 4drealign
0ED6 no N/A ? ?
I07H yes Bad histogram : bimodal, with second distribution centered around 2.5.
1P0Y no N/A
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
data_files = [
('narps_open/utils/configuration', ['narps_open/utils/configuration/default_config.toml']),
('narps_open/utils/configuration', ['narps_open/utils/configuration/testing_config.toml']),
('narps_open/data/description', ['narps_open/data/description/analysis_pipelines_comments.tsv']),
('narps_open/data/description', ['narps_open/data/description/analysis_pipelines_derived_descriptions.tsv']),
('narps_open/data/description', ['narps_open/data/description/analysis_pipelines_full_descriptions.tsv'])
]
Expand Down
3 changes: 3 additions & 0 deletions tests/data/test_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def test_arguments_properties():
assert description['analysis.RT_modeling'] == 'duration'
assert description['categorized_for_analysis.analysis_SW_with_version'] == 'SPM12'
assert description['derived.func_fwhm'] == '8'
assert description['comments.excluded_from_narps_analysis'] == 'no'

# 4 - Check properties
assert isinstance(description.general, dict)
Expand All @@ -63,6 +64,7 @@ def test_arguments_properties():
assert isinstance(description.analysis, dict)
assert isinstance(description.categorized_for_analysis, dict)
assert isinstance(description.derived, dict)
assert isinstance(description.comments, dict)

assert list(description.general.keys()) == [
'teamID',
Expand All @@ -82,6 +84,7 @@ def test_arguments_properties():
assert description.analysis['RT_modeling'] == 'duration'
assert description.categorized_for_analysis['analysis_SW_with_version'] == 'SPM12'
assert description.derived['func_fwhm'] == '8'
assert description.comments['excluded_from_narps_analysis'] == 'no'

# 6 - Test another team
description = TeamDescription('9Q6R')
Expand Down
5 changes: 5 additions & 0 deletions tests/test_data/data/description/test_markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ Model EVs (2): eq_indiff, eq_range
* `excluded_participants` : 018, 030, 088, 100
* `func_fwhm` : 5
* `con_fwhm` :
## Comments
* `excluded_from_narps_analysis` : no
* `exclusion_comment` : N/A
* `reproducibility` :
* `reproducibility_comment` :
6 changes: 5 additions & 1 deletion tests/test_data/data/description/test_str.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,9 @@
"derived.n_participants": "104",
"derived.excluded_participants": "018, 030, 088, 100",
"derived.func_fwhm": "5",
"derived.con_fwhm": ""
"derived.con_fwhm": "",
"comments.excluded_from_narps_analysis": "no",
"comments.exclusion_comment": "N/A",
"comments.reproducibility": "",
"comments.reproducibility_comment": ""
}

0 comments on commit c10e3a4

Please sign in to comment.