Skip to content

Commit

Permalink
Merge pull request #299 from usnistgov/ruff_fix
Browse files Browse the repository at this point in the history
Fix ruff problems
  • Loading branch information
joefowler authored Oct 15, 2024
2 parents 9411575 + e7c642c commit 74b056f
Show file tree
Hide file tree
Showing 18 changed files with 70 additions and 87 deletions.
1 change: 1 addition & 0 deletions VERSIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* Fix problem where numpy 2.0 was failing a regression test. Not a true regression, so we broaden the acceptance criteria (issue 295).
* Add installation instructions to README for https-based installation, in addition to ssh-based.
* Fix Ruff errors.

**0.8.4** June 5, 2024

Expand Down
2 changes: 1 addition & 1 deletion mass/calibration/line_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def _smear_exponential_tail(cleanspectrum_fn, x, P_resolution, P_tailfrac, P_tai
nhi = min(10 * len(x), nhi)
x_wide = np.arange(-nlow, nhi + len(x)) * energy_step + x[0]
if len(x_wide) > 100000:
msg = "you're trying to FFT data of length %i (bad fit param?)" % len(x_wide)
msg = f"you're trying to FFT data of length {len(x_wide)} (bad fit param?)"
raise ValueError(msg)

freq = np.fft.rfftfreq(len(x_wide), d=energy_step) # Units of 1/energy
Expand Down
49 changes: 22 additions & 27 deletions mass/core/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def compute_autocorrelation(self, n_lags=None, data_samples=None, plot=True, max
max_excursion=max_excursion)

if self.hdf5_group is not None:
grp = self.hdf5_group.require_group("reclen%d" % n_lags)
grp = self.hdf5_group.require_group(f"reclen{n_lags}")
ds = grp.require_dataset("autocorrelation", shape=(n_lags,), dtype=np.float64)
ds[:] = self.autocorrelation[:]

Expand Down Expand Up @@ -474,9 +474,9 @@ def __open_file(self, filename, file_format=None):
setattr(self, attr, getattr(self.datafile, attr))

def __str__(self):
return "%s path '%s'\n%d samples (%d pretrigger) at %.2f microsecond sample time" % (
self.__class__.__name__, self.filename, self.nSamples, self.nPresamples,
1e6 * self.timebase)
line1 = f"{self.__class__.__name__} path '{self.filename}'\n"
line2 = f"{self.nSamples} samples ({self.nPresamples} pretriggger) at {1e6 * self.timebase:.2f} µs sample time"
return "\n".join((line1, line2))

def __repr__(self):
return f"{self.__class__.__name__}('{self.filename}')"
Expand Down Expand Up @@ -857,9 +857,9 @@ def subframes_from_nearest_external_trigger(self):
"run tes_group.calc_external_trigger_timing before accessing this")

def __str__(self):
return "%s path '%s'\n%d samples (%d pretrigger) at %.2f microsecond sample time" % (
self.__class__.__name__, self.filename, self.nSamples, self.nPresamples,
1e6 * self.timebase)
line1 = f"{self.__class__.__name__} path '{self.filename}'\n"
line2 = f"{self.nSamples} samples ({self.nPresamples} pretriggger) at {1e6 * self.timebase:.2f} µs sample time"
return "\n".join((line1, line2))

def __repr__(self):
return f"{self.__class__.__name__}('{self.filename}')"
Expand All @@ -877,8 +877,7 @@ def bad(self, *args, **kwargs):

def resize(self, nPulses):
if self.nPulses < nPulses:
raise ValueError("Can only shrink using resize(), but the requested size %d is larger than current %d" %
(nPulses, self.nPulses))
raise ValueError(f"Can only shrink using resize(), but the requested size {nPulses} > than current {self.nPulses}")
self.nPulses = nPulses
self.__setup_vectors()

Expand Down Expand Up @@ -1046,10 +1045,10 @@ def _summarize_data_segment(self, idx_slice, doPretrigFit=False):
self.p_promptness[idx_slice] = prompt

self.p_rise_time[idx_slice] = mass.core.analysis_algorithms.estimateRiseTime(
all_data, timebase=self.timebase, nPretrig=self.nPresamples - self.cut_pre)
all_data, timebase=self.timebase, nPretrig=self.nPresamples - self.cut_pre)

self.p_postpeak_deriv[idx_slice] = mass.core.analysis_algorithms.compute_max_deriv(
all_data, ignore_leading=self.peak_samplenumber - self.cut_pre)
all_data, ignore_leading=self.peak_samplenumber - self.cut_pre)

def __parse_expt_states(self):
"""
Expand Down Expand Up @@ -1909,7 +1908,7 @@ def fit_spectral_line(self, prange, mask=None, times=None, fit_type='dc', line='

@property
def pkl_fname(self):
return ljh_util.mass_folder_from_ljh_fname(self.filename, filename="ch%d_calibration.pkl" % self.channum)
return ljh_util.mass_folder_from_ljh_fname(self.filename, filename=f"ch{self.channum}_calibration.pkl")

@_add_group_loop()
def calibrate(self, attr, line_names, name_ext="", size_related_to_energy_resolution=10, # noqa: PLR0917
Expand Down Expand Up @@ -1956,7 +1955,7 @@ def convert_to_energy(self, attr, calname=None):
if calname is None:
calname = attr
if calname not in self.calibration:
raise ValueError("For chan %d calibration %s does not exist" % (self.channum, calname))
raise ValueError(f"For chan {self.channum} calibration {calname} does not exist")
cal = self.calibration[calname]
self.p_energy[:] = cal.ph2energy(getattr(self, attr))
self.last_used_calibration = cal
Expand Down Expand Up @@ -2051,10 +2050,9 @@ def plot_traces(self, pulsenums, pulse_summary=True, axis=None, difference=False
linestyle=linestyle, alpha=alpha, linewidth=linewidth)
if pulse_summary and pulses_plotted < MAX_TO_SUMMARIZE and len(self.p_pretrig_mean) >= pn:
try:
summary = "%s%6d: %5.0f %7.2f %6.1f %5.0f %5.0f %7.1f" % (
cutchar, pn, self.p_pretrig_mean[pn], self.p_pretrig_rms[pn],
self.p_postpeak_deriv[pn], self.p_rise_time[pn] * 1e6,
self.p_peak_value[pn], self.p_pulse_average[pn])
summary = f"{cutchar}{pn:6d}: {self.p_pretrig_mean[pn]:5.0f} {self.p_pretrig_rms[pn]:7.2f} "
summary += f"{self.p_postpeak_deriv[pn]:6.1f} {self.p_rise_time[pn] * 1e6:5.0f} "
summary += f"{self.p_peak_value[pn]:5.0f} {self.p_pulse_average[pn]:7.1f}"
except IndexError:
pulse_summary = False
continue
Expand Down Expand Up @@ -2112,7 +2110,7 @@ def compare_calibrations(self):
plt.xlabel("energy (eV)")
plt.ylabel("energy resolution fwhm (eV)")
plt.grid("on")
plt.title("chan %d cal comparison" % self.channum)
plt.title(f"chan {self.channum} cal comparison")

def count_rate(self, goodonly=False, bin_s=60):
g = self.cuts.good()
Expand All @@ -2139,12 +2137,11 @@ def cut_summary(self):
bad2 = self.cuts.bad(c2)
n_and = np.logical_and(bad1, bad2).sum()
n_or = np.logical_or(bad1, bad2).sum()
print("%6d (and) %6d (or) pulses cut by [%s and/or %s]" %
(n_and, n_or, c1.upper(), c2.upper()))
print(f"{n_and:6d} (and) %{n_or:6d} (or) pulses cut by [{c1.upper()} and/or {c2.upper()}]")
print()
for cut_name in boolean_fields:
print("%6d pulses cut by %s" % (self.cuts.bad(cut_name).sum(), cut_name.upper()))
print("%6d pulses total" % self.nPulses)
print("{self.cuts.bad(cut_name).sum():6d} pulses cut by {cut_name.upper()}")
print(f"{self.nPulses:6d} pulses total")

@_add_group_loop()
def auto_cuts(self, nsigma_pt_rms=8.0, nsigma_max_deriv=8.0, pretrig_rms_percentile=None, forceNew=False, clearCuts=True):
Expand Down Expand Up @@ -2364,7 +2361,7 @@ def crosstalk_flagging_loop(channelsToCompare):
if np.sum(np.isin(self.tes_group.channel.keys(), selectNeighbors)) > 0:
h5grp[crosstalk_key][:] = crosstalk_flagging_loop(combinedNearestNeighbors)
else:
msg = "Channel %d skipping crosstalk cuts: no nearest neighbors matching criteria" % self.channum
msg = f"Channel {self.channum} skipping crosstalk cuts: no nearest neighbors matching criteria"
LOG.info(msg)

else:
Expand All @@ -2375,14 +2372,12 @@ def crosstalk_flagging_loop(channelsToCompare):
selectNeighbors = subgroupNeighbors[:, 0][np.isin(
subgroupNeighbors[:, 2], nearestNeighborsDistances)]
if np.sum(np.isin(self.tes_group.channel.keys(), selectNeighbors)) > 0:
LOG.info('Checking crosstalk between channel %d and %s neighbors...' % (
self.channum, neighborCategory))
LOG.info(f'Checking crosstalk between channel {self.channum} and {neighborCategory} neighbors...')
h5grp[categoryField][:] = crosstalk_flagging_loop(selectNeighbors)
h5grp[crosstalk_key][:] = np.logical_or(
h5grp[crosstalk_key], h5grp[categoryField])
else:
msg = "channel %d skipping %s crosstalk cuts because" % (
self.channum, neighborCategory)
msg = f"channel {self.channum} skipping {neighborCategory} crosstalk cuts because"
msg += " no nearest neighbors matching criteria in category"
LOG.info(msg)

Expand Down
2 changes: 1 addition & 1 deletion mass/core/channel_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -1270,7 +1270,7 @@ def helper(ds, ax):
plt.xlabel(x_attr, fontsize=8)
plt.ylabel(y_attr, fontsize=8)
ax.tick_params(axis='both', labelsize=8)
plt.title('MATTER Ch%d' % ch, fontsize=10)
plt.title(f'MATTER Chan {ch}', fontsize=10)

plot_multipage(self, subplot_shape, helper, filename_template_per_file,
filename_template_glob, filename_one_file, format, one_file)
Expand Down
4 changes: 2 additions & 2 deletions mass/core/channel_group_hdf5_only.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def make_or_get_master_hdf5_from_julia_hdf5_file(hdf5_filenames=None, forceNew=F
single_channel_file.attrs["npulses"] = len(
single_channel_file["filt_value"])
single_channel_file.attrs["filename"] = h5fname
master_hdf5_file["chan%i" % channum] = h5py.ExternalLink(h5fname, "/")
master_hdf5_file[f"chan{channum}"] = h5py.ExternalLink(h5fname, "/")
except KeyError:
print("failed to load chan %d hdf5 only" % channum)
print(f"failed to load chan {channum} hdf5 only")

return h5master_fname

Expand Down
6 changes: 3 additions & 3 deletions mass/core/cut.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ def cut_categorical(self, field, booldict):
for (category, catbool) in booldict.items():
labels[catbool] = category_names[category]
for (category, catbool) in booldict.items():
if not all(labels[booldict[category]] == category_names[category]):
if not all(labels[catbool] == category_names[category]):
raise ValueError(f"bools passed for {category} conflict with some other")
self.cut(field, labels)

Expand Down Expand Up @@ -633,7 +633,7 @@ def bad(self, *args, **kwargs):
return g

def __repr__(self):
return "Cuts(%d)" % len(self._mask)
return f"Cuts({len(self._mask)})"

def __str__(self):
return "Cuts(%d) with %d cut and %d uncut" % (len(self._mask), self.bad().sum(), self.good().sum())
return f"Cuts({len(self._mask)}) with {self.bad().sum()} cut and {self.good().sum()} uncut"
2 changes: 1 addition & 1 deletion mass/core/fake_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def _generate_virtual_file(self, n_pulses, distributions=None,
data[i, :] = self.model * scale[i] + self.pretrig_level + \
0.5 + self.rng.standard_normal(self.n_samples) * self.white_noise
vfile = VirtualFile(data, times=pulse_times)
vfile.filename = "virtual_file_chan%d.vtf" % channum
vfile.filename = f"virtual_file_chan{channum}.vtf"
vfile.timebase = self.sample_time_us / 1e6
vfile.nPresamples = self.n_presamples
return vfile
Expand Down
4 changes: 2 additions & 2 deletions mass/core/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ def set_segment_size(self, segmentsize=None):
segmentsize = 2**24
maxitems = segmentsize // self.pulse_size_bytes
if maxitems < 1:
raise ValueError("segmentsize=%d is not permitted to be smaller than pulse record (%d bytes)" %
(segmentsize, self.pulse_size_bytes))
raise ValueError(
f"segmentsize={segmentsize} is not permitted to be smaller than pulse record ({self.pulse_size_bytes} bytes)")
self.segmentsize = maxitems * self.pulse_size_bytes
self.pulses_per_seg = self.segmentsize // self.pulse_size_bytes
self.n_segments = 1 + (self.binary_size - 1) // self.segmentsize
Expand Down
20 changes: 7 additions & 13 deletions mass/core/optimal_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,9 @@ def __init__(self, avg_signal, n_pretrigger, noise_psd=None, noise_autocorr=None
self.ns = len(avg_signal)

if self.cut_pre < 0 or self.cut_post < 0:
raise ValueError("(cut_pre,cut_post)=(%d,%d), but neither can be negative" %
(self.cut_pre, self.cut_post))
raise ValueError(f"(cut_pre,cut_post)=({self.cut_pre},{self.cut_post}), but neither can be negative")
if self.cut_pre + self.cut_post >= self.ns - 2 * self.shorten:
raise ValueError("cut_pre+cut_post = %d but should be < %d" % (
self.cut_pre + self.cut_post, self.ns - 2 * self.shorten))
raise ValueError(f"cut_pre+cut_post = {self.cut_pre + self.cut_post} but should be < {self.ns - 2 * self.shorten}")

pre_avg = avg_signal[self.cut_pre:n_pretrigger - 1].mean()

Expand Down Expand Up @@ -153,8 +151,7 @@ def _compute_fourier_filter(self):
sig_ft = np.fft.rfft(self.avg_signal * window)

if len(sig_ft) != n - self.shorten:
raise ValueError("signal real DFT and noise PSD are not the same length (%d and %d)" %
(len(sig_ft), n))
raise ValueError(f"signal real DFT and noise PSD are not the same length ({len(sig_ft)} and {n})")

# Careful with PSD: "shorten" it by converting into a real space autocorrelation,
# truncating the middle, and going back to Fourier space
Expand Down Expand Up @@ -278,8 +275,7 @@ def bracketR(q, noise):
"""

if len(noise) < len(q):
raise ValueError("Vector q (length %d) cannot be longer than the noise (length %d)" %
(len(q), len(noise)))
raise ValueError(f"Vector q (length {len(q)}) cannot be longer than the noise (length {len(noise)})")
n = len(q)
r = np.zeros(2 * n - 1, dtype=float)
r[n - 1:] = noise[:n]
Expand Down Expand Up @@ -335,7 +331,7 @@ def isstr(x):
fwhm_eV = std_energy / v_dv
print(f"{f} {v_dv=:.2f} {var=:.2f} {fwhm_eV=:.2f} at {std_energy=:.2f} eV")
except KeyError:
print("%-20s not known" % f)
print(f"{f:20s} not known")


class ArrivalTimeSafeFilter(Filter):
Expand Down Expand Up @@ -371,12 +367,10 @@ def compute(self, fmax=None, f_3db=None, cut_pre=0, cut_post=0):
raise ValueError(
"Filter must have a sample_time if it's to be smoothed with fmax or f_3db")
if cut_pre < 0 or cut_post < 0:
raise ValueError("(cut_pre,cut_post)=(%d,%d), but neither can be negative" %
(cut_pre, cut_post))
raise ValueError(f"(cut_pre,cut_post)=({self.cut_pre},{self.cut_post}), but neither can be negative")
ns = self.pulsemodel.shape[0]
if cut_pre + cut_post >= ns:
raise ValueError("cut_pre+cut_post = %d but should be < %d" % (
cut_pre + cut_post, ns))
raise ValueError(f"cut_pre+cut_post = {cut_pre + cut_post} but should be < {ns}")

self.fmax = fmax
self.f_3db = f_3db
Expand Down
8 changes: 4 additions & 4 deletions mass/core/param_dict_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,13 @@ def set(self, **kwargs):
self.usage_set()
return

for prm in kwargs:
for prm, kwval in kwargs.items():
set = False
for d in self._prm_list:
if len(d.keys()) == 0:
raise ValueError('self._prm_list is wrong (empty)')
try:
if self.set_in_dict(prm, kwargs[prm], d):
if self.set_in_dict(prm, kwval, d):
set = True
break
except TypeError as msg:
Expand All @@ -116,8 +116,8 @@ def set(self, **kwargs):
if not set: # maybe set prm as meta data?
if isinstance(self.user_prm, dict):
# not a registered parameter:
self.user_prm[prm] = kwargs[prm]
message(f'{prm}={kwargs[prm]} assigned in self.user_prm')
self.user_prm[prm] = kwval
message(f'{prm}={kwval} assigned in self.user_prm')
else:
raise NameError(f'parameter "{prm}" not registered')
self._update()
Expand Down
2 changes: 1 addition & 1 deletion mass/mathstat/interpolate.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ def __init__(self, knots):

def __call__(self, x, id, der=0):
if id < 0 or id >= self.Nk:
raise ValueError("Require 0 <= id < Nk=%d" % self.Nk)
raise ValueError(f"Require 0 <= id < Nk={self.Nk}")
coef = np.zeros(self.Nk + 2, dtype=float)
coef[id + 1] = 1.0
if id < 2:
Expand Down
7 changes: 3 additions & 4 deletions mass/mathstat/power_spectrum.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ def addDataSegment(self, data, window=None):
given. window can be None (square window), a callable taking the
length and returning a sequence, or a sequence."""
if len(data) != self.m2:
raise ValueError("wrong size data segment. len(data)=%d but require %d" %
(len(data), self.m2))
raise ValueError(f"wrong size data segment. len(data)={len(data)} but require {self.m2}")
if np.isnan(data).any():
raise ValueError("data contains NaN")
if window is None:
Expand Down Expand Up @@ -135,7 +134,7 @@ def spectrum(self, nbins=None):
if nbins is None:
return self.specsum / self.nsegments
if nbins > self.m:
raise ValueError("Cannot rebin into more than m=%d bins" % self.m)
raise ValueError(f"Cannot rebin into more than m={self.m} bins")

newbin = np.asarray(0.5 + np.arange(self.m + 1, dtype=float) / (self.m + 1) * nbins, dtype=int)
result = np.zeros(nbins + 1, dtype=float)
Expand All @@ -152,7 +151,7 @@ def frequencies(self, nbins=None):
if nbins is None:
nbins = self.m
if nbins > self.m:
raise ValueError("Cannot rebin into more than m=%d bins" % self.m)
raise ValueError(f"Cannot rebin into more than m={self.m} bins")
return np.arange(nbins + 1, dtype=float) / (2 * self.dt * nbins)

def plot(self, axis=None, arb_to_unit_scale_and_label=(1, "arb"), sqrt_psd=True, **plotkwarg):
Expand Down
2 changes: 1 addition & 1 deletion mass/mathstat/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def find_range_randomly(A, nl, q=1):
Review* v53 #2 (2011) pp217-288. http://epubs.siam.org/doi/abs/10.1137/090771806
"""
if q < 0:
msg = "The number of power iterations q=%d needs to be at least 0" % q
msg = f"The number of power iterations q={q} needs to be at least 0"
raise ValueError(msg)
A = np.asarray(A)
_m, n = A.shape
Expand Down
Loading

0 comments on commit 74b056f

Please sign in to comment.