From 9ea6a1a589be8beb9bda325bf893b22305293881 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Mon, 1 Jul 2024 01:29:18 -0500 Subject: [PATCH 1/9] Update jigsaw-python submodule The latest `master` includes a bug fix needed for numpy 2.0 support. --- jigsaw-python | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jigsaw-python b/jigsaw-python index d9d70e60f..5729a3800 160000 --- a/jigsaw-python +++ b/jigsaw-python @@ -1 +1 @@ -Subproject commit d9d70e60fae9b5686c85113d1d1d4b21ae341789 +Subproject commit 5729a380039c4df5de484cb9ec331e14b16e7c55 From 320bc83c6789abac79986baf0f1b3c898c223039 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Mon, 1 Jul 2024 01:30:42 -0500 Subject: [PATCH 2/9] fix cosine bell analysis for numpy 2.0 --- .../cosine_bell/analysis.py | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/compass/ocean/tests/global_convergence/cosine_bell/analysis.py b/compass/ocean/tests/global_convergence/cosine_bell/analysis.py index 2874a65ab..79af08f34 100644 --- a/compass/ocean/tests/global_convergence/cosine_bell/analysis.py +++ b/compass/ocean/tests/global_convergence/cosine_bell/analysis.py @@ -131,21 +131,20 @@ def rmse(self, mesh_name): # find time since the beginning of run ds = xr.open_dataset(f'{mesh_name}_output.nc') for j in range(len(ds.xtime)): - tt = str(ds.xtime[j].values) - tt.rfind('_') - DY = float(tt[10:12]) - 1 - if DY == pd: + time_string = str(np.strings.decode(ds.xtime[j].values)) + day = float(time_string[8:10]) - 1 + if day == pd: sliceTime = j break - HR = float(tt[13:15]) - MN = float(tt[16:18]) - t = 86400.0 * DY + HR * 3600. + MN + hour = float(time_string[11:13]) + min = float(time_string[14:16]) + t = 86400.0 * day + hour * 3600. + min # find new location of blob center # center is based on equatorial velocity - R = init.sphere_radius - distTrav = 2.0 * 3.14159265 * R / (86400.0 * pd) * t + r = init.sphere_radius + distTrav = 2.0 * np.pi * r / (86400.0 * pd) * t # distance in radians is - distRad = distTrav / R + distRad = distTrav / r newLon = lonCent + distRad if newLon > 2.0 * np.pi: newLon -= 2.0 * np.pi @@ -154,12 +153,12 @@ def rmse(self, mesh_name): tracer = np.zeros_like(init.tracer1[0, :, 0].values) latC = init.latCell.values lonC = init.lonCell.values - temp = R * np.arccos(np.sin(latCent) * np.sin(latC) + - np.cos(latCent) * np.cos(latC) * np.cos( - lonC - newLon)) + temp = r * np.arccos(np.sin(latCent) * np.sin(latC) + + (np.cos(latCent) * np.cos(latC) * + np.cos(lonC - newLon))) mask = temp < radius tracer[mask] = psi0 / 2.0 * ( - 1.0 + np.cos(3.1415926 * temp[mask] / radius)) + 1.0 + np.cos(np.pi * temp[mask] / radius)) # oad forward mode data tracerF = ds.tracer1[sliceTime, :, 0].values @@ -167,4 +166,4 @@ def rmse(self, mesh_name): init.close() ds.close() - return rmseValue, init.dims['nCells'] + return rmseValue, init.sizes['nCells'] From a92c4ca4eecd6aa0ce9ad4873cfe6bd88b9f78fc Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Mon, 1 Jul 2024 01:31:08 -0500 Subject: [PATCH 3/9] Update to v1.4.0-alpha.4 --- compass/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compass/version.py b/compass/version.py index 5e933f6d2..48a3c1efd 100644 --- a/compass/version.py +++ b/compass/version.py @@ -1 +1 @@ -__version__ = '1.4.0-alpha.3' +__version__ = '1.4.0-alpha.4' From 6d3640e5e312d42d2bea72f01b087736c34de342 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Mon, 1 Jul 2024 01:31:31 -0500 Subject: [PATCH 4/9] Update to mpas_tools 0.34.0 and numpy >= 2.0 --- conda/compass_env/spec-file.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conda/compass_env/spec-file.template b/conda/compass_env/spec-file.template index 195940493..f9d0d0eac 100644 --- a/conda/compass_env/spec-file.template +++ b/conda/compass_env/spec-file.template @@ -22,10 +22,10 @@ matplotlib-base metis moab >=5.5.1 moab=*={{ mpi_prefix }}_tempest_* -mpas_tools=0.33.0 +mpas_tools=0.34.0 nco netcdf4=*=nompi_* -numpy <2.0 +numpy >=2.0,<3.0 {% if supports_otps %} otps=2021.10 {% endif %} From d2cbc7244d513ab01159a7d5f8959218f29861fa Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Wed, 3 Jul 2024 12:34:48 -0500 Subject: [PATCH 5/9] Require matplotlib >=3.9.0 --- conda/compass_env/spec-file.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conda/compass_env/spec-file.template b/conda/compass_env/spec-file.template index f9d0d0eac..f923b54ff 100644 --- a/conda/compass_env/spec-file.template +++ b/conda/compass_env/spec-file.template @@ -18,7 +18,7 @@ lxml {% if include_mache %} mache=1.23.0 {% endif %} -matplotlib-base +matplotlib-base >=3.9.0 metis moab >=5.5.1 moab=*={{ mpi_prefix }}_tempest_* From 44b98e907ee3b3330b8b0cd8fa9828d6a0b254a3 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Wed, 3 Jul 2024 12:36:09 -0500 Subject: [PATCH 6/9] Fixes to matplotlib colormaps --- .../dt_convergence_test/__init__.py | 14 ++++++++------ .../eismint2/standard_experiments/visualize.py | 5 +++-- .../tests/ensemble_generator/plot_ensemble.py | 2 +- .../tests/sphere_transport/process_output.py | 15 ++++++++------- compass/ocean/tests/tides/analysis/__init__.py | 15 ++++++++------- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/compass/landice/tests/calving_dt_convergence/dt_convergence_test/__init__.py b/compass/landice/tests/calving_dt_convergence/dt_convergence_test/__init__.py index bea2754e0..d4e748c79 100644 --- a/compass/landice/tests/calving_dt_convergence/dt_convergence_test/__init__.py +++ b/compass/landice/tests/calving_dt_convergence/dt_convergence_test/__init__.py @@ -1,10 +1,11 @@ -from compass.testcase import TestCase -from compass.landice.tests.calving_dt_convergence.run_model import RunModel +import matplotlib.cm +import matplotlib.pyplot as plt +import netCDF4 # from compass.validate import compare_variables # not currently used import numpy -import netCDF4 -import matplotlib.pyplot as plt -import matplotlib.cm + +from compass.landice.tests.calving_dt_convergence.run_model import RunModel +from compass.testcase import TestCase class DtConvergenceTest(TestCase): @@ -77,7 +78,8 @@ def validate(self): ax[3].set_ylabel('# warnings', color='c') ax2 = ax[3].twinx() ax2.set_ylabel('fraction with warnings', color='g') - colors = matplotlib.cm.jet(numpy.linspace(0, 1, len(self.fractions))) + jet = matplotlib.colormaps['jet'] + colors = jet(numpy.linspace(0, 1, len(self.fractions))) nWarn = numpy.zeros([len(self.fractions)]) nTimesteps = numpy.zeros([len(self.fractions)]) diff --git a/compass/landice/tests/eismint2/standard_experiments/visualize.py b/compass/landice/tests/eismint2/standard_experiments/visualize.py index 8e813220f..01145cd5c 100644 --- a/compass/landice/tests/eismint2/standard_experiments/visualize.py +++ b/compass/landice/tests/eismint2/standard_experiments/visualize.py @@ -1,6 +1,7 @@ import datetime -import netCDF4 + import matplotlib.pyplot as plt +import netCDF4 import numpy as np from scipy.interpolate import griddata @@ -473,7 +474,7 @@ def _contour_mpas(field, nCells, xCell, yCell, contour_levs=None): if len(contour_levs) == 1: im = plt.contour(xi, yi, zi) else: - im = plt.contour(xi, yi, zi, contour_levs, cmap=plt.cm.jet) + im = plt.contour(xi, yi, zi, contour_levs, cmap=plt.get_cmap('jet')) # to see the raw data on top # plt.scatter(xCell, yCell, c=temperature[timelev,:,-1], s=100, diff --git a/compass/landice/tests/ensemble_generator/plot_ensemble.py b/compass/landice/tests/ensemble_generator/plot_ensemble.py index 2a2cdb892..14cdbaade 100644 --- a/compass/landice/tests/ensemble_generator/plot_ensemble.py +++ b/compass/landice/tests/ensemble_generator/plot_ensemble.py @@ -522,7 +522,7 @@ def filter_run(): if plot_maps: # axMaps2.plot(GLX, GLY, '.') - axMaps2.hist2d(GLX, GLY, (50, 50), cmap=plt.cm.jet) + axMaps2.hist2d(GLX, GLY, (50, 50), cmap=plt.get_cmap('jet')) figMaps.savefig('figure_maps.png') if plot_time_series: diff --git a/compass/ocean/tests/sphere_transport/process_output.py b/compass/ocean/tests/sphere_transport/process_output.py index 7dd4cd014..e3defa711 100755 --- a/compass/ocean/tests/sphere_transport/process_output.py +++ b/compass/ocean/tests/sphere_transport/process_output.py @@ -1,9 +1,10 @@ -import matplotlib.pyplot as plt -from matplotlib.gridspec import GridSpec -from matplotlib.colors import ListedColormap +from importlib import resources + import matplotlib +import matplotlib.pyplot as plt import numpy as np -from importlib import resources +from matplotlib.colors import ListedColormap +from matplotlib.gridspec import GridSpec def appx_mesh_size(dataset): @@ -260,8 +261,8 @@ def read_ncl_rgb_file(cmap_filename): map_file_found = False try: with resources.open_text( - "compass.ocean.tests.sphere_transport.resources", cmap_filename) \ - as f: + "compass.ocean.tests.sphere_transport.resources", + cmap_filename) as f: flines = f.readlines() map_file_found = True except BaseException: @@ -277,7 +278,7 @@ def read_ncl_rgb_file(cmap_filename): result = ListedColormap(rgb, name=cmap_filename) else: print("error reading ncl colormap. using matplotlib default instead.") - result = matplotlib.cm.get_cmap() + result = matplotlib.pyplot.get_cmap() return result diff --git a/compass/ocean/tests/tides/analysis/__init__.py b/compass/ocean/tests/tides/analysis/__init__.py index 789e85dbc..667b991e5 100644 --- a/compass/ocean/tests/tides/analysis/__init__.py +++ b/compass/ocean/tests/tides/analysis/__init__.py @@ -1,14 +1,15 @@ -from compass.step import Step +import os -import netCDF4 -import matplotlib.pyplot as plt -import matplotlib.cm as cm -import numpy as np import cartopy.crs as ccrs import cartopy.feature as cfeature -import os +import matplotlib.pyplot as plt +import netCDF4 +import numpy as np +from matplotlib import colormaps from mpas_tools.logging import check_call +from compass.step import Step + class Analysis(Step): """ @@ -255,7 +256,7 @@ def plot(self): """ plt.switch_backend('agg') - cmap_reversed = cm.get_cmap('Spectral_r') + cmap_reversed = colormaps['Spectral_r'] # Initialize plotting variables TW = 2 # Tick width From ce1e7384b6432934528dd40bb3654120866b34a1 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Wed, 3 Jul 2024 13:18:52 -0500 Subject: [PATCH 7/9] Lint affected land-ice code --- .../dt_convergence_test/__init__.py | 6 +-- .../standard_experiments/visualize.py | 40 ++++++++++--------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/compass/landice/tests/calving_dt_convergence/dt_convergence_test/__init__.py b/compass/landice/tests/calving_dt_convergence/dt_convergence_test/__init__.py index d4e748c79..c3012cbc5 100644 --- a/compass/landice/tests/calving_dt_convergence/dt_convergence_test/__init__.py +++ b/compass/landice/tests/calving_dt_convergence/dt_convergence_test/__init__.py @@ -29,7 +29,7 @@ def __init__(self, test_group, mesh, calving, velo): test_group : compass.landice.tests.calving_dt_convergence.CalvingDtConvergence The test group that this test case belongs to - """ + """ # noqa: E501 self.name = f'calving_dt_convergence_test_{mesh}_{calving}_{velo}' subdir = f'{mesh}.{calving}.{velo}' super().__init__(test_group=test_group, name=self.name, subdir=subdir) @@ -93,7 +93,7 @@ def validate(self): ax[0].plot(yr[1:], calv[1:], '-', label=f'{frac:.2f}', color=colors[i]) - ax[1].plot(yr[1:], (calv[1:]*deltat[1:]).cumsum(), '-', + ax[1].plot(yr[1:], (calv[1:] * deltat[1:]).cumsum(), '-', color=colors[i]) ratio = f.variables['dtCalvingCFLratio'][:] @@ -109,7 +109,7 @@ def validate(self): nWarn[i] = logcontents.count("WARNING: Failed to ablate") nTimesteps[i] = logcontents.count("Starting timestep number") ax[3].plot(frac, nWarn[i], 'co') - ax2.plot(frac, nWarn[i]/nTimesteps[i], 'gx') + ax2.plot(frac, nWarn[i] / nTimesteps[i], 'gx') f.close() i += 1 diff --git a/compass/landice/tests/eismint2/standard_experiments/visualize.py b/compass/landice/tests/eismint2/standard_experiments/visualize.py index 01145cd5c..17e2dadec 100644 --- a/compass/landice/tests/eismint2/standard_experiments/visualize.py +++ b/compass/landice/tests/eismint2/standard_experiments/visualize.py @@ -20,7 +20,7 @@ def __init__(self, test_case): ---------- test_case : compass.landice.tests.eismint2.standard_experiments.StandardExperiments The test case this step belongs to - """ + """ # noqa: E501 super().__init__(test_case=test_case, name='visualize') # depending on settings, this may produce no outputs, so we won't add @@ -71,8 +71,8 @@ def visualize_eismint2(config, logger, experiment): # open supplied MPAS output file and get variables needed filein = netCDF4.Dataset(filename, 'r') - xCell = filein.variables['xCell'][:]/1000.0 - yCell = filein.variables['yCell'][:]/1000.0 + xCell = filein.variables['xCell'][:] / 1000.0 + yCell = filein.variables['yCell'][:] / 1000.0 xtime = filein.variables['xtime'][:] nCells = len(filein.dimensions['nCells']) nVertLevels = len(filein.dimensions['nVertLevels']) @@ -104,16 +104,17 @@ def visualize_eismint2(config, logger, experiment): # make an educated guess about how big the markers should be. if nCells**0.5 < 100.0: - markersize = max(int(round(3600.0/(nCells**0.5))), 1) + markersize = max(int(round(3600.0 / (nCells**0.5))), 1) # use hexes if the points are big enough, otherwise just dots markershape = 'h' else: - markersize = max(int(round(1800.0/(nCells**0.5))), 1) + markersize = max(int(round(1800.0 / (nCells**0.5))), 1) markershape = '.' logger.info('Using a markersize of {}'.format(markersize)) fig = plt.figure(1, facecolor='w') - fig.suptitle('Payne et al. Fig. 1, 3, 6, 9, or 11', fontsize=10, fontweight='bold') + fig.suptitle('Payne et al. Fig. 1, 3, 6, 9, or 11', fontsize=10, + fontweight='bold') iceIndices = np.where(thickness[timelev, :] > 10.0)[0] plt.scatter(xCell[iceIndices], yCell[iceIndices], markersize, @@ -139,7 +140,8 @@ def visualize_eismint2(config, logger, experiment): plt.savefig('EISMINT2-{}-basaltemp.png'.format(experiment), dpi=150) # ================ - # STEADY STATE MAPS - panels b and c are switched and with incorrect units in the paper + # STEADY STATE MAPS - panels b and c are switched and with incorrect + # units in the paper # ================ fig = plt.figure(2, facecolor='w', figsize=(12, 6), dpi=72) fig.suptitle('Payne et al. Fig. 2 or 4', fontsize=10, fontweight='bold') @@ -153,7 +155,7 @@ def visualize_eismint2(config, logger, experiment): edgecolors='none') # add contours of ice thickness over the top - contour_intervals = np.linspace(0.0, 5000.0, int(5000.0/250.0)+1) + contour_intervals = np.linspace(0.0, 5000.0, int(5000.0 / 250.0) + 1) _contour_mpas(thickness[timelev, :], nCells, xCell, yCell, contour_levs=contour_intervals) @@ -168,8 +170,8 @@ def visualize_eismint2(config, logger, experiment): flux = np.zeros((nCells,)) for k in range(nVertLevels): - speedLevel = (uReconstructX[timelev, :, k:k+2].mean(axis=1)**2 + - uReconstructY[timelev, :, k:k+2].mean(axis=1)**2)**0.5 + speedLevel = (uReconstructX[timelev, :, k:k + 2].mean(axis=1)**2 + + uReconstructY[timelev, :, k:k + 2].mean(axis=1)**2)**0.5 flux += speedLevel * thickness[timelev, :] * layerThicknessFractions[k] plt.scatter(xCell[iceIndices], yCell[iceIndices], markersize, @@ -177,8 +179,8 @@ def visualize_eismint2(config, logger, experiment): edgecolors='none') # add contours over the top - contour_intervals = np.linspace(0.0, 20.0, 11) - _contour_mpas(flux * 3600.0*24.0*365.0 / 10000.0, nCells, xCell, yCell, + contour_intervals = np.linspace(0.0, 20.0, 11) + _contour_mpas(flux * 3600.0 * 24.0 * 365.0 / 10000.0, nCells, xCell, yCell, contour_levs=contour_intervals) ax.set_aspect('equal') plt.title('Final flux (m$^2$ a$^{-1}$ / 10000)') @@ -200,7 +202,7 @@ def visualize_eismint2(config, logger, experiment): if flwa[timelev, :, :].max() > 0.0: # NOT SURE WHICH LEVEL FLWA SHOULD COME FROM - so taking column average _contour_mpas( - flwa[timelev, :, :].mean(axis=1) * 3600.0*24.0*365.0 / 1.0e-17, + flwa[timelev, :, :].mean(axis=1) * 3600.0 * 24.0 * 365.0 / 1.0e-17, nCells, xCell, yCell) ax.set_aspect('equal') # Note: the paper's figure claims units of 10$^{-25}$ Pa$^{-3}$ a$^{-1}$ @@ -216,7 +218,8 @@ def visualize_eismint2(config, logger, experiment): # DIVIDE EVOLUTION TIME SERIES # ================ fig = plt.figure(3, facecolor='w') - fig.suptitle('Payne et al. Fig. 5, 7, or 8', fontsize=10, fontweight='bold') + fig.suptitle('Payne et al. Fig. 5, 7, or 8', fontsize=10, + fontweight='bold') # get indices for given time if experiment == 'b': @@ -233,14 +236,15 @@ def visualize_eismint2(config, logger, experiment): # panel a - thickness fig.add_subplot(211) timeInd = np.nonzero(years <= endTime)[0][0:] - plt.plot(years[timeInd]/1000.0, thickness[timeInd, divideIndex], 'k.-') + plt.plot(years[timeInd] / 1000.0, thickness[timeInd, divideIndex], 'k.-') plt.ylabel('Thickness (m)') # panel b - basal temperature fig.add_subplot(212) # skip the first index cause basalTemperature isn't calculated then timeInd = np.nonzero(years <= endTime)[0][1:] - plt.plot(years[timeInd]/1000.0, basalTemperature[timeInd, divideIndex], 'k.-') + plt.plot(years[timeInd] / 1000.0, basalTemperature[timeInd, divideIndex], + 'k.-') plt.ylabel('Basal temperature (K)') plt.xlabel('Time (kyr)') @@ -297,8 +301,8 @@ def visualize_eismint2(config, logger, experiment): 'min/mean/max of community', fontsize=10, fontweight='bold') fig.add_subplot(151) - volume = ((thickness[timelev, iceIndices] * areaCell[iceIndices]).sum() - / 1000.0**3 / 10.0**6) + volume = ((thickness[timelev, iceIndices] * areaCell[iceIndices]).sum() / + 1000.0**3 / 10.0**6) # benchmark results plt.plot(np.zeros((3,)), bench['volume'], 'k*') if bench['stattype'] == 'relative': From 3353ed5e76b5dcd43fb0272fa75bb1ab9dba7669 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Wed, 3 Jul 2024 13:28:16 -0500 Subject: [PATCH 8/9] Lint affected ocean code --- .../tests/sphere_transport/process_output.py | 7 +- .../ocean/tests/tides/analysis/__init__.py | 80 ++++++++++--------- 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/compass/ocean/tests/sphere_transport/process_output.py b/compass/ocean/tests/sphere_transport/process_output.py index e3defa711..82288d77a 100755 --- a/compass/ocean/tests/sphere_transport/process_output.py +++ b/compass/ocean/tests/sphere_transport/process_output.py @@ -365,8 +365,7 @@ def plot_sol(fig, tcname, dataset): cmap="seismic", vmin=diffmin, vmax=diffmax) - lcm = axes[9].tricontourf(xc, yc, dataset.variables["layerThickness"] - [0, :, 1]) + axes[9].tricontourf(xc, yc, dataset.variables["layerThickness"][0, :, 1]) axes[9].set_ylabel('layer thickness') axes[10].tricontourf(xc, yc, dataset.variables["layerThickness"] [0, :, 1]) @@ -390,8 +389,8 @@ def plot_sol(fig, tcname, dataset): axes[9 + i].set_xticklabels(xticklabels) for i in range(9): axes[i].set_xticklabels([]) - cb1 = fig.colorbar(cm, ax=axes[8]) - cb2 = fig.colorbar(tcm, ax=axes[5]) + fig.colorbar(cm, ax=axes[8]) + fig.colorbar(tcm, ax=axes[5]) # cb3 = fig.colorbar(lcm, ax=axes[11]) fig.suptitle(tcname) diff --git a/compass/ocean/tests/tides/analysis/__init__.py b/compass/ocean/tests/tides/analysis/__init__.py index 667b991e5..423dc32ac 100644 --- a/compass/ocean/tests/tides/analysis/__init__.py +++ b/compass/ocean/tests/tides/analysis/__init__.py @@ -104,7 +104,7 @@ def write_coordinate_file(self, idx): # Write coordinate file for OTPS2 f = open('lat_lon', 'w') for i in range(nCells): - f.write(str(lat_grid[i])+' '+str(lon_grid[i])+'\n') + f.write(f'{lat_grid[i]} {lon_grid[i]} \n') f.close() def setup_otps2(self): @@ -122,7 +122,7 @@ def setup_otps2(self): 'comment': '! 2. latitude/longitude/