diff --git a/docs/api.rst b/docs/api.rst index 83c5c692..125a4ea5 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -35,6 +35,5 @@ Other Utilities api/qsirecon.interfaces api/qsirecon.utils - api/qsirecon.report - api/qsirecon.viz + api/qsirecon.reports api/qsirecon.qc diff --git a/pyproject.toml b/pyproject.toml index d44d7a09..8682f17e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,7 @@ dependencies = [ "nibabel <= 5.2.0", "nilearn == 0.10.1", "nipype == 1.8.6", + "nireports", "niworkflows >=1.9,<= 1.10", "numpy <= 1.26.3", "pandas < 2.0.0", @@ -177,6 +178,7 @@ markers = [ "pyafq_recon_full: test 19", "mrtrix3_recon: test 20", "tortoise_recon: test 21", + "autotrack: test 22", ] env = [ "RUNNING_PYTEST = 1", diff --git a/qsirecon/cli/parser.py b/qsirecon/cli/parser.py index bfa0119f..9d7bf996 100644 --- a/qsirecon/cli/parser.py +++ b/qsirecon/cli/parser.py @@ -450,9 +450,6 @@ def parse_args(args=None, namespace=None): work_dir = config.execution.work_dir version = config.environment.version - if config.execution.reportlets_dir is None: - config.execution.reportlets_dir = work_dir / "reportlets" - # Update the config with an empty dict to trigger initialization of all config # sections (we used `init=False` above). # This must be done after cleaning the work directory, or we could delete an @@ -479,7 +476,6 @@ def parse_args(args=None, namespace=None): config.execution.log_dir = config.execution.output_dir / "logs" # Check and create output and working directories config.execution.log_dir.mkdir(exist_ok=True, parents=True) - config.execution.reportlets_dir.mkdir(exist_ok=True, parents=True) work_dir.mkdir(exist_ok=True, parents=True) # Force initialization of the BIDSLayout diff --git a/qsirecon/cli/run.py b/qsirecon/cli/run.py index 5e4b87ab..213b35b4 100644 --- a/qsirecon/cli/run.py +++ b/qsirecon/cli/run.py @@ -171,17 +171,13 @@ def main(): errno = 0 finally: - from ..viz.reports import generate_reports + from ..reports.core import generate_reports + from ..workflows.base import _load_recon_spec + from .workflow import copy_boilerplate # Generate reports phase - # session_list = ( - # config.execution.get().get('bids_filters', {}).get('dwi', {}).get('session') - # ) + session_list = config.execution.get().get("bids_filters", {}).get("dwi", {}).get("session") - failed_reports = generate_reports( - config.execution.participant_label, - # session_list=session_list, - ) write_derivative_description( config.execution.bids_dir, config.execution.output_dir, @@ -189,21 +185,39 @@ def main(): ) write_bidsignore(config.execution.output_dir) + workflow_spec = _load_recon_spec() + # Compile list of output folders + # TODO: Retain QSIRecon pipeline names in the config object + qsirecon_suffixes = [] + for node_spec in workflow_spec["nodes"]: + qsirecon_suffix = node_spec.get("qsirecon_suffix", None) + qsirecon_suffixes += [qsirecon_suffix] if qsirecon_suffix else [] + + qsirecon_suffixes = sorted(list(set(qsirecon_suffixes))) + config.loggers.cli.info(f"QSIRecon pipeline suffixes: {qsirecon_suffixes}") + failed_reports = [] + for qsirecon_suffix in qsirecon_suffixes: + suffix_dir = str(config.execution.output_dir / f"qsirecon-{qsirecon_suffix}") + + # Copy the boilerplate files + copy_boilerplate(config.execution.output_dir, suffix_dir) + + suffix_failed_reports = generate_reports( + config.execution.participant_label, + suffix_dir, + config.execution.run_uuid, + session_list=session_list, + qsirecon_suffix=qsirecon_suffix, + ) + failed_reports += suffix_failed_reports + write_derivative_description( + config.execution.bids_dir, + suffix_dir, + # dataset_links=config.execution.dataset_links, + ) + write_bidsignore(suffix_dir) + if failed_reports: print(failed_reports) - # msg = ( - # 'Report generation was not successful for the following participants ' - # f': {", ".join(failed_reports)}.' - # ) - # config.loggers.cli.error(msg) - # if sentry_sdk is not None: - # sentry_sdk.capture_message(msg, level='error') - - # If preprocessing and recon are requested in the same call, start the recon workflow now. - if errno > 0: - if config.nipype.stop_on_first_crash: - config.loggers.workflow.critical( - "Errors occurred during preprocessing - Recon will not run." - ) - sys.exit(int((errno + failed_reports) > 0)) + sys.exit(int(errno + len(failed_reports)) > 0) diff --git a/qsirecon/cli/workflow.py b/qsirecon/cli/workflow.py index b37e329f..5466a32e 100644 --- a/qsirecon/cli/workflow.py +++ b/qsirecon/cli/workflow.py @@ -45,8 +45,8 @@ def build_workflow(config_file, retval): # from niworkflows.utils.misc import check_valid_fs_license # from ..utils.bids import check_pipeline_version from .. import config + from ..reports.core import generate_reports from ..utils.misc import check_deps - from ..viz.reports import generate_reports from ..workflows.base import init_qsirecon_wf config.load(config_file) @@ -99,6 +99,7 @@ def build_workflow(config_file, retval): config.execution.output_dir, config.execution.run_uuid, session_list=session_list, + qsirecon_suffix="", ) if failed_reports: config.loggers.cli.error( @@ -224,3 +225,17 @@ def build_boilerplate(config_file, workflow): check_call(cmd, timeout=10) except (FileNotFoundError, CalledProcessError, TimeoutExpired): config.loggers.cli.warning("Could not generate CITATION.tex file:\n%s", " ".join(cmd)) + + +def copy_boilerplate(in_dir, out_dir): + import shutil + + in_logs_path = Path(in_dir) / "logs" + out_logs_path = Path(out_dir) / "logs" + out_logs_path.mkdir(exist_ok=True, parents=True) + citation_files = { + ext: in_logs_path / ("CITATION.%s" % ext) for ext in ("bib", "tex", "md", "html") + } + for ext, citation_file in citation_files.items(): + if citation_file.exists(): + shutil.copy(citation_file, out_logs_path / f"CITATION.{ext}") diff --git a/qsirecon/config.py b/qsirecon/config.py index c08cd119..86cba184 100644 --- a/qsirecon/config.py +++ b/qsirecon/config.py @@ -426,8 +426,6 @@ class execution(_Config): """List of participant identifiers that are to be preprocessed.""" freesurfer_input = None """Directory containing FreeSurfer directories to use for recon workflows.""" - reportlets_dir = None - """Path where reportlets are written.""" templateflow_home = _templateflow_home """The root folder of the TemplateFlow client.""" work_dir = Path("work").absolute() @@ -436,6 +434,8 @@ class execution(_Config): """Write out the computational graph corresponding to the planned postprocessing.""" dataset_links = {} """A dictionary of dataset links to be used to track Sources in sidecars.""" + aggr_ses_reports = 4 # TODO: Change to None when implemented on command line + """Maximum number of sessions aggregated in one subject's visual report.""" _layout = None @@ -450,7 +450,6 @@ class execution(_Config): "layout", "log_dir", "output_dir", - "reportlets_dir", "templateflow_home", "work_dir", ) diff --git a/qsirecon/data/__init__.py b/qsirecon/data/__init__.py index 2cc826d4..0b93b473 100644 --- a/qsirecon/data/__init__.py +++ b/qsirecon/data/__init__.py @@ -1,5 +1,182 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- -# vi: set ft=python sts=4 ts=4 sw=4 et: -""" Data fetchers module """ +"""QSIRecon data files + +.. autofunction:: load + +.. automethod:: load.readable + +.. automethod:: load.as_path + +.. automethod:: load.cached + +.. autoclass:: Loader +""" + +from __future__ import annotations + +import atexit +import os +from contextlib import AbstractContextManager, ExitStack +from functools import cached_property +from pathlib import Path +from types import ModuleType + +try: + from functools import cache +except ImportError: # PY38 + from functools import lru_cache as cache + +try: # Prefer backport to leave consistency to dependency spec + from importlib_resources import as_file, files +except ImportError: + from importlib.resources import as_file, files # type: ignore + +try: # Prefer stdlib so Sphinx can link to authoritative documentation + from importlib.resources.abc import Traversable +except ImportError: + from importlib_resources.abc import Traversable + +__all__ = ["load"] + + +class Loader: + """A loader for package files relative to a module + + This class wraps :mod:`importlib.resources` to provide a getter + function with an interpreter-lifetime scope. For typical packages + it simply passes through filesystem paths as :class:`~pathlib.Path` + objects. For zipped distributions, it will unpack the files into + a temporary directory that is cleaned up on interpreter exit. + + This loader accepts a fully-qualified module name or a module + object. + + Expected usage:: + + '''Data package + + .. autofunction:: load_data + + .. automethod:: load_data.readable + + .. automethod:: load_data.as_path + + .. automethod:: load_data.cached + ''' + + from qsirecon.data import Loader + + load_data = Loader(__package__) + + :class:`~Loader` objects implement the :func:`callable` interface + and generate a docstring, and are intended to be treated and documented + as functions. + + For greater flexibility and improved readability over the ``importlib.resources`` + interface, explicit methods are provided to access resources. + + +---------------+----------------+------------------+ + | On-filesystem | Lifetime | Method | + +---------------+----------------+------------------+ + | `True` | Interpreter | :meth:`cached` | + +---------------+----------------+------------------+ + | `True` | `with` context | :meth:`as_path` | + +---------------+----------------+------------------+ + | `False` | n/a | :meth:`readable` | + +---------------+----------------+------------------+ + + It is also possible to use ``Loader`` directly:: + + from qsirecon.data import Loader + + Loader(other_package).readable('data/resource.ext').read_text() + + with Loader(other_package).as_path('data') as pkgdata: + # Call function that requires full Path implementation + func(pkgdata) + + # contrast to + + from importlib_resources import files, as_file + + files(other_package).joinpath('data/resource.ext').read_text() + + with as_file(files(other_package) / 'data') as pkgdata: + func(pkgdata) + + .. automethod:: readable + + .. automethod:: as_path + + .. automethod:: cached + """ + + def __init__(self, anchor: str | ModuleType): + self._anchor = anchor + self.files = files(anchor) + self.exit_stack = ExitStack() + atexit.register(self.exit_stack.close) + # Allow class to have a different docstring from instances + self.__doc__ = self._doc + + @cached_property + def _doc(self): + """Construct docstring for instances + + Lists the public top-level paths inside the location, where + non-public means has a `.` or `_` prefix or is a 'tests' + directory. + """ + top_level = sorted( + os.path.relpath(p, self.files) + "/"[: p.is_dir()] + for p in self.files.iterdir() + if p.name[0] not in (".", "_") and p.name != "tests" + ) + doclines = [ + f"Load package files relative to ``{self._anchor}``.", + "", + "This package contains the following (top-level) files/directories:", + "", + *(f"* ``{path}``" for path in top_level), + ] + + return "\n".join(doclines) + + def readable(self, *segments) -> Traversable: + """Provide read access to a resource through a Path-like interface. + + This file may or may not exist on the filesystem, and may be + efficiently used for read operations, including directory traversal. + + This result is not cached or copied to the filesystem in cases where + that would be necessary. + """ + return self.files.joinpath(*segments) + + def as_path(self, *segments) -> AbstractContextManager[Path]: + """Ensure data is available as a :class:`~pathlib.Path`. + + This method generates a context manager that yields a Path when + entered. + + This result is not cached, and any temporary files that are created + are deleted when the context is exited. + """ + return as_file(self.files.joinpath(*segments)) + + @cache # noqa: B019 + def cached(self, *segments) -> Path: + """Ensure data is available as a :class:`~pathlib.Path`. + + Any temporary files that are created remain available throughout + the duration of the program, and are deleted when Python exits. + + Results are cached so that multiple calls do not unpack the same + data multiple times, but the cache is sensitive to the specific + argument(s) passed. + """ + return self.exit_stack.enter_context(as_file(self.files.joinpath(*segments))) + + __call__ = cached + + +load = Loader(__package__) diff --git a/qsirecon/data/reports-spec-anat.yml b/qsirecon/data/reports-spec-anat.yml new file mode 100644 index 00000000..1b3ba4cf --- /dev/null +++ b/qsirecon/data/reports-spec-anat.yml @@ -0,0 +1,40 @@ +package: qsirecon +title: Anatomical report for participant '{subject}' - QSIRecon-{qsirecon_suffix} +sections: +- name: Summary + reportlets: + - bids: {datatype: figures, desc: summary, suffix: T1w} + +- name: Anatomical + reportlets: + - bids: + datatype: figures + desc: conform + extension: [.html] + suffix: T1w + - bids: {datatype: figures, suffix: dseg} + caption: | + This panel shows the template T1-weighted image (if several T1w images were found), + with contours delineating the detected brain mask and brain tissue segmentations. + subtitle: Brain mask and brain tissue segmentation of the T1w + +- name: About + reportlets: + - bids: {datatype: figures, desc: about, suffix: T1w} + - custom: boilerplate + path: '{out_dir}/logs' + bibfile: ['qsirecon', 'data/boilerplate.bib'] + caption: | +
We kindly ask to report results preprocessed with this tool using the following boilerplate.
++ Copyright Waiver. + The boilerplate text was automatically generated by NiReports with the + express intention that users should copy and paste this text into their manuscripts unchanged. + It is released under the + CC0 license. +
+ title: Methods + - custom: errors + path: '{out_dir}/sub-{subject}/log/{run_uuid}' + captions: NiReports may have recorded failure conditions. + title: Errors diff --git a/qsirecon/data/reports-spec-dwi.yml b/qsirecon/data/reports-spec-dwi.yml new file mode 100644 index 00000000..13330904 --- /dev/null +++ b/qsirecon/data/reports-spec-dwi.yml @@ -0,0 +1,132 @@ +package: qsirecon +title: Diffusion report for participant '{subject}', session '{session}' - QSIRecon-{qsirecon_suffix} +sections: +- name: MRtrix3 + ordering: session,task,acquisition,ceagent,reconstruction,direction,run,echo + reportlets: + - bids: {datatype: figures, desc: wmFOD, suffix: peaks} + subtitle: Constrained Spherical Deconvolution + caption: Directionally color-coded FOD peaks overlaid on the b=0 reference image. + - bids: {datatype: figures, desc: wmFOD, suffix: odfs} + subtitle: Constrained Spherical Deconvolution + caption: Three views of ODFs in ROIs. + - bids: {datatype: figures, suffix: unringing} + subtitle: Gibbs Ringing Removal + caption: Effect of removing Gibbs ringing on a low and high-b image. + - bids: {datatype: figures, suffix: biascorr} + subtitle: DWI Bias Correction + caption: | + Effect of bias correction on a low and high-b image. Bias field contour lines are drawn as an overlay. + - bids: {datatype: figures, desc: MRtrix3Connectivity, suffix: matrices} + subtitle: MRtrix3 Connectivity + caption: Connectivity estimated by tck2connectome. + +- name: DSI Studio + ordering: session,task,acquisition,ceagent,reconstruction,direction,run,echo + reportlets: + - bids: {datatype: figures, desc: GQIODF, suffix: peaks} + subtitle: Generalized q-sampling Imaging (GQI) + caption: Directionally color-coded ODF peaks overlaid on the b=0 reference image. + - bids: {datatype: figures, desc: GQIODF, suffix: odfs} + subtitle: GQI + caption: Three views of ODFs in ROIs. + - bids: {datatype: figures, desc: DSIStudioConnectivity, suffix: matrices} + subtitle: Connectivity + caption: Connectivity estimated by DSI Studio. + +- name: Dipy + ordering: session,task,acquisition,ceagent,reconstruction,direction,run,echo + reportlets: + - bids: {datatype: figures, desc: 3dSHOREODF, suffix: peaks} + subtitle: 3dSHORE + caption: Directionally color-coded ODF peaks overlaid on the b=0 reference image. + - bids: {datatype: figures, desc: 3dSHOREODF, suffix: odfs} + subtitle: 3dSHORE + caption: Three views of ODFs in ROIs. + - bids: {datatype: figures, desc: MAPLMRIODF, suffix: peaks} + subtitle: MAP(L)MRI + caption: Directionally color-coded ODF peaks overlaid on the b=0 reference image. + - bids: {datatype: figures, desc: MAPLMRIODF, suffix: odfs} + subtitle: MAP(L)MRI + caption: Three views of ODFs in ROIs. + +- name: AMICO + ordering: session,task,acquisition,ceagent,reconstruction,direction,run,echo + reportlets: + - bids: {datatype: figures, desc: NODDI, suffix: peaks} + subtitle: NODDI + caption: Directionally color-coded ODF peaks overlaid on the b=0 reference image. + +- name: Connectome + ordering: session,task,acquisition,ceagent,reconstruction,direction,run,echo + reportlets: + - bids: {datatype: figures, suffix: summary} + - bids: {datatype: figures, suffix: validation} + - bids: {datatype: figures, suffix: b0ref} + subtitle: b=0 Reference Image + caption: | + b=0 template and final mask output. The t1 and signal intersection mask is blue, + their xor is red and the entire mask is plotted in cyan. + - bids: {datatype: figures, desc: sampling, suffix: scheme} + subtitle: DWI Sampling Scheme + caption: Animation of the DWI sampling scheme. Each separate scan is its own color. + - bids: {datatype: figures, desc: shoreline, suffix: iterdata} + subtitle: SHORELine Convergence + caption: | + Difference in motion estimates over SHORELine iterations. + Values close to zero indicate good convergence. + - bids: {datatype: figures, suffix: intramodal} + subtitle: Registration to Intramodal Template + caption: | + b0 reference image warped to the across-scan/session b0 template + - bids: {datatype: figures, desc: shoreline, suffix: animation} + subtitle: SHORELine Registration + caption: | + Maximum intensity projections of each DWI before and after SHORELine registration. + Orange lines are from the observed image and magenta lines are from the model-based registration target. + - bids: {datatype: figures, desc: fmap, suffix: reg} + subtitle: Fieldmap to EPI registration + caption: | + Results of affine coregistration between the magnitude image of the fieldmap and the reference EPI image. + - bids: {datatype: figures, desc: fmap, suffix: regvsm} + subtitle: Fieldmap + caption: | + Overlaid on the reference EPI image. + - bids: {datatype: figures, suffix: sdc} + subtitle: Susceptibility distortion correction + caption: | + Results of performing susceptibility distortion correction (SDC) on the EPI. + - bids: {datatype: figures, suffix: forcedsyn} + subtitle: Experimental fieldmap-less susceptibility distortion correction + caption: | + The dataset contained some fieldmap information, but the argument--force-syn
was used.
+ The higher-priority SDC method was used.
+ Here, we show the results of performing SyN-based SDC on the EPI for comparison.
+ - bids: {datatype: figures, suffix: coreg}
+ subtitle: b0 to T1 registration
+ caption: |
+ antsRegistration
was used to generate transformations from b0I-space to T1w-space.
+ - bids: {datatype: figures, suffix: intramodal}
+ subtitle: Registration to the Intramodal Template
+ caption: |
+ The B0 template registered to the modpoint B=0 image.
+ - bids: {datatype: figures, suffix: interactive}
+ subtitle: INTERACT
+ caption: |
+ Interactive QC Widgets.
+ - bids: {datatype: figures, suffix: carpetplot}
+ subtitle: DWI Summary
+ caption: |
+ Summary statistics are plotted, which may reveal trends or artifacts in the DWI data.
+ Global signals calculated within the whole-brain (GS),
+ within the white-matter (WM) and within cerebro-spinal fluid (CSF) show the mean DWI signal in their
+ corresponding masks.
+ DVARS and FD show the standardized DVARS and framewise-displacement measures for each time point.
+ --force-syn
was used.
+ The higher-priority SDC method was used.
+ Here, we show the results of performing SyN-based SDC on the EPI for comparison.
+ - bids: {datatype: figures, suffix: coreg}
+ subtitle: b0 to T1 registration
+ caption: |
+ antsRegistration
was used to generate transformations from b0I-space to T1w-space.
+ - bids: {datatype: figures, suffix: intramodal}
+ subtitle: Registration to the Intramodal Template
+ caption: |
+ The B0 template registered to the modpoint B=0 image.
+ - bids: {datatype: figures, suffix: interactive}
+ subtitle: INTERACT
+ caption: |
+ Interactive QC Widgets.
+ - bids: {datatype: figures, suffix: carpetplot}
+ subtitle: DWI Summary
+ caption: |
+ Summary statistics are plotted, which may reveal trends or artifacts in the DWI data.
+ Global signals calculated within the whole-brain (GS),
+ within the white-matter (WM) and within cerebro-spinal fluid (CSF) show the mean DWI signal in their
+ corresponding masks.
+ DVARS and FD show the standardized DVARS and framewise-displacement measures for each time point.
+ We kindly ask to report results preprocessed with this tool using the following boilerplate.
++ Copyright Waiver. + The boilerplate text was automatically generated by NiReports with the + express intention that users should copy and paste this text into their manuscripts unchanged. + It is released under the + CC0 license. +
+ title: Methods + - custom: errors + path: '{out_dir}/sub-{subject}/log/{run_uuid}' + captions: NiReports may have recorded failure conditions. + title: Errors diff --git a/qsirecon/reports/core.py b/qsirecon/reports/core.py index a9924d4b..c7df2323 100644 --- a/qsirecon/reports/core.py +++ b/qsirecon/reports/core.py @@ -35,6 +35,7 @@ def run_reports( out_filename="report.html", reportlets_dir=None, errorname="report.err", + metadata=None, **entities, ): """ @@ -48,7 +49,7 @@ def run_reports( reportlets_dir=reportlets_dir, plugins=None, plugin_meta=None, - metadata=None, + metadata=metadata, **entities, ) @@ -67,7 +68,13 @@ def run_reports( def generate_reports( - subject_list, output_dir, run_uuid, session_list=None, bootstrap_file=None, work_dir=None + subject_list, + output_dir, + run_uuid, + session_list=None, + bootstrap_file=None, + work_dir=None, + qsirecon_suffix="", ): """Generate reports for a list of subjects.""" reportlets_dir = None @@ -105,6 +112,7 @@ def generate_reports( out_filename=html_report, reportlets_dir=reportlets_dir, errorname=f"report-{run_uuid}-{subject_label}.err", + metadata={"qsirecon_suffix": qsirecon_suffix}, subject=subject_label, ) # If the report generation failed, append the subject label for which it failed @@ -136,6 +144,7 @@ def generate_reports( out_filename=html_report, reportlets_dir=reportlets_dir, errorname=f"report-{run_uuid}-{subject_label}-func.err", + metadata={"qsirecon_suffix": qsirecon_suffix}, subject=subject_label, session=session_label, ) diff --git a/qsirecon/tests/data/amico_noddi_outputs.txt b/qsirecon/tests/data/amico_noddi_outputs.txt index 9032b10a..e6f6b1b8 100644 --- a/qsirecon/tests/data/amico_noddi_outputs.txt +++ b/qsirecon/tests/data/amico_noddi_outputs.txt @@ -4,10 +4,15 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-NODDI +qsirecon-NODDI/dataset_description.json +qsirecon-NODDI/logs +qsirecon-NODDI/logs/CITATION.bib +qsirecon-NODDI/logs/CITATION.html +qsirecon-NODDI/logs/CITATION.md +qsirecon-NODDI/logs/CITATION.tex qsirecon-NODDI/sub-PNC +qsirecon-NODDI/sub-PNC.html qsirecon-NODDI/sub-PNC/dwi qsirecon-NODDI/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_dwimap.fib.gz qsirecon-NODDI/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_model-NODDI_mfp-AMICOconfig_dwimap.pickle.gz @@ -15,8 +20,4 @@ qsirecon-NODDI/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_model-no qsirecon-NODDI/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_model-noddi_mdp-isovf_dwimap.nii.gz qsirecon-NODDI/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_model-noddi_mdp-od_dwimap.nii.gz qsirecon-NODDI/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_model-noddi_mfp-direction_dwimap.nii.gz -qsirecon/dwiqc.json -qsirecon/sub-PNC -qsirecon/sub-PNC -qsirecon/sub-PNC.html sub-PNC diff --git a/qsirecon/tests/data/autotrack_outputs.txt b/qsirecon/tests/data/autotrack_outputs.txt index 27283456..295bca89 100644 --- a/qsirecon/tests/data/autotrack_outputs.txt +++ b/qsirecon/tests/data/autotrack_outputs.txt @@ -4,9 +4,14 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-DSIStudio +qsirecon-DSIStudio/dataset_description.json +qsirecon-DSIStudio/logs +qsirecon-DSIStudio/logs/CITATION.bib +qsirecon-DSIStudio/logs/CITATION.html +qsirecon-DSIStudio/logs/CITATION.md +qsirecon-DSIStudio/logs/CITATION.tex +qsirecon-DSIStudio/sub-ABCD.html qsirecon-DSIStudio/sub-ABCD qsirecon-DSIStudio/sub-ABCD/dwi qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_bundle-Association_ArcuateFasciculusL_streamlines.tck.gz @@ -14,7 +19,4 @@ qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_bun qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_bundlestats.csv qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap.fib.gz qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_mapping.map.gz -qsirecon/dwiqc.json -qsirecon/sub-ABCD -qsirecon/sub-ABCD.html sub-ABCD diff --git a/qsirecon/tests/data/cuda_outputs.txt b/qsirecon/tests/data/cuda_outputs.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/qsirecon/tests/data/dipy_dki_outputs.txt b/qsirecon/tests/data/dipy_dki_outputs.txt index fd7a1eb4..b8cbed1a 100644 --- a/qsirecon/tests/data/dipy_dki_outputs.txt +++ b/qsirecon/tests/data/dipy_dki_outputs.txt @@ -4,10 +4,15 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-DKI +qsirecon-DKI/dataset_description.json +qsirecon-DKI/logs +qsirecon-DKI/logs/CITATION.bib +qsirecon-DKI/logs/CITATION.html +qsirecon-DKI/logs/CITATION.md +qsirecon-DKI/logs/CITATION.tex qsirecon-DKI/sub-ABCD +qsirecon-DKI/sub-ABCD.html qsirecon-DKI/sub-ABCD/dwi qsirecon-DKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-dki_mdp-AD_dwimap.nii.gz qsirecon-DKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-dki_mdp-AK_dwimap.nii.gz @@ -18,7 +23,4 @@ qsirecon-DKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-dki qsirecon-DKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-dki_mdp-RD_dwimap.nii.gz qsirecon-DKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-dki_mdp-RK_dwimap.nii.gz qsirecon-DKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-tensor_mdp-FA_dwimap.nii.gz -qsirecon/dwiqc.json -qsirecon/sub-ABCD -qsirecon/sub-ABCD.html sub-ABCD diff --git a/qsirecon/tests/data/dipy_mapmri_outputs.txt b/qsirecon/tests/data/dipy_mapmri_outputs.txt index 916b992a..6bbd454b 100644 --- a/qsirecon/tests/data/dipy_mapmri_outputs.txt +++ b/qsirecon/tests/data/dipy_mapmri_outputs.txt @@ -4,10 +4,15 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-DIPYMAPMRI +qsirecon-DIPYMAPMRI/dataset_description.json +qsirecon-DIPYMAPMRI/logs +qsirecon-DIPYMAPMRI/logs/CITATION.bib +qsirecon-DIPYMAPMRI/logs/CITATION.html +qsirecon-DIPYMAPMRI/logs/CITATION.md +qsirecon-DIPYMAPMRI/logs/CITATION.tex qsirecon-DIPYMAPMRI/sub-ABCD +qsirecon-DIPYMAPMRI/sub-ABCD.html qsirecon-DIPYMAPMRI/sub-ABCD/dwi qsirecon-DIPYMAPMRI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap.fib.gz qsirecon-DIPYMAPMRI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap.mif @@ -20,7 +25,4 @@ qsirecon-mapmri_recon/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_ qsirecon-mapmri_recon/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-mapmri_mdp-RTOP_dwimap.nii.gz qsirecon-mapmri_recon/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-mapmri_mdp-RTPP_dwimap.nii.gz qsirecon-mapmri_recon/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-mapmri_mfp-lapnorm_dwimap.nii.gz -qsirecon/dwiqc.json -qsirecon/sub-ABCD -qsirecon/sub-ABCD.html sub-ABCD diff --git a/qsirecon/tests/data/mrtrix3_recon_outputs.txt b/qsirecon/tests/data/mrtrix3_recon_outputs.txt index ab52c710..18ca052d 100644 --- a/qsirecon/tests/data/mrtrix3_recon_outputs.txt +++ b/qsirecon/tests/data/mrtrix3_recon_outputs.txt @@ -4,10 +4,15 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-MRtrix3_act-FAST +qsirecon-MRtrix3_act-FAST/dataset_description.json +qsirecon-MRtrix3_act-FAST/logs +qsirecon-MRtrix3_act-FAST/logs/CITATION.bib +qsirecon-MRtrix3_act-FAST/logs/CITATION.html +qsirecon-MRtrix3_act-FAST/logs/CITATION.md +qsirecon-MRtrix3_act-FAST/logs/CITATION.tex qsirecon-MRtrix3_act-FAST/sub-ABCD +qsirecon-MRtrix3_act-FAST/sub-ABCD.html qsirecon-MRtrix3_act-FAST/sub-ABCD/dwi qsirecon-MRtrix3_act-FAST/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_connectivity.mat qsirecon-MRtrix3_act-FAST/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_exemplarbundles.zip @@ -46,7 +51,4 @@ qsirecon-anat/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_atlas-sc qsirecon-anat/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_atlas-schaefer400_dseg.mif.gz qsirecon-anat/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_atlas-schaefer400_dseg.nii.gz qsirecon-anat/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_atlas-schaefer400_dseg.txt -qsirecon/dwiqc.json -qsirecon/sub-ABCD -qsirecon/sub-ABCD.html sub-ABCD diff --git a/qsirecon/tests/data/mrtrix_singleshell_ss3t_act_outputs.txt b/qsirecon/tests/data/mrtrix_singleshell_ss3t_act_outputs.txt index 1cf9586d..eb015d09 100644 --- a/qsirecon/tests/data/mrtrix_singleshell_ss3t_act_outputs.txt +++ b/qsirecon/tests/data/mrtrix_singleshell_ss3t_act_outputs.txt @@ -4,9 +4,14 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-MRtrix3_fork-SS3T_act-FAST +qsirecon-MRtrix3_fork-SS3T_act-FAST/dataset_description.json +qsirecon-MRtrix3_fork-SS3T_act-FAST/logs +qsirecon-MRtrix3_fork-SS3T_act-FAST/logs/CITATION.bib +qsirecon-MRtrix3_fork-SS3T_act-FAST/logs/CITATION.html +qsirecon-MRtrix3_fork-SS3T_act-FAST/logs/CITATION.md +qsirecon-MRtrix3_fork-SS3T_act-FAST/logs/CITATION.tex +qsirecon-MRtrix3_fork-SS3T_act-FAST/sub-PNC.html qsirecon-MRtrix3_fork-SS3T_act-FAST/sub-PNC qsirecon-MRtrix3_fork-SS3T_act-FAST/sub-PNC/dwi qsirecon-MRtrix3_fork-SS3T_act-FAST/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_connectivity.mat @@ -46,8 +51,4 @@ qsirecon-anat/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_atlas-sch qsirecon-anat/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_atlas-schaefer400_dseg.mif.gz qsirecon-anat/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_atlas-schaefer400_dseg.nii.gz qsirecon-anat/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_atlas-schaefer400_dseg.txt -qsirecon/dwiqc.json -qsirecon/sub-PNC -qsirecon/sub-PNC -qsirecon/sub-PNC.html sub-PNC diff --git a/qsirecon/tests/data/mrtrix_singleshell_ss3t_noact_outputs.txt b/qsirecon/tests/data/mrtrix_singleshell_ss3t_noact_outputs.txt index 878e39d2..0fa67003 100644 --- a/qsirecon/tests/data/mrtrix_singleshell_ss3t_noact_outputs.txt +++ b/qsirecon/tests/data/mrtrix_singleshell_ss3t_noact_outputs.txt @@ -4,10 +4,15 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-MRtrix3_fork-SS3T_act-None +qsirecon-MRtrix3_fork-SS3T_act-None/dataset_description.json +qsirecon-MRtrix3_fork-SS3T_act-None/logs +qsirecon-MRtrix3_fork-SS3T_act-None/logs/CITATION.bib +qsirecon-MRtrix3_fork-SS3T_act-None/logs/CITATION.html +qsirecon-MRtrix3_fork-SS3T_act-None/logs/CITATION.md +qsirecon-MRtrix3_fork-SS3T_act-None/logs/CITATION.tex qsirecon-MRtrix3_fork-SS3T_act-None/sub-PNC +qsirecon-MRtrix3_fork-SS3T_act-None/sub-PNC.html qsirecon-MRtrix3_fork-SS3T_act-None/sub-PNC/dwi qsirecon-MRtrix3_fork-SS3T_act-None/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_connectivity.mat qsirecon-MRtrix3_fork-SS3T_act-None/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_exemplarbundles.zip @@ -46,8 +51,4 @@ qsirecon-anat/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_atlas-sch qsirecon-anat/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_atlas-schaefer400_dseg.mif.gz qsirecon-anat/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_atlas-schaefer400_dseg.nii.gz qsirecon-anat/sub-PNC/dwi/sub-PNC_acq-realistic_space-T1w_desc-preproc_atlas-schaefer400_dseg.txt -qsirecon/dwiqc.json -qsirecon/sub-PNC -qsirecon/sub-PNC -qsirecon/sub-PNC.html sub-PNC diff --git a/qsirecon/tests/data/pyafq_recon_external_trk_outputs.txt b/qsirecon/tests/data/pyafq_recon_external_trk_outputs.txt index 74d57ded..fb16ee0f 100644 --- a/qsirecon/tests/data/pyafq_recon_external_trk_outputs.txt +++ b/qsirecon/tests/data/pyafq_recon_external_trk_outputs.txt @@ -1,16 +1,19 @@ -qsirecon dataset_description.json -qsirecon/dwiqc.json logs logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex sub-ABCD -qsirecon/sub-ABCD.html -qsirecon qsirecon-MRtrix3 +qsirecon-MRtrix3/dataset_description.json +qsirecon-MRtrix3/logs +qsirecon-MRtrix3/logs/CITATION.bib +qsirecon-MRtrix3/logs/CITATION.html +qsirecon-MRtrix3/logs/CITATION.md +qsirecon-MRtrix3/logs/CITATION.tex qsirecon-MRtrix3/sub-ABCD +qsirecon-MRtrix3/sub-ABCD.html qsirecon-MRtrix3/sub-ABCD/dwi qsirecon-MRtrix3/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-SD_Stream_streamlines.tck qsirecon-MRtrix3/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-msmt_csd_mfp-FOD_label-CSF_dwimap.mif.gz @@ -24,7 +27,14 @@ qsirecon-MRtrix3/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model qsirecon-MRtrix3/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-sift2_mu.txt qsirecon-MRtrix3/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-sift2_streamlineweights.csv qsirecon-PYAFQ +qsirecon-PYAFQ/dataset_description.json +qsirecon-PYAFQ/logs +qsirecon-PYAFQ/logs/CITATION.bib +qsirecon-PYAFQ/logs/CITATION.html +qsirecon-PYAFQ/logs/CITATION.md +qsirecon-PYAFQ/logs/CITATION.tex qsirecon-PYAFQ/sub-ABCD +qsirecon-PYAFQ/sub-ABCD.html qsirecon-PYAFQ/sub-ABCD/dwi qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/ROIs @@ -120,4 +130,3 @@ qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/ qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/viz_core_bundles/sub-ABCD_acq-10per000_coordsys-RASMM_trkmethod-probCSD_recogmethod-AFQ_desc-LeftCorticospinalviz_dwi.html qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/viz_core_bundles/sub-ABCD_acq-10per000_coordsys-RASMM_trkmethod-probCSD_recogmethod-AFQ_desc-LeftSuperiorLongitudinalviz_dwi.html qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/viz_core_bundles/sub-ABCD_acq-10per000_coordsys-RASMM_trkmethod-probCSD_recogmethod-AFQ_desc-RightCorticospinalviz_dwi.html -qsirecon/sub-ABCD \ No newline at end of file diff --git a/qsirecon/tests/data/pyafq_recon_full_outputs.txt b/qsirecon/tests/data/pyafq_recon_full_outputs.txt index 54745c2b..cf9c709e 100644 --- a/qsirecon/tests/data/pyafq_recon_full_outputs.txt +++ b/qsirecon/tests/data/pyafq_recon_full_outputs.txt @@ -4,10 +4,15 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-PYAFQ +qsirecon-PYAFQ/dataset_description.json +qsirecon-PYAFQ/logs +qsirecon-PYAFQ/logs/CITATION.bib +qsirecon-PYAFQ/logs/CITATION.html +qsirecon-PYAFQ/logs/CITATION.md +qsirecon-PYAFQ/logs/CITATION.tex qsirecon-PYAFQ/sub-ABCD +qsirecon-PYAFQ/sub-ABCD.html qsirecon-PYAFQ/sub-ABCD/dwi qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/ROIs @@ -108,7 +113,4 @@ qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/ qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/viz_core_bundles/sub-ABCD_acq-10per000_coordsys-RASMM_trkmethod-probCSD_recogmethod-AFQ_desc-LeftCorticospinalviz_dwi.html qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/viz_core_bundles/sub-ABCD_acq-10per000_coordsys-RASMM_trkmethod-probCSD_recogmethod-AFQ_desc-LeftSuperiorLongitudinalviz_dwi.html qsirecon-PYAFQ/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_dwimap/viz_core_bundles/sub-ABCD_acq-10per000_coordsys-RASMM_trkmethod-probCSD_recogmethod-AFQ_desc-RightCorticospinalviz_dwi.html -qsirecon/dwiqc.json -qsirecon/sub-ABCD -qsirecon/sub-ABCD.html sub-ABCD diff --git a/qsirecon/tests/data/scalar_mapper_outputs.txt b/qsirecon/tests/data/scalar_mapper_outputs.txt index c1e51c72..fb7cf69c 100644 --- a/qsirecon/tests/data/scalar_mapper_outputs.txt +++ b/qsirecon/tests/data/scalar_mapper_outputs.txt @@ -4,10 +4,15 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-DIPYDKI +qsirecon-DIPYDKI/dataset_description.json +qsirecon-DIPYDKI/logs +qsirecon-DIPYDKI/logs/CITATION.bib +qsirecon-DIPYDKI/logs/CITATION.html +qsirecon-DIPYDKI/logs/CITATION.md +qsirecon-DIPYDKI/logs/CITATION.tex qsirecon-DIPYDKI/sub-ABCD +qsirecon-DIPYDKI/sub-ABCD.html qsirecon-DIPYDKI/sub-ABCD/dwi qsirecon-DIPYDKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-MNI152NLin2009cAsym_desc-preproc_model-dki_mdp-AD_dwimap.nii.gz qsirecon-DIPYDKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-MNI152NLin2009cAsym_desc-preproc_model-dki_mdp-AK_dwimap.nii.gz @@ -29,7 +34,14 @@ qsirecon-DIPYDKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model qsirecon-DIPYDKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-dki_mdp-RK_dwimap.nii.gz qsirecon-DIPYDKI/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-tensor_mdp-FA_dwimap.nii.gz qsirecon-DSIStudio +qsirecon-DSIStudio/dataset_description.json +qsirecon-DSIStudio/logs +qsirecon-DSIStudio/logs/CITATION.bib +qsirecon-DSIStudio/logs/CITATION.html +qsirecon-DSIStudio/logs/CITATION.md +qsirecon-DSIStudio/logs/CITATION.tex qsirecon-DSIStudio/sub-ABCD +qsirecon-DSIStudio/sub-ABCD.html qsirecon-DSIStudio/sub-ABCD/dwi qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-MNI152NLin2009cAsym_desc-preproc_fit-GQI_mdp-gfa_dwimap.nii.gz qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-MNI152NLin2009cAsym_desc-preproc_fit-GQI_mdp-iso_dwimap.nii.gz @@ -70,7 +82,4 @@ qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_mod qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-tensor_mfp-tyy_dwimap.nii.gz qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-tensor_mfp-tyz_dwimap.nii.gz qsirecon-DSIStudio/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-tensor_mfp-tzz_dwimap.nii.gz -qsirecon/dwiqc.json -qsirecon/sub-ABCD -qsirecon/sub-ABCD.html sub-ABCD diff --git a/qsirecon/tests/data/tortoise_recon_outputs.txt b/qsirecon/tests/data/tortoise_recon_outputs.txt index 6fe4c50f..d1bd8b82 100644 --- a/qsirecon/tests/data/tortoise_recon_outputs.txt +++ b/qsirecon/tests/data/tortoise_recon_outputs.txt @@ -4,10 +4,15 @@ logs/CITATION.bib logs/CITATION.html logs/CITATION.md logs/CITATION.tex -qsirecon -qsirecon qsirecon-TORTOISE +qsirecon-TORTOISE/dataset_description.json +qsirecon-TORTOISE/logs +qsirecon-TORTOISE/logs/CITATION.bib +qsirecon-TORTOISE/logs/CITATION.html +qsirecon-TORTOISE/logs/CITATION.md +qsirecon-TORTOISE/logs/CITATION.tex qsirecon-TORTOISE/sub-ABCD +qsirecon-TORTOISE/sub-ABCD.html qsirecon-TORTOISE/sub-ABCD/dwi qsirecon-TORTOISE/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-mapmri_mdp-NG_dwimap.nii.gz qsirecon-TORTOISE/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-mapmri_mdp-NGpar_dwimap.nii.gz @@ -22,7 +27,4 @@ qsirecon-TORTOISE/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_mode qsirecon-TORTOISE/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-tensor_mdp-li_dwimap.nii.gz qsirecon-TORTOISE/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-tensor_mdp-rd_dwimap.nii.gz qsirecon-TORTOISE/sub-ABCD/dwi/sub-ABCD_acq-10per000_space-T1w_desc-preproc_model-tensor_mfp-AM_dwimap.nii.gz -qsirecon/dwiqc.json -qsirecon/sub-ABCD -qsirecon/sub-ABCD.html sub-ABCD diff --git a/qsirecon/tests/test_cli.py b/qsirecon/tests/test_cli.py index 5bb5572b..116b50e9 100644 --- a/qsirecon/tests/test_cli.py +++ b/qsirecon/tests/test_cli.py @@ -10,13 +10,13 @@ from qsirecon.cli import run from qsirecon.cli.parser import parse_args from qsirecon.cli.workflow import build_boilerplate, build_workflow +from qsirecon.reports.core import generate_reports from qsirecon.tests.utils import ( check_generated_files, download_test_data, get_test_data_path, ) from qsirecon.utils.bids import write_derivative_description -from qsirecon.viz.reports import generate_reports nipype_config.enable_debug_mode() @@ -465,6 +465,7 @@ def _run_and_generate(test_name, parameters, test_main=True): output_dir=config.execution.output_dir, run_uuid=config.execution.run_uuid, session_list=session_list, + qsirecon_suffix="", ) output_list_file = os.path.join(get_test_data_path(), f"{test_name}_outputs.txt") diff --git a/qsirecon/viz/__init__.py b/qsirecon/viz/__init__.py deleted file mode 100644 index 45a15998..00000000 --- a/qsirecon/viz/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- -# vi: set ft=python sts=4 ts=4 sw=4 et: -""" -The qsirecon reporting engine for visual assessment -""" -from .reports import generate_reports, run_reports diff --git a/qsirecon/viz/report.tpl b/qsirecon/viz/report.tpl deleted file mode 100644 index 0f73ff67..00000000 --- a/qsirecon/viz/report.tpl +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - -{{ elem.description }}
{% endif %} - {% for content in elem.contents %} - {% if elem.raw %}{{ content }}{% else %} -
{{ elem.description }}
{% endif %}
- {% for content in elem.contents %}
- {% if elem.raw %}{{ content }}{% else %}
-
We kindly ask to report results preprocessed with qsirecon using the following - boilerplate
- -Failed to generate the boilerplate
- {% endif %} -Alternatively, an interactive boilerplate generator is available in the documentation website.
-%s\n" % (logs_path / "CITATION.md").read_text(encoding="UTF-8") - boilerplate.append((boiler_idx, "Markdown", text)) - boiler_idx += 1 - - if (logs_path / "CITATION.tex").exists(): - text = (logs_path / "CITATION.tex").read_text(encoding="UTF-8") - text = ( - re.compile(r"\\begin{document}(.*?)\\end{document}", re.DOTALL | re.IGNORECASE) - .findall(text)[0] - .strip() - ) - text = "
%s\n" % text - text += "
%s\n" % Path(pkgrf("qsirecon", "data/boilerplate.bib")).read_text( - encoding="UTF-8" - ) - boilerplate.append((boiler_idx, "LaTeX", text)) - boiler_idx += 1 - - searchpath = pkgrf("qsirecon", "/") - env = jinja2.Environment( - loader=jinja2.FileSystemLoader(searchpath=searchpath), - trim_blocks=True, - lstrip_blocks=True, - ) - report_tpl = env.get_template("viz/report.tpl") - report_render = report_tpl.render( - sections=self.sections, errors=self.errors, boilerplate=boilerplate - ) - - # Write out report - (self.out_dir / self.pipeline_type / self.out_filename).write_text( - report_render, encoding="UTF-8" - ) - return len(self.errors) - - -def order_by_run(subreport): - ordered = [] - run_reps = {} - for element in subreport.reportlets: - if len(element.source_files) == 1 and element.source_files[0]: - ordered.append(element) - continue - - for filename, file_contents in zip(element.source_files, element.contents): - name, title = generate_name_title(filename) - if not filename or not name: - continue - - new_element = Reportlet( - name=element.name, - title=element.title, - file_pattern=element.file_pattern, - description=element.description, - raw=element.raw, - imgtype=element.imgtype, - ) - new_element.contents.append(file_contents) - new_element.source_files.append(filename) - - if name not in run_reps: - run_reps[name] = SubReport(name, title=title) - - run_reps[name].reportlets.append(new_element) - - if run_reps: - keys = list(sorted(run_reps.keys())) - for key in keys: - ordered.append(run_reps[key]) - subreport.isnested = True - - subreport.reportlets = ordered - return subreport - - -def generate_name_title(filename): - fname = Path(filename).name - expr = re.compile( - "^sub-(?P