Skip to content

Commit

Permalink
[ENH] improve error messages for invalid input data (#150)
Browse files Browse the repository at this point in the history
* improve doc

* add extra check

* improve error msg

* fix
  • Loading branch information
Remi-Gau authored Aug 1, 2024
1 parent 7435e94 commit de73e5b
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 29 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
node_modules
package-lock.json
package.json

# folders
outputs
download
Expand Down
11 changes: 9 additions & 2 deletions bidsmreye/bids_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ def check_layout(cfg: Config, layout: BIDSLayout, for_file: str = "bold") -> Non
or "DatasetType" in desc
and desc["DatasetType"] != "derivative"
):
raise RuntimeError("DatasetType must be 'derivative' in dataset_description.json")
raise RuntimeError(
"DatasetType must be 'derivative' in dataset_description.json\n."
"Check the FAQ for more information: "
"https://bidsmreye.readthedocs.io/en/latest/FAQ.html"
)

this_filter = get_bids_filter_config()[for_file]

Expand Down Expand Up @@ -71,7 +75,10 @@ def check_layout(cfg: Config, layout: BIDSLayout, for_file: str = "bold") -> Non
if bf == []:
raise RuntimeError(
f"Input dataset {layout.root} does not have "
"any data to process for filter\n{this_filter}"
f"any data to process for filter\n{this_filter}.\n"
"Is your dataset a BIDS derivative dataset?\n"
"Check the FAQ for more information: "
"https://bidsmreye.readthedocs.io/en/latest/FAQ.html"
)


Expand Down
13 changes: 11 additions & 2 deletions bidsmreye/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,17 @@ def __attrs_post_init__(self) -> None:
database_path=database_path,
reset_database=self.reset_database,
)

log.debug(f"Layout in:\n{layout_in}")
log.debug(f"Layout in:\n{layout_in.root}")

value = layout_in.get(return_type="id", target="subject", datatype="func")
if not value:
raise RuntimeError(
f"Input dataset {layout_in.root} does not have "
f"any data to process.\n"
"Is your dataset a BIDS derivative dataset?\n"
"Check the FAQ for more information: "
"https://bidsmreye.readthedocs.io/en/latest/FAQ.html"
)

if not database_path.is_dir():
layout_in.save(database_path)
Expand Down
12 changes: 3 additions & 9 deletions bidsmreye/quality_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,17 +232,11 @@ def compute_robust_outliers(
points (assuming we don't want to 'remove' too many).

References:
- `Rousseeuw, P. J., and Croux, C. (1993). Alternatives to the the median
absolute deviation. J. Am. Stat. Assoc. 88, 1273-1263.
<https://www.tandfonline.com/doi/abs/10.1080/01621459.1993.10476408>`_
- :cite:t:`rousseeuw_alternatives_1993`
- :cite:t:`carling_resistant_2000`
- :cite:t:`hoaglin_performance_1986`

- `Carling, K. (2000). Resistant outlier rules and the non-Gaussian case.
Stat. Data Anal. 33, 249:258.
<http://www.sciencedirect.com/science/article/pii/S0167947399000572>`_

- `Hoaglin, D.C., Iglewicz, B. (1987) Fine-tuning some resistant rules for
outlier labelling. J. Amer. Statist. Assoc., 82 , 1147:1149
<http://www.tandfonline.com/doi/abs/10.1080/01621459.1986.10478363>`_
"""
if outlier_type is None:
outlier_type = "S-outliers"
Expand Down
34 changes: 34 additions & 0 deletions bidsmreye/templates/CITATION.bib
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ @article{deepmreye
}



@article{alexander_open_2017,
title = {An open resource for transdiagnostic research in pediatric mental health and learning disorders},
volume = {4},
Expand Down Expand Up @@ -119,3 +120,36 @@ @article{carling_resistant_2000
pages = {249--258},
file = {Submitted Version:/home/remi/Zotero/storage/VHQYXF6K/Carling - 2000 - Resistant outlier rules and the non-Gaussian case.pdf:application/pdf},
}

@article{hoaglin_performance_1986,
title = {Performance of {Some} {Resistant} {Rules} for {Outlier} {Labeling}},
volume = {81},
issn = {0162-1459, 1537-274X},
url = {http://www.tandfonline.com/doi/abs/10.1080/01621459.1986.10478363},
doi = {10.1080/01621459.1986.10478363},
language = {en},
number = {396},
urldate = {2023-05-24},
journal = {Journal of the American Statistical Association},
author = {Hoaglin, David C. and Iglewicz, Boris and Tukey, John W.},
month = dec,
year = {1986},
pages = {991--999},
}


@article{rousseeuw_alternatives_1993,
title = {Alternatives to the {Median} {Absolute} {Deviation}},
volume = {88},
issn = {0162-1459, 1537-274X},
url = {http://www.tandfonline.com/doi/abs/10.1080/01621459.1993.10476408},
doi = {10.1080/01621459.1993.10476408},
language = {en},
number = {424},
urldate = {2023-05-24},
journal = {Journal of the American Statistical Association},
author = {Rousseeuw, Peter J. and Croux, Christophe},
month = dec,
year = {1993},
pages = {1273--1283},
}
40 changes: 36 additions & 4 deletions docs/questions/validation.question.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,44 @@ alt_titles:
- "What input format does bidsmreye expect?"
---

bidsmreye requires your input fmri data:

- to be minimally preprocessed
- with filenames and structure that conforms to a BIDS derivative dataset.
bidsmreye requires a BIDS **preprocessed** dataset as input.

Two bids apps are available to generate those types of preprocessed data:

- [fmriprep](https://fmriprep.org/en/stable/)
- [bidspm](https://bidspm.readthedocs.io/en/latest/general_information.html)

bidsmreye requires your input fmri data:

- to be minimally preprocessed
- with [filenames and structure that conforms to a BIDS derivative dataset](https://bids-specification.readthedocs.io/en/latest/derivatives/imaging.html#preprocessed-coregistered-andor-resampled-volumes).

More specifically the dataset should look like this:

```
dataset_description.json
sub-{sub}
[ses-{session}]
func (func_dir)
sub-{sub}[_ses-{session}]_task-{task}[_acq-{acq}][_ce-{ce}][_dir-{dir}][_rec-{rec}][_run-{run_index}]_space-{space}[_res-{res}]_desc-preproc_bold.nii[.gz]
[participants.tsv]
[README]
[CHANGES]
[LICENSE]
```

- Filename entities, files or directories between square brackets
(for example, `[_ses-<label>]`) are OPTIONAL.
Note that for bidsmreye to work, the `space` entity is required.
- `[.gz]` means that both the unzipped and gzipped versions of the extension are valid.

Moreover the dataset_description.json file specify
that the input dataset is a derivative dataset:

```json
{
"Name": "my_dataset",
"BIDSVersion": "1.8.0",
"DatasetType": "derivative",
}
```
40 changes: 36 additions & 4 deletions docs/source/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,48 @@
<a name="how-i-should-structure-my-input-data"></a>
## How I should structure my input data?

bidsmreye requires your input fmri data:

- to be minimally preprocessed
- with filenames and structure that conforms to a BIDS derivative dataset.
bidsmreye requires a BIDS **preprocessed** dataset as input.

Two bids apps are available to generate those types of preprocessed data:

- [fmriprep](https://fmriprep.org/en/stable/)
- [bidspm](https://bidspm.readthedocs.io/en/latest/general_information.html)

bidsmreye requires your input fmri data:

- to be minimally preprocessed
- with [filenames and structure that conforms to a BIDS derivative dataset](https://bids-specification.readthedocs.io/en/latest/derivatives/imaging.html#preprocessed-coregistered-andor-resampled-volumes).

More specifically the dataset should look like this:

```
dataset_description.json
sub-{sub}
[ses-{session}]
func (func_dir)
sub-{sub}[_ses-{session}]_task-{task}[_acq-{acq}][_ce-{ce}][_dir-{dir}][_rec-{rec}][_run-{run_index}]_space-{space}[_res-{res}]_desc-preproc_bold.nii[.gz]
[participants.tsv]
[README]
[CHANGES]
[LICENSE]
```

- Filename entities, files or directories between square brackets
(for example, `[_ses-<label>]`) are OPTIONAL.
Note that for bidsmreye to work, the `space` entity is required.
- `[.gz]` means that both the unzipped and gzipped versions of the extension are valid.

Moreover the dataset_description.json file specify
that the input dataset is a derivative dataset:

```json
{
"Name": "my_dataset",
"BIDSVersion": "1.8.0",
"DatasetType": "derivative",
}
```

<a name="is-the-"prepare"-only-suitable-for-the-datasets-that-have-eye-tracking-info"></a>
## Is the "prepare" only suitable for the datasets that have eye-tracking info?

Expand Down
5 changes: 5 additions & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"sphinx_copybutton",
"myst_parser",
"sphinxarg.ext",
"sphinxcontrib.bibtex",
]

# Add any paths that contain templates here, relative to this directory.
Expand Down Expand Up @@ -85,6 +86,10 @@
# Configuration of sphinx.ext.coverage
coverage_show_missing_items = True

bibtex_bibfiles = ["references.bib"]
bibtex_style = "unsrt"
bibtex_reference_style = "author_year"

# -- Options for HTML output -------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Welcome to bidsMReye's documentation!
demo
FAQ
modules
references

Indices and tables
==================
Expand Down
1 change: 1 addition & 0 deletions docs/source/references.bib
8 changes: 8 additions & 0 deletions docs/source/references.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
References
**********

Bilbiography
============

.. bibliography::
:all:
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ doc = [
"sphinx",
"sphinx-argparse",
"sphinx-copybutton",
"sphinx-rtd-theme"
"sphinx-rtd-theme",
"sphinxcontrib-bibtex"
]
docs = ["bidsmreye[doc]"]
style = [
Expand Down
27 changes: 27 additions & 0 deletions tests/test_bids_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import shutil
from pathlib import Path

import pytest

from bidsmreye.bids_utils import (
check_layout,
create_bidsname,
Expand Down Expand Up @@ -102,3 +104,28 @@ def test_check_layout_prepare_data():
reset_database=True,
)
check_layout(cfg, layout_in)


def test_check_layout_error_no_space_entity(tmp_path):
shutil.copytree(pybids_test_dataset(), tmp_path, dirs_exist_ok=True)
for file in tmp_path.rglob("*_space-*"):
file.unlink()

cfg = Config(
tmp_path,
tmp_path / "foo",
)

print(cfg.input_dir)

layout_in = get_dataset_layout(
cfg.input_dir,
use_database=False,
config=["bids", "derivatives"],
reset_database=True,
)

with pytest.raises(
RuntimeError, match="does not have any data to process for filter"
):
check_layout(cfg, layout_in)
10 changes: 3 additions & 7 deletions tests/test_quality_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,9 @@ def test_quality_control_output():
quality_control_output(cfg)


def test_quality_control_input():
input_dir = Path().resolve().joinpath("tests", "data", "ds000201-der")
output_dir = input_dir.joinpath("derivatives")

rm_dir(output_dir)
def test_quality_control_input(tmp_path):
input_dir = Path("tests") / "data" / "ds000201-der"
output_dir = tmp_path / "derivatives"

cfg = Config(
input_dir,
Expand All @@ -148,8 +146,6 @@ def test_quality_control_input():

quality_control_input(cfg)

rm_dir(output_dir)


def test_perform_quality_control():
create_basic_json()
Expand Down

0 comments on commit de73e5b

Please sign in to comment.