def test_verify_AOTIM5_2018(self, parameters): #-- model parameters for AOTIM-5-2018 modelpath = os.path.join(filepath, 'Arc5km2018') grid_file = os.path.join(modelpath, parameters['grid']) model_file = os.path.join(modelpath, parameters['model']) TYPE = parameters['type'] GRID = 'OTIS' EPSG = 'PSNorth' #-- open Arctic Tidal Current Atlas list of records with open(os.path.join(filepath, 'List_of_records.txt'), 'r') as f: file_contents = f.read().splitlines() #-- skip 2 header rows count = 2 #-- iterate over number of stations arctic_stations = len(file_contents) - count stations = [None] * arctic_stations shortname = [None] * arctic_stations station_lon = np.zeros((arctic_stations)) station_lat = np.zeros((arctic_stations)) for s in range(arctic_stations): line_contents = file_contents[count + s].split() stations[s] = line_contents[1] shortname[s] = line_contents[2] station_lat[s] = np.float64(line_contents[10]) station_lon[s] = np.float64(line_contents[11]) #-- calculate daily results for a time period #-- convert time to days since 1992-01-01T00:00:00 tide_time = np.arange( pyTMD.time.convert_calendar_dates(2000, 1, 1), pyTMD.time.convert_calendar_dates(2000, 12, 31) + 1) #-- serial dates for matlab program (days since 0000-01-01T00:00:00) SDtime = np.arange(convert_calendar_serial(2000, 1, 1), convert_calendar_serial(2000, 12, 31) + 1) #-- presently not converting times to dynamic times for model comparisons deltat = np.zeros_like(tide_time) #-- number of days ndays = len(tide_time) #-- extract amplitude and phase from tide model amp, ph, D, c = pyTMD.read_tide_model.extract_tidal_constants( station_lon, station_lat, grid_file, model_file, EPSG, TYPE=TYPE, METHOD='spline', GRID=GRID) #-- calculate complex phase in radians for Euler's cph = -1j * ph * np.pi / 180.0 #-- will verify differences between model outputs are within tolerance eps = np.finfo(np.float16).eps #-- compare daily outputs at each station point invalid_list = ['KS14'] #-- remove coastal stations from the list valid_stations = [ i for i, s in enumerate(shortname) if s not in invalid_list ] #-- compute validation data from Matlab TMD program using octave #-- https://github.com/EarthAndSpaceResearch/TMD_Matlab_Toolbox_v2.5 TMDpath = os.path.join(filepath, '..', 'TMD_Matlab_Toolbox', 'TMD') octave.addpath(octave.genpath(os.path.normpath(TMDpath))) octave.addpath(filepath) octave.addpath(modelpath) #-- turn off octave warnings octave.warning('off', 'all') #-- input control file for model CFname = os.path.join(filepath, 'Model_Arc5km2018') assert os.access(CFname, os.F_OK) #-- run Matlab TMD program with octave #-- MODE: OB time series validation, _ = octave.tmd_tide_pred_plus(CFname, SDtime, station_lat[valid_stations], station_lon[valid_stations], TYPE, nout=2) #-- for each valid station for i, s in enumerate(valid_stations): #-- calculate constituent oscillation for station hc = amp[s, None, :] * np.exp(cph[s, None, :]) #-- allocate for out tides at point tide = np.ma.zeros((ndays)) tide.mask = np.zeros((ndays), dtype=bool) #-- predict tidal elevations at time and infer minor corrections tide.mask[:] = np.any(hc.mask) tide.data[:] = pyTMD.predict_tidal_ts(tide_time, hc, c, DELTAT=deltat, CORRECTIONS=GRID) minor = pyTMD.infer_minor_corrections(tide_time, hc, c, DELTAT=deltat, CORRECTIONS=GRID) tide.data[:] += minor.data[:] #-- calculate differences between matlab and python version difference = np.ma.zeros((ndays)) difference.data[:] = tide.data - validation[:, i] difference.mask = (tide.mask | np.isnan(validation[:, i])) difference.data[difference.mask] = 0.0 if not np.all(difference.mask): assert np.all(np.abs(difference) < eps)
def test_verify_CATS2008(self, parameters): #-- model parameters for CATS2008 modelpath = os.path.join(filepath, 'CATS2008') grid_file = os.path.join(modelpath, parameters['grid']) model_file = os.path.join(modelpath, parameters['model']) TYPE = parameters['type'] GRID = 'OTIS' EPSG = 'CATS2008' #-- open Antarctic Tide Gauge (AntTG) database with open(os.path.join(filepath, 'AntTG_ocean_height_v1.txt'), 'r') as f: file_contents = f.read().splitlines() #-- counts the number of lines in the header count = 0 HEADER = True #-- Reading over header text while HEADER: #-- check if file line at count starts with matlab comment string HEADER = file_contents[count].startswith('%') #-- add 1 to counter count += 1 #-- rewind 1 line count -= 1 #-- iterate over number of stations antarctic_stations = (len(file_contents) - count) // 10 stations = [None] * antarctic_stations shortname = [None] * antarctic_stations station_type = [None] * antarctic_stations station_lon = np.zeros((antarctic_stations)) station_lat = np.zeros((antarctic_stations)) for s in range(antarctic_stations): i = count + s * 10 stations[s] = file_contents[i + 1].strip() shortname[s] = file_contents[i + 3].strip() lat, lon, _, _ = file_contents[i + 4].split() station_type[s] = file_contents[i + 6].strip() station_lon[s] = np.float64(lon) station_lat[s] = np.float64(lat) #-- calculate daily results for a time period #-- convert time to days since 1992-01-01T00:00:00 tide_time = np.arange( pyTMD.time.convert_calendar_dates(2000, 1, 1), pyTMD.time.convert_calendar_dates(2000, 12, 31) + 1) #-- serial dates for matlab program (days since 0000-01-01T00:00:00) SDtime = np.arange(convert_calendar_serial(2000, 1, 1), convert_calendar_serial(2000, 12, 31) + 1) #-- presently not converting times to dynamic times for model comparisons deltat = np.zeros_like(tide_time) #-- number of days ndays = len(tide_time) #-- extract amplitude and phase from tide model amp, ph, D, c = pyTMD.read_tide_model.extract_tidal_constants( station_lon, station_lat, grid_file, model_file, EPSG, TYPE=TYPE, METHOD='spline', GRID=GRID) #-- calculate complex phase in radians for Euler's cph = -1j * ph * np.pi / 180.0 #-- will verify differences between model outputs are within tolerance eps = np.finfo(np.float16).eps #-- compare daily outputs at each station point invalid_list = [ 'Ablation Lake', 'Amery', 'Bahia Esperanza', 'Beaver Lake', 'Cape Roberts', 'Casey', 'Doake Ice Rumples', 'EE4A', 'EE4B', 'Eklund Islands', 'Gerlache C', 'Groussac', 'Gurrachaga', 'Half Moon Is.', 'Heard Island', 'Hobbs Pool', 'Mawson', 'McMurdo', 'Mikkelsen', 'Palmer', 'Primavera', 'Rutford GL', 'Rutford GPS', 'Rothera', 'Scott Base', 'Seymour Is', 'Terra Nova Bay' ] #-- remove coastal stations from the list valid_stations = [ i for i, s in enumerate(shortname) if s not in invalid_list ] #-- compute validation data from Matlab TMD program using octave #-- https://github.com/EarthAndSpaceResearch/TMD_Matlab_Toolbox_v2.5 TMDpath = os.path.join(filepath, '..', 'TMD_Matlab_Toolbox', 'TMD') octave.addpath(octave.genpath(os.path.normpath(TMDpath))) octave.addpath(filepath) octave.addpath(modelpath) #-- turn off octave warnings octave.warning('off', 'all') #-- input control file for model CFname = os.path.join(filepath, 'Model_CATS2008') assert os.access(CFname, os.F_OK) #-- run Matlab TMD program with octave #-- MODE: OB time series validation, _ = octave.tmd_tide_pred_plus(CFname, SDtime, station_lat[valid_stations], station_lon[valid_stations], TYPE, nout=2) #-- for each valid station for i, s in enumerate(valid_stations): #-- calculate constituent oscillation for station hc = amp[s, None, :] * np.exp(cph[s, None, :]) #-- allocate for out tides at point tide = np.ma.zeros((ndays)) tide.mask = np.zeros((ndays), dtype=bool) #-- predict tidal elevations at time and infer minor corrections tide.mask[:] = np.any(hc.mask) tide.data[:] = pyTMD.predict_tidal_ts(tide_time, hc, c, DELTAT=deltat, CORRECTIONS=GRID) minor = pyTMD.infer_minor_corrections(tide_time, hc, c, DELTAT=deltat, CORRECTIONS=GRID) tide.data[:] += minor.data[:] #-- calculate differences between matlab and python version difference = np.ma.zeros((ndays)) difference.data[:] = tide.data - validation[:, i] difference.mask = (tide.mask | np.isnan(validation[:, i])) difference.data[difference.mask] = 0.0 if not np.all(difference.mask): assert np.all(np.abs(difference) < eps)