34
34
from ..interfaces .base import (BaseInterface , traits , TraitedSpec , File ,
35
35
InputMultiPath , OutputMultiPath ,
36
36
BaseInterfaceInputSpec , isdefined ,
37
- DynamicTraitedSpec )
37
+ DynamicTraitedSpec , Undefined )
38
38
from nipype .utils .filemanip import fname_presuffix , split_filename
39
39
iflogger = logging .getLogger ('interface' )
40
40
@@ -785,7 +785,8 @@ def _list_outputs(self):
785
785
786
786
787
787
class AddCSVRowInputSpec (DynamicTraitedSpec , BaseInterfaceInputSpec ):
788
- in_file = traits .File (mandatory = True , desc = 'Input comma-separated value (CSV) files' )
788
+ in_file = traits .File (mandatory = True ,
789
+ desc = 'Input comma-separated value (CSV) files' )
789
790
_outputs = traits .Dict (traits .Any , value = {}, usedefault = True )
790
791
791
792
def __setattr__ (self , key , value ):
@@ -804,13 +805,15 @@ class AddCSVRowOutputSpec(TraitedSpec):
804
805
805
806
806
807
class AddCSVRow (BaseInterface ):
808
+
807
809
"""Simple interface to add an extra row to a csv file
808
810
809
811
.. note:: Requires `pandas <http://pandas.pydata.org/>`_
810
812
811
813
.. warning:: Multi-platform thread-safe execution is possible with
812
- `lockfile <https://pythonhosted.org/lockfile/lockfile.html>`_. Please recall that (1)
813
- this module is alpha software; and (2) it should be installed for thread-safe writing.
814
+ `lockfile <https://pythonhosted.org/lockfile/lockfile.html>`_. Please
815
+ recall that (1) this module is alpha software; and (2) it should be
816
+ installed for thread-safe writing.
814
817
If lockfile is not installed, then the interface is not thread-safe.
815
818
816
819
@@ -822,7 +825,7 @@ class AddCSVRow(BaseInterface):
822
825
>>> addrow.inputs.in_file = 'scores.csv'
823
826
>>> addrow.inputs.si = 0.74
824
827
>>> addrow.inputs.di = 0.93
825
- >>> addrow.subject_id = 'S400'
828
+ >>> addrow.inputs. subject_id = 'S400'
826
829
>>> addrow.inputs.list_of_values = [ 0.4, 0.7, 0.3 ]
827
830
>>> addrow.run() # doctest: +SKIP
828
831
"""
@@ -850,22 +853,26 @@ def _run_interface(self, runtime):
850
853
try :
851
854
import pandas as pd
852
855
except ImportError :
853
- raise ImportError ('This interface requires pandas (http://pandas.pydata.org/) to run.' )
856
+ raise ImportError (('This interface requires pandas '
857
+ '(http://pandas.pydata.org/) to run.' ))
854
858
855
859
try :
856
860
import lockfile as pl
857
861
self ._have_lock = True
858
862
except ImportError :
859
- import warnings
860
- warnings . warn (('Python module lockfile was not found: AddCSVRow will not be thread-safe '
861
- ' in multi-processor execution' ))
863
+ from warnings import warn
864
+ warn (('Python module lockfile was not found: AddCSVRow will not be'
865
+ ' thread-safe in multi-processor execution' ))
862
866
863
867
input_dict = {}
864
868
for key , val in self .inputs ._outputs .items ():
865
869
# expand lists to several columns
870
+ if key == 'trait_added' and val in self .inputs .copyable_trait_names ():
871
+ continue
872
+
866
873
if isinstance (val , list ):
867
- for i ,v in enumerate (val ):
868
- input_dict ['%s_%d' % (key ,i )]= v
874
+ for i , v in enumerate (val ):
875
+ input_dict ['%s_%d' % (key , i )] = v
869
876
else :
870
877
input_dict [key ] = val
871
878
@@ -887,6 +894,13 @@ def _run_interface(self, runtime):
887
894
if self ._have_lock :
888
895
self ._lock .release ()
889
896
897
+ # Using nipype.external.portalocker this might be something like:
898
+ # with pl.Lock(self.inputs.in_file, timeout=1) as fh:
899
+ # if op.exists(fh):
900
+ # formerdf = pd.read_csv(fh, index_col=0)
901
+ # df = pd.concat([formerdf, df], ignore_index=True)
902
+ # df.to_csv(fh)
903
+
890
904
return runtime
891
905
892
906
def _list_outputs (self ):
0 commit comments