Skip to content

Commit d2e53fb

Browse files
committed
Merge master and fix merge conflict
2 parents 3c21466 + 6b74fd2 commit d2e53fb

24 files changed

+394
-68
lines changed

.mailmap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Josh Warner <[email protected]> JDWarner <[email protected]
9393
Josh Warner <[email protected]> Josh Warner (Mac) <[email protected]>
9494
Kai Schlamp <[email protected]> medihack <[email protected]>Jessica Forbes <[email protected]> jessicaforbes <[email protected]>
9595
Katie Bottenhorn <[email protected]> 62442katieb <[email protected]>
96-
Kesshi Jordan <[email protected]> Kesshi Jordan <[email protected]>
96+
Kesshi Jordan <[email protected]> Kesshi Jordan <[email protected]>
9797
Kesshi Jordan <[email protected]> Kesshi Jordan <[email protected]>
9898
Kesshi Jordan <[email protected]> Kesshi Jordan <[email protected]>
9999
Kesshi Jordan <[email protected]> Kesshi Jordan <[email protected]>

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,10 @@ before_install:
9494

9595
install:
9696
- travis_retry pip install $EXTRA_PIP_FLAGS -e .[$NIPYPE_EXTRAS]
97+
- travis_retry pip install pytest-xdist
9798

9899
script:
99-
- py.test -v --cov nipype --cov-config .coveragerc --cov-report xml:cov.xml -c nipype/pytest.ini --doctest-modules nipype
100+
- py.test -v --cov nipype --cov-config .coveragerc --cov-report xml:cov.xml -c nipype/pytest.ini --doctest-modules nipype -n auto
100101

101102
after_script:
102103
- codecov --file cov.xml --flags unittests -e TRAVIS_JOB_NUMBER

.zenodo.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,11 @@
589589
"affiliation": "MIT, HMS",
590590
"name": "Ghosh, Satrajit",
591591
"orcid": "0000-0002-5312-6729"
592+
},
593+
{
594+
"affiliation": "University of Washington",
595+
"name": "Richie-Halford, Adam",
596+
"orcid": "0000-0001-9276-9084"
592597
}
593598
],
594599
"keywords": [

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ To participate in the Nipype development related discussions please use the foll
9191

9292
Please add *[nipype]* to the subject line when posting on the mailing list.
9393

94-
You can even hangout with the Nipype developers in their
94+
You can even hangout with the Nipype developers in their
9595
`Gitter <https://gitter.im/nipy/nipype>`_ channel or in the BrainHack `Slack <https://brainhack.slack.com/messages/C1FR76RAL>`_ channel. (Click `here <https://brainhack-slack-invite.herokuapp.com>`_ to join the Slack workspace.)
9696

9797

doc/devel/interface_specs.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ In case of trouble, we encourage you to post on `NeuroStars <https://neurostars.
1212
NeuroStars.org is a platform similar to StackOverflow but dedicated to neuroinformatics.
1313
You can also post on the nipype developers mailing list: http://mail.python.org/mailman/listinfo/neuroimaging.
1414
As we are sharing a mailing list with the nipy community, please add ``[nipype]`` to the message title.
15-
Alternatively, you're welcome to chat with us in the Nipype
16-
`Gitter <https://gitter.im/nipy/nipype>`_ channel or in the
15+
Alternatively, you're welcome to chat with us in the Nipype
16+
`Gitter <https://gitter.im/nipy/nipype>`_ channel or in the
1717
BrainHack `Slack <https://brainhack.slack.com/messages/C1FR76RAL>`_ channel.
1818
(Click `here <https://brainhack-slack-invite.herokuapp.com>`_ to join the Slack workspace.)
1919

docker/files/run_pytests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export COVERAGE_FILE=${WORKDIR}/tests/.coverage.py${PYTHON_VERSION}
2929
py.test -v --junitxml=${WORKDIR}/tests/pytests_py${PYTHON_VERSION}.xml \
3030
--cov nipype --cov-config /src/nipype/.coveragerc \
3131
--cov-report xml:${WORKDIR}/tests/coverage_py${PYTHON_VERSION}.xml \
32+
-n auto \
3233
-c ${TESTPATH}/pytest.ini ${TESTPATH}
3334
exit_code=$?
3435

docker/generate_dockerfiles.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ function generate_main_dockerfile() {
9292
conda_install='python=${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}
9393
icu=58.1 libxml2 libxslt matplotlib mkl numpy paramiko
9494
pandas psutil scikit-learn scipy traits=4.6.0' \
95-
pip_install="grabbit==0.2.6 https://github.com/bids-standard/pybids/tarball/0.7.0" \
95+
pip_install="pytest-xdist" \
9696
activate=true \
9797
--copy docker/files/run_builddocs.sh docker/files/run_examples.sh \
9898
docker/files/run_pytests.sh nipype/external/fsl_imglob.py /usr/bin/ \
@@ -107,7 +107,7 @@ function generate_main_dockerfile() {
107107
--user neuro \
108108
--miniconda use_env=neuro \
109109
pip_opts="-e" \
110-
pip_install="/src/nipype[all]" \
110+
pip_install="/src/nipype[all] https://github.com/bids-standard/pybids/tarball/0.7.0" \
111111
--workdir /work \
112112
--label org.label-schema.build-date='$BUILD_DATE' \
113113
org.label-schema.name="NIPYPE" \

nipype/__init__.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,22 @@
2525

2626

2727
class NipypeTester(object):
28-
def __call__(self, doctests=True, parallel=True):
28+
def __call__(self, doctests=True, parallel=False):
2929
try:
3030
import pytest
31-
except:
31+
except ImportError:
3232
raise RuntimeError(
3333
'py.test not installed, run: pip install pytest')
3434
args = []
3535
if not doctests:
3636
args.extend(['-p', 'no:doctest'])
37-
if not parallel:
38-
args.append('-n0')
37+
if parallel:
38+
try:
39+
import xdist
40+
except ImportError:
41+
raise RuntimeError(
42+
"pytest-xdist required for parallel run")
43+
args.append('-n auto')
3944
args.append(os.path.dirname(__file__))
4045
pytest.main(args=args)
4146

nipype/algorithms/modelgen.py

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,61 @@ def scale_timings(timelist, input_units, output_units, time_repetition):
144144
timelist = [np.max([0., _scalefactor * t]) for t in timelist]
145145
return timelist
146146

147+
def bids_gen_info(bids_event_files,
148+
condition_column='trial_type',
149+
amplitude_column=None,
150+
time_repetition=False,
151+
):
152+
"""Generate subject_info structure from a list of BIDS .tsv event files.
153+
154+
Parameters
155+
----------
156+
157+
bids_event_files : list of str
158+
Filenames of BIDS .tsv event files containing columns including:
159+
'onset', 'duration', and 'trial_type' or the `condition_column` value.
160+
condition_column : str
161+
Column of files in `bids_event_files` based on the values of which
162+
events will be sorted into different regressors
163+
amplitude_column : str
164+
Column of files in `bids_event_files` based on the values of which
165+
to apply amplitudes to events. If unspecified, all events will be
166+
represented with an amplitude of 1.
167+
168+
Returns
169+
-------
170+
171+
list of Bunch
172+
"""
173+
info = []
174+
for bids_event_file in bids_event_files:
175+
with open(bids_event_file) as f:
176+
f_events = csv.DictReader(f, skipinitialspace=True, delimiter='\t')
177+
events = [{k: v for k, v in row.items()} for row in f_events]
178+
conditions = list(set([i[condition_column] for i in events]))
179+
runinfo = Bunch(conditions=[], onsets=[], durations=[], amplitudes=[])
180+
for condition in conditions:
181+
selected_events = [i for i in events if i[condition_column]==condition]
182+
onsets = [float(i['onset']) for i in selected_events]
183+
durations = [float(i['duration']) for i in selected_events]
184+
if time_repetition:
185+
decimals = math.ceil(-math.log10(time_repetition))
186+
onsets = [np.round(i, decimals) for i in onsets]
187+
durations = [np.round(i ,decimals) for i in durations]
188+
if condition:
189+
runinfo.conditions.append(condition)
190+
else:
191+
runinfo.conditions.append('e0')
192+
runinfo.onsets.append(onsets)
193+
runinfo.durations.append(durations)
194+
try:
195+
amplitudes = [float(i[amplitude_column]) for i in selected_events]
196+
runinfo.amplitudes.append(amplitudes)
197+
except KeyError:
198+
runinfo.amplitudes.append([1] * len(onsets))
199+
info.append(runinfo)
200+
return info
201+
147202

148203
def gen_info(run_event_files):
149204
"""Generate subject_info structure from a list of event files
@@ -190,6 +245,23 @@ class SpecifyModelInputSpec(BaseInterfaceInputSpec):
190245
desc='List of event description files 1, 2 or 3 '
191246
'column format corresponding to onsets, '
192247
'durations and amplitudes')
248+
bids_event_file = InputMultiPath(
249+
File(exists=True),
250+
mandatory=True,
251+
xor=['subject_info', 'event_files', 'bids_event_file'],
252+
desc='TSV event file containing common BIDS fields: `onset`,'
253+
'`duration`, and categorization and amplitude columns')
254+
bids_condition_column = traits.Str(exists=True,
255+
mandatory=False,
256+
default_value='trial_type',
257+
usedefault=True,
258+
desc='Column of the file passed to `bids_event_file` to the '
259+
'unique values of which events will be assigned'
260+
'to regressors')
261+
bids_amplitude_column = traits.Str(exists=True,
262+
mandatory=False,
263+
desc='Column of the file passed to `bids_event_file` '
264+
'according to which to assign amplitudes to events')
193265
realignment_parameters = InputMultiPath(
194266
File(exists=True),
195267
desc='Realignment parameters returned '
@@ -432,8 +504,15 @@ def _generate_design(self, infolist=None):
432504
if infolist is None:
433505
if isdefined(self.inputs.subject_info):
434506
infolist = self.inputs.subject_info
435-
else:
507+
elif isdefined(self.inputs.event_files):
436508
infolist = gen_info(self.inputs.event_files)
509+
elif isdefined(self.inputs.bids_event_file):
510+
infolist = bids_gen_info(
511+
self.inputs.bids_event_file,
512+
self.inputs.bids_condition_column,
513+
self.inputs.bids_amplitude_column,
514+
self.inputs.time_repetition,
515+
)
437516
self._sessinfo = self._generate_standard_design(
438517
infolist,
439518
functional_runs=self.inputs.functional_runs,

nipype/algorithms/tests/test_auto_SpecifyModel.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@
55

66
def test_SpecifyModel_inputs():
77
input_map = dict(
8+
bids_amplitude_column=dict(
9+
exists=True,
10+
mandatory=False,
11+
),
12+
bids_condition_column=dict(
13+
exists=True,
14+
mandatory=False,
15+
usedefault=True,
16+
),
17+
bids_event_file=dict(
18+
mandatory=True,
19+
xor=['subject_info', 'event_files', 'bids_event_file'],
20+
),
821
event_files=dict(
922
mandatory=True,
1023
xor=['subject_info', 'event_files'],

0 commit comments

Comments
 (0)