@@ -1147,6 +1147,142 @@ def _list_outputs(self):
1147
1147
return outputs
1148
1148
1149
1149
1150
+ class AddCSVRowInputSpec (TraitedSpec ):
1151
+ in_file = traits .File (mandatory = True , desc = 'Input comma-separated value (CSV) files' )
1152
+ cols = traits .Int (desc = 'Number of columns' )
1153
+ field_headings = traits .List (traits .Str (), mandatory = True ,
1154
+ desc = 'Heading list of available field to be added.' )
1155
+
1156
+ float_trait = traits .Float ( 0.0 , argstr = '%.5f' )
1157
+ int_trait = traits .Int ( 0 , argstr = '%d' )
1158
+ str_trait = traits .Str ( '' , argstr = '"%s"' )
1159
+ row_trait = traits .Either ( int_trait , float_trait , str_trait )
1160
+ new_fields = traits .List ( row_trait , mandatory = True , desc = 'List of new values in row' )
1161
+
1162
+ class AddCSVRowOutputSpec (TraitedSpec ):
1163
+ csv_file = File (desc = 'Output CSV file containing rows ' )
1164
+
1165
+
1166
+ class AddCSVRow (BaseInterface ):
1167
+ """
1168
+ Short interface to add an extra row to a text file
1169
+
1170
+ Example
1171
+ -------
1172
+
1173
+ >>> import nipype.algorithms.misc as misc
1174
+ >>> addrow = misc.AddCSVRow()
1175
+ >>> addrow.inputs.in_file = 'degree.csv'
1176
+ >>> addrow.inputs.field_headings = [ 'id', 'group', 'age', 'degree' ]
1177
+ >>> addrow.inputs.new_fields = [ 'S400', 'male', '25', '10.5' ]
1178
+ >>> addrow.run() # doctest: +SKIP
1179
+ """
1180
+ input_spec = AddCSVRowInputSpec
1181
+ output_spec = AddCSVRowOutputSpec
1182
+
1183
+ def _run_interface (self , runtime ):
1184
+ cols = 0
1185
+ headings = []
1186
+
1187
+ if not isdefined ( self .inputs .cols ) and not isdefined ( self .inputs .field_headings ):
1188
+ iflogger .error ( 'Either number of cols or field headings is required' )
1189
+
1190
+ if isdefined ( self .inputs .cols ) and isdefined ( self .inputs .field_headings ):
1191
+ if ( len ( self .inputs .field_headings ) != self .inputs .cols ):
1192
+ iflogger .error ( 'Number of cols and length of field headings list should match' )
1193
+ else :
1194
+ cols = self .inputs .cols
1195
+ headings = self .inputs .field_headings
1196
+
1197
+ if isdefined ( self .inputs .cols ) and not isdefined ( self .inputs .field_headings ):
1198
+ cols = self .inputs .cols
1199
+ iflogger .warn ( 'No column headers were set.' )
1200
+
1201
+ if not isdefined ( self .inputs .cols ) and isdefined ( self .inputs .field_headings ):
1202
+ cols = len ( self .inputs .field_headings )
1203
+
1204
+ if cols == 0 :
1205
+ iflogger .error ( 'Number of cols and length of field headings must be > 0' )
1206
+
1207
+ if len ( self .inputs .new_fields ) != cols :
1208
+ iflogger .error ( 'Wrong length of fields, does not match number of cols' )
1209
+
1210
+ with open (self .inputs .in_file , 'r+' ) as in_file :
1211
+ lines = in_file .readlines ()
1212
+
1213
+ if len (headings )> 0 and (len (lines ) == 0 or lines [0 ] == '' ):
1214
+ hdr = [ '"%s"' % h for h in self .inputs .field_headings ]
1215
+ hdrstr = "," .join (hdr )
1216
+ lines .insert ( 0 , hdrstr )
1217
+
1218
+ print self .inputs .new_fields .items ()
1219
+
1220
+ metadata = dict (argstr = lambda t : t is not None )
1221
+ for name , spec in sorted (self .inputs .traits (** metadata ).items ()):
1222
+ print name
1223
+ value = getattr (self .inputs , name )
1224
+ if not value is None :
1225
+ print value
1226
+ #arg = self._format_row( name, spec, value )
1227
+
1228
+
1229
+
1230
+ #newrow = ",".join( self.inputs.new_fields )
1231
+ #lines.append( newrow )
1232
+ #in_file.writelines( lines )
1233
+
1234
+ return runtime
1235
+
1236
+
1237
+
1238
+ def _format_row (self , name , trait_spec , value ):
1239
+ """A helper function for _run_interface
1240
+ """
1241
+ argstr = trait_spec .argstr
1242
+ iflogger .debug ('%s_%s' % (name , str (value )))
1243
+ if trait_spec .is_trait_type (traits .Bool ) and "%" not in argstr :
1244
+ if value :
1245
+ # Boolean options have no format string. Just append options
1246
+ # if True.
1247
+ return argstr
1248
+ else :
1249
+ return None
1250
+ # traits.Either turns into traits.TraitCompound and does not have any
1251
+ # inner_traits
1252
+ elif trait_spec .is_trait_type (traits .List ) \
1253
+ or (trait_spec .is_trait_type (traits .TraitCompound )
1254
+ and isinstance (value , list )):
1255
+ # This is a bit simple-minded at present, and should be
1256
+ # construed as the default. If more sophisticated behavior
1257
+ # is needed, it can be accomplished with metadata (e.g.
1258
+ # format string for list member str'ification, specifying
1259
+ # the separator, etc.)
1260
+
1261
+ # Depending on whether we stick with traitlets, and whether or
1262
+ # not we beef up traitlets.List, we may want to put some
1263
+ # type-checking code here as well
1264
+ sep = trait_spec .sep
1265
+ if sep is None :
1266
+ sep = ' '
1267
+ if argstr .endswith ('...' ):
1268
+
1269
+ # repeatable option
1270
+ # --id %d... will expand to
1271
+ # --id 1 --id 2 --id 3 etc.,.
1272
+ argstr = argstr .replace ('...' , '' )
1273
+ return sep .join ([argstr % elt for elt in value ])
1274
+ else :
1275
+ return argstr % sep .join (str (elt ) for elt in value )
1276
+ else :
1277
+ # Append options using format string.
1278
+ return argstr % value
1279
+
1280
+ def _list_outputs (self ):
1281
+ outputs = self .output_spec ().get ()
1282
+ outputs ['csv_file' ] = self .inputs .in_file
1283
+ return outputs
1284
+
1285
+
1150
1286
class CalculateNormalizedMomentsInputSpec (TraitedSpec ):
1151
1287
timeseries_file = File (
1152
1288
exists = True , mandatory = True ,
0 commit comments