-
Notifications
You must be signed in to change notification settings - Fork 536
FIX: AddCSVRow failed when using infields #1028
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
e98181b
cb9e220
4c7e452
58778a7
9f881bb
84e5410
6498abc
769dece
e53fa06
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,7 +34,7 @@ | |
| from ..interfaces.base import (BaseInterface, traits, TraitedSpec, File, | ||
| InputMultiPath, OutputMultiPath, | ||
| BaseInterfaceInputSpec, isdefined, | ||
| DynamicTraitedSpec) | ||
| DynamicTraitedSpec, Undefined) | ||
| from nipype.utils.filemanip import fname_presuffix, split_filename | ||
| iflogger = logging.getLogger('interface') | ||
|
|
||
|
|
@@ -785,7 +785,8 @@ def _list_outputs(self): | |
|
|
||
|
|
||
| class AddCSVRowInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): | ||
| in_file = traits.File(mandatory=True, desc='Input comma-separated value (CSV) files') | ||
| in_file = traits.File(mandatory=True, | ||
| desc='Input comma-separated value (CSV) files') | ||
| _outputs = traits.Dict(traits.Any, value={}, usedefault=True) | ||
|
|
||
| def __setattr__(self, key, value): | ||
|
|
@@ -804,13 +805,15 @@ class AddCSVRowOutputSpec(TraitedSpec): | |
|
|
||
|
|
||
| class AddCSVRow(BaseInterface): | ||
|
|
||
| """Simple interface to add an extra row to a csv file | ||
|
|
||
| .. note:: Requires `pandas <http://pandas.pydata.org/>`_ | ||
|
|
||
| .. warning:: Multi-platform thread-safe execution is possible with | ||
| `lockfile <https://pythonhosted.org/lockfile/lockfile.html>`_. Please recall that (1) | ||
| this module is alpha software; and (2) it should be installed for thread-safe writing. | ||
| `lockfile <https://pythonhosted.org/lockfile/lockfile.html>`_. Please | ||
| recall that (1) this module is alpha software; and (2) it should be | ||
| installed for thread-safe writing. | ||
| If lockfile is not installed, then the interface is not thread-safe. | ||
|
|
||
|
|
||
|
|
@@ -822,7 +825,7 @@ class AddCSVRow(BaseInterface): | |
| >>> addrow.inputs.in_file = 'scores.csv' | ||
| >>> addrow.inputs.si = 0.74 | ||
| >>> addrow.inputs.di = 0.93 | ||
| >>> addrow.subject_id = 'S400' | ||
| >>> addrow.inputs.subject_id = 'S400' | ||
| >>> addrow.inputs.list_of_values = [ 0.4, 0.7, 0.3 ] | ||
| >>> addrow.run() # doctest: +SKIP | ||
| """ | ||
|
|
@@ -850,22 +853,26 @@ def _run_interface(self, runtime): | |
| try: | ||
| import pandas as pd | ||
| except ImportError: | ||
| raise ImportError('This interface requires pandas (http://pandas.pydata.org/) to run.') | ||
| raise ImportError(('This interface requires pandas ' | ||
| '(http://pandas.pydata.org/) to run.')) | ||
|
|
||
| try: | ||
| import lockfile as pl | ||
| self._have_lock = True | ||
| except ImportError: | ||
| import warnings | ||
| warnings.warn(('Python module lockfile was not found: AddCSVRow will not be thread-safe ' | ||
| 'in multi-processor execution')) | ||
| from warnings import warn | ||
| warn(('Python module lockfile was not found: AddCSVRow will not be' | ||
| ' thread-safe in multi-processor execution')) | ||
|
|
||
| input_dict = {} | ||
| for key, val in self.inputs._outputs.items(): | ||
| # expand lists to several columns | ||
| if key == 'trait_added' and val in self.inputs._outputs.keys(): | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @satra, I'm not very happy with this way of checking that
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This situation also happens now in #1047
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i haven't looked into that in a while. it's possible to use some combination of np.setdiff1d with copyable_trait_names.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've written the same code using copyable_trait_names, but it is still necessary to check that the key is not |
||
| continue | ||
|
|
||
| if isinstance(val, list): | ||
| for i,v in enumerate(val): | ||
| input_dict['%s_%d' % (key,i)]=v | ||
| for i, v in enumerate(val): | ||
| input_dict['%s_%d' % (key, i)] = v | ||
| else: | ||
| input_dict[key] = val | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i know this wasn't the change here, but in nipype.externals there is a lock file code that might work across multiprocessor and possibly in nfs settings. in nfs, the default cache time could be 30s or higher, so the lock may not propagate across nodes without timeout settings in place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@satra, I've been looking at
portalocker(http://portalocker.readthedocs.org/en/latest/usage.html#examples) included in nipype.externals, and before integrating it in this interface I have a minor concern:I would proceed with this PR as it fixes a bug on this interface. Then update portalocker and finally integrate it in all io classes.