Repository: bids-standard/pybids

Issue:
Derivatives indexing fails silently for deriv directories that lack a `dataset_description.json` file
I have a set of derivatives files that look like this:

derivatives/rt/sub-02/func/sub-02_task-dts_meanRT.tsv

they seem to pass the validator fine, but I get nothing when I use .get(scope='derivatives'):

```
In [35]: layout2 = BIDSLayout(args.bids_dir, derivatives=True)

In [36]: layout2.get(scope='derivatives')
Out[36]: []

```

Discussion:

Patch:
diff --git a/bids/layout/layout.py b/bids/layout/layout.py
index bf6319e4..e9f9e8cc 100644
--- a/bids/layout/layout.py
+++ b/bids/layout/layout.py
@@ -6,6 +6,7 @@ from io import open
 from functools import reduce, partial
 from itertools import chain
 import copy
+import warnings
 
 from bids_validator import BIDSValidator
 from ..utils import listify, natural_sort, check_path_matches_patterns
@@ -117,6 +118,8 @@ class BIDSLayout(object):
             the paths to one or more derivatives directories to index. If False
             or None, the derivatives/ directory is ignored during indexing, and
             derivatives will have to be added manually via add_derivatives().
+            Note: derivatives datasets MUST contain a dataset_description.json
+            file in order to be indexed.
         config (str, list): Optional name(s) of configuration file(s) to use.
             By default (None), uses 'bids'.
         sources (BIDLayout, list): Optional BIDSLayout(s) from which the
@@ -356,6 +359,10 @@ class BIDSLayout(object):
                 pipeline directory (e.g., derivatives/fmriprep).
             kwargs (dict): Optional keyword arguments to pass on to
                 BIDSLayout() when initializing each of the derivative datasets.
+
+        Note: Every derivatives directory intended for indexing MUST contain a
+            valid dataset_description.json file. See the BIDS-Derivatives
+            specification for details.
         '''
         paths = listify(path)
         deriv_dirs = []
@@ -378,6 +385,14 @@ class BIDSLayout(object):
                         if check_for_description(sd):
                             deriv_dirs.append(sd)
 
+        if not deriv_dirs:
+            warnings.warn("Derivative indexing was enabled, but no valid "
+                          "derivatives datasets were found in any of the "
+                          "provided or default locations. Please make sure "
+                          "all derivatives datasets you intend to index "
+                          "contain a 'dataset_description.json' file, as "
+                          "described in the BIDS-derivatives specification.")
+
         for deriv in deriv_dirs:
             dd = os.path.join(deriv, 'dataset_description.json')
             with open(dd, 'r', encoding='utf-8') as ddfd:


Test patch:
diff --git a/bids/layout/tests/test_layout.py b/bids/layout/tests/test_layout.py
index acbcc239..f5e2d59d 100644
--- a/bids/layout/tests/test_layout.py
+++ b/bids/layout/tests/test_layout.py
@@ -448,6 +448,21 @@ def test_parse_file_entities_from_layout(layout_synthetic):
     assert target == layout.parse_file_entities(filename, config='derivatives')
 
 
+def test_deriv_indexing():
+    data_dir = join(get_test_data_path(), 'ds005')
+    deriv_dir = join(data_dir, 'derivatives', 'bbr')
+
+    # missing dataset_description.json
+    with pytest.warns(UserWarning):
+        layout = BIDSLayout(data_dir, derivatives=deriv_dir)
+
+    # Should work fine
+    deriv_dir = join(data_dir, 'derivatives', 'events')
+    layout = BIDSLayout(data_dir, derivatives=deriv_dir)
+    assert layout.get(scope='derivatives')
+    assert layout.get(scope='events')
+    assert not layout.get(scope='nonexistent')
+
 def test_add_config_paths():
     bids_dir = dirname(bids.__file__)
     bids_json = os.path.join(bids_dir, 'layout', 'config', 'bids.json')