Skip to content

Commit

Permalink
Merge pull request #61 from sadielbartholomew/fixes-for-passing-tests
Browse files Browse the repository at this point in the history
Testing: apply fixes to test methods & add current output images
  • Loading branch information
sadielbartholomew authored Jul 23, 2024
2 parents 3694b74 + 7b2a1ea commit 397845c
Show file tree
Hide file tree
Showing 27 changed files with 133 additions and 52 deletions.
5 changes: 5 additions & 0 deletions cfplot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@
__version__ = "3.3.0"

from .cfplot import * # noqa: F403, F401

# Internal-use methods required for testing
from .cfplot import _gvals
from .cfplot import _mapaxis
from .cfplot import _which
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
180 changes: 128 additions & 52 deletions cfplot/test/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,58 @@

import coverage
import faulthandler
import hashlib
import numpy as np
from scipy.interpolate import griddata
import unittest

from netCDF4 import Dataset as ncfile
from scipy.interpolate import griddata

import cfplot as cfp
import cf


faulthandler.enable() # to debug seg faults and timeouts


DATA_DIR = "../../cfplot_data"
DATA_DIR = "cfplot_data"
TEST_GEN_DIR = "./generated-example-images"
TEST_REF_DIR = "./reference-example-images"


def compare_images(example=None):
"""
Compare images and return an error string if they don't match.
"""
import hashlib

# TODO SLB: convert all 'home/andy/' paths to general configurable path
# (there are many examples below but also throughout this script)

disp = _which("display")
conv = _which("convert")
comp = _which("compare")
file = f"fig{example}.png"
file_new = f"/home/andy/cfplot.src/cfplot/{file}"
file_ref = f"/home/andy/regression/{file}"

# Check md5 checksums are the same and display files if not
if (
hashlib.md5(open(file_new, "rb").read()).hexdigest()
!= hashlib.md5(open(file_ref, "rb").read()).hexdigest()
):
print(f"***Failed example {example}***")
error_image = f"/home/andy/cfplot.src/cfplot/error_{file}"
diff_image = f"/home/andy/cfplot.src/cfplot/difference_{file}"
p = subprocess.Popen([comp, file_new, file_ref, diff_image])
(output, err) = p.communicate()
p.wait()
p = subprocess.Popen(
[conv, "+append", file_new, file_ref, error_image]
)
(output, err) = p.communicate()
p.wait()
subprocess.Popen([disp, diff_image])

else:
print(f"Passed example {example}")
# disp = cfp._which("display")
# conv = cfp._which("convert")
# comp = cfp._which("compare")
# file = f"fig{example}.png"
# file_gen = f"{TEST_GEN_DIR}/{file}"
# file_ref = f"{TEST_REF_DIR}/{file}"

# # Check md5 checksums are the same and display files if not
# with open(file_gen, "rb") as gen_image:
# with open(file_ref, "rb") as ref_image:
# if (
# hashlib.md5(gen_image).hexdigest()
# != hashlib.md5(ref_image).hexdigest()
# ):
# print(f"***Failed example {example}***")
# error_image = f"{TEST_HOME_DIR}/error_{file}"
# diff_image = f"{TEST_HOME_DIR}/difference_{file}"
# p = subprocess.Popen([comp, file_new, file_ref, diff_image])
# (output, err) = p.communicate()
# p.wait()
# p = subprocess.Popen(
# [conv, "+append", file_new, file_ref, error_image]
# )
# (output, err) = p.communicate()
# p.wait()
# subprocess.Popen([disp, diff_image])
# else:
# print(f"Passed example {example}")
pass


def compare_arrays(
Expand All @@ -75,23 +77,24 @@ def compare_arrays(
"""
Compare arrays and return an error string if they don't match.
"""
plotvar_levs = cfp.plotvars.levels

anom = 0
if levs_test:
levs(min, max, step)
if np.size(ref) != np.size(plotvars.levels):
cfp.levs(min, max, step)
if np.size(ref) != np.size(plotvar_levs):
anom = 1
else:
for val in np.arange(np.size(ref)):
if abs(ref[val] - plotvars.levels[val]) >= 1e-6:
if abs(ref[val] - plotvar_levs[val]) >= 1e-6:
anom = 1

if anom == 1:
print(
"***levs failure***\n"
"***cfp.levs failure***\n"
f"min, max, step are {min}, {max}, {step}\n"
"generated levels are:\n"
f"{plotvars.levels}\n"
f"{plotvar_levs}\n"
f"expected levels:\n{ref}"
)
else:
Expand All @@ -100,7 +103,7 @@ def compare_arrays(

anom = 0
if gvals_test:
vals, testmult = _gvals(min, max)
vals, testmult = cfp._gvals(min, max)
if np.size(ref) != np.size(vals):
anom = 1
else:
Expand All @@ -127,7 +130,7 @@ def compare_arrays(
if mapaxis_test:
ref_ticks = ref[0]
ref_labels = ref[1]
test_ticks, test_labels = _mapaxis(min=min, max=max, type=type)
test_ticks, test_labels = cfp._mapaxis(min=min, max=max, type=type)
if np.size(test_ticks) != np.size(ref_ticks):
anom = 1
else:
Expand Down Expand Up @@ -539,8 +542,29 @@ def test_example_8(self):
cfp.con(f.collapse("mean", "longitude"), ylog=1)
compare_images(8)

@unittest.expectedFailure # works standalone, test suite gives IndexError
def test_example_9(self):
"""Test Example 9."""
# TODO SLB, flaky/bad test alert! This works in interactive Python
# but in test suite it fails with:
# Traceback (most recent call last):
# File "/home/slb93/git-repos/cf-plot/cfplot/test/test_examples.py", line 551, in test_example_9
# cfp.con(lat_mean)
# File "/home/slb93/git-repos/cf-plot/cfplot/cfplot.py", line 3262, in con
# f = f.subspace(Y=cf.wi(-90.0, plotvars.boundinglat))
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# File "/home/slb93/git-repos/cf-python/cf/subspacefield.py", line 353, in __call__
# raise error
# File "/home/slb93/git-repos/cf-python/cf/subspacefield.py", line 348, in __call__
# out = field[indices]
# ~~~~~^^^^^^^^^
# File "/home/slb93/git-repos/cf-python/cf/field.py", line 450, in __getitem__
# raise IndexError(
# IndexError: Indices [slice(None, None, None), slice(None, None, None),
# array([], dtype=int64), slice(None, None, None)] result in a
# subspaced shape of (1, 23, 0, 320), but can't create a subspace
#of Field that has a size 0 axis

cfp.setvars(file="fig9.png")
f = cf.read(f"{self.data_dir}/ggap.nc")[0]

Expand Down Expand Up @@ -629,6 +653,7 @@ def test_example_15(self):
)
compare_images(15)

@unittest.expectedFailure # errors due to cf-python Issue #797
def test_example_16(self):
"""Test Example 16."""
cfp.setvars(file="fig16.png")
Expand All @@ -643,6 +668,8 @@ def test_example_16(self):
g = g.subspace(X=cf.wi(80, 160))
g = g.collapse("T: mean X: mean")

# This fails due to a cf-python field bug, see cf-python Issue #797:
# https://github.com/NCAS-CMS/cf-python/issues/797
cfp.vect(
u=c,
v=-g,
Expand All @@ -651,6 +678,7 @@ def test_example_16(self):
title="DJF",
key_location=[0.95, -0.05],
)

compare_images(16)

def test_example_17(self):
Expand Down Expand Up @@ -689,7 +717,6 @@ def test_example_18(self):

def test_example_19(self):
"""Test Example 19."""
cfp.reset()
cfp.setvars(file="fig19.png")
f = cf.read(f"{self.data_dir}/ggap.nc")[1]
cfp.gopen(rows=2, columns=2, bottom=0.2)
Expand All @@ -711,6 +738,7 @@ def test_example_19(self):
cfp.gclose()
compare_images(19)

@unittest.expectedFailure # works standalone, test suite gives ValueError
def test_example_20(self):
"""Test Example 20."""
cfp.setvars(file="fig20.png")
Expand All @@ -719,6 +747,7 @@ def test_example_20(self):
cfp.con(f.subspace[9])
compare_images(20)

@unittest.expectedFailure # works standalone, test suite gives ValueError
def test_example_21(self):
"""Test Example 21."""
cfp.setvars(file="fig21.png")
Expand All @@ -734,10 +763,11 @@ def test_example_21(self):
)
compare_images(21)

@unittest.expectedFailure # works standalone, test suite gives ValueError
def test_example_22(self):
"""Test Example 22."""
cfp.setvars(file="fig22.png")
f = cf.read_field(f"{self.data_dir}/rgp.nc")
f = cf.read(f"{self.data_dir}/rgp.nc")[0]

cfp.cscale("gray")

Expand All @@ -747,11 +777,11 @@ def test_example_22(self):
def test_example_23(self):
"""Test Example 23."""
cfp.setvars(file="fig23.png")
f = cf.read_field(f"{self.data_dir}/rgp.nc")
f = cf.read(f"{self.data_dir}/rgp.nc")[0]

data = f.array
xvec = f.construct("dim1").array
yvec = f.construct("dim0").array
xvec = f.construct("ncvar%x").array
yvec = f.construct("ncvar%y").array
xpole = 160
ypole = 30

Expand All @@ -769,6 +799,7 @@ def test_example_23(self):

compare_images(23)

@unittest.expectedFailure # IndexError after griddata API conformance
def test_example_24(self):
"""Test Example 24."""
cfp.setvars(file="fig24.png")
Expand All @@ -792,19 +823,49 @@ def test_example_24(self):
# Linearly interpolate data to a regular grid
lons_new = np.arange(140) * 0.1 - 11.0
lats_new = np.arange(140) * 0.1 + 49.0
# TODO SLB needs fixing, fails on an IndexError
temp_new = griddata(
lons, lats, temp, lons_new, lats_new, interp="linear"
points=(lons, lats), values=temp, xi=(lons_new, lats_new),
method="linear"
)

cfp.cscale("parula")

cfp.con(x=lons_new, y=lats_new, f=temp_new, ptype=1)
compare_images(24)

@unittest.expectedFailure # IndexError after griddata API conformance
def test_example_25(self):
"""Test Example 25."""
cfp.setvars(file="fig25.png")

# Note the block of code until '---' is shared with example 24.
# Arrays for data
lons = []
lats = []
pressure = []
temp = []

f = open(f"{self.data_dir}/synop_data.txt")

lines = f.readlines()
for line in lines:
mysplit = line.split()
lons = np.append(lons, float(mysplit[1]))
lats = np.append(lats, float(mysplit[2]))
pressure = np.append(pressure, float(mysplit[3]))
temp = np.append(temp, float(mysplit[4]))

# Linearly interpolate data to a regular grid
lons_new = np.arange(140) * 0.1 - 11.0
lats_new = np.arange(140) * 0.1 + 49.0
# TODO SLB needs fixing, fails on an IndexError
temp_new = griddata(
points=(lons, lats), values=temp, xi=(lons_new, lats_new),
method="linear"
)
# ---

cfp.gopen()

cfp.con(x=lons_new, y=lats_new, f=temp_new, ptype=1)
Expand All @@ -821,11 +882,10 @@ def test_example_25(self):

compare_images(25)

@unittest.expectedFailure # ValueError after griddata API conformance
def test_example_26(self):
"""Test Example 26."""
cfp.setvars(file="fig26.png")
from matplotlib.mlab import griddata
from netCDF4 import Dataset as ncfile

# Get an Orca grid and flatten the arrays
nc = ncfile(f"{self.data_dir}/orca2.nc")
Expand All @@ -849,8 +909,10 @@ def test_example_26(self):

lons_new = np.arange(181 * 8) * 0.25 - 180.0
lats_new = np.arange(91 * 8) * 0.25 - 90.0
# TODO SLB needs fixing, fails on a ValueError
temp_new = griddata(
lons, lats, temp, lons_new, lats_new, interp="linear"
points=(lons, lats), values=temp, xi=(lons_new, lats_new),
method="linear"
)

cfp.con(x=lons_new, y=lats_new, f=temp_new, ptype=1)
Expand Down Expand Up @@ -941,17 +1003,31 @@ def test_example_29(self):
)
compare_images(29)

def test_example_30(self):
"""Test Example 30."""
# TODO SLB missing example 30.
pass

@unittest.expectedFailure # errors due to 1 of 2 x bugs, see #59 and #60
def test_example_31(self):
"""Test Example 31."""
# TODO SLB this test errors
f = cf.read(f"{self.data_dir}/ukcp_rcm_test.nc")[0]

# There is a bug such that this example fails here, see Issue #59,
# https://github.com/NCAS-CMS/cf-plot/issues/59:
#
# File "/home/slb93/git-repos/cf-plot/cfplot/cfplot.py", line 2982, in _plot_map_axes
# if plotvars.proj == "UKCP" and plotvars.grid:
# ^^^^^^^^^^^^^
# AttributeError: 'pvars' object has no attribute 'grid'
cfp.mapset(proj="UKCP", resolution="50m")
cfp.levs(-3, 7, 0.5)
cfp.setvars(grid_x_spacing=1, grid_y_spacing=1)

# This can fail with 'UnboundLocalError', see Issue #60
cfp.con(f, lines=False)

# TODO SLB: add image comparison here.
compare_images(31)

# TODO SLB: add rest of examples from current documentation here

Expand Down

0 comments on commit 397845c

Please sign in to comment.