Repository: bids-standard/pybids

Issue:
Regex selector crashses analysis.setup
```Python
>>> from pybids import grabbids as gb, analysis as ba
>>> bids_dir = '/data/bids/openfmri/ds000030'
>>> preproc_dir = '/data/out/ds000030/derivatives/fmriprep'
>>> model_file = '/data/bids/openfmri/ds000030/model.json'

>>> layout = gb.BIDSLayout([bids_dir, preproc_dir])
>>> selectors = {'subject': ['.*']}
>>> analysis = ba.Analysis(model=model_file, layout=layout)
>>> analysis.setup(**selectors)

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-4-10190862a8ee> in <module>()
      2 selectors = {'subject': ['.*']}
      3 analysis = ba.Analysis(model=model_file, layout=layout)
----> 4 analysis.setup(**selectors)

/opt/conda/envs/neuro/lib/python3.6/site-packages/bids/analysis/analysis.py in setup(self, blocks, agg_func, identity_contrasts, **kwargs)
     98                 continue
     99 
--> 100             b.setup(input_nodes, identity_contrasts, **kwargs)
    101             input_nodes = b.output_nodes
    102 

/opt/conda/envs/neuro/lib/python3.6/site-packages/bids/analysis/analysis.py in setup(self, input_nodes, identity_contrasts, **kwargs)
    190             kwargs.pop('scan_length', None)
    191 
--> 192         collections = self.layout.get_collections(self.level, **kwargs)
    193         objects = collections + input_nodes
    194 

/opt/conda/envs/neuro/lib/python3.6/site-packages/bids/grabbids/bids_layout.py in get_collections(self, level, types, variables, merge, sampling_rate, **kwargs)
    305                         sampling_rate=None, **kwargs):
    306         from bids.variables import load_variables
--> 307         index = load_variables(self, types=types, levels=level, **kwargs)
    308         return index.get_collections(level, variables, merge,
    309                                      sampling_rate=sampling_rate)

/opt/conda/envs/neuro/lib/python3.6/site-packages/bids/variables/io.py in load_variables(layout, types, levels, skip_empty, **kwargs)
     73 
     74     for t in ({'scans', 'sessions', 'participants'} & set(types)):
---> 75         dataset = _load_tsv_variables(layout, t, dataset, **kwargs)
     76 
     77     return dataset

/opt/conda/envs/neuro/lib/python3.6/site-packages/bids/variables/io.py in _load_tsv_variables(layout, type_, dataset, columns, prepend_type, **selectors)
    368                 col_name = '%s.%s' % (type_, col_name)
    369 
--> 370             node.add_variable(SimpleVariable(col_name, df, type_))
    371 
    372     return dataset

/opt/conda/envs/neuro/lib/python3.6/site-packages/bids/variables/variables.py in __init__(self, name, data, source, **kwargs)
    235         values.name = name
    236 
--> 237         super(SimpleVariable, self).__init__(name, values, source)
    238 
    239     def split(self, grouper):

/opt/conda/envs/neuro/lib/python3.6/site-packages/bids/variables/variables.py in __init__(self, name, values, source)
     24         self.values = values
     25         self.source = source
---> 26         self._index_entities()
     27 
     28     def clone(self, data=None, **kwargs):

/opt/conda/envs/neuro/lib/python3.6/site-packages/bids/variables/variables.py in _index_entities(self)
    207             self.entities = {}
    208         else:
--> 209             keep = self.index.columns[constant]
    210             self.entities = {k: self.index[k].iloc[0] for k in keep}
    211 

/opt/conda/envs/neuro/lib/python3.6/site-packages/pandas/core/indexes/base.py in __getitem__(self, key)
   1752 
   1753         key = _values_from_object(key)
-> 1754         result = getitem(key)
   1755         if not is_scalar(result):
   1756             return promote(result)

IndexError: arrays used as indices must be of integer (or boolean) type
```


Discussion:
The issue is with line in `_load_tsv_variables`:
    
    _data = _data.query('%s in @vals' % col)`. with `vals = '.*'`


Resolving patch:
diff --git a/bids/variables/io.py b/bids/variables/io.py
--- a/bids/variables/io.py
+++ b/bids/variables/io.py
@@ -342,11 +342,25 @@ def _load_tsv_variables(layout, type_, dataset=None, columns=None,
             _data = _data.rename(columns={'participant_id': 'subject'})
             _data['subject'] = _data['subject'].str.replace('sub-', '')
 
+        def make_patt(x, regex_search=False):
+            patt = '%s' % x
+            if isinstance(x, (int, float)):
+                # allow for leading zeros if a number was specified
+                # regardless of regex_search
+                patt = '0*' + patt
+            if not regex_search:
+                patt = '^%s$' % patt
+            return patt
+
         # Filter rows on all selectors
         comm_cols = list(set(_data.columns) & set(selectors.keys()))
         for col in comm_cols:
-            vals = listify(selectors.get(col))
-            _data = _data.query('%s in @vals' % col)
+            for val in listify(selectors.get(col)):
+                ent_patts = [make_patt(x, regex_search=layout.regex_search)
+                             for x in listify(selectors.get(col))]
+                patt = '|'.join(ent_patts)
+
+                _data = _data[_data[col].str.contains(patt)]
 
         level = {'scans': 'session', 'sessions': 'subject',
                  'participants': 'dataset'}[type_]


Test patch:
diff --git a/bids/variables/tests/test_io.py b/bids/variables/tests/test_io.py
--- a/bids/variables/tests/test_io.py
+++ b/bids/variables/tests/test_io.py
@@ -47,6 +47,10 @@ def test_load_participants(layout1):
     assert age.index.shape == (16, 1)
     assert age.values.shape == (16,)
 
+    index = load_variables(layout1, types='participants', subject=['^1.*'])
+    age = index.get_nodes(level='dataset')[0].variables['age']
+    assert age.index.shape == (7, 1)
+    assert age.values.shape == (7,)
 
 def test_load_synthetic_dataset(synthetic):
     # Runs