11import atexit
22import datetime
33import faulthandler
4+ import itertools
45import os
56import tempfile
67import unittest
78
9+ import netCDF4
810import numpy as np
911
1012faulthandler .enable () # to debug seg faults and timeouts
1416warnings = False
1517
1618# Set up temporary files
17- n_tmpfiles = 1
19+ n_tmpfiles = 2
1820tmpfiles = [
19- tempfile .mkstemp ("_test_read_write .nc" , dir = os .getcwd ())[1 ]
21+ tempfile .mkstemp ("_test_ugrid .nc" , dir = os .getcwd ())[1 ]
2022 for i in range (n_tmpfiles )
2123]
22- [tmpfile1 ] = tmpfiles
24+ [tmpfile , tmpfile1 ] = tmpfiles
2325
2426
2527def _remove_tmpfiles ():
@@ -34,6 +36,22 @@ def _remove_tmpfiles():
3436atexit .register (_remove_tmpfiles )
3537
3638
39+ def n_mesh_variables (filename ):
40+ """Return the number of mesh variables in the file."""
41+ nc = netCDF4 .Dataset (filename , "r" )
42+ n = 0
43+ for v in nc .variables .values ():
44+ try :
45+ v .getncattr ("topology_dimension" )
46+ except AttributeError :
47+ pass
48+ else :
49+ n += 1
50+
51+ nc .close ()
52+ return n
53+
54+
3755class UGRIDTest (unittest .TestCase ):
3856 """Test UGRID field constructs."""
3957
@@ -76,10 +94,6 @@ def test_UGRID_read(self):
7694 g .cell_connectivity ().get_connectivity (), "edge"
7795 )
7896
79- # Check that all fields have the same mesh id
80- mesh_ids1 = set (g .get_mesh_id () for g in f1 )
81- self .assertEqual (len (mesh_ids1 ), 1 )
82-
8397 f2 = cf .read (self .filename2 )
8498 self .assertEqual (len (f2 ), 3 )
8599 for g in f2 :
@@ -98,13 +112,6 @@ def test_UGRID_read(self):
98112 g .cell_connectivity ().get_connectivity (), "edge"
99113 )
100114
101- # Check that all fields have the same mesh id
102- mesh_ids2 = set (g .get_mesh_id () for g in f2 )
103- self .assertEqual (len (mesh_ids2 ), 1 )
104-
105- # Check that the different files have different mesh ids
106- self .assertNotEqual (mesh_ids1 , mesh_ids2 )
107-
108115 def test_UGRID_data (self ):
109116 """Test reading of UGRID data."""
110117 node1 , face1 , edge1 = cf .read (self .filename1 )
@@ -177,9 +184,108 @@ def test_read_UGRID_domain(self):
177184 g .cell_connectivity ().get_connectivity (), "edge"
178185 )
179186
180- # Check that all domains have the same mesh id
181- mesh_ids1 = set (g .get_mesh_id () for g in d1 )
182- self .assertEqual (len (mesh_ids1 ), 1 )
187+ def test_read_write_UGRID_field (self ):
188+ """Test the cf.read and cf.write with UGRID fields."""
189+ # Face, edge, and point fields that are all part of the same
190+ # UGRID mesh
191+ ugrid = cf .example_fields (8 , 9 , 10 )
192+
193+ face , edge , point = (0 , 1 , 2 )
194+
195+ tmpfile = "tmpfileu.nc"
196+ # Test for equality with the fields defined in memory. Only
197+ # works for face and edge fields.
198+ for cell in (face , edge ):
199+ f = ugrid [cell ]
200+ cf .write (f , tmpfile )
201+ g = cf .read (tmpfile )
202+ self .assertEqual (len (g ), 1 )
203+ self .assertTrue (g [0 ].equals (f ))
204+
205+ # Test round-tripping fields with multiple fields
206+ #
207+ # Get the indices of 'ugrid' for all possible combinations of
208+ # fields:
209+ #
210+ # combinations = [(0,), (1,), ..., (2, 0, 1), (2, 1, 0)]
211+ combinations = [
212+ i
213+ for n in range (1 , 4 )
214+ for i in itertools .permutations ([face , edge , point ], n )
215+ ]
216+
217+ for cells in combinations :
218+ f = []
219+ for cell in cells :
220+ f .append (ugrid [cell ])
221+
222+ cf .write (f , tmpfile )
223+
224+ # Check that there's only one mesh variable in the file
225+ self .assertEqual (n_mesh_variables (tmpfile ), 1 )
226+
227+ g = cf .read (tmpfile )
228+ self .assertEqual (len (g ), len (f ))
229+
230+ cf .write (g , tmpfile1 )
231+
232+ # Check that there's only one mesh variable in the file
233+ self .assertEqual (n_mesh_variables (tmpfile1 ), 1 )
234+
235+ h = cf .read (tmpfile1 )
236+ self .assertEqual (len (h ), len (g ))
237+ self .assertTrue (h [0 ].equals (g [0 ]))
238+
239+ def test_read_write_UGRID_domain (self ):
240+ """Test the cf.read and cf.write with UGRID domains."""
241+ # Face, edge, and point fields/domains that are all part of
242+ # the same UGRID mesh
243+ ugrid = [f .domain for f in cf .example_fields (8 , 9 , 10 )]
244+
245+ face , edge , point = (0 , 1 , 2 )
246+
247+ # Test for equality with the fields defined in memory. Only
248+ # works for face and edge domains.
249+ for cell in (face , edge ):
250+ d = ugrid [cell ]
251+ cf .write (d , tmpfile )
252+ e = cf .read (tmpfile , domain = True )
253+ self .assertEqual (len (e ), 2 )
254+ self .assertTrue (e [0 ].equals (d ))
255+ self .assertEqual (e [1 ].domain_topology ().get_cell (), "point" )
256+
257+ # Test round-tripping fields with all three domains
258+ #
259+ # combinations = [(0, 1, 2), (0, 2, 1), ..., (2, 0, 1), (2, 1, 0)]
260+ combinations = list (itertools .permutations ([face , edge , point ], 3 ))
261+ for cells in combinations :
262+ d = []
263+ for cell in cells :
264+ d .append (ugrid [cell ])
265+
266+ cf .write (d , tmpfile )
267+
268+ # Check that there's only one mesh variable in the file
269+ self .assertEqual (n_mesh_variables (tmpfile ), 1 )
270+
271+ e = cf .read (tmpfile , domain = True )
272+
273+ self .assertEqual (len (e ), len (d ))
274+
275+ cf .write (e , tmpfile1 )
276+
277+ # Check that there's only one mesh variable in the file
278+ self .assertEqual (n_mesh_variables (tmpfile1 ), 1 )
279+
280+ f = cf .read (tmpfile1 , domain = True )
281+ self .assertEqual (len (f ), len (e ))
282+ for i , j in zip (f , e ):
283+ self .assertTrue (i .equals (j ))
284+
285+ # Note: Other combintations of domain read/write are tricky,
286+ # because the mesh variable *and* the domain variable in
287+ # the dataset *both* define domains. Let's not worry
288+ # about that now!
183289
184290
185291if __name__ == "__main__" :
0 commit comments