Skip to content

ENH: Added csvReader() utility #1044

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

Merged
merged 2 commits into from
Feb 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,46 @@ Next release
* FIX: Fix split_filename behaviour when path has no file component (https://github.com/nipy/nipype/pull/1035)
* ENH: Updated FSL dtifit to include option for grad non-linearities (https://github.com/nipy/nipype/pull/1032)
* ENH: Updated Camino tracking interfaces, which can now use FSL bedpostx output.
New options also include choice of tracker, interpolator, stepsize and
New options also include choice of tracker, interpolator, stepsize and
curveinterval for angle threshold (https://github.com/nipy/nipype/pull/1029)
* FIX: Interfaces redirecting X crashed if $DISPLAY not defined (https://github.com/nipy/nipype/pull/1027)
* FIX: Bug crashed 'make api' (https://github.com/nipy/nipype/pull/1026)
* ENH: Updated antsIntroduction to handle RA and RI registrations (https://github.com/nipy/nipype/pull/1009)
* ENH: Updated N4BiasCorrection input spec to include weight image and spline order. Made
* ENH: Updated N4BiasCorrection input spec to include weight image and spline order. Made
argument formatting consistent. Cleaned ants.segmentation according to PEP8.
(https://github.com/nipy/nipype/pull/990/files)
* ENH: SPM12 Normalize interface (https://github.com/nipy/nipype/pull/986)
* FIX: Utility interface test dir (https://github.com/nipy/nipype/pull/986)
* FIX: IPython engine directory reset after crash (https://github.com/nipy/nipype/pull/987)
* ENH: Resting state fMRI example with NiPy realignment and no SPM (https://github.com/nipy/nipype/pull/992)
* FIX: Corrected Freesurfer SegStats _list_outputs to avoid error if summary_file is
* FIX: Corrected Freesurfer SegStats _list_outputs to avoid error if summary_file is
undefined (issue #994)(https://https://github.com/nipy/nipype/pull/996)
* FIX: OpenfMRI support and FSL 5.0.7 changes (https://github.com/nipy/nipype/pull/1006)
* FIX: Output prefix in SPM Normalize with modulation (https://github.com/nipy/nipype/pull/1023)
* ENH: Usability improvements in cluster environments (https://github.com/nipy/nipype/pull/1025)
* ENH: ANTs JointFusion() (https://github.com/nipy/nipype/pull/1042)
* ENH: Added csvReader() utility (https://github.com/nipy/nipype/pull/1044)

Release 0.10.0 (October 10, 2014)
============

* ENH: New miscelaneous interfaces: SplitROIs (mapper), MergeROIs (reducer)
to enable parallel processing of very large images.
* ENH: Updated FSL interfaces: BEDPOSTX and XFibres, former interfaces are still
available with the version suffix: BEDPOSTX4 and XFibres4. Added gpu
available with the version suffix: BEDPOSTX4 and XFibres4. Added gpu
versions of BEDPOSTX: BEDPOSTXGPU, BEDPOSTX5GPU, and BEDPOSTX4GPU
* ENH: Added experimental support for MIPAV algorithms thorugh JIST plugins
* ENH: New dipy interfaces: Denoise, Resample
* ENH: New Freesurfer interfaces: Tkregister2 (for conversion of fsl style matrices to freesurfer format), MRIPretess
* ENH: New FSL interfaces: WarpPoints, WarpPointsToStd, EpiReg, ProbTrackX2, WarpUtils, ConvertWarp
* ENH: New miscelaneous interfaces: AddCSVRow, NormalizeProbabilityMapSet, AddNoise
* ENH: New AFNI interfaces: Eval, Means, SVMTest, SVMTrain
* ENH: FUGUE interface has been refactored to use the name_template system, 3 examples
* ENH: FUGUE interface has been refactored to use the name_template system, 3 examples
added to doctests, some bugs solved.
* API: Interfaces to external packages are no longer available in the top-level
``nipype`` namespace, and must be imported directly (e.g.
``from nipype.interfaces import fsl``).
* ENH: Support for elastix via a set of new interfaces: Registration, ApplyWarp,
* ENH: Support for elastix via a set of new interfaces: Registration, ApplyWarp,
AnalyzeWarp, PointsWarp, and EditTransform
* ENH: New ANTs interface: ApplyTransformsToPoints, LaplacianThickness
* ENH: New Diffusion Toolkit interface: TrackMerge
Expand All @@ -59,7 +60,7 @@ Release 0.10.0 (October 10, 2014)
* ENH: New color mode for write_graph
* ENH: You can now force MapNodes to be run serially
* ENH: Added ANTS based openfmri workflow
* ENH: MapNode now supports flattening of nested lists
* ENH: MapNode now supports flattening of nested lists
* ENH: Support for headless mode using Xvfb
* ENH: nipype_display_crash has a debugging mode
* FIX: MRTrix tracking algorithms were ignoring mask parameters.
Expand Down
29 changes: 28 additions & 1 deletion nipype/interfaces/tests/test_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# vi: set ft=python sts=4 ts=4 sw=4 et:
import os
import shutil
from tempfile import mkdtemp
from tempfile import mkdtemp, mkstemp

import numpy as np
from nipype.testing import assert_equal, assert_true, assert_raises
Expand Down Expand Up @@ -138,3 +138,30 @@ def test_split():
finally:
os.chdir(origdir)
shutil.rmtree(tempdir)


def test_csvReader():
header = "files,labels,erosion\n"
lines = ["foo,hello,300.1\n",
"bar,world,5\n",
"baz,goodbye,0.3\n"]
for x in range(2):
fd, name = mkstemp(suffix=".csv")
with open(name, 'w+b') as fid:
reader = utility.CSVReader()
if x % 2 == 0:
fid.write(header)
reader.inputs.header = True
fid.writelines(lines)
fid.flush()
reader.inputs.in_file = name
out = reader.run()
if x % 2 == 0:
yield assert_equal, out.outputs.files, ['foo', 'bar', 'baz']
yield assert_equal, out.outputs.labels, ['hello', 'world', 'goodbye']
yield assert_equal, out.outputs.erosion, ['300.1', '5', '0.3']
else:
yield assert_equal, out.outputs.column_0, ['foo', 'bar', 'baz']
yield assert_equal, out.outputs.column_1, ['hello', 'world', 'goodbye']
yield assert_equal, out.outputs.column_2, ['300.1', '5', '0.3']
os.unlink(name)
80 changes: 80 additions & 0 deletions nipype/interfaces/utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,3 +479,83 @@ def _run_interface(self, runtime):
assert_equal(data1, data2)

return runtime


class CSVReaderInputSpec(DynamicTraitedSpec, TraitedSpec):
in_file = File(exists=True, mandatory=True, desc='Input comma-seperated value (CSV) file')
header = traits.Bool(False, usedefault=True, desc='True if the first line is a column header')


class CSVReader(BaseInterface):
"""
Examples
--------

>>> reader = CSVReader() # doctest: +SKIP
>>> reader.inputs.in_file = 'noHeader.csv' # doctest: +SKIP
>>> out = reader.run() # doctest: +SKIP
>>> out.outputs.column_0 == ['foo', 'bar', 'baz'] # doctest: +SKIP
True
>>> out.outputs.column_1 == ['hello', 'world', 'goodbye'] # doctest: +SKIP
True
>>> out.outputs.column_2 == ['300.1', '5', '0.3'] # doctest: +SKIP
True

>>> reader = CSVReader() # doctest: +SKIP
>>> reader.inputs.in_file = 'header.csv' # doctest: +SKIP
>>> reader.inputs.header = True # doctest: +SKIP
>>> out = reader.run() # doctest: +SKIP
>>> out.outputs.files == ['foo', 'bar', 'baz'] # doctest: +SKIP
True
>>> out.outputs.labels == ['hello', 'world', 'goodbye'] # doctest: +SKIP
True
>>> out.outputs.erosion == ['300.1', '5', '0.3'] # doctest: +SKIP
True

"""
input_spec = CSVReaderInputSpec
output_spec = DynamicTraitedSpec
_always_run = True

def _append_entry(self, outputs, entry):
for key, value in zip(self._outfields, entry):
outputs[key].append(value)
return outputs

def _parse_line(self, line):
line = line.replace('\n', '')
entry = [x.strip() for x in line.split(',')]
return entry

def _get_outfields(self):
with open(self.inputs.in_file, 'r') as fid:
entry = self._parse_line(fid.readline())
if self.inputs.header:
self._outfields = tuple(entry)
else:
self._outfields = tuple(['column_' + str(x) for x in range(len(entry))])
return self._outfields

def _run_interface(self, runtime):
self._get_outfields()
return runtime

def _outputs(self):
return self._add_output_traits(super(CSVReader, self)._outputs())

def _add_output_traits(self, base):
return add_traits(base, self._get_outfields())

def _list_outputs(self):
outputs = self.output_spec().get()
isHeader = True
for key in self._outfields:
outputs[key] = [] # initialize outfields
with open(self.inputs.in_file, 'r') as fid:
for line in fid.readlines():
if self.inputs.header and isHeader: # skip header line
isHeader = False
continue
entry = self._parse_line(line)
outputs = self._append_entry(outputs, entry)
return outputs