Skip to content

Commit f836118

Browse files
committed
Merge remote-tracking branch 'upstream/master' into rf/multiproc_futures
2 parents a16ac8e + fa864aa commit f836118

File tree

6 files changed

+116
-13
lines changed

6 files changed

+116
-13
lines changed

nipype/interfaces/afni/preprocess.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
from ...utils.filemanip import (load_json, save_json, split_filename,
1414
fname_presuffix)
1515
from ..base import (CommandLineInputSpec, CommandLine, TraitedSpec, traits,
16-
isdefined, File, InputMultiPath, Undefined, Str)
16+
isdefined, File, InputMultiPath, Undefined, Str,
17+
InputMultiObject)
1718

1819
from .base import (AFNICommandBase, AFNICommand, AFNICommandInputSpec,
1920
AFNICommandOutputSpec, AFNIPythonCommandInputSpec,
@@ -2492,6 +2493,15 @@ class TProjectInputSpec(AFNICommandInputSpec):
24922493
even if -ort contains constant terms, as all means are
24932494
removed.""",
24942495
argstr="-polort %d")
2496+
dsort = InputMultiObject(
2497+
File(
2498+
exists=True,
2499+
copyfile=False),
2500+
argstr="-dsort %s...",
2501+
desc="""Remove the 3D+time time series in dataset fset.
2502+
++ That is, 'fset' contains a different nuisance time
2503+
series for each voxel (e.g., from AnatICOR).
2504+
++ Multiple -dsort options are allowed.""")
24952505
bandpass = traits.Tuple(
24962506
traits.Float, traits.Float,
24972507
desc="""Remove all frequencies EXCEPT those in the range""",
@@ -2559,6 +2569,7 @@ class TProject(AFNICommand):
25592569
_cmd = '3dTproject'
25602570
input_spec = TProjectInputSpec
25612571
output_spec = AFNICommandOutputSpec
2572+
25622573

25632574
class TShiftInputSpec(AFNICommandInputSpec):
25642575
in_file = File(

nipype/interfaces/afni/tests/test_auto_TProject.py

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def test_TProject_inputs():
1717
censor=dict(argstr='-censor %s', ),
1818
censortr=dict(argstr='-CENSORTR %s', ),
1919
concat=dict(argstr='-concat %s', ),
20+
dsort=dict(argstr='-dsort %s...', ),
2021
environ=dict(
2122
nohash=True,
2223
usedefault=True,

nipype/interfaces/ants/tests/test_auto_AntsJointFusion.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ def test_AntsJointFusion_inputs():
5757
hash_files=False,
5858
),
5959
out_label_post_prob_name_format=dict(
60-
requires=['out_label_fusion', 'out_intensity_fusion_name_format'],
61-
),
60+
requires=['out_label_fusion',
61+
'out_intensity_fusion_name_format'], ),
6262
patch_metric=dict(argstr='-m %s', ),
6363
patch_radius=dict(
6464
argstr='-p %s',

nipype/pipeline/plugins/tools.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ def report_crash(node, traceback=None, hostname=None):
5858
if crashfile.endswith('.txt'):
5959
crash2txt(crashfile, dict(node=node, traceback=traceback))
6060
else:
61-
savepkl(crashfile, dict(node=node, traceback=traceback))
61+
savepkl(crashfile, dict(node=node, traceback=traceback),
62+
versioning=True)
6263
return crashfile
6364

6465

nipype/utils/filemanip.py

+49-8
Original file line numberDiff line numberDiff line change
@@ -628,13 +628,13 @@ def load_json(filename):
628628

629629

630630
def loadcrash(infile, *args):
631-
if '.pkl' in infile:
632-
return loadpkl(infile)
631+
if infile.endswith('pkl') or infile.endswith('pklz'):
632+
return loadpkl(infile, versioning=True)
633633
else:
634634
raise ValueError('Only pickled crashfiles are supported')
635635

636636

637-
def loadpkl(infile):
637+
def loadpkl(infile, versioning=False):
638638
"""Load a zipped or plain cPickled file
639639
"""
640640
fmlogger.debug('Loading pkl: %s', infile)
@@ -643,11 +643,44 @@ def loadpkl(infile):
643643
else:
644644
pkl_file = open(infile, 'rb')
645645

646+
if versioning:
647+
pkl_metadata = {}
648+
649+
# Look if pkl file contains version file
650+
try:
651+
pkl_metadata_line = pkl_file.readline()
652+
pkl_metadata = json.loads(pkl_metadata_line)
653+
except:
654+
# Could not get version info
655+
pkl_file.seek(0)
656+
646657
try:
647-
unpkl = pickle.load(pkl_file)
648-
except UnicodeDecodeError:
649-
unpkl = pickle.load(pkl_file, fix_imports=True, encoding='utf-8')
650-
return unpkl
658+
try:
659+
unpkl = pickle.load(pkl_file)
660+
except UnicodeDecodeError:
661+
unpkl = pickle.load(pkl_file, fix_imports=True, encoding='utf-8')
662+
663+
return unpkl
664+
665+
# Unpickling problems
666+
except Exception as e:
667+
if not versioning:
668+
raise e
669+
670+
from nipype import __version__ as version
671+
672+
if 'version' in pkl_metadata:
673+
if pkl_metadata['version'] != version:
674+
fmlogger.error('Your Nipype version is: %s',
675+
version)
676+
fmlogger.error('Nipype version of the pkl is: %s',
677+
pkl_metadata['version'])
678+
else:
679+
fmlogger.error('No metadata was found in the pkl file.')
680+
fmlogger.error('Make sure that you are using the same Nipype'
681+
'version from the generated pkl.')
682+
683+
raise e
651684

652685

653686
def crash2txt(filename, record):
@@ -682,11 +715,19 @@ def read_stream(stream, logger=None, encoding=None):
682715
return out.splitlines()
683716

684717

685-
def savepkl(filename, record):
718+
def savepkl(filename, record, versioning=False):
686719
if filename.endswith('pklz'):
687720
pkl_file = gzip.open(filename, 'wb')
688721
else:
689722
pkl_file = open(filename, 'wb')
723+
724+
if versioning:
725+
from nipype import __version__ as version
726+
metadata = json.dumps({'version': version})
727+
728+
pkl_file.write(metadata.encode('utf-8'))
729+
pkl_file.write('\n'.encode('utf-8'))
730+
690731
pickle.dump(record, pkl_file)
691732
pkl_file.close()
692733

nipype/utils/tests/test_filemanip.py

+50-1
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
import time
99
import warnings
1010

11+
import mock
1112
import pytest
1213
from ...testing import TempFATFS
1314
from ...utils.filemanip import (
1415
save_json, load_json, fname_presuffix, fnames_presuffix, hash_rename,
1516
check_forhash, _parse_mount_table, _cifs_table, on_cifs, copyfile,
1617
copyfiles, ensure_list, simplify_list, check_depends,
17-
split_filename, get_related_files, indirectory)
18+
split_filename, get_related_files, indirectory,
19+
loadpkl, loadcrash, savepkl)
1820

1921

2022
def _ignore_atime(stat):
@@ -521,3 +523,50 @@ def test_indirectory(tmpdir):
521523
except ValueError:
522524
pass
523525
assert os.getcwd() == tmpdir.strpath
526+
527+
528+
def test_pklization(tmpdir):
529+
tmpdir.chdir()
530+
531+
exc = Exception("There is something wrong here")
532+
savepkl('./except.pkz', exc)
533+
newexc = loadpkl('./except.pkz')
534+
535+
assert exc.args == newexc.args
536+
assert os.getcwd() == tmpdir.strpath
537+
538+
539+
class Pickled:
540+
541+
def __getstate__(self):
542+
return self.__dict__
543+
544+
545+
class PickledBreaker:
546+
547+
def __setstate__(self, d):
548+
raise Exception()
549+
550+
551+
def test_versioned_pklization(tmpdir):
552+
tmpdir.chdir()
553+
554+
obj = Pickled()
555+
savepkl('./pickled.pkz', obj, versioning=True)
556+
557+
with pytest.raises(Exception):
558+
with mock.patch('nipype.utils.tests.test_filemanip.Pickled', PickledBreaker), \
559+
mock.patch('nipype.__version__', '0.0.0'):
560+
561+
loadpkl('./pickled.pkz', versioning=True)
562+
563+
564+
def test_unversioned_pklization(tmpdir):
565+
tmpdir.chdir()
566+
567+
obj = Pickled()
568+
savepkl('./pickled.pkz', obj)
569+
570+
with pytest.raises(Exception):
571+
with mock.patch('nipype.utils.tests.test_filemanip.Pickled', PickledBreaker):
572+
loadpkl('./pickled.pkz', versioning=True)

0 commit comments

Comments
 (0)