Skip to content
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

STY: Apply ruff preview rules #1369

Merged
merged 9 commits into from
Oct 2, 2024
6 changes: 3 additions & 3 deletions nibabel/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,7 @@ def set_zooms(self, zooms):
ndim = dims[0]
zooms = np.asarray(zooms)
if len(zooms) != ndim:
raise HeaderDataError('Expecting %d zoom values for ndim %d' % (ndim, ndim))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wondering, does ndim really must appear twice in the error message?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's reasonable to say you were expecting N zooms for an N-dim image. I think it would also make sense to rewrite something along the lines of "Zooms must have one value per dimension (ndim={ndim}). Received: {zooms}."

raise HeaderDataError(f'Expecting {ndim} zoom values for ndim {ndim}')
if np.any(zooms < 0):
raise HeaderDataError('zooms must be positive')
pixdims = hdr['pixdim']
Expand Down Expand Up @@ -818,11 +818,11 @@ def _chk_datatype(klass, hdr, fix=False):
dtype = klass._data_type_codes.dtype[code]
except KeyError:
rep.problem_level = 40
rep.problem_msg = 'data code %d not recognized' % code
rep.problem_msg = f'data code {code} not recognized'
else:
if dtype.itemsize == 0:
rep.problem_level = 40
rep.problem_msg = 'data code %d not supported' % code
rep.problem_msg = f'data code {code} not supported'
else:
return hdr, rep
if fix:
Expand Down
5 changes: 2 additions & 3 deletions nibabel/cifti2/cifti2_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def from_mask(cls, mask, name='other', affine=None):
else:
raise ValueError(
'Mask should be either 1-dimensional (for surfaces) or '
'3-dimensional (for volumes), not %i-dimensional' % mask.ndim
DimitriPapadopoulos marked this conversation as resolved.
Show resolved Hide resolved
f'3-dimensional (for volumes), not {mask.ndim}-dimensional'
)

@classmethod
Expand Down Expand Up @@ -1519,7 +1519,6 @@ def get_element(self, index):
index = self.size + index
if index >= self.size or index < 0:
raise IndexError(
'index %i is out of range for SeriesAxis with size %i'
% (original_index, self.size)
f'index {original_index} is out of range for SeriesAxis with size {self.size}'
)
return self.start + self.step * index
2 changes: 1 addition & 1 deletion nibabel/cifti2/tests/test_cifti2io_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def test_read_and_proxies():

@needs_nibabel_data('nitest-cifti2')
def test_version():
for i, dat in enumerate(datafiles):
for dat in datafiles:
img = nib.load(dat)
assert Version(img.header.version) == Version('2')

Expand Down
12 changes: 6 additions & 6 deletions nibabel/cmdline/dicomfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
self.direct_io = False

def __str__(self):
return 'FileHandle(%d)' % self.fno
return f'FileHandle({self.fno})'

Check warning on line 54 in nibabel/cmdline/dicomfs.py

View check run for this annotation

Codecov / codecov/patch

nibabel/cmdline/dicomfs.py#L54

Added line #L54 was not covered by tests


class DICOMFS(fuse.Fuse):
Expand Down Expand Up @@ -85,11 +85,11 @@
series_info += f'UID: {series.uid}\n'
series_info += f'number: {series.number}\n'
series_info += f'description: {series.description}\n'
series_info += 'rows: %d\n' % series.rows
series_info += 'columns: %d\n' % series.columns
series_info += 'bits allocated: %d\n' % series.bits_allocated
series_info += 'bits stored: %d\n' % series.bits_stored
series_info += 'storage instances: %d\n' % len(series.storage_instances)
series_info += f'rows: {series.rows}\n'
series_info += f'columns: {series.columns}\n'
series_info += f'bits allocated: {series.bits_allocated}\n'
series_info += f'bits stored: {series.bits_stored}\n'
series_info += f'storage instances: {len(series.storage_instances)}\n'

Check warning on line 92 in nibabel/cmdline/dicomfs.py

View check run for this annotation

Codecov / codecov/patch

nibabel/cmdline/dicomfs.py#L88-L92

Added lines #L88 - L92 were not covered by tests
d[series.number] = {
'INFO': series_info.encode('ascii', 'replace'),
f'{series.number}.nii': (series.nifti_size, series.as_nifti),
Expand Down
4 changes: 2 additions & 2 deletions nibabel/cmdline/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ def get_data_diff(files, max_abs=0, max_rel=0, dtype=np.float64):
diffs1.append({'CMP': 'incompat'})

if any(diffs1):
diffs['DATA(diff %d:)' % (i + 1)] = diffs1
diffs[f'DATA(diff {i + 1}:)'] = diffs1

return diffs

Expand All @@ -293,7 +293,7 @@ def display_diff(files, diff):
output += field_width.format('Field/File')

for i, f in enumerate(files, 1):
output += '%d:%s' % (i, filename_width.format(os.path.basename(f)))
output += f'{i}:{filename_width.format(os.path.basename(f))}'

output += '\n'

Expand Down
10 changes: 5 additions & 5 deletions nibabel/cmdline/ls.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def get_opt_parser():
action='store_true',
dest='all_counts',
default=False,
help='Output all counts, even if number of unique values > %d' % MAX_UNIQUE,
help=f'Output all counts, even if number of unique values > {MAX_UNIQUE}',
),
Option(
'-z',
Expand Down Expand Up @@ -117,7 +117,7 @@ def proc_file(f, opts):
row += ['']

if hasattr(h, 'extensions') and len(h.extensions):
row += ['@l#exts: %d' % len(h.extensions)]
row += [f'@l#exts: {len(h.extensions)}']
else:
row += ['']

Expand Down Expand Up @@ -166,16 +166,16 @@ def proc_file(f, opts):
d = d.reshape(-1)
if opts.stats:
# just # of elements
row += ['@l[%d]' % np.prod(d.shape)]
row += [f'@l[{np.prod(d.shape)}]']
# stats
row += [f'@l[{np.min(d):.2g}, {np.max(d):.2g}]' if len(d) else '-']
if opts.counts:
items, inv = np.unique(d, return_inverse=True)
if len(items) > 1000 and not opts.all_counts:
counts = _err('%d uniques. Use --all-counts' % len(items))
counts = _err(f'{len(items)} uniques. Use --all-counts')
else:
freq = np.bincount(inv)
counts = ' '.join('%g:%d' % (i, f) for i, f in zip(items, freq))
counts = ' '.join(f'{i:g}:{f}' for i, f in zip(items, freq))
row += ['@l' + counts]
except OSError as e:
verbose(2, f'Failed to obtain stats/counts -- {e}')
Expand Down
2 changes: 1 addition & 1 deletion nibabel/dft.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def as_nifti(self):
for i, si in enumerate(self.storage_instances):
if i + 1 != si.instance_number:
raise InstanceStackError(self, i, si)
logger.info('reading %d/%d' % (i + 1, len(self.storage_instances)))
logger.info(f'reading {i + 1}/{len(self.storage_instances)}')
d = self.storage_instances[i].dicom()
data[i, :, :] = d.pixel_array

Expand Down
4 changes: 2 additions & 2 deletions nibabel/ecat.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,14 @@
"""
code = self._structarr['patient_orientation'].item()
if code not in self._patient_orient_codes:
raise KeyError('Ecat Orientation CODE %d not recognized' % code)
raise KeyError(f'Ecat Orientation CODE {code} not recognized')

Check warning on line 312 in nibabel/ecat.py

View check run for this annotation

Codecov / codecov/patch

nibabel/ecat.py#L312

Added line #L312 was not covered by tests
return self._patient_orient_codes[code]

def get_filetype(self):
"""Type of ECAT Matrix File from code stored in header"""
code = self._structarr['file_type'].item()
if code not in self._ft_codes:
raise KeyError('Ecat Filetype CODE %d not recognized' % code)
raise KeyError(f'Ecat Filetype CODE {code} not recognized')

Check warning on line 319 in nibabel/ecat.py

View check run for this annotation

Codecov / codecov/patch

nibabel/ecat.py#L319

Added line #L319 was not covered by tests
return self._ft_codes[code]

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion nibabel/fileslice.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def canonical_slicers(sliceobj, shape, check_inds=True):
if slicer < 0:
slicer = dim_len + slicer
elif check_inds and slicer >= dim_len:
raise ValueError('Integer index %d to large' % slicer)
raise ValueError(f'Integer index {slicer} too large')
can_slicers.append(slicer)
# Fill out any missing dimensions
if n_real < n_dim:
Expand Down
10 changes: 5 additions & 5 deletions nibabel/freesurfer/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@
for i in range(n_entries):
# structure name length + string
name_length = np.fromfile(fobj, dt, 1)[0]
name = np.fromfile(fobj, '|S%d' % name_length, 1)[0]
name = np.fromfile(fobj, f'|S{name_length}', 1)[0]
names.append(name)
# read RGBT for this entry
ctab[i, :4] = np.fromfile(fobj, dt, 4)
Expand Down Expand Up @@ -465,13 +465,13 @@
dt = _ANNOT_DT
# This code works with a file version == 2, nothing else
if ctab_version != 2:
raise Exception('Unrecognised .annot file version (%i)', ctab_version)
raise Exception(f'Unrecognised .annot file version ({ctab_version})')

Check warning on line 468 in nibabel/freesurfer/io.py

View check run for this annotation

Codecov / codecov/patch

nibabel/freesurfer/io.py#L468

Added line #L468 was not covered by tests
# maximum LUT index present in the file
max_index = np.fromfile(fobj, dt, 1)[0]
ctab = np.zeros((max_index, 5), dt)
# orig_tab string length + string
length = np.fromfile(fobj, dt, 1)[0]
np.fromfile(fobj, '|S%d' % length, 1)[0] # Orig table path
np.fromfile(fobj, f'|S{length}', 1)[0] # Orig table path
# number of LUT entries present in the file
entries_to_read = np.fromfile(fobj, dt, 1)[0]
names = list()
Expand All @@ -480,7 +480,7 @@
idx = np.fromfile(fobj, dt, 1)[0]
# structure name length + string
name_length = np.fromfile(fobj, dt, 1)[0]
name = np.fromfile(fobj, '|S%d' % name_length, 1)[0]
name = np.fromfile(fobj, f'|S{name_length}', 1)[0]
names.append(name)
# RGBT
ctab[idx, :4] = np.fromfile(fobj, dt, 4)
Expand Down Expand Up @@ -525,7 +525,7 @@
def write_string(s):
s = (s if isinstance(s, bytes) else s.encode()) + b'\x00'
write(len(s))
write(s, dtype='|S%d' % len(s))
write(s, dtype=f'|S{len(s)}')

# Generate annotation values for each ctab entry
if fill_ctab:
Expand Down
2 changes: 1 addition & 1 deletion nibabel/freesurfer/mghformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def set_zooms(self, zooms):
zooms = np.asarray(zooms)
ndims = self._ndims()
if len(zooms) > ndims:
raise HeaderDataError('Expecting %d zoom values' % ndims)
raise HeaderDataError(f'Expecting {ndims} zoom values')
if np.any(zooms[:3] <= 0):
raise HeaderDataError(
f'Spatial (first three) zooms must be positive; got {tuple(zooms[:3])}'
Expand Down
2 changes: 1 addition & 1 deletion nibabel/gifti/gifti.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ def _to_xml_element(self):
},
)
for di, dn in enumerate(self.dims):
data_array.attrib['Dim%d' % di] = str(dn)
data_array.attrib[f'Dim{di}'] = str(dn)

if self.meta is not None:
data_array.append(self.meta._to_xml_element())
Expand Down
4 changes: 2 additions & 2 deletions nibabel/gifti/parse_gifti_fast.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ def EndElementHandler(self, name):
if name == 'GIFTI':
if hasattr(self, 'expected_numDA') and self.expected_numDA != self.img.numDA:
warnings.warn(
'Actual # of data arrays does not match '
'# expected: %d != %d.' % (self.expected_numDA, self.img.numDA)
'Actual # of data arrays does not match # expected: '
f'{self.expected_numDA} != {self.img.numDA}.'
)
# remove last element of the list
self.fsm_state.pop()
Expand Down
2 changes: 1 addition & 1 deletion nibabel/gifti/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ..volumeutils import Recoder

# Translate dtype.kind char codes to XML text output strings
KIND2FMT = {'i': '%i', 'u': '%i', 'f': '%10.6f', 'c': '%10.6f', 'V': ''}
KIND2FMT = {'i': '%d', 'u': '%d', 'f': '%10.6f', 'c': '%10.6f', 'V': ''}

array_index_order_codes = Recoder(
(
Expand Down
2 changes: 1 addition & 1 deletion nibabel/nicom/csareader.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@
if len(items) == 0:
return None
if len(items) != n:
raise ValueError('Expecting %d vector' % n)
raise ValueError(f'Expecting {n} vector')

Check warning on line 182 in nibabel/nicom/csareader.py

View check run for this annotation

Codecov / codecov/patch

nibabel/nicom/csareader.py#L182

Added line #L182 was not covered by tests
return np.array(items)


Expand Down
4 changes: 2 additions & 2 deletions nibabel/nicom/dicomreaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def slices_to_series(wrappers):
break
else: # no match in current volume lists
volume_lists.append([dw])
print('We appear to have %d Series' % len(volume_lists))
print(f'We appear to have {len(volume_lists)} Series')
# second pass
out_vol_lists = []
for vol_list in volume_lists:
Expand All @@ -143,7 +143,7 @@ def slices_to_series(wrappers):
out_vol_lists += _third_pass(vol_list)
continue
out_vol_lists.append(vol_list)
print('We have %d volumes after second pass' % len(out_vol_lists))
print(f'We have {len(out_vol_lists)} volumes after second pass')
# final pass check
for vol_list in out_vol_lists:
zs = [s.slice_indicator for s in vol_list]
Expand Down
2 changes: 1 addition & 1 deletion nibabel/nicom/dicomwrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ def applies(self, dcm_wrp) -> bool:
warnings.warn(
'A multi-stack file was passed without an explicit filter, just using lowest StackID'
)
self._selected = sorted(stack_ids)[0]
self._selected = min(stack_ids)
return True
return False

Expand Down
4 changes: 2 additions & 2 deletions nibabel/nicom/tests/test_dicomwrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -991,8 +991,8 @@ def test_scale_data(self):
assert_array_equal(data * 3 - 2, MFW(fake_mf)._scale_data(data))
# Decimals are OK
for frame in frames:
frame.PixelValueTransformationSequence[0].RescaleSlope = Decimal('3')
frame.PixelValueTransformationSequence[0].RescaleIntercept = Decimal('-2')
frame.PixelValueTransformationSequence[0].RescaleSlope = Decimal(3)
frame.PixelValueTransformationSequence[0].RescaleIntercept = Decimal(-2)
assert_array_equal(data * 3 - 2, MFW(fake_mf)._scale_data(data))
# A per-frame RWV scaling takes precedence over per-frame PixelValueTransformation
for frame in frames:
Expand Down
10 changes: 5 additions & 5 deletions nibabel/nifti1.py
Original file line number Diff line number Diff line change
Expand Up @@ -1559,7 +1559,7 @@ def get_intent(self, code_repr='label'):
else:
raise TypeError('repr can be "label" or "code"')
n_params = len(recoder.parameters[code]) if known_intent else 0
params = (float(hdr['intent_p%d' % (i + 1)]) for i in range(n_params))
params = (float(hdr[f'intent_p{i}']) for i in range(1, n_params + 1))
name = hdr['intent_name'].item().decode('latin-1')
return label, tuple(params), name

Expand Down Expand Up @@ -1632,8 +1632,8 @@ def set_intent(self, code, params=(), name='', allow_unknown=False):
hdr['intent_name'] = name
all_params = [0] * 3
all_params[: len(params)] = params[:]
for i, param in enumerate(all_params):
hdr['intent_p%d' % (i + 1)] = param
for i, param in enumerate(all_params, start=1):
hdr[f'intent_p{i}'] = param

def get_slice_duration(self):
"""Get slice duration
Expand Down Expand Up @@ -1911,7 +1911,7 @@ def _chk_offset(hdr, fix=False):
return hdr, rep
if magic == hdr.single_magic and offset < hdr.single_vox_offset:
rep.problem_level = 40
rep.problem_msg = 'vox offset %d too low for single file nifti1' % offset
rep.problem_msg = f'vox offset {int(offset)} too low for single file nifti1'
if fix:
hdr['vox_offset'] = hdr.single_vox_offset
rep.fix_msg = f'setting to minimum value of {hdr.single_vox_offset}'
Expand Down Expand Up @@ -1943,7 +1943,7 @@ def _chk_xform_code(klass, code_type, hdr, fix):
if code in recoder.value_set():
return hdr, rep
rep.problem_level = 30
rep.problem_msg = '%s %d not valid' % (code_type, code)
rep.problem_msg = f'{code_type} {code} not valid'
if fix:
hdr[code_type] = 0
rep.fix_msg = 'setting to 0'
Expand Down
4 changes: 2 additions & 2 deletions nibabel/orientations.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def ornt_transform(start_ornt, end_ornt):
result[start_in_idx, :] = [end_in_idx, flip]
break
else:
raise ValueError('Unable to find out axis %d in start_ornt' % end_out_idx)
raise ValueError(f'Unable to find out axis {end_out_idx} in start_ornt')
return result


Expand Down Expand Up @@ -322,7 +322,7 @@ def axcodes2ornt(axcodes, labels=None):
[ 2., 1.]])
"""
labels = list(zip('LPI', 'RAS')) if labels is None else labels
allowed_labels = sum([list(L) for L in labels], []) + [None]
allowed_labels = sum((list(L) for L in labels), []) + [None]
DimitriPapadopoulos marked this conversation as resolved.
Show resolved Hide resolved
if len(allowed_labels) != len(set(allowed_labels)):
raise ValueError(f'Duplicate labels in {allowed_labels}')
if not set(axcodes).issubset(allowed_labels):
Expand Down
2 changes: 1 addition & 1 deletion nibabel/spatialimages.py
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ def set_zooms(self, zooms: Sequence[float]) -> None:
shape = self.get_data_shape()
ndim = len(shape)
if len(zooms) != ndim:
raise HeaderDataError('Expecting %d zoom values for ndim %d' % (ndim, ndim))
raise HeaderDataError(f'Expecting {ndim} zoom values for ndim {ndim}')
if any(z < 0 for z in zooms):
raise HeaderDataError('zooms must be positive')
self._zooms = zooms
Expand Down
2 changes: 1 addition & 1 deletion nibabel/streamlines/tests/test_array_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def test_creating_arraysequence_from_list(self):
# List of ndarrays.
N = 5
for ndim in range(1, N + 1):
common_shape = tuple([SEQ_DATA['rng'].randint(1, 10) for _ in range(ndim - 1)])
common_shape = tuple(SEQ_DATA['rng'].randint(1, 10) for _ in range(ndim - 1))
data = generate_data(nb_arrays=5, common_shape=common_shape, rng=SEQ_DATA['rng'])
check_arr_seq(ArraySequence(data), data)

Expand Down
2 changes: 1 addition & 1 deletion nibabel/tests/test_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

def _as_fname(img):
global _counter
fname = 'img%3d.nii' % _counter
fname = f'img{_counter:3d}.nii'
_counter = _counter + 1
save(img, fname)
return fname
Expand Down
4 changes: 2 additions & 2 deletions nibabel/tests/test_nifti1.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,12 +578,12 @@ def test_slice_times(self):
with pytest.raises(HeaderDataError):
# all None
hdr.set_slice_times((None,) * len(times))
n_mid_times = times[:]
n_mid_times = times.copy()
effigies marked this conversation as resolved.
Show resolved Hide resolved
n_mid_times[3] = None
with pytest.raises(HeaderDataError):
# None in middle
hdr.set_slice_times(n_mid_times)
funny_times = times[:]
funny_times = times.copy()
funny_times[3] = 0.05
with pytest.raises(HeaderDataError):
# can't get single slice duration
Expand Down
Loading
Loading