From 0e8d3689311c43d94583e60af6ccc4f89538dbeb Mon Sep 17 00:00:00 2001 From: zssherman Date: Fri, 22 Nov 2024 15:53:41 -0600 Subject: [PATCH 1/4] FIX: Update to use f-format strings. --- pyart/_debug_info.py | 8 -------- pyart/aux_io/gamicfile.py | 2 +- pyart/core/radar.py | 3 +-- pyart/correct/phase_proc.py | 6 +++--- pyart/correct/region_dealias.py | 4 +--- pyart/graph/common.py | 2 +- pyart/io/common.py | 2 +- pyart/io/mdv_common.py | 20 ++++++++++---------- pyart/io/nexrad_level3.py | 15 +++++++-------- pyart/io/rsl.py | 2 +- pyart/retrieve/spectra_calculations.py | 2 +- pyart/testing/data/make_small_mdv_ppi.py | 2 +- pyart/testing/data/make_small_mdv_rhi.py | 2 +- pyart/xradar/accessor.py | 4 ++-- 14 files changed, 31 insertions(+), 43 deletions(-) diff --git a/pyart/_debug_info.py b/pyart/_debug_info.py index 2d8bfc678c1..d19915b1c5b 100644 --- a/pyart/_debug_info.py +++ b/pyart/_debug_info.py @@ -81,13 +81,6 @@ def _debug_info(stream=None): except: cylp_available = "MISSING" - try: - import glpk - - glpk_version = "%i.%i" % (glpk.env.version) - except: - glpk_version = "MISSING" - try: import cvxopt.info @@ -122,7 +115,6 @@ def _debug_info(stream=None): print("---- Optional dependencies ----", file=stream) print("CyLP:", cylp_available, file=stream) - print("PyGLPK version:", glpk_version, file=stream) print("CVXOPT version:", cvxopt_version, file=stream) print("Cartopy version:", cartopy_version, file=stream) print("pytest version:", pytest_version, file=stream) diff --git a/pyart/aux_io/gamicfile.py b/pyart/aux_io/gamicfile.py index 8cc636f45d3..269df22b8db 100644 --- a/pyart/aux_io/gamicfile.py +++ b/pyart/aux_io/gamicfile.py @@ -37,7 +37,7 @@ def __init__(self, filename): """initialize object.""" self._hfile = h5py.File(filename, "r") self.nsweeps = self._hfile["what"].attrs["sets"] - self._scans = ["scan%i" % (i) for i in range(self.nsweeps)] + self._scans = [f"scan{i}" for i in range(self.nsweeps)] self.rays_per_sweep = self.how_attrs("ray_count", "int32") self.total_rays = sum(self.rays_per_sweep) self.gates_per_sweep = self.how_attrs("bin_count", "int32") diff --git a/pyart/core/radar.py b/pyart/core/radar.py index 94126eda6c3..c6e4a4000d7 100644 --- a/pyart/core/radar.py +++ b/pyart/core/radar.py @@ -797,8 +797,7 @@ def add_field(self, field_name, dic, replace_existing=False): if "data" not in dic: raise KeyError("dic must contain a 'data' key") if dic["data"].shape != (self.nrays, self.ngates): - t = (self.nrays, self.ngates) - err = "'data' has invalid shape, should be (%i, %i)" % t + err = "'data' has invalid shape, should be ({self.nrays}, {self.ngates})" raise ValueError(err) # add the field self.fields[field_name] = dic diff --git a/pyart/correct/phase_proc.py b/pyart/correct/phase_proc.py index 27b6901f1c9..4bc9883426e 100644 --- a/pyart/correct/phase_proc.py +++ b/pyart/correct/phase_proc.py @@ -902,13 +902,13 @@ def LP_solver_cylp_mp(A_Matrix, B_vectors, weights, really_verbose=False, proc=1 # check if equal sized chunks can be distributed to worker processes if n_rays % chunksize != 0: print( - "Problem of %d rays cannot be split to %d worker processes!\n\r" - "Fallback to 1 process!" % (n_rays, proc) + "Problem of {n_rays} rays cannot be split to {proc} worker processes!\n\r" + "Fallback to 1 process!" ) chunksize = n_rays # fall back to one process proc = 1 - print("Calculating with %d processes, %d rays per chunk" % (proc, chunksize)) + print(f"Calculating with {proc} processes, {chunksize} rays per chunk") def worker(model, B_vectors, weights, ray, chunksize, out_q): """ diff --git a/pyart/correct/region_dealias.py b/pyart/correct/region_dealias.py index 45995944195..0c467f7e871 100644 --- a/pyart/correct/region_dealias.py +++ b/pyart/correct/region_dealias.py @@ -316,9 +316,7 @@ def _find_sweep_interval_splits(nyquist, interval_splits, velocities, nsweep): max_vel = velocities.max() min_vel = velocities.min() if max_vel > nyquist or min_vel < -nyquist: - msg = "Velocities outside of the Nyquist interval found in " "sweep %i." % ( - nsweep - ) + msg = f"Velocities outside of the Nyquist interval found in sweep {nsweep}." warnings.warn(msg, UserWarning) # additional intervals must be added to capture the velocities # outside the nyquist limits diff --git a/pyart/graph/common.py b/pyart/graph/common.py index 803fdb8ec10..69ed34b8910 100644 --- a/pyart/graph/common.py +++ b/pyart/graph/common.py @@ -448,7 +448,7 @@ def generate_ray_title(radar, field, ray): l1 = f"{generate_radar_name(radar)} {time_str}" azim = radar.azimuth["data"][ray] elev = radar.elevation["data"][ray] - l2 = "Ray: %i Elevation: %.1f Azimuth: %.1f" % (ray, elev, azim) + l2 = f"Ray: {ray} Elevation: {elev:.1f} Azimuth: {azim:.1f}" field_name = generate_field_name(radar, field) return l1 + "\n" + l2 + "\n" + field_name diff --git a/pyart/io/common.py b/pyart/io/common.py index e5780a2c4bd..5722d33acd6 100644 --- a/pyart/io/common.py +++ b/pyart/io/common.py @@ -82,7 +82,7 @@ def stringarray_to_chararray(arr, numchars=None): arr_numchars = carr.shape[-1] if numchars <= arr_numchars: - raise ValueError("numchars must be >= %i" % (arr_numchars)) + raise ValueError(f"numchars must be >= {arr_numchars}") chararr = np.zeros(arr.shape + (numchars,), dtype="S1") chararr[..., :arr_numchars] = carr[:] return chararr diff --git a/pyart/io/mdv_common.py b/pyart/io/mdv_common.py index 244ff7d26b0..9d1cb4ff787 100644 --- a/pyart/io/mdv_common.py +++ b/pyart/io/mdv_common.py @@ -550,13 +550,13 @@ def read_a_field(self, fnum, debug=False): compr_data = self.fileptr.read(compr_info["nbytes_coded"]) encoding_type = field_header["encoding_type"] if encoding_type == ENCODING_INT8: - fmt = ">%iB" % (nx * ny) + fmt = f">{nx*ny}B" np_form = ">B" elif encoding_type == ENCODING_INT16: - fmt = ">%iH" % (nx * ny) + fmt = f">{nx*ny}H" np_form = ">H" elif encoding_type == ENCODING_FLOAT32: - fmt = ">%if" % (nx * ny) + fmt = f">{nx*ny}f" np_form = ">f" else: raise NotImplementedError("encoding: ", encoding_type) @@ -885,7 +885,7 @@ def _get_chunks(self, debug=False): else: if debug: - print("getting unknown chunk %i" % chunk_id) + print(f"getting unknown chunk {chunk_id}") self.chunk_data[cnum] = self._get_unknown_chunk(cnum) return radar_info, elevations, calib_info @@ -913,7 +913,7 @@ def _write_chunks(self, debug=False): else: if debug: - print("writing unknown chunk %i" % chunk_id) + print(f"writing unknown chunk {chunk_id}") self._write_unknown_chunk(self.chunk_data[cnum]) def _get_radar_info(self): @@ -941,14 +941,14 @@ def _get_elevs(self, nbytes): # the file pointer must be set at the correct location prior to call SIZE_FLOAT = 4.0 nelevations = np.floor(nbytes / SIZE_FLOAT) - fmt = ">%df" % (nelevations) + fmt = f">{nelevations}f" packet = struct.unpack(fmt, self.fileptr.read(struct.calcsize(fmt))) return np.array(packet) def _write_elevs(self, packet): """Write an array of elevation.""" # the file pointer must be set at the correct location prior to call - fmt = ">%df" % (len(packet)) + fmt = f">{len(packet)}f" # cast to string as Python < 2.7.7 pack does not except unicode fmt = str(fmt) string = struct.pack(fmt, *packet) @@ -1006,7 +1006,7 @@ def _write_unknown_chunk(self, data): def _get_levels_info(self, nlevels): """Get nlevel information, return a dict.""" # the file pointer must be set at the correct location prior to call - fmt = ">%iI %iI" % (nlevels, nlevels) + fmt = f">{nlevels}I {nlevels}I" if self.fileptr: packet = struct.unpack(fmt, self.fileptr.read(struct.calcsize(fmt))) else: @@ -1019,7 +1019,7 @@ def _get_levels_info(self, nlevels): def _write_levels_info(self, nlevels, d): """write levels information, return a dict.""" # the file pointer must be set at the correct location prior to call - fmt = "%iI %iI" % (nlevels, nlevels) + fmt = f"{nlevels}I {nlevels}I" packet = d["vlevel_offsets"] + d["vlevel_nbytes"] # cast to string as Python < 2.7.7 pack does not except unicode fmt = str(fmt) @@ -1101,7 +1101,7 @@ def _calc_geometry(self): else: proj_type = self.field_headers[0]["proj_type"] message = ( - "Unsupported projection type: %i, " % (proj_type) + f"Unsupported projection type: {proj_type}, " + "is MDV file in antenna coordinates?" ) raise NotImplementedError(message) diff --git a/pyart/io/nexrad_level3.py b/pyart/io/nexrad_level3.py index 72605fb3a6e..3c24247f8f8 100644 --- a/pyart/io/nexrad_level3.py +++ b/pyart/io/nexrad_level3.py @@ -124,9 +124,9 @@ def __init__(self, filename): # Read and decode 18 byte Message Header Block self.msg_header = _unpack_from_buf(buf, bpos, MESSAGE_HEADER) if self.msg_header["code"] not in SUPPORTED_PRODUCTS: - code = self.msg_header["code"] + code = self.msg_header["code"] # noqa: F841 raise NotImplementedError( - "Level3 product with code %i is not supported" % (code) + "Level3 product with code {code} is not supported" ) bpos += 18 @@ -139,10 +139,9 @@ def __init__(self, filename): supp_ver = SUPPORTED_VERSION_NUMBERS[self.msg_header["code"]] if ver > supp_ver: warnings.warn( - "Radar product version is %d. Py-ART implementation \ - supports max version of %d. Most recent product version has not \ - yet been implemented/tested." - % (ver, supp_ver), + f"Radar product version is {ver}. Py-ART implementation \ + supports max version of {supp_ver}. Most recent product version has not \ + yet been implemented/tested.", UserWarning, ) @@ -456,7 +455,7 @@ def __call__(self, packet_code): if packet_code == 28: xdr.update(self._unpack_prod_desc()) else: - raise NotImplementedError("Unknown XDR Component: %d" % (packet_code)) + raise NotImplementedError(f"Unknown XDR Component: {packet_code}") # Check that we got it all self.done() @@ -530,7 +529,7 @@ def _unpack_components(self): if i < num - 1: self.unpack_int() # Another pointer for the 'list' ? except KeyError: - raise NotImplementedError("Unknown XDR Component: %d" % (code)) + raise NotImplementedError(f"Unknown XDR Component: {code}") break if num == 1: diff --git a/pyart/io/rsl.py b/pyart/io/rsl.py index 0b396848b01..51d7ebcc8c3 100644 --- a/pyart/io/rsl.py +++ b/pyart/io/rsl.py @@ -175,7 +175,7 @@ def read_rsl( for volume_num in available_vols: # if a volume number is not recognized it is skipped. if volume_num not in VOLUMENUM2RSLNAME: - warnings.warn("Unknown Volume Number %d" % volume_num) + warnings.warn(f"Unknown Volume Number {volume_num}") continue rsl_field_name = VOLUMENUM2RSLNAME[volume_num] field_name = filemetadata.get_field_name(rsl_field_name) diff --git a/pyart/retrieve/spectra_calculations.py b/pyart/retrieve/spectra_calculations.py index 9a00707fa72..bab07e73015 100644 --- a/pyart/retrieve/spectra_calculations.py +++ b/pyart/retrieve/spectra_calculations.py @@ -35,7 +35,7 @@ def spectra_moments(radar): wavelength = radar.ds.attrs["wavelength"] for i in range(times): if i % 100 == 0: - print("Dealiasing %d/%d" % (i, times)) + print(f"Dealiasing {i}/{times}") spectra_idx = spectra[i, :, :] # Get the raw spectra, bins, and wavelength # Subtract the noise floor from the spectra. Also, return the integration limits diff --git a/pyart/testing/data/make_small_mdv_ppi.py b/pyart/testing/data/make_small_mdv_ppi.py index 5ecdd4f7939..687e19be951 100755 --- a/pyart/testing/data/make_small_mdv_ppi.py +++ b/pyart/testing/data/make_small_mdv_ppi.py @@ -156,7 +156,7 @@ # read/write elevs chunk f.seek(elevs_chunk_offset) -fmt = "%df" % (18) +fmt = f"{18}f" packet = list(struct.unpack(fmt, f.read(struct.calcsize(fmt)))) out.write(struct.pack(fmt, *packet)) diff --git a/pyart/testing/data/make_small_mdv_rhi.py b/pyart/testing/data/make_small_mdv_rhi.py index c7e105c2aa5..e31c23d94ec 100755 --- a/pyart/testing/data/make_small_mdv_rhi.py +++ b/pyart/testing/data/make_small_mdv_rhi.py @@ -151,7 +151,7 @@ # read/write elevs chunk f.seek(elevs_chunk_offset) -fmt = "%df" % (2) +fmt = f"{2}f" packet = list(struct.unpack(fmt, f.read(struct.calcsize(fmt)))) out.write(struct.pack(fmt, *packet)) diff --git a/pyart/xradar/accessor.py b/pyart/xradar/accessor.py index b9efd7ea63b..09c084fc9b0 100644 --- a/pyart/xradar/accessor.py +++ b/pyart/xradar/accessor.py @@ -210,7 +210,7 @@ def add_field(self, field_name, dic, replace_existing=False): raise KeyError("dic must contain a 'data' key") if dic["data"].shape != (self.nz, self.ny, self.nx): t = (self.nz, self.ny, self.nx) - err = "'data' has invalid shape, should be (%i, %i)" % t + err = "'data' has invalid shape, should be ({}, {})".format(*t) raise ValueError(err) self.fields[field_name] = dic @@ -458,7 +458,7 @@ def add_field(self, field_name, dic, replace_existing=False): raise KeyError("dic must contain a 'data' key") if dic["data"].shape != (self.nrays, self.ngates): t = (self.nrays, self.ngates) - err = "'data' has invalid shape, should be (%i, %i)" % t + err = "'data' has invalid shape, should be ({}, {})".format(*t) raise ValueError(err) # add the field self.fields[field_name] = dic From 076207f632deb78f08ee98586779f555989e2c57 Mon Sep 17 00:00:00 2001 From: zssherman Date: Fri, 22 Nov 2024 15:59:43 -0600 Subject: [PATCH 2/4] STY: PEP8 fix. --- pyart/correct/region_dealias.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyart/correct/region_dealias.py b/pyart/correct/region_dealias.py index 0c467f7e871..632a83aef6b 100644 --- a/pyart/correct/region_dealias.py +++ b/pyart/correct/region_dealias.py @@ -52,7 +52,7 @@ def dealias_region_based( set_limits=True, vel_field=None, corr_vel_field=None, - **kwargs + **kwargs, ): """ Dealias Doppler velocities using a region based algorithm. From d2a8d42dc5bddd00bb62fda05725fed69f0c0aa6 Mon Sep 17 00:00:00 2001 From: zssherman Date: Fri, 22 Nov 2024 16:28:04 -0600 Subject: [PATCH 3/4] FIX: Need int for correct struct fmt. Also forgot two 'f' pre quotes. --- pyart/correct/phase_proc.py | 4 ++-- pyart/io/mdv_common.py | 2 +- pyart/io/nexrad_level3.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyart/correct/phase_proc.py b/pyart/correct/phase_proc.py index 4bc9883426e..41012a8f1f6 100644 --- a/pyart/correct/phase_proc.py +++ b/pyart/correct/phase_proc.py @@ -902,8 +902,8 @@ def LP_solver_cylp_mp(A_Matrix, B_vectors, weights, really_verbose=False, proc=1 # check if equal sized chunks can be distributed to worker processes if n_rays % chunksize != 0: print( - "Problem of {n_rays} rays cannot be split to {proc} worker processes!\n\r" - "Fallback to 1 process!" + f"Problem of {n_rays} rays cannot be split to {proc} worker processes!\n\r" + f"Fallback to 1 process!" ) chunksize = n_rays # fall back to one process proc = 1 diff --git a/pyart/io/mdv_common.py b/pyart/io/mdv_common.py index 9d1cb4ff787..80294e1843a 100644 --- a/pyart/io/mdv_common.py +++ b/pyart/io/mdv_common.py @@ -941,7 +941,7 @@ def _get_elevs(self, nbytes): # the file pointer must be set at the correct location prior to call SIZE_FLOAT = 4.0 nelevations = np.floor(nbytes / SIZE_FLOAT) - fmt = f">{nelevations}f" + fmt = f">{int(nelevations)}f" packet = struct.unpack(fmt, self.fileptr.read(struct.calcsize(fmt))) return np.array(packet) diff --git a/pyart/io/nexrad_level3.py b/pyart/io/nexrad_level3.py index 3c24247f8f8..6658bb6ea62 100644 --- a/pyart/io/nexrad_level3.py +++ b/pyart/io/nexrad_level3.py @@ -124,9 +124,9 @@ def __init__(self, filename): # Read and decode 18 byte Message Header Block self.msg_header = _unpack_from_buf(buf, bpos, MESSAGE_HEADER) if self.msg_header["code"] not in SUPPORTED_PRODUCTS: - code = self.msg_header["code"] # noqa: F841 + code = self.msg_header["code"] raise NotImplementedError( - "Level3 product with code {code} is not supported" + f"Level3 product with code {code} is not supported" ) bpos += 18 From f1a0d108809233aa050c83f0714e72d70e1adef1 Mon Sep 17 00:00:00 2001 From: zssherman Date: Fri, 22 Nov 2024 16:30:58 -0600 Subject: [PATCH 4/4] FIX: Last missing 'f' --- pyart/core/radar.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyart/core/radar.py b/pyart/core/radar.py index c6e4a4000d7..39eb1cee558 100644 --- a/pyart/core/radar.py +++ b/pyart/core/radar.py @@ -797,7 +797,7 @@ def add_field(self, field_name, dic, replace_existing=False): if "data" not in dic: raise KeyError("dic must contain a 'data' key") if dic["data"].shape != (self.nrays, self.ngates): - err = "'data' has invalid shape, should be ({self.nrays}, {self.ngates})" + err = f"'data' has invalid shape, should be ({self.nrays}, {self.ngates})" raise ValueError(err) # add the field self.fields[field_name] = dic