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)