Skip to content

Commit

Permalink
Implement BIDS Exec (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
rob-luke authored Jun 20, 2021
1 parent c81aa31 commit f0d18ec
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 21 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/boutiques.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: "Tests - Boutique"
on:
# Trigger the workflow on push or pull request, but only for the main branch
push:
branches:
- main
pull_request:
branches:
- main

jobs:
docker:
runs-on: ubuntu-latest
steps:

- uses: actions/checkout@v2
with:
fetch-depth: 0

- uses: actions/setup-python@v1

- uses: BSFishy/pip-action@v1
with:
packages: |
boutiques
- name: Download test data
shell: bash -el {0}
run: |
curl -L https://github.com/rob-luke/BIDS-NIRS-Tapping/archive/master.zip --output data.zip
pwd
unzip data.zip -d ./example_data
ls
- name: Where are we and whats around
run: |
pwd
ls
- name: Run bosh
run: |
bosh exec launch fnirsapp_qr.json example_invocation.json --debug
- name: Where are we and whats around
run: |
pwd
ls
ls example_data
ls example_data/BIDS-NIRS-Tapping-master
ls example_data/BIDS-NIRS-Tapping-master/derivatives
ls example_data/BIDS-NIRS-Tapping-master/derivatives/fnirs-app-quality-reports
- uses: actions/upload-artifact@v2
with:
name: Bosh output
path: |
/home/runner/work/fnirs-apps-quality-reports/fnirs-apps-quality-reports/*bosh*
example_data/BIDS-NIRS-Tapping-master/derivatives/fnirs-app-quality-reports/*
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ jobs:
run: docker build --progress=plain -t test .

- name: Run docker image
run: docker run -v /home/runner/example_data/BIDS-NIRS-Tapping-master/:/bids_dataset test --participant_label 03
run: docker run -v /home/runner/example_data/BIDS-NIRS-Tapping-master/:/bids_dataset test --subject-label 03

- name: Run docker image
run: docker run -v /home/runner/example_data/BIDS-NIRS-Tapping-master/:/bids_dataset test --participant_label 03 --pp_threshold 0.6
run: docker run -v /home/runner/example_data/BIDS-NIRS-Tapping-master/:/bids_dataset test --subject-label 03 --pp-threshold 0.6

- name: Run docker image
run: docker run -v /home/runner/example_data/BIDS-NIRS-Tapping-master/:/bids_dataset test --participant_label 03 --pp_threshold 0.6 --sci_threshold 0.8
run: docker run -v /home/runner/example_data/BIDS-NIRS-Tapping-master/:/bids_dataset test --subject-label 03 --pp-threshold 0.6 --sci-threshold 0.8
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ RUN pip install https://github.com/nilearn/nilearn/archive/main.zip
RUN pip install mne-nirs
RUN pip install h5py

COPY run.py /run.py
COPY fnirsapp_qr.py /run.py
RUN chmod +x /run.py

ENTRYPOINT ["/run.py"]
13 changes: 13 additions & 0 deletions example_invocation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"input_datasets": "/home/runner/work/fnirs-apps-quality-reports/fnirs-apps-quality-reports/example_data/BIDS-NIRS-Tapping-master",
"output_location": "/home/runner/work/fnirs-apps-quality-reports/fnirs-apps-quality-reports/example_data/BIDS-NIRS-Tapping-master/derivatives/fnirs-app-quality-reports",
"subject_label": [
"01",
"02"
],
"task_label": [
"tapping"
],
"pp_threshold": 0.6,
"sci_threshold": 0.7
}
100 changes: 100 additions & 0 deletions fnirsapp_qr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"name": "fNIRS Apps: Quality Reports",
"description": "A GLM pipeline for quality reports",
"author": "Robert Luke",
"tool-version": "v0.1.0",
"schema-version": "0.5",
"command-line": "/run.py [InputDataset] [OutputLocation] [SubjectLabel] [TaskLabel] [SCIThreshold] [PeakPowerThreshold]",
"container-image": {
"image": "ghcr.io/rob-luke/fnirs-apps-quality-reports/app",
"index": "ghcr.io",
"type": "docker",
"entrypoint": true
},
"inputs": [
{
"command-line-flag": "--input-datasets",
"id": "input_datasets",
"description": "The directory with the input dataset formatted according to the BIDS standard.",
"name": "input-datasets",
"optional": true,
"type": "File",
"value-key": "[InputDataset]"
},
{
"command-line-flag": "--output-location",
"id": "output_location",
"description": "The directory where the output files should be stored.",
"name": "output-location",
"optional": true,
"type": "File",
"value-key": "[OutputLocation]"
},
{
"command-line-flag": "--subject-label",
"description": "The label(s) of the subjects(s) that should be analyzed. The label corresponds to sub-<subject_label> from the BIDS spec (so it does not include \"sub-\"). If this parameter is not provided all subjects should be analyzed. Multiple participants can be specified with a space separated list.",
"id": "subject_label",
"name": "subject-label",
"optional": true,
"type": "String",
"list": true,
"value-key": "[SubjectLabel]"
},
{
"command-line-flag": "--task-label",
"description": "The label(s) of the tasks(s) that should be analyzed. The label corresponds to task-<subject_label> from the BIDS spec. If this parameter is not provided all tasks should be analyzed. Multiple tasks can be specified with a space separated list.",
"id": "task_label",
"name": "task-label",
"optional": true,
"type": "String",
"list": true,
"value-key": "[TaskLabel]"
},
{
"command-line-flag": "--sci-threshold",
"id": "sci_threshold",
"name": "sci-threshold",
"optional": true,
"type": "Number",
"value-key": "[SCIThreshold]"
},
{
"command-line-flag": "--pp-threshold",
"id": "pp_threshold",
"name": "pp-threshold",
"optional": true,
"type": "Number",
"value-key": "[PeakPowerThreshold]"
}
],
"output-files": [
{
"id": "output_directory",
"name": "BIDS derivatives directory",
"optional": false,
"path-template": "[OutputLocation]"
}
],
"suggested-resources": {
"cpu-cores": 1,
"ram": 1,
"walltime-estimate": 60
},
"tags": {
"domain": [
"neuroimaging",
"fnirs",
"quality",
"bids"
]
},
"error-codes": [
{
"code": 1,
"description": "Crashed"
}
],
"custom": {
"BIDSAppSpecVersion": "Draft"
}
}
36 changes: 19 additions & 17 deletions run.py → fnirsapp_qr.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
import os
import subprocess

__version__ = "v0.0.13"
__version__ = "v0.1.0"


def run(command, env={}):
def fnirsapp_qr(command, env={}):
merged_env = os.environ
merged_env.update(env)
process = subprocess.Popen(command, stdout=subprocess.PIPE,
Expand All @@ -35,27 +35,29 @@ def run(command, env={}):


parser = argparse.ArgumentParser(description='Quality Reports')
parser.add_argument('--bids_dir', default="/bids_dataset", type=str,
parser.add_argument('--input-datasets', default="/bids_dataset", type=str,
help='The directory with the input dataset '
'formatted according to the BIDS standard.')
parser.add_argument('--sci_threshold', type=float, default=0.0,
help='Threshold below which a channel is marked as bad.')
parser.add_argument('--pp_threshold', type=float, default=0.0,
help='Threshold below which a channel is marked as bad.')
parser.add_argument('--participant_label',
parser.add_argument('--output-location', default="/bids_dataset/derivatives/fnirs-apps-quality-reports",
type=str, help='The directory where the output files should be stored.')
parser.add_argument('--subject-label',
help='The label(s) of the participant(s) that should be '
'analyzed. The label corresponds to '
'sub-<participant_label> from the BIDS spec (so it does '
'sub-<subject-label> from the BIDS spec (so it does '
'not include "sub-"). If this parameter is not provided '
'all subjects should be analyzed. Multiple participants '
'can be specified with a space separated list.',
nargs="+")
parser.add_argument('--task_label',
parser.add_argument('--task-label',
help='The label(s) of the tasks(s) that should be '
'analyzed. If this parameter is not provided '
'all tasks should be analyzed. Multiple tasks '
'can be specified with a space separated list.',
nargs="+")
parser.add_argument('--sci-threshold', type=float, default=0.0,
help='Threshold below which a channel is marked as bad.')
parser.add_argument('--pp-threshold', type=float, default=0.0,
help='Threshold below which a channel is marked as bad.')
parser.add_argument('-v', '--version', action='version',
version='BIDS-App Scalp Coupling Index version '
f'{__version__}')
Expand All @@ -69,11 +71,11 @@ def run(command, env={}):

ids = []
# only for a subset of subjects
if args.participant_label:
ids = args.participant_label
if args.subject_label:
ids = args.subject_label
# for all subjects
else:
subject_dirs = glob(op.join(args.bids_dir, "sub-*"))
subject_dirs = glob(op.join(args.input_datasets, "sub-*"))
ids = [subject_dir.split("-")[-1] for
subject_dir in subject_dirs]
print(f"No participants specified, processing {ids}")
Expand All @@ -83,7 +85,7 @@ def run(command, env={}):
if args.task_label:
tasks = args.task_label
else:
all_snirfs = glob(f"{args.bids_dir}/**/*_nirs.snirf", recursive=True)
all_snirfs = glob(f"{args.input_datasets}/**/*_nirs.snirf", recursive=True)
for a in all_snirfs:
s = a.split("_task-")[1]
s = s.split("_nirs.snirf")[0]
Expand Down Expand Up @@ -198,11 +200,11 @@ def summarise_odpsd(raw, report):
########################################

print(" ")
Path(f"{args.bids_dir}/derivatives/fnirs-apps-quality-reports/").\
Path(f"{args.output_location}/").\
mkdir(parents=True, exist_ok=True)
for id in ids:
report = mne.Report(verbose=True, raw_psd=True)
report.parse_folder(f"{args.bids_dir}/sub-{id}", render_bem=False)
report.parse_folder(f"{args.input_datasets}/sub-{id}", render_bem=False)
for idx, fname in enumerate(report.fnames):
if mne.report._endswith(fname, 'nirs'):
raw = mne.io.read_raw_snirf(fname)
Expand All @@ -215,7 +217,7 @@ def summarise_odpsd(raw, report):
raw, report = summarise_sci(raw, report, threshold=args.sci_threshold)
raw, report = summarise_montage(raw, report)

report.save(f"{args.bids_dir}/derivatives/fnirs-apps-quality-reports/"
report.save(f"{args.output_location}/"
f"report_basic_{id}.html",
overwrite=True, open_browser=False)

0 comments on commit f0d18ec

Please sign in to comment.