Skip to content

Commit b53dc9a

Browse files
authored
Merge pull request #11 from NeuroHackademy2024/first-implementation
First implementation
2 parents 636e636 + 4a86b91 commit b53dc9a

File tree

10 files changed

+1626
-3
lines changed

10 files changed

+1626
-3
lines changed

.github/workflows/lint.yaml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Code Style
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
name: "Lint Code Base"
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout code
11+
uses: actions/checkout@v4
12+
13+
- name: Set up Python 3.10
14+
uses: actions/setup-python@v5
15+
with:
16+
# change this to a version matrix
17+
python-version: '3.10'
18+
19+
- name: Install and configure Poetry
20+
uses: snok/install-poetry@v1
21+
with:
22+
version: 1.8.3
23+
virtualenvs-create: true
24+
25+
- name: Install dependencies
26+
run: |
27+
poetry install --only dev --no-root --no-interaction
28+
29+
- name: Lint with flake8
30+
run: |
31+
# stop the build if there are Python syntax errors or undefined names
32+
poetry run flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
33+
poetry run flake8 . --count --max-complexity=10 --max-line-length=88 --statistics
34+
35+
- name: Check with black
36+
run: |
37+
poetry run black . --check --diff
38+
39+
- name: Run GitHub super-linter
40+
uses: github/super-linter/slim@v6
41+
env:
42+
DEFAULT_BRANCH: master
43+
# To report GitHub Actions status checks
44+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45+
VALIDATE_ALL_CODEBASE: true
46+
VALIDATE_YAML: true
47+
VALIDATE_JSON: true
48+
VALIDATE_MD: true
49+
VALIDATE_BASH: true
50+
VALIDATE_DOCKER: true
51+
VALIDATE_ENV: true

bidsinspec/__init__.py

Whitespace-only changes.

bidsinspec/__version__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__version__ = "0.0.1"

bidsinspec/cli.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import argparse
2+
from pathlib import Path
3+
4+
from bidsinspec.__version__ import __version__
5+
from bidsinspec.workflows.report import ReportPipeline
6+
7+
8+
def handler(args: argparse.Namespace) -> int:
9+
10+
bids_dir: Path = args.bids_dir
11+
output_dir: Path = args.output_dir
12+
13+
pipeline = ReportPipeline(
14+
bids_dir=bids_dir,
15+
output_dir=output_dir,
16+
)
17+
pipeline.create_workflow()
18+
pipeline.run()
19+
20+
return 0
21+
22+
23+
def create_parser() -> argparse.ArgumentParser:
24+
25+
parser = argparse.ArgumentParser()
26+
27+
parser.add_argument("bids_dir", type=Path, help="The BIDS directory to inspec.")
28+
parser.add_argument("output_dir", type=Path, help="The output directory.")
29+
parser.add_argument("-v", "--version", action="version", version=__version__)
30+
31+
parser.set_defaults(handler=handler)
32+
33+
return parser
34+
35+
36+
def main() -> int:
37+
parser = create_parser()
38+
args = parser.parse_args()
39+
if hasattr(args, "handler"):
40+
return args.handler(args)
41+
42+
parser.print_help()
43+
return 1

bidsinspec/interfaces/__init__.py

Whitespace-only changes.

bidsinspec/interfaces/bvecs.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# WIP
2+
# Create a custom Nipype interface that plots the bvec file on a sphere and saves figure
3+
from nipype.interfaces.base import BaseInterfaceInputSpec
4+
from nipype.interfaces.base import File
5+
from nipype.interfaces.base import SimpleInterface
6+
from nipype.interfaces.base import TraitedSpec
7+
from nipype.interfaces.base import traits
8+
9+
10+
class _PlotBvecsInputSpec(BaseInterfaceInputSpec):
11+
in_file = File(exists=True, mandatory=True, desc="DWI bvec file to be plotted")
12+
title = traits.Str(desc="a title string for the plot")
13+
out_file = File("bvec.svg", usedefault=True, desc="output file name")
14+
15+
16+
class _PlotBvecsOutputSpec(TraitedSpec):
17+
out_file = File(exists=True, desc="written file path")
18+
19+
20+
class PlotBvecs(SimpleInterface):
21+
"""Plot DWI bvecs on a sphere"""
22+
23+
input_spec = _PlotBvecsInputSpec
24+
output_spec = _PlotBvecsOutputSpec
25+
26+
def _run_interface(self, runtime):
27+
self._results["out_file"] = str(out_file) # noqa wip
28+
29+
# need to create a function that plots bvecs on a sphere
30+
# plot_bvecs()
31+
32+
return runtime

bidsinspec/workflows/__init__.py

Whitespace-only changes.

bidsinspec/workflows/report.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from pathlib import Path
2+
3+
from nipype import IdentityInterface
4+
from nipype.interfaces.io import BIDSDataGrabber
5+
from nipype.pipeline import MapNode
6+
from nipype.pipeline import Node
7+
from nipype.pipeline import Workflow
8+
from nireports.interfaces.fmri import FMRISummary
9+
from nireports.interfaces.mosaic import PlotMosaic
10+
11+
12+
class ReportPipeline:
13+
def __init__(
14+
self,
15+
bids_dir: str | Path,
16+
output_dir: str | Path,
17+
name: str = "report_processing",
18+
):
19+
self.name = name
20+
self.bids_dir = bids_dir
21+
self.base_dir = output_dir
22+
23+
def create_workflow(self):
24+
workflow = Workflow(name=self.name, base_dir=self.base_dir)
25+
workflow.config["execution"] = {"remove_unnecessary_outputs": False}
26+
27+
i = 0
28+
input_node = Node(
29+
IdentityInterface(
30+
fields=[
31+
"bids_dir",
32+
],
33+
),
34+
name="inputnode",
35+
)
36+
37+
i += 1
38+
bids_grab = Node(BIDSDataGrabber(), name=f"{i:02}_BIDSGrabber")
39+
40+
workflow.connect(input_node, "bids_dir", bids_grab, "base_dir")
41+
42+
i += 1
43+
plot_anat = MapNode(
44+
PlotMosaic(title="Raw T1w"), name=f"{i:02}_PlotAnat", iterfield="in_file"
45+
)
46+
workflow.connect(bids_grab, "T1w", plot_anat, "in_file")
47+
48+
i += 1
49+
fmri_summary = MapNode(
50+
FMRISummary(), name=f"{i:02}_FMRISummary", iterfield="in_func"
51+
)
52+
workflow.connect(bids_grab, "bold", fmri_summary, "in_func")
53+
54+
return workflow
55+
56+
def run(self):
57+
workflow = self.create_workflow()
58+
workflow.write_graph("pipeline_flat.dot", graph2use="flat")
59+
workflow.write_graph("pipeline_hier.dot", graph2use="hierarchical")
60+
workflow.write_graph("pipeline_col.dot", graph2use="colored")
61+
62+
in_node = workflow.get_node("inputnode")
63+
in_node.inputs.bids_dir = self.bids_dir
64+
workflow.run()

0 commit comments

Comments
 (0)