diff --git a/pynemo/gui/nemo_bdy_mask.py b/pynemo/gui/nemo_bdy_mask.py index ea062abc4d3f19311d8aafe6ce516109d7ea4cff..ef5bd24e07df96af41ccce85c97e47cac23481a1 100644 --- a/pynemo/gui/nemo_bdy_mask.py +++ b/pynemo/gui/nemo_bdy_mask.py @@ -68,15 +68,32 @@ class Mask(object): self.bathymetry_file = str(bathy_file) #open the bathymetry file self.bathy_nc = Dataset(self.bathymetry_file) - self.lon = np.asarray(self.bathy_nc.variables['nav_lon']) - self.lat = np.asarray(self.bathy_nc.variables['nav_lat']) - self.bathy_data = self.bathy_nc.variables['Bathymetry'][:,:] + try: + self.lon = np.asarray(self.bathy_nc.variables['nav_lon']) + self.lat = np.asarray(self.bathy_nc.variables['nav_lat']) + except: + self.lon = np.asarray(self.bathy_nc.variables['lon']) + self.lat = np.asarray(self.bathy_nc.variables['lat']) + # expand lat and lon 1D arrays into 2D array matching nav_lat nav_lon + self.lon = np.tile(self.lon, (np.shape(self.lat)[0], 1)) + self.lat = np.tile(self.lat, (np.shape(self.lon)[1], 1)) + self.lat = np.rot90(self.lat) + + try: + self.bathy_data = self.bathy_nc.variables['Bathymetry'][:,:] + except: + self.bathy_data = self.bathy_nc.variables['deptho'][:,:] try: #check if units exists otherwise unknown. TODO self.data_units = self.bathy_nc.variables['Bathymetry'].units - except AttributeError: - self.data_units = "unknown" + except: + self.data_units = self.bathy_nc.variables['deptho'].units +# except AttributeError: +# self.data_units = "unknown" if self.data is None: - self.data = self.bathy_nc.variables['Bathymetry'] + try: + self.data = self.bathy_nc.variables['Bathymetry'] + except: + self.data = self.bathy_nc.variables['deptho'] self.data = np.asarray(self.data[:, :]) self.data = np.around((self.data + .5).clip(0, 1)) #apply default 1px border diff --git a/pynemo/nemo_bdy_ncpop.py b/pynemo/nemo_bdy_ncpop.py index 45223ab93304e57e0a99f6dda0b55335b903714b..1f55c5dd98fa61ad81ce692a5327eedd06b7cd27 100644 --- a/pynemo/nemo_bdy_ncpop.py +++ b/pynemo/nemo_bdy_ncpop.py @@ -19,7 +19,7 @@ def write_data_to_file(filename, variable_name, data): count = data.shape three_dim_variables = ['votemper', 'vosaline', 'N1p', 'N3n', 'N5s','thetao','so'] - two_dim_variables = ['sossheig', 'vobtcrtx', 'vobtcrty', 'iicethic', 'ileadfra', 'isnowthi'] + two_dim_variables = ['sossheig', 'vobtcrtx', 'vobtcrty', 'iicethic', 'ileadfra', 'isnowthi','zos'] if variable_name in three_dim_variables: if len(count) == 3: diff --git a/pynemo/profile.py b/pynemo/profile.py index 1dc8b28dec46f942fc8e9ccbf9355b1a0d498468..7931c68ef7f547788315390be24bf29559ae121c 100644 --- a/pynemo/profile.py +++ b/pynemo/profile.py @@ -77,12 +77,6 @@ logging.basicConfig(filename='nrct.log', level=logging.INFO) # define a Handler which writes INFO messages or higher to the sys.stderr console = logging.StreamHandler() console.setLevel(logging.INFO) -# set a format which is simpler for console use -formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') -# tell the handler to use this format -console.setFormatter(formatter) -# add the handler to the root logger -logging.getLogger('').addHandler(console) def download_cmems(setup_filepath=0): ''' diff --git a/pynemo_37.yml b/pynemo_37.yml index 8c728403364e79419d2652ffcc22777b375dc8cb..8d24b7fa6bd0fd15d2968f5c1de609c1e0129d2d 100644 --- a/pynemo_37.yml +++ b/pynemo_37.yml @@ -9,9 +9,11 @@ dependencies: - python=3.7.6 - pip=20.0.2 - pandas=1.0.1 + - pytest=5.3.5 - pip: - idna==2.9 - lxml==4.5.0 - pyjnius==1.2.1 - seawater==3.3.4 - thredds-crawler==1.5.4 + - motuclient==1.8.4 \ No newline at end of file diff --git a/unit_tests/namelist_unit_test.bdy b/unit_tests/namelist_unit_test.bdy new file mode 100644 index 0000000000000000000000000000000000000000..48746cf4ec6c186c82b1b5bb34e90e11daaf64cc --- /dev/null +++ b/unit_tests/namelist_unit_test.bdy @@ -0,0 +1,109 @@ +!!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> +!! NEMO/OPA : namelist for BDY generation tool +!! +!! User inputs for generating open boundary conditions +!! employed by the BDY module in NEMO. Boundary data +!! can be set up for v3.2 NEMO and above. +!! +!! More info here..... +!! +!!>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + +!------------------------------------------------------------------------------ +! vertical coordinate +!------------------------------------------------------------------------------ + ln_zco = .false. ! z-coordinate - full steps (T/F) + ln_zps = .true. ! z-coordinate - partial steps (T/F) + ln_sco = .false. ! s- or hybrid z-s-coordinate (T/F) + rn_hmin = -10 ! min depth of the ocean (>0) or + ! min number of ocean level (<0) + +!------------------------------------------------------------------------------ +! s-coordinate or hybrid z-s-coordinate +!------------------------------------------------------------------------------ + rn_sbot_min = 10. ! minimum depth of s-bottom surface (>0) (m) + rn_sbot_max = 7000. ! maximum depth of s-bottom surface + ! (= ocean depth) (>0) (m) + ln_s_sigma = .false. ! hybrid s-sigma coordinates + rn_hc = 150.0 ! critical depth with s-sigma + +!------------------------------------------------------------------------------ +! grid information +!------------------------------------------------------------------------------ + sn_src_hgr = '/Users/thopri/Projects/PyNEMO/inputs/subset_coordinates.nc' + sn_src_zgr = '/Users/thopri/Projects/PyNEMO/inputs/subset_coordinates.nc' + sn_dst_hgr = 'http://opendap4gws.jasmin.ac.uk/thredds/noc_msm/dodsC/pynemo_grid_C/mesh_hgr_zps.nc' + sn_dst_zgr = 'http://opendap4gws.jasmin.ac.uk/thredds/noc_msm/dodsC/pynemo_grid_C/mesh_zgr_zps.nc' + sn_src_msk = '/Users/thopri/Projects/PyNEMO/inputs/subset_bathy.nc' + sn_bathy = 'http://opendap4gws.jasmin.ac.uk/thredds/noc_msm/dodsC/pynemo_grid_C/NNA_R12_bathy_meter_bench.nc' + +!------------------------------------------------------------------------------ +! I/O +!------------------------------------------------------------------------------ + sn_src_dir = '/Users/thopri/Projects/PyNEMO/unit_tests/src_data_unit_tests.ncml' ! src_files/' + sn_dst_dir = '/Users/thopri/Projects/PyNEMO/unit_tests/test_outputs' + sn_fn = 'unit_test' ! prefix for output files + nn_fv = -1e20 ! set fill value for output files + nn_src_time_adj = 0 ! src time adjustment + sn_dst_metainfo = 'Benchmarking Data' + +!------------------------------------------------------------------------------ +! CMEMS Data Source Configuration +!------------------------------------------------------------------------------ + ln_use_cmems = .true. + +!------------------------------------------------------------------------------ +! unstructured open boundaries +!------------------------------------------------------------------------------ + ln_coords_file = .true. ! =T : produce bdy coordinates files + cn_coords_file = 'coordinates.bdy.nc' ! name of bdy coordinates files + ! (if ln_coords_file=.TRUE.) + ln_mask_file = .false. ! =T : read mask from file + cn_mask_file = 'mask.nc' ! name of mask file + ! (if ln_mask_file=.TRUE.) + ln_dyn2d = .false. ! boundary conditions for + ! barotropic fields + ln_dyn3d = .false. ! boundary conditions for + ! baroclinic velocities + ln_tra = .true. ! boundary conditions for T and S + ln_ice = .false. ! ice boundary condition + nn_rimwidth = 9 ! width of the relaxation zone + +!------------------------------------------------------------------------------ +! unstructured open boundaries tidal parameters +!------------------------------------------------------------------------------ + ln_tide = .false. ! =T : produce bdy tidal conditions + sn_tide_model = 'FES' ! Name of tidal model (FES|TPXO) + clname(1) = 'M2' ! constituent name + clname(2) = 'S2' + clname(3) = 'K2' + ln_trans = .true. ! interpolate transport rather than + ! velocities +!------------------------------------------------------------------------------ +! Time information +!------------------------------------------------------------------------------ + nn_year_000 = 2017 ! year start + nn_year_end = 2017 ! year end + nn_month_000 = 01 ! month start (default = 1 is years>1) + nn_month_end = 01 ! month end (default = 12 is years>1) + sn_dst_calendar = 'gregorian' ! output calendar format + nn_base_year = 1960 ! base year for time counter + sn_tide_grid = './src_data/tide/grid_tpxo7.2.nc' + sn_tide_h = './src_data/tide/h_tpxo7.2.nc' + sn_tide_u = './src_data/tide/u_tpxo7.2.nc' + +!------------------------------------------------------------------------------ +! Additional parameters +!------------------------------------------------------------------------------ + nn_wei = 1 ! smoothing filter weights + rn_r0 = 0.041666666 ! decorrelation distance use in gauss + ! smoothing onto dst points. Need to + ! make this a funct. of dlon + sn_history = 'Benchmarking test case' + ! history for netcdf file + ln_nemo3p4 = .true. ! else presume v3.2 or v3.3 + nn_alpha = 0 ! Euler rotation angle + nn_beta = 0 ! Euler rotation angle + nn_gamma = 0 ! Euler rotation angle + rn_mask_max_depth = 100.0 ! Maximum depth to be ignored for the mask + rn_mask_shelfbreak_dist = 20000.0 ! Distance from the shelf break diff --git a/unit_tests/src_data_unit_tests.ncml b/unit_tests/src_data_unit_tests.ncml new file mode 100644 index 0000000000000000000000000000000000000000..2b91153cd46adf38c560f7f129d523d434108cf6 --- /dev/null +++ b/unit_tests/src_data_unit_tests.ncml @@ -0,0 +1,16 @@ +<ns0:netcdf xmlns:ns0="http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2" title="NEMO aggregation"> + <ns0:aggregation type="union"> + <ns0:netcdf> + <ns0:aggregation dimName="time" name="temperature" type="joinExisting"> + <ns0:scan location="file://Users/thopri/Projects/PyNEMO/unit_tests/test_data/" regExp=".*T\.nc$" /> + </ns0:aggregation> + </ns0:netcdf> + <ns0:netcdf> + <ns0:aggregation dimName="time" name="sea_surface_height" type="joinExisting"> + <ns0:scan location="file://Users/thopri/Projects/PyNEMO/unit_tests/test_data/" regExp=".*T\.nc$" /> + </ns0:aggregation> + </ns0:netcdf> + </ns0:aggregation> + <ns0:variable name="thetao" orgName="thetao" /> + <ns0:variable name="zos" orgName="zos" /> +</ns0:netcdf> diff --git a/unit_tests/unit_test.py b/unit_tests/unit_test.py new file mode 100644 index 0000000000000000000000000000000000000000..bbfe4a0f882d26d14fbb6e76b9461345fbbdb0e8 --- /dev/null +++ b/unit_tests/unit_test.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +""" +Set of test functions to test PyNEMO functionality. + +""" +from subprocess import Popen, PIPE +from netCDF4 import Dataset +import numpy as np +import glob +import os + +def test_run(): + stdout, stderr = Popen(['pynemo','-s','unit_tests/namelist_unit_test.bdy'], stdout=PIPE, stderr=PIPE, + universal_newlines=True).communicate() + assert 'Execution Time' in stdout + +def test_temp(): + test_files = glob.glob('unit_tests/test_outputs/unit_test*') + for t in test_files: + results = Dataset(t) # open results + temp = results['thetao'][:] + results.close() + temp_ = np.ma.masked_array(temp,temp == -32767.0) + assert abs(temp_[temp_!=0.0].mean() - 15) <= 0.001 + assert abs(temp_[temp_ != 0.0].max() - 15) <= 0.001 + assert abs(temp_[temp_ != 0.0].min() - 15) <= 0.001 + +#def test_salinty(): +# test_files = glob.glob('unit_tests/test_outputs/unit_test*') +# for t in test_files: +# results = Dataset(t) # open results +# sal = results['so'][:] +# results.close() +# sal_ = np.ma.masked_array(sal,sal == -32767.0) +# assert abs(sal_[sal_!=0.0].mean() - 35) <= 0.001 +# assert abs(sal_[sal_ != 0.0].max() - 35) <= 0.001 +# assert abs(sal_[sal_ != 0.0].min() - 35) <= 0.001 + +def test_rm_output(): + files = glob.glob('unit_tests/test_outputs/*') + for f in files: + os.remove(f) + files = glob.glob('unit_tests/test_outputs/*') + assert len(files) == 0 +