Skip to content

Commit 7f0d029

Browse files
committed
Fixed AddNoise interface
1 parent 1ad0f8c commit 7f0d029

File tree

2 files changed

+65
-26
lines changed

2 files changed

+65
-26
lines changed

nipype/algorithms/misc.py

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -955,20 +955,21 @@ def calc_moments(timeseries_file, moment):
955955
zero = (m2 == 0)
956956
return np.where(zero, 0, m3 / m2**(moment/2.0))
957957

958-
<<<<<<< HEAD
959-
class AddNoiseInputSpec(TraitedSpec):
960-
in_file = File( exists=True, mandatory=True,
961-
desc='input image that will be corrupted with noise')
962-
963-
in_mask = File( exists=True, desc='input mask, voxels outside this mask\
964-
will be considered background and corrupted with noise\
965-
with Rayleigh distribution' )
966958

967-
snr = traits.Float( 10.0, desc='desired output SNR in dB', usedefault=True )
959+
class AddNoiseInputSpec(TraitedSpec):
960+
in_file = File(exists=True, mandatory=True,
961+
desc='input image that will be corrupted with noise')
962+
in_mask = File(exists=True, desc=('input mask, voxels outside this mask '
963+
'will be considered background'))
964+
snr = traits.Float(10.0, desc='desired output SNR in dB', usedefault=True)
965+
dist = traits.Enum('normal', usedefault=True, mandatory=True,
966+
desc=('desired noise distribution, currently '
967+
'only normal is implemented'))
968+
bg_dist = traits.Enum('normal', 'rayleigh', usedefault=True, mandatory=True,
969+
desc=('desired noise distribution, currently '
970+
'only normal is implemented'))
971+
out_file = File(desc='desired output filename')
968972

969-
dist = traits.Enum( 'normal', desc='desired noise distribution, currently\
970-
only gaussian is implemented' )
971-
out_file = File( desc='desired output filename' )
972973

973974
class AddNoiseOutputSpec(TraitedSpec):
974975
out_file = File(exists=True, desc='corrupted image')
@@ -1001,9 +1002,10 @@ def _run_interface(self, runtime):
10011002
else:
10021003
in_mask = np.ones_like( in_data )
10031004

1004-
result = self.gen_noise( in_data, mask=in_mask, snr_db=snr )
1005-
res_im = nb.Nifti1Image( result, in_image.get_affine(), in_image.get_header() )
1006-
nb.save( res_im, self._gen_output_filename() )
1005+
result = self.gen_noise(in_data, mask=in_mask, snr_db=snr,
1006+
dist=self.inputs.dist, bg_dist=self.inputs.bg_dist)
1007+
res_im = nb.Nifti1Image(result, in_image.get_affine(), in_image.get_header())
1008+
res_im.to_filename(self._gen_output_filename())
10071009
return runtime
10081010

10091011
def _gen_output_filename( self ):
@@ -1020,28 +1022,32 @@ def _list_outputs(self):
10201022
outputs['out_file'] = self._gen_output_filename()
10211023
return outputs
10221024

1023-
def gen_noise( self, image, mask=None, snr_db=10.0 ):
1025+
def gen_noise(self, image, mask=None, snr_db=10.0, dist='normal', bg_dist='normal'):
10241026
"""
10251027
Generates a copy of an image with a certain amount of
10261028
added gaussian noise (rayleigh for background in mask)
10271029
"""
10281030
from math import sqrt
1029-
snr = sqrt( np.power( 10.0, snr_db/10.0 ) )
1030-
noise = np.random.normal( size=image.shape )
1031+
snr = sqrt(np.power(10.0, snr_db/10.0))
10311032

1032-
if mask is None:
1033-
mask = np.ones_like( image )
1033+
if dist == 'normal':
1034+
noise = np.random.normal(size=image.shape)
1035+
else:
1036+
raise NotImplementedError('Only normal distribution is supported')
10341037

1038+
if mask is None:
1039+
mask = np.ones_like(image)
10351040

1036-
S = np.mean(image[mask>0])
1041+
signal = image[mask>0].reshape(-1)
1042+
signal = signal - signal.mean()
1043+
S = (signal.var())**2
10371044

1038-
if np.any( mask==0 ):
1039-
S = S - np.mean( image[mask==0] )
1040-
bg_noise = np.random.rayleigh( size=image.shape )
1041-
noise[mask==0] = bg_noise[mask==0]
1045+
if np.any(mask==0):
1046+
if bg_dist == 'rayleigh':
1047+
bg_noise = np.random.rayleigh(size=image.shape)
1048+
noise[mask==0] = bg_noise[mask==0]
10421049

10431050
im_noise = image + noise * (S/snr)
1044-
10451051
return im_noise
10461052

10471053

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from nipype.testing import assert_equal
3+
from nipype.algorithms.misc import AddNoise
4+
5+
def test_AddNoise_inputs():
6+
input_map = dict(bg_dist=dict(mandatory=True,
7+
usedefault=True,
8+
),
9+
dist=dict(mandatory=True,
10+
usedefault=True,
11+
),
12+
in_file=dict(mandatory=True,
13+
),
14+
in_mask=dict(),
15+
out_file=dict(),
16+
snr=dict(usedefault=True,
17+
),
18+
)
19+
inputs = AddNoise.input_spec()
20+
21+
for key, metadata in input_map.items():
22+
for metakey, value in metadata.items():
23+
yield assert_equal, getattr(inputs.traits()[key], metakey), value
24+
25+
def test_AddNoise_outputs():
26+
output_map = dict(out_file=dict(),
27+
)
28+
outputs = AddNoise.output_spec()
29+
30+
for key, metadata in output_map.items():
31+
for metakey, value in metadata.items():
32+
yield assert_equal, getattr(outputs.traits()[key], metakey), value
33+

0 commit comments

Comments
 (0)